From b1171ed4eb6d7d1c80e92a49a5ddff0d8559924c Mon Sep 17 00:00:00 2001 From: Bronwen Date: Sat, 28 Jan 2023 13:03:13 -0500 Subject: [PATCH] selection ui exclusivity --- .../xyz/valnet/engine/graphics/IModalUI.java | 12 ++++ .../hadean/gameobjects/SelectionUI.java | 67 ++++++++++++++++--- .../gameobjects/ui/ExclusivityManager.java | 7 +- .../hadean/gameobjects/ui/tabs/Tab.java | 13 ++-- 4 files changed, 81 insertions(+), 18 deletions(-) create mode 100644 src/main/java/xyz/valnet/engine/graphics/IModalUI.java diff --git a/src/main/java/xyz/valnet/engine/graphics/IModalUI.java b/src/main/java/xyz/valnet/engine/graphics/IModalUI.java new file mode 100644 index 0000000..7e10260 --- /dev/null +++ b/src/main/java/xyz/valnet/engine/graphics/IModalUI.java @@ -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(); + } +} diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/SelectionUI.java b/src/main/java/xyz/valnet/hadean/gameobjects/SelectionUI.java index 90673b1..df20883 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/SelectionUI.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/SelectionUI.java @@ -6,16 +6,20 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import xyz.valnet.engine.graphics.IModalUI; import xyz.valnet.engine.graphics.ImmediateUI; import xyz.valnet.engine.scenegraph.ITransient; 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.ISelectionChangeListener; import xyz.valnet.hadean.util.Action; import xyz.valnet.hadean.util.Layers; 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, List> {} @@ -30,7 +34,11 @@ public class SelectionUI extends ImmediateUI implements ISelectionChangeListener private final int width = 300, height = 200; 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 // a button has been pressed to update the selection. @@ -47,19 +55,34 @@ public class SelectionUI extends ImmediateUI implements ISelectionChangeListener @Override public void update(float dTime) { + openness = lerp(openness, opened ? 1 : 0, dTime / 20); if(newSelection != null) { selectionManager.updateSelection(newSelection); newSelection = null; } + if(!opened && openness < 0.0001f && selected.size() > 0) { + resetCache(); + } + } + + private void resetCache() { + selected = new ArrayList(); + selectedByType.clear(); + selectedCount = selected.size(); + actions.clear(); } @Override public void selectionChanged(List newSelection) { + if(newSelection.size() == 0) { + close(); + return; + } + + resetCache(); selected = newSelection; - selectedByType.clear(); - selectedCount = newSelection.size(); - actions.clear(); + selectedCount = selected.size(); for(ISelectable selectable : newSelection) { Class clazz = selectable.getClass(); @@ -70,13 +93,14 @@ public class SelectionUI extends ImmediateUI implements ISelectionChangeListener actions.add(action); } - if(!selectedByType.containsKey(clazz)) { selectedByType.put(clazz, new ArrayList()); } selectedByType.get(clazz).add(selectable); } + + open(); } @Override @@ -84,11 +108,17 @@ public class SelectionUI extends ImmediateUI implements ISelectionChangeListener return Layers.GENERAL_UI; } + private int animate(int a, int b) { + System.out.println(openness); + return (int) Math.round(lerp(a, b, openness)); + } + @Override 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(selectedCount == 1) { 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); + } } diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/ui/ExclusivityManager.java b/src/main/java/xyz/valnet/hadean/gameobjects/ui/ExclusivityManager.java index 677488a..6500ba8 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/ui/ExclusivityManager.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/ui/ExclusivityManager.java @@ -1,5 +1,6 @@ package xyz.valnet.hadean.gameobjects.ui; +import xyz.valnet.engine.graphics.IModalUI; import xyz.valnet.engine.scenegraph.GameObject; import xyz.valnet.engine.scenegraph.ITransient; 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; public class ExclusivityManager extends GameObject implements ITransient { - private Tab current = null; + private IModalUI current = null; 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 == null) { closeCurrent(); diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/Tab.java b/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/Tab.java index 2c6f1e5..750f5fe 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/Tab.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/Tab.java @@ -1,7 +1,8 @@ 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.scenegraph.ITransient; 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.util.Layers; -public abstract class Tab extends ImmediateUI implements IBottomBarItem, ITransient { +public abstract class Tab extends ImmediateUI implements IBottomBarItem, ITransient, IModalUI { private BottomBar bottombar; @@ -49,7 +50,7 @@ public abstract class Tab extends ImmediateUI implements IBottomBarItem, ITransi } 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 @@ -58,6 +59,7 @@ public abstract class Tab extends ImmediateUI implements IBottomBarItem, ITransi else open(); } + @Override public final void open() { if(opened) return; opened = true; @@ -65,6 +67,7 @@ public abstract class Tab extends ImmediateUI implements IBottomBarItem, ITransi onOpen(); } + @Override public final void close() { if(!opened) return; opened = false; @@ -72,10 +75,6 @@ public abstract class Tab extends ImmediateUI implements IBottomBarItem, ITransi onClose(); } - public void back() { - close(); - } - protected abstract void onClose(); protected abstract void onOpen(); }