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

Reply via email to