diff --git a/src/heronarts/p3lx/ui/component/UIItemList.java b/src/heronarts/p3lx/ui/component/UIItemList.java index e2036f9..930d4d4 100644 --- a/src/heronarts/p3lx/ui/component/UIItemList.java +++ b/src/heronarts/p3lx/ui/component/UIItemList.java @@ -45,6 +45,12 @@ */ public interface UIItemList { + public interface Listener { + public void onItemFocused(Item item); + public void onItemActivated(Item item); + public void onItemDeactivated(Item item); + } + /** * Interface to which items in the list must conform */ @@ -189,7 +195,9 @@ public static class Impl { private final UI2dContainer list; - private List items = new CopyOnWriteArrayList(); + private final List items = new CopyOnWriteArrayList(); + + private final List listeners = new ArrayList(); private int focusIndex = -1; @@ -224,6 +232,14 @@ private Impl(UI ui, UI2dContainer list) { list.setBorderRounding(4); } + private void addListener(Listener listener) { + this.listeners.add(listener); + } + + private void removeListener(Listener listener) { + this.listeners.remove(listener); + } + private void focusNext(int increment) { int index = this.focusIndex + increment; while (index >= 0 && index < this.items.size()) { @@ -254,12 +270,20 @@ private void setFocusIndex(int focusIndex, boolean scroll) { } this.focusIndex = focusIndex; if (this.focusIndex >= 0) { - this.items.get(this.focusIndex).onFocus(); + Item item = this.items.get(this.focusIndex); + item.onFocus(); + for (Listener listener : this.listeners) { + listener.onItemFocused(item); + } } this.list.redraw(); } } + private int getFocusedIndex() { + return this.focusIndex; + } + /** * Retrieves the currently focused item in the list. * @@ -327,7 +351,11 @@ private void removeItem(Item item) { if (this.focusIndex >= this.items.size()) { setFocusIndex(items.size() - 1); } else if (this.focusIndex >= 0) { - this.items.get(this.focusIndex).onFocus(); + Item focusItem = this.items.get(this.focusIndex); + focusItem.onFocus(); + for (Listener listener : this.listeners) { + listener.onItemFocused(focusItem); + } } recomputeContentHeight(); this.list.redraw(); @@ -345,7 +373,11 @@ private void setItems(List items) { if (this.focusIndex >= items.size()) { setFocusIndex(items.size() - 1); } else if (this.focusIndex >= 0) { - this.items.get(this.focusIndex).onFocus(); + Item item = this.items.get(this.focusIndex); + item.onFocus(); + for (Listener listener : this.listeners) { + listener.onItemFocused(item); + } } setContentHeight(ROW_SPACING * items.size() + ROW_MARGIN); this.list.redraw(); @@ -389,6 +421,9 @@ private void activate() { this.list.redraw(); } else { item.onActivate(); + for (Listener listener : this.listeners) { + listener.onItemActivated(item); + } } } } @@ -632,7 +667,11 @@ private void onMouseDragged(MouseEvent mouseEvent, float mx, float my, float dx, private void onMouseReleased(MouseEvent mouseEvent, float mx, float my) { this.dragging = false; if (this.mouseActivate >= 0 && this.mouseActivate < this.items.size()) { - this.items.get(this.mouseActivate).onDeactivate(); + Item item = this.items.get(this.mouseActivate); + item.onDeactivate(); + for (Listener listener : this.listeners) { + listener.onItemDeactivated(item); + } } this.mouseActivate = -1; } @@ -743,7 +782,11 @@ private boolean onKeyReleased(KeyEvent keyEvent, char keyChar, int keyCode) { if (this.isMomentary) { if (this.keyActivate >= 0 && this.keyActivate < this.items.size()) { consume = true; - this.items.get(this.keyActivate).onDeactivate(); + Item item = this.items.get(this.keyActivate); + item.onDeactivate(); + for (Listener listener : this.listeners) { + listener.onItemDeactivated(item); + } } this.keyActivate = -1; } @@ -773,6 +816,10 @@ public UIItemList setFocusIndex(int focusIndex) { return this; } + public int getFocusedIndex() { + return this.impl.getFocusedIndex(); + } + public UIItemList.Item getFocusedItem() { return this.impl.getFocusedItem(); } @@ -832,6 +879,18 @@ public UIItemList setControlSurfaceFocus(int index, int length) { return this; } + @Override + public UIItemList addListener(Listener listener) { + this.impl.addListener(listener); + return this; + } + + @Override + public UIItemList removeListener(Listener listener) { + this.impl.removeListener(listener); + return this; + } + @Override public void drawFocus(UI ui, PGraphics pg) { this.impl.drawFocus(ui, pg); @@ -905,6 +964,10 @@ public UIItemList setFocusIndex(int focusIndex) { return this; } + public int getFocusedIndex() { + return this.impl.getFocusedIndex(); + } + public UIItemList.Item getFocusedItem() { return this.impl.getFocusedItem(); } @@ -963,6 +1026,18 @@ public UIItemList setControlSurfaceFocus(int index, int length) { return this; } + @Override + public UIItemList addListener(Listener listener) { + this.impl.addListener(listener); + return this; + } + + @Override + public UIItemList removeListener(Listener listener) { + this.impl.removeListener(listener); + return this; + } + @Override public void drawFocus(UI ui, PGraphics pg) { this.impl.drawFocus(ui, pg); @@ -1030,6 +1105,13 @@ public void onFocus() { */ public UIItemList setFocusIndex(int focusIndex); + /** + * Returns the index of the currently focused item in the list + * + * @return Index of focused item + */ + public int getFocusedIndex(); + /** * Retrieves the currently focused item in the list. * @@ -1121,4 +1203,20 @@ public void onFocus() { */ public UIItemList setControlSurfaceFocus(int index, int length); + /** + * Adds a listener to receive notifications about list operations + * + * @param listener Listener + * @return this + */ + public UIItemList addListener(Listener listener); + + /** + * Removes a listener from receiving notifications about list operations + * + * @param listener Listener + * @return this + */ + public UIItemList removeListener(Listener listener); + }