selection ui exclusivity

bottom-bar
Bronwen 2023-01-28 13:03:13 -05:00
parent 91c3e87c6e
commit b1171ed4eb
4 changed files with 81 additions and 18 deletions

View File

@ -0,0 +1,12 @@
package xyz.valnet.engine.graphics;
// TODO there is some shared logic for these in tabs & selection ui.
// combine them into a base class, probably extending immediateUI...
public interface IModalUI {
public void open();
public void close();
public default void back() {
close();
}
}

View File

@ -6,16 +6,20 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import xyz.valnet.engine.graphics.IModalUI;
import xyz.valnet.engine.graphics.ImmediateUI; import xyz.valnet.engine.graphics.ImmediateUI;
import xyz.valnet.engine.scenegraph.ITransient; import xyz.valnet.engine.scenegraph.ITransient;
import xyz.valnet.hadean.gameobjects.inputlayer.SelectionLayer; import xyz.valnet.hadean.gameobjects.inputlayer.SelectionLayer;
import xyz.valnet.hadean.gameobjects.ui.ExclusivityManager;
import xyz.valnet.hadean.interfaces.ISelectable; import xyz.valnet.hadean.interfaces.ISelectable;
import xyz.valnet.hadean.interfaces.ISelectionChangeListener; import xyz.valnet.hadean.interfaces.ISelectionChangeListener;
import xyz.valnet.hadean.util.Action; import xyz.valnet.hadean.util.Action;
import xyz.valnet.hadean.util.Layers; import xyz.valnet.hadean.util.Layers;
import xyz.valnet.hadean.util.detail.Detail; import xyz.valnet.hadean.util.detail.Detail;
public class SelectionUI extends ImmediateUI implements ISelectionChangeListener, ITransient { import static xyz.valnet.engine.util.Math.lerp;
public class SelectionUI extends ImmediateUI implements ISelectionChangeListener, ITransient, IModalUI {
private class SelectedByType extends HashMap<Class<? extends ISelectable>, List<ISelectable>> {} private class SelectedByType extends HashMap<Class<? extends ISelectable>, List<ISelectable>> {}
@ -30,7 +34,11 @@ public class SelectionUI extends ImmediateUI implements ISelectionChangeListener
private final int width = 300, height = 200; private final int width = 300, height = 200;
private final int padding = 10; private final int padding = 10;
private final int actionButtonSize = 100;
private boolean opened = false;
private float openness = 0f;
private ExclusivityManager exclusivityManager;
// this will be null normally, but set if // this will be null normally, but set if
// a button has been pressed to update the selection. // a button has been pressed to update the selection.
@ -47,19 +55,34 @@ public class SelectionUI extends ImmediateUI implements ISelectionChangeListener
@Override @Override
public void update(float dTime) { public void update(float dTime) {
openness = lerp(openness, opened ? 1 : 0, dTime / 20);
if(newSelection != null) { if(newSelection != null) {
selectionManager.updateSelection(newSelection); selectionManager.updateSelection(newSelection);
newSelection = null; newSelection = null;
} }
if(!opened && openness < 0.0001f && selected.size() > 0) {
resetCache();
}
}
private void resetCache() {
selected = new ArrayList<ISelectable>();
selectedByType.clear();
selectedCount = selected.size();
actions.clear();
} }
@Override @Override
public void selectionChanged(List<ISelectable> newSelection) { public void selectionChanged(List<ISelectable> newSelection) {
if(newSelection.size() == 0) {
close();
return;
}
resetCache();
selected = newSelection; selected = newSelection;
selectedByType.clear(); selectedCount = selected.size();
selectedCount = newSelection.size();
actions.clear();
for(ISelectable selectable : newSelection) { for(ISelectable selectable : newSelection) {
Class<? extends ISelectable> clazz = selectable.getClass(); Class<? extends ISelectable> clazz = selectable.getClass();
@ -70,13 +93,14 @@ public class SelectionUI extends ImmediateUI implements ISelectionChangeListener
actions.add(action); actions.add(action);
} }
if(!selectedByType.containsKey(clazz)) { if(!selectedByType.containsKey(clazz)) {
selectedByType.put(clazz, new ArrayList<ISelectable>()); selectedByType.put(clazz, new ArrayList<ISelectable>());
} }
selectedByType.get(clazz).add(selectable); selectedByType.get(clazz).add(selectable);
} }
open();
} }
@Override @Override
@ -84,11 +108,17 @@ public class SelectionUI extends ImmediateUI implements ISelectionChangeListener
return Layers.GENERAL_UI; return Layers.GENERAL_UI;
} }
private int animate(int a, int b) {
System.out.println(openness);
return (int) Math.round(lerp(a, b, openness));
}
@Override @Override
protected void gui() { protected void gui() {
if(selected.isEmpty()) return; // if(selected.isEmpty()) return;
if(!opened && openness <= 0.0001f) return;
window(padding, 576 - padding - height - BottomBar.bottomBarHeight, width, height, () -> { window(animate(-width - 50, padding), 576 - padding - height - BottomBar.bottomBarHeight, width, height, () -> {
if(selectedByType.size() == 1) { if(selectedByType.size() == 1) {
if(selectedCount == 1) { if(selectedCount == 1) {
text(properName); text(properName);
@ -137,4 +167,25 @@ public class SelectionUI extends ImmediateUI implements ISelectionChangeListener
} }
} }
@Override
public void open() {
if(opened) return;
opened = true;
exclusivityManager.switchTo(this);
}
@Override
public void close() {
if(!opened) return;
opened = false;
exclusivityManager.closeCurrent();
selectionManager.clearSelection();
}
@Override
protected void connect() {
super.connect();
exclusivityManager = get(ExclusivityManager.class);
}
} }

View File

@ -1,5 +1,6 @@
package xyz.valnet.hadean.gameobjects.ui; package xyz.valnet.hadean.gameobjects.ui;
import xyz.valnet.engine.graphics.IModalUI;
import xyz.valnet.engine.scenegraph.GameObject; import xyz.valnet.engine.scenegraph.GameObject;
import xyz.valnet.engine.scenegraph.ITransient; import xyz.valnet.engine.scenegraph.ITransient;
import xyz.valnet.hadean.gameobjects.ui.tabs.BuildTab; import xyz.valnet.hadean.gameobjects.ui.tabs.BuildTab;
@ -7,13 +8,13 @@ import xyz.valnet.hadean.gameobjects.ui.tabs.Tab;
import xyz.valnet.hadean.util.Assets; import xyz.valnet.hadean.util.Assets;
public class ExclusivityManager extends GameObject implements ITransient { public class ExclusivityManager extends GameObject implements ITransient {
private Tab current = null; private IModalUI current = null;
private boolean switching = false; private boolean switching = false;
private Tab defaultTab = null; private IModalUI defaultTab = null;
public void switchTo(Tab tab) { public void switchTo(IModalUI tab) {
if(tab == current) return; if(tab == current) return;
if(tab == null) { if(tab == null) {
closeCurrent(); closeCurrent();

View File

@ -1,7 +1,8 @@
package xyz.valnet.hadean.gameobjects.ui.tabs; package xyz.valnet.hadean.gameobjects.ui.tabs;
import static xyz.valnet.engine.util.Math.*; import static xyz.valnet.engine.util.Math.lerp;
import xyz.valnet.engine.graphics.IModalUI;
import xyz.valnet.engine.graphics.ImmediateUI; import xyz.valnet.engine.graphics.ImmediateUI;
import xyz.valnet.engine.scenegraph.ITransient; import xyz.valnet.engine.scenegraph.ITransient;
import xyz.valnet.hadean.gameobjects.BottomBar; import xyz.valnet.hadean.gameobjects.BottomBar;
@ -9,7 +10,7 @@ import xyz.valnet.hadean.gameobjects.ui.ExclusivityManager;
import xyz.valnet.hadean.interfaces.IBottomBarItem; import xyz.valnet.hadean.interfaces.IBottomBarItem;
import xyz.valnet.hadean.util.Layers; import xyz.valnet.hadean.util.Layers;
public abstract class Tab extends ImmediateUI implements IBottomBarItem, ITransient { public abstract class Tab extends ImmediateUI implements IBottomBarItem, ITransient, IModalUI {
private BottomBar bottombar; private BottomBar bottombar;
@ -49,7 +50,7 @@ public abstract class Tab extends ImmediateUI implements IBottomBarItem, ITransi
} }
protected final int animate(float a, float b) { protected final int animate(float a, float b) {
return (int)Math.round(lerp(a, b, animation)); return (int) Math.round(lerp(a, b, animation));
} }
@Override @Override
@ -58,6 +59,7 @@ public abstract class Tab extends ImmediateUI implements IBottomBarItem, ITransi
else open(); else open();
} }
@Override
public final void open() { public final void open() {
if(opened) return; if(opened) return;
opened = true; opened = true;
@ -65,6 +67,7 @@ public abstract class Tab extends ImmediateUI implements IBottomBarItem, ITransi
onOpen(); onOpen();
} }
@Override
public final void close() { public final void close() {
if(!opened) return; if(!opened) return;
opened = false; opened = false;
@ -72,10 +75,6 @@ public abstract class Tab extends ImmediateUI implements IBottomBarItem, ITransi
onClose(); onClose();
} }
public void back() {
close();
}
protected abstract void onClose(); protected abstract void onClose();
protected abstract void onOpen(); protected abstract void onOpen();
} }