All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tripleplay.ui.Selector Maven / Gradle / Ivy

There is a newer version: 2.0.8
Show newest version
//
// Triple Play - utilities for use in PlayN-based games
// Copyright (c) 2011-2014, Three Rings Design, Inc. - All rights reserved.
// http://github.com/threerings/tripleplay/blob/master/LICENSE

package tripleplay.ui;

import react.Slot;
import react.Value;
import react.ValueView;

/**
 * Maintains a single selected item among a specified set of {@code Element} instances. The
 * elements may be added individually, or the children of an {@code Elements} may be tracked
 * automatically.
 *
 * 

A click on a tracked element that implements {@code Clickable} makes it the selected item, or * {@code selected} can be used to manually control the selected item.

*/ public class Selector { /** The selected item. May be updated to set the selection manually. */ public final Value> selected = Value.create(null); /** Create a selector with a null initial selection. */ public Selector () { selected.connect(new ValueView.Listener> () { @Override public void onChange (Element selected, Element deselected) { if (deselected != null) get(deselected).update(false); if (selected != null) get(selected).update(true); } }); } /** Creates a selector containing the children of elements with initialSelection selected. */ public Selector (Elements elements, Element initialSelection) { this(); add(elements); if (initialSelection instanceof Togglable) { selected.update(initialSelection); } } /** * Tracks the children of {@code elements} for setting the selection. Children subsequently * added or removed from {@code elements} are automatically handled appropriately. */ public Selector add (Elements elements) { for (Element child : elements) { _addSlot.onEmit(child); } elements.childAdded().connect(_addSlot); elements.childRemoved().connect(_removeSlot); return this; } /** Prevent a deselection (null {@link #selected}.get()) occurring as a result of toggling * the currently selected button off. */ public Selector preventDeselection () { _preventDeselection = true; return this; } /** * Stops tracking the children of {@code elements} for setting the selection. */ public Selector remove (Elements elements) { for (Element child : elements) { _removeSlot.onEmit(child); } elements.childAdded().disconnect(_addSlot); elements.childRemoved().disconnect(_removeSlot); return this; } /** * Tracks one or more elements. */ public Selector add (Element elem, Element... more) { _addSlot.onEmit(elem); for (Element e : more) { _addSlot.onEmit(e); } return this; } /** * Stops tracking one or more elements. */ public Selector remove (Element elem, Element... more) { _removeSlot.onEmit(elem); for (Element e : more) { _removeSlot.onEmit(e); } return this; } /** * Internal method to get the selection value of an element (non-null). */ protected Value get (Element elem) { return ((Togglable)elem).selected(); } protected final Slot> _addSlot = new Slot>() { @Override public void onEmit (Element child) { if (child instanceof Togglable) { ((Togglable)child).clicked().connect(_clickSlot); } } }; protected final Slot> _removeSlot = new Slot>() { @Override public void onEmit (Element removed) { if (removed instanceof Togglable) { ((Togglable)removed).clicked().disconnect(_clickSlot); } if (selected.get() == removed) selected.update(null); } }; protected final Slot> _clickSlot = new Slot>() { @Override public void onEmit (Element clicked) { final Value sel = get(clicked); if (_preventDeselection) { if (!sel.get()) { sel.update(true); return; } } selected.update(sel.get() ? clicked : null); } }; protected boolean _preventDeselection; }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy