Lior Vernia has uploaded a new change for review. Change subject: webadmin: Added ValueSuggestBox widget ......................................................................
webadmin: Added ValueSuggestBox widget This is a widget based on SuggestBox, that can hold values of an arbitrary type and not just String. To achieve this, the constructor is passed both a Renderer to convert the object to string, and a newly-defined ObjectForStringFactory to create an object from an arbitrary user-typed string. Change-Id: I07d419d0eb83e189b6bf6138c6e4b2b6953a2012 Signed-off-by: Lior Vernia <[email protected]> --- A frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/utils/ObjectForStringFactory.java A frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/ValueSuggestBox.java 2 files changed, 161 insertions(+), 0 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/29/12529/1 diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/utils/ObjectForStringFactory.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/utils/ObjectForStringFactory.java new file mode 100644 index 0000000..6dfefb0 --- /dev/null +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/utils/ObjectForStringFactory.java @@ -0,0 +1,13 @@ +package org.ovirt.engine.ui.common.utils; + +/** + * An interface for instantiating objects according to a passed String. + * + * @param <T> + * the object type. + */ +public interface ObjectForStringFactory<T> { + + T getObjectForString(String string); + +} diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/ValueSuggestBox.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/ValueSuggestBox.java new file mode 100644 index 0000000..eb20b55 --- /dev/null +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/ValueSuggestBox.java @@ -0,0 +1,148 @@ +package org.ovirt.engine.ui.common.widget; + +import com.google.gwt.editor.client.IsEditor; +import com.google.gwt.editor.client.adapters.TakesValueEditor; +import com.google.gwt.event.dom.client.FocusEvent; +import com.google.gwt.event.dom.client.FocusHandler; +import com.google.gwt.event.logical.shared.SelectionEvent; +import com.google.gwt.event.logical.shared.SelectionHandler; +import com.google.gwt.event.logical.shared.ValueChangeEvent; +import com.google.gwt.event.logical.shared.ValueChangeHandler; +import com.google.gwt.event.shared.HandlerRegistration; +import com.google.gwt.text.shared.Renderer; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.HasConstrainedValue; +import com.google.gwt.user.client.ui.MultiWordSuggestOracle; +import com.google.gwt.user.client.ui.SuggestBox; +import com.google.gwt.user.client.ui.SuggestOracle.Suggestion; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.ovirt.engine.ui.common.utils.ObjectForStringFactory; + +/** + * A {@link SuggestBox} that can handle value types other than String. + * <p> + * A {@link Renderer Renderer<T>} is used to get user-presentable strings to display in the select element. + * <p> + * A {@link ObjectForStringFactory ObjectForStringFactory<T>} is used to instantiate new values corresponding to + * arbitrary user-typed strings. + * + * @param <T> + * the value type + */ +public class ValueSuggestBox<T> extends Composite implements + HasConstrainedValue<T>, IsEditor<TakesValueEditor<T>> { + + private final Map<String, T> stringToValue = new HashMap<String, T>(); + private final Renderer<T> renderer; + private final ObjectForStringFactory<T> factory; + private final boolean suggestWhenEmpty; + + private TakesValueEditor<T> editor; + private T value; + private MultiWordSuggestOracle suggestOracle = new MultiWordSuggestOracle(); + + public ValueSuggestBox(Renderer<T> renderer, ObjectForStringFactory<T> factory) { + + this(renderer, factory, false); + } + + public ValueSuggestBox(Renderer<T> renderer, ObjectForStringFactory<T> factory, boolean suggestWhenEmpty) { + + this.renderer = renderer; + this.factory = factory; + this.suggestWhenEmpty = suggestWhenEmpty; + + final SuggestBox suggestBox = new SuggestBox(suggestOracle); + initWidget(suggestBox); + + suggestBox.addValueChangeHandler(new ValueChangeHandler<String>() { + public void onValueChange(ValueChangeEvent<String> event) { + String currentText = suggestBox.getValue(); + + if (stringToValue.containsKey(currentText)) { + setValue(stringToValue.get(currentText), true); + } else { + setValue(ValueSuggestBox.this.factory.getObjectForString(currentText), true); + } + } + }); + + suggestBox.addSelectionHandler(new SelectionHandler<Suggestion>() { + public void onSelection(SelectionEvent<Suggestion> event) { + ValueChangeEvent.fire(ValueSuggestBox.this, + stringToValue.get(event.getSelectedItem().getReplacementString())); + } + }); + + suggestBox.getTextBox().addFocusHandler(new FocusHandler() { + public void onFocus(FocusEvent event) { + suggestBox.showSuggestionList(); + } + }); + } + + public HandlerRegistration addValueChangeHandler(ValueChangeHandler<T> handler) { + return addHandler(handler, ValueChangeEvent.getType()); + } + + /** + * Returns a {@link TakesValueEditor} backed by the ValueSuggestBox. + */ + public TakesValueEditor<T> asEditor() { + if (editor == null) { + editor = TakesValueEditor.of(this); + } + return editor; + } + + public T getValue() { + return value; + } + + public void setAcceptableValues(Collection<T> newValues) { + stringToValue.clear(); + suggestOracle.clear(); + + Collection<String> newStrings = new ArrayList<String>(); + for (T nextNewValue : newValues) { + String nextString = renderer.render(nextNewValue); + newStrings.add(nextString); + stringToValue.put(nextString, nextNewValue); + } + + suggestOracle.addAll(newStrings); + if (suggestWhenEmpty) { + suggestOracle.setDefaultSuggestionsFromText(newStrings); + } + } + + /** + * Set the value and display it in the select element. Do not add the value to the acceptable set. + */ + public void setValue(T value) { + setValue(value, false); + } + + public void setValue(T value, boolean fireEvents) { + if (value == this.value || (this.value != null && this.value.equals(value))) { + return; + } + + T before = this.value; + this.value = value; + getSuggestBox().setText(renderer.render(value)); + + if (fireEvents) { + ValueChangeEvent.fireIfNotEqual(this, before, value); + } + } + + private SuggestBox getSuggestBox() { + return (SuggestBox) getWidget(); + } +} -- To view, visit http://gerrit.ovirt.org/12529 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I07d419d0eb83e189b6bf6138c6e4b2b6953a2012 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Lior Vernia <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
