selection ui exclusivity
parent
91c3e87c6e
commit
b1171ed4eb
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue