Implement selection on trees
Rename 'onDataChange' -> 'setData', etc.
Minor stylistic fixes
Review at http://gwt-code-reviews.appspot.com/333802
Review by: jgw@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7916 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/client/HasCell.java b/bikeshed/src/com/google/gwt/bikeshed/list/client/HasCell.java
index 30a0ef2..e6eb667 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/list/client/HasCell.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/client/HasCell.java
@@ -28,6 +28,8 @@
* @param <V> the view data type
*/
public interface HasCell<T, C, V> {
+
+ boolean dependsOnSelection();
Cell<C, V> getCell();
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/client/ListView.java b/bikeshed/src/com/google/gwt/bikeshed/list/client/ListView.java
index b23145e..9934406 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/list/client/ListView.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/client/ListView.java
@@ -15,9 +15,8 @@
*/
package com.google.gwt.bikeshed.list.client;
-import com.google.gwt.bikeshed.list.shared.ListEvent;
+import com.google.gwt.bikeshed.list.shared.DataChanged;
import com.google.gwt.bikeshed.list.shared.Range;
-import com.google.gwt.bikeshed.list.shared.SizeChangeEvent;
/**
* A list view.
@@ -35,13 +34,12 @@
void onRangeChanged(ListView<T> listView);
}
- void setDelegate(Delegate<T> delegate);
-
Range getRange();
// TODO - rename to setData, don't use event?
- void onDataChanged(ListEvent<T> event);
+ void setData(DataChanged<T> event);
- // TODO - rename to setDataSize, don't use event?
- void onSizeChanged(SizeChangeEvent event);
+ void setDelegate(Delegate<T> delegate);
+
+ void setSize(int size, boolean exact);
}
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/client/PagingTableListView.java b/bikeshed/src/com/google/gwt/bikeshed/list/client/PagingTableListView.java
index d883ac9..e411916 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/list/client/PagingTableListView.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/client/PagingTableListView.java
@@ -15,11 +15,10 @@
*/
package com.google.gwt.bikeshed.list.client;
-import com.google.gwt.bikeshed.list.shared.ListEvent;
+import com.google.gwt.bikeshed.list.shared.DataChanged;
import com.google.gwt.bikeshed.list.shared.ProvidesKey;
import com.google.gwt.bikeshed.list.shared.Range;
import com.google.gwt.bikeshed.list.shared.SelectionModel;
-import com.google.gwt.bikeshed.list.shared.SizeChangeEvent;
import com.google.gwt.bikeshed.list.shared.AbstractListViewAdapter.DefaultRange;
import com.google.gwt.bikeshed.list.shared.SelectionModel.SelectionChangeEvent;
import com.google.gwt.bikeshed.list.shared.SelectionModel.SelectionChangeHandler;
@@ -179,20 +178,6 @@
}
}
- public void onDataChanged(ListEvent<T> event) {
- render(event.getStart(), event.getLength(), event.getValues());
- }
-
- public void onSizeChanged(SizeChangeEvent event) {
- totalSize = event.getSize();
- if (totalSize <= 0) {
- numPages = 0;
- } else {
- numPages = 1 + (totalSize - 1) / pageSize;
- }
- setPage(curPage);
- }
-
public void previousPage() {
setPage(curPage - 1);
}
@@ -229,6 +214,10 @@
}
}
+ public void setData(DataChanged<T> event) {
+ render(event.getStart(), event.getLength(), event.getValues());
+ }
+
public void setDelegate(Delegate<T> delegate) {
this.delegate = delegate;
if (delegate != null) {
@@ -284,6 +273,15 @@
}
}
+ public void setSize(int size, boolean exact) {
+ if (size <= 0) {
+ numPages = 0;
+ } else {
+ numPages = 1 + (size - 1) / pageSize;
+ }
+ setPage(curPage);
+ }
+
@Override
protected void onLoad() {
// Attach a selection handler.
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/client/SimpleCellList.java b/bikeshed/src/com/google/gwt/bikeshed/list/client/SimpleCellList.java
index 7738c44..c1431ac 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/list/client/SimpleCellList.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/client/SimpleCellList.java
@@ -17,9 +17,8 @@
import com.google.gwt.bikeshed.cells.client.Cell;
import com.google.gwt.bikeshed.cells.client.ValueUpdater;
-import com.google.gwt.bikeshed.list.shared.ListEvent;
+import com.google.gwt.bikeshed.list.shared.DataChanged;
import com.google.gwt.bikeshed.list.shared.Range;
-import com.google.gwt.bikeshed.list.shared.SizeChangeEvent;
import com.google.gwt.bikeshed.list.shared.AbstractListViewAdapter.DefaultRange;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Document;
@@ -111,7 +110,7 @@
}
}
- public void onDataChanged(ListEvent<T> event) {
+ public void setData(DataChanged<T> event) {
int start = event.getStart();
int len = event.getLength();
List<T> values = event.getValues();
@@ -137,11 +136,6 @@
}
}
- public void onSizeChanged(SizeChangeEvent event) {
- size = event.getSize();
- sizeChanged();
- }
-
public void setDelegate(Delegate<T> delegate) {
this.delegate = delegate;
if (delegate != null) {
@@ -149,6 +143,11 @@
}
}
+ public void setSize(int size, boolean exact) {
+ this.size = size;
+ sizeChanged();
+ }
+
public void setValueUpdater(ValueUpdater<T, Void> valueUpdater) {
this.valueUpdater = valueUpdater;
}
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/shared/AbstractListViewAdapter.java b/bikeshed/src/com/google/gwt/bikeshed/list/shared/AbstractListViewAdapter.java
index d1e5cf6..cf47a09 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/list/shared/AbstractListViewAdapter.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/shared/AbstractListViewAdapter.java
@@ -69,7 +69,7 @@
/**
* The provider of keys for list items.
*/
- private ProvidesKey<T> keyProvider;
+ private ProvidesKey<T> providesKey;
public void addView(ListView<T> view) {
if (views.contains(view)) {
@@ -87,7 +87,7 @@
* @return the key that represents the item
*/
public Object getKey(T item) {
- return keyProvider == null ? item : keyProvider.getKey(item);
+ return providesKey == null ? item : providesKey.getKey(item);
}
/**
@@ -95,8 +95,8 @@
*
* @return the {@link ProvidesKey}
*/
- public ProvidesKey<T> getKeyProvider() {
- return keyProvider;
+ public ProvidesKey<T> getProvidesKey() {
+ return providesKey;
}
/**
@@ -124,10 +124,10 @@
/**
* Set the {@link ProvidesKey} that provides keys for list items.
*
- * @param keyProvider the {@link ProvidesKey}
+ * @param providesKey a {@link ProvidesKey} instance
*/
- public void setKeyProvider(ProvidesKey<T> keyProvider) {
- this.keyProvider = keyProvider;
+ public void setKeyProvider(ProvidesKey<T> providesKey) {
+ this.providesKey = providesKey;
}
/**
@@ -144,9 +144,8 @@
* @param exact true if the size is exact, false if it is a guess
*/
protected void updateDataSize(int size, boolean exact) {
- SizeChangeEvent event = new SizeChangeEvent(size, exact);
for (ListView<T> view : views) {
- view.onSizeChanged(event);
+ view.setSize(size, exact);
}
}
@@ -184,8 +183,8 @@
int realLength = realEnd - realStart;
List<T> realValues = values.subList(realStart - start, realStart
- start + realLength);
- ListEvent<T> event = new ListEvent<T>(realStart, realLength, realValues);
- view.onDataChanged(event);
+ DataChanged<T> event = new DataChanged<T>(realStart, realLength, realValues);
+ view.setData(event);
}
}
}
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListEvent.java b/bikeshed/src/com/google/gwt/bikeshed/list/shared/DataChanged.java
similarity index 91%
rename from bikeshed/src/com/google/gwt/bikeshed/list/shared/ListEvent.java
rename to bikeshed/src/com/google/gwt/bikeshed/list/shared/DataChanged.java
index 1c78314..ade217a 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListEvent.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/shared/DataChanged.java
@@ -22,20 +22,20 @@
*
* @param <T> the type of data in the list
*/
-public class ListEvent<T> {
+public class DataChanged<T> {
private final int length;
private final int start;
private final List<T> values;
/**
- * Creates a {@link ListEvent}.
+ * Creates a {@link DataChanged} instance.
*
* @param start the start index of the data
* @param length the length of the data
* @param values the new values
*/
- public ListEvent(int start, int length, List<T> values) {
+ public DataChanged(int start, int length, List<T> values) {
this.start = start;
this.length = length;
this.values = values;
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/shared/DefaultSelectionModel.java b/bikeshed/src/com/google/gwt/bikeshed/list/shared/DefaultSelectionModel.java
index 30e5f7a..8793b38 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/list/shared/DefaultSelectionModel.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/shared/DefaultSelectionModel.java
@@ -31,7 +31,7 @@
private final Map<Object, Boolean> exceptions = new HashMap<Object, Boolean>();
- private final ProvidesKey<T> keyProvider = getKeyProvider();
+ private final ProvidesKey<T> providesKey = getProvidesKey();
/**
* Removes all exceptions.
@@ -93,9 +93,9 @@
}
private Object getKey(T object) {
- if (keyProvider == null) {
+ if (providesKey == null) {
return object;
}
- return keyProvider.getKey(object);
+ return providesKey.getKey(object);
}
}
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/shared/SelectionModel.java b/bikeshed/src/com/google/gwt/bikeshed/list/shared/SelectionModel.java
index 3b3a0ee..8016638 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/list/shared/SelectionModel.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/shared/SelectionModel.java
@@ -125,7 +125,7 @@
/**
* Returns a ProvidesKey instance that simply returns the input data item.
*/
- public ProvidesKey<T> getKeyProvider() {
+ public ProvidesKey<T> getProvidesKey() {
if (keyProvider == null) {
keyProvider = new ProvidesKey<T>() {
public Object getKey(T item) {
@@ -165,7 +165,7 @@
* Returns a ProvidesKey instance that may be used to provide a unique
* key for each record.
*/
- ProvidesKey<T> getKeyProvider();
+ ProvidesKey<T> getProvidesKey();
/**
* Check if an object is selected.
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/shared/SizeChangeEvent.java b/bikeshed/src/com/google/gwt/bikeshed/list/shared/SizeChangeEvent.java
deleted file mode 100644
index 81dd219..0000000
--- a/bikeshed/src/com/google/gwt/bikeshed/list/shared/SizeChangeEvent.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.bikeshed.list.shared;
-
-/**
- * Fired when the size of a list is known or changed.
- */
-public class SizeChangeEvent {
-
- private final boolean exact;
- private final int size;
-
- /**
- * Creates a {@link SizeChangeEvent}.
- *
- * @param size the total size of the list
- * @param exact true if this is an exact size
- */
- public SizeChangeEvent(int size, boolean exact) {
- this.size = size;
- this.exact = exact;
- }
-
- /**
- * Get the length of the changed data set.
- *
- * @return the length of the data set
- */
- public int getSize() {
- return size;
- }
-
- /**
- * Check if the size is an exact size or an approximation.
- *
- * @return true if exact, false if approximation
- */
- public boolean isExact() {
- return exact;
- }
-}
diff --git a/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeNodeView.java b/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeNodeView.java
index 6818ac8..36e2b4c 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeNodeView.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeNodeView.java
@@ -250,9 +250,4 @@
setChildContainer(null);
}
-
- private <C, X> void render(StringBuilder sb, C childValue,
- HasCell<C, X, Void> hc) {
- hc.getCell().render(hc.getValue(childValue), null, sb);
- }
}
diff --git a/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeView.java b/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeView.java
index 0e0cdfa..5cf621e 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeView.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeView.java
@@ -114,6 +114,15 @@
}
if (inCell) {
nodeView.fireEventToCell(event);
+
+ // TODO(jgw): Kind of a hacky way to set selection. Need to generalize
+ // this to some sort of keyboard/mouse->selection controller.
+ if (getSelectionModel() != null) {
+ String type = event.getType();
+ if ("mouseup".equals(type)) {
+ getSelectionModel().setSelected(nodeView.getValue(), true);
+ }
+ }
} else {
nodeView.setState(!nodeView.getState());
}
diff --git a/bikeshed/src/com/google/gwt/bikeshed/tree/client/StandardTreeNodeView.java b/bikeshed/src/com/google/gwt/bikeshed/tree/client/StandardTreeNodeView.java
index 483ca34..0906b0c 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/StandardTreeNodeView.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/StandardTreeNodeView.java
@@ -66,9 +66,9 @@
int idx = 0;
for (C childValue : childValues) {
- sb.append("<div style=\"position:relative;padding-left:");
+ sb.append("<div style='position:relative;padding-left:");
sb.append(imageWidth);
- sb.append("px;\">");
+ sb.append("px;'>");
if (savedViews.get(idx) != null) {
sb.append(tree.getOpenImageHtml(0));
} else if (model.isLeaf(childValue, this)) {
@@ -79,7 +79,7 @@
if (selectionModel != null && selectionModel.isSelected(childValue)) {
sb.append("<div class='gwt-stree-selectedItem'>");
} else {
- sb.append("<div>");
+ sb.append("<div class='gwt-stree-unselectedItem'>");
}
for (int i = 0; i < hasCells.size(); i++) {
@@ -133,9 +133,4 @@
protected void postClose() {
getTree().maybeAnimateTreeNode(this);
}
-
- private <C, X> void render(StringBuilder sb, C childValue,
- HasCell<C, X, Void> hc) {
- hc.getCell().render(hc.getValue(childValue), null, sb);
- }
}
diff --git a/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeNodeView.java b/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeNodeView.java
index 90d302e..efaa2b5 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeNodeView.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeNodeView.java
@@ -17,10 +17,9 @@
import com.google.gwt.bikeshed.list.client.HasCell;
import com.google.gwt.bikeshed.list.client.ListView;
-import com.google.gwt.bikeshed.list.shared.ListEvent;
+import com.google.gwt.bikeshed.list.shared.DataChanged;
import com.google.gwt.bikeshed.list.shared.ProvidesKey;
import com.google.gwt.bikeshed.list.shared.Range;
-import com.google.gwt.bikeshed.list.shared.SizeChangeEvent;
import com.google.gwt.bikeshed.list.shared.AbstractListViewAdapter.DefaultRange;
import com.google.gwt.bikeshed.tree.client.TreeViewModel.NodeInfo;
import com.google.gwt.dom.client.Document;
@@ -43,6 +42,16 @@
public abstract class TreeNodeView<T> extends UIObject implements TreeNode<T> {
/**
+ * A NodeInfo and list of data items of matching type.
+ *
+ * @param <C> the data type
+ */
+ static class SavedInfo<C> {
+ NodeInfo<C> nodeInfo;
+ List<C> values;
+ }
+
+ /**
* The element used in place of an image when a node has no children.
*/
public static final String LEAF_IMAGE = "<div style='position:absolute;display:none;'></div>";
@@ -93,6 +102,11 @@
private final NodeInfo<T> parentNodeInfo;
/**
+ * The NodeInfo for this node along with saved child data values.
+ */
+ private SavedInfo<?> savedInfo;
+
+ /**
* The info about this node.
*/
private final TreeView tree;
@@ -353,6 +367,12 @@
ensureChildContainer().setInnerHTML(tree.getLoadingHtml());
ensureAnimationFrame().getStyle().setProperty("display", "");
+ // Create a SavedInfo object to store the NodeInfo and data values
+ final SavedInfo<C> localSavedInfo = new SavedInfo<C>();
+ localSavedInfo.nodeInfo = nodeInfo;
+ localSavedInfo.values = new ArrayList<C>();
+ TreeNodeView.this.savedInfo = localSavedInfo;
+
// Get the node info.
final ProvidesKey<C> providesKey = nodeInfo.getProvidesKey();
ListView<C> view = new ListView<C>() {
@@ -360,9 +380,21 @@
return new DefaultRange(0, 100);
}
- public void onDataChanged(ListEvent<C> event) {
+ public void setData(DataChanged<C> event) {
// TODO - handle event start and length
+ int start = event.getStart();
+ int end = start + event.getLength();
+ // Ensure savedInfo has a place to store the data values
+ while (localSavedInfo.values.size() < end) {
+ savedInfo.values.add(null);
+ }
+ // Save child values into savedInfo
+ int index = event.getStart();
+ for (C childValue : event.getValues()) {
+ localSavedInfo.values.set(index++, childValue);
+ }
+
// Construct a map of former child views based on their value keys.
Map<Object, TreeNodeView<?>> map = new HashMap<Object, TreeNodeView<?>>();
if (children != null) {
@@ -428,8 +460,15 @@
}
}
- public void onSizeChanged(SizeChangeEvent event) {
- if (event.getSize() == 0 && event.isExact()) {
+ public void setDelegate(ListView.Delegate<C> delegate) {
+ // Range never actually changes so no need to store the delegate
+ if (delegate != null) {
+ delegate.onRangeChanged(this);
+ }
+ }
+
+ public void setSize(int size, boolean exact) {
+ if (size == 0 && exact) {
ensureChildContainer().setInnerHTML("<i>no data</i>");
if (children != null) {
for (TreeNodeView<?> child : children) {
@@ -439,13 +478,6 @@
}
}
}
-
- public void setDelegate(ListView.Delegate<C> delegate) {
- // Range never actually changes so no need to store the delegate
- if (delegate != null) {
- delegate.onRangeChanged(this);
- }
- }
};
nodeInfo.setView(view);
this.listView = view;
@@ -463,6 +495,16 @@
protected void preOpen() {
}
+ /**
+ * Refresh any cells that depend on the selection state. The default
+ * implementation works for {@link StandardTreeNodeView} and
+ * {@link SideBySideTreeNodeView}; other subclasses will need to implement
+ * their own versions of this method.
+ */
+ protected void refreshSelection() {
+ refreshSelection(savedInfo);
+ }
+
protected void setChildContainer(Element childContainer) {
this.childContainer = childContainer;
}
@@ -491,4 +533,49 @@
TreeView getTree() {
return tree;
}
+
+ /**
+ * Helper method to render the contents of a cell without needing to know
+ * the type of the cell.
+ *
+ * @param <C> the child value type
+ * @param <X> the cell type
+ * @param sb a StringBuilder instance
+ * @param childValue the child value
+ * @param hasCell a HasCell instance
+ */
+ <C, X> void render(StringBuilder sb, C childValue,
+ HasCell<C, X, Void> hasCell) {
+ hasCell.getCell().render(hasCell.getValue(childValue), null, sb);
+ }
+
+ /**
+ * Refresh any cells that depend on the selection state. Note that this
+ * implementation is dependent on the particular DOM structure used by
+ * {@link StandardTreeNodeView} and {@link SideBySideTreeNodeView}.
+ *
+ * @param <C> the child data type
+ * @param savedInfo a SavedInfo object containing a NodeInfo instance
+ * and a list of saved child data values
+ */
+ private <C> void refreshSelection(SavedInfo<C> savedInfo) {
+ List<HasCell<C, ?, Void>> hasCells = savedInfo.nodeInfo.getHasCells();
+ Element outerDiv = childContainer.getFirstChildElement();
+ int index = 0;
+ while (outerDiv != null) {
+ C childValue = savedInfo.values.get(index);
+ Element span = outerDiv.getFirstChildElement().getNextSiblingElement().getFirstChildElement();
+
+ for (HasCell<C, ?, Void> hasCell : hasCells) {
+ if (hasCell.dependsOnSelection()) {
+ StringBuilder sb = new StringBuilder();
+ render(sb, childValue, hasCell);
+ span.setInnerHTML(sb.toString());
+ }
+ span = span.getNextSiblingElement();
+ }
+ outerDiv = outerDiv.getNextSibling().cast();
+ index++;
+ }
+ }
}
diff --git a/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeView.java b/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeView.java
index 563b4e0..00da75c 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeView.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeView.java
@@ -17,6 +17,8 @@
import com.google.gwt.animation.client.Animation;
import com.google.gwt.bikeshed.list.shared.SelectionModel;
+import com.google.gwt.bikeshed.list.shared.SelectionModel.SelectionChangeEvent;
+import com.google.gwt.bikeshed.list.shared.SelectionModel.SelectionChangeHandler;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.ImageResource;
@@ -27,7 +29,7 @@
* A view of a tree.
*/
public abstract class TreeView extends Widget {
-
+
/**
* An Animation of a {@link TreeNodeView}.
*/
@@ -77,6 +79,12 @@
ImageResource treeOpen();
}
+ private class TreeSelectionHandler implements SelectionChangeHandler {
+ public void onSelectionChange(SelectionChangeEvent event) {
+ refreshSelection();
+ }
+ }
+
private static final Resources DEFAULT_RESOURCES = GWT.create(Resources.class);
/**
@@ -144,6 +152,10 @@
return rootNode;
}
+ /**
+ * Returns the {@link SelectionModel} containing the selection state for
+ * this tree.
+ */
public SelectionModel<Object> getSelectionModel() {
return selectionModel;
}
@@ -157,6 +169,13 @@
}
/**
+ * Refresh any visible cells of this tree that depend on the selection state.
+ */
+ public void refreshSelection() {
+ refreshSelection(rootNode);
+ }
+
+ /**
* Set the animation used to open and close nodes in this tree. You must call
* {@link #setAnimationEnabled(boolean)} to enable or disable animation.
*
@@ -177,6 +196,10 @@
public void setSelectionModel(SelectionModel<Object> selectionModel) {
this.selectionModel = selectionModel;
+ // Attach a selection handler.
+ if (selectionModel != null) {
+ selectionModel.addSelectionChangeHandler(new TreeSelectionHandler());
+ }
}
/**
@@ -257,4 +280,15 @@
protected void setRootNode(TreeNodeView<?> rootNode) {
this.rootNode = rootNode;
}
+
+ private void refreshSelection(TreeNodeView<?> node) {
+ node.refreshSelection();
+ int count = node.getChildCount();
+ for (int i = 0; i < count; i++) {
+ TreeNodeView<?> child = node.getChildTreeNodeView(i);
+ if (child.isOpen()) {
+ refreshSelection(child);
+ }
+ }
+ }
}
diff --git a/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeViewModel.java b/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeViewModel.java
index b619971..d33b4f5 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeViewModel.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeViewModel.java
@@ -47,10 +47,11 @@
* @param adapter the {@link AbstractListViewAdapter} that provides the
* child values
* @param cell the {@link Cell} used to render the child values
+ * @param dependsOnSelection TODO
*/
public DefaultNodeInfo(AbstractListViewAdapter<T> adapter,
- Cell<T, Void> cell) {
- this(adapter, cell, null);
+ Cell<T, Void> cell, boolean dependsOnSelection) {
+ this(adapter, cell, dependsOnSelection, null);
}
/**
@@ -60,11 +61,17 @@
* @param adapter the {@link AbstractListViewAdapter} that provides the
* child values
* @param cell the {@link Cell} used to render the child values
+ * @param dependsOnSelection TODO
* @param valueUpdater the {@link ValueUpdater}
*/
public DefaultNodeInfo(AbstractListViewAdapter<T> adapter,
- final Cell<T, Void> cell, final ValueUpdater<T, Void> valueUpdater) {
+ final Cell<T, Void> cell, final boolean dependsOnSelection,
+ final ValueUpdater<T, Void> valueUpdater) {
hasCells.add(new HasCell<T, T, Void>() {
+ public boolean dependsOnSelection() {
+ return dependsOnSelection;
+ }
+
public Cell<T, Void> getCell() {
return cell;
}
@@ -98,7 +105,6 @@
return listViewAdapter;
}
- // TODO - dispatch into cells
public void onBrowserEvent(Element elem, final T object, NativeEvent event) {
Element target = event.getEventTarget().cast();
String idxString = "";
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/BasicTreeRecipe.java b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/BasicTreeRecipe.java
index 1fd42e9..9682628 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/BasicTreeRecipe.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/BasicTreeRecipe.java
@@ -40,8 +40,7 @@
final MultiSelectionModel<Object> selectionModel = new MultiSelectionModel<Object>();
selectionModel.addSelectionChangeHandler(new SelectionModel.SelectionChangeHandler() {
public void onSelectionChange(SelectionChangeEvent event) {
- label.setText("Selected "
- + selectionModel.getSelectedSet().toString());
+ label.setText("Selected " + selectionModel.getSelectedSet().toString());
}
});
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/Cookbook.java b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/Cookbook.java
index 6ae4be6..61fc940 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/Cookbook.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/Cookbook.java
@@ -61,12 +61,12 @@
public <T> NodeInfo<?> getNodeInfo(T value, TreeNode<T> treeNode) {
if (value == null) {
// Categories at the root.
- return new DefaultNodeInfo<Category>(adapter, new CategoryCell());
+ return new DefaultNodeInfo<Category>(adapter, new CategoryCell(), false);
} else if (value instanceof Category) {
// Demos for each category.
Category category = (Category) value;
return new DefaultNodeInfo<Recipe>(new ListViewAdapter<Recipe>(
- category.getRecipes()), new RecipeCell());
+ category.getRecipes()), new RecipeCell(), false);
}
return null;
}
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MailRecipe.java b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MailRecipe.java
index 4456372..9a6c191 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MailRecipe.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MailRecipe.java
@@ -69,7 +69,7 @@
private Type type = Type.NONE;
@Override
- public ProvidesKey<Message> getKeyProvider() {
+ public ProvidesKey<Message> getProvidesKey() {
return keyProvider;
}
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MultiSelectionModel.java b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MultiSelectionModel.java
index c5c8be2..985a6f7 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MultiSelectionModel.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MultiSelectionModel.java
@@ -21,7 +21,8 @@
import java.util.TreeSet;
/**
- * A simple selection model that allows only multiple objects to be selected.
+ * A simple selection model that allows multiple objects to be selected.
+ * Each object must implement the {@link Comparable} interface.
*
* @param <T> the record data type
*/
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MyTreeViewModel.java b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MyTreeViewModel.java
index bdc6b7b..a355e58 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MyTreeViewModel.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MyTreeViewModel.java
@@ -108,6 +108,10 @@
public MyTreeViewModel(final SelectionModel<Object> selectionModel) {
hasCells.add(new HasCell<String, Boolean, Void>() {
+ public boolean dependsOnSelection() {
+ return true;
+ }
+
public Cell<Boolean, Void> getCell() {
return new CheckboxCell();
}
@@ -126,6 +130,10 @@
}
});
hasCells.add(new HasCell<String, String, Void>() {
+ public boolean dependsOnSelection() {
+ return false;
+ }
+
public Cell<String, Void> getCell() {
return ButtonCell.getInstance();
}
@@ -166,7 +174,7 @@
} else {
AbstractListViewAdapter<Integer> adapter = new IntegerListViewAdapter(value.length());
return new DefaultNodeInfo<Integer>(adapter, INTEGER_CELL,
- new ValueUpdater<Integer, Void>() {
+ false, new ValueUpdater<Integer, Void>() {
public void update(Integer value, Void viewData) {
Window.alert("Integer = " + value);
}
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StocksDesktop.java b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StocksDesktop.java
index cbc7b94..ec39cac 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StocksDesktop.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StocksDesktop.java
@@ -118,7 +118,7 @@
update();
}
};
- searchListViewAdapter.setKeyProvider(StockQuote.KEY_PROVIDER);
+ searchListViewAdapter.setKeyProvider(StockQuote.PROVIDES_KEY);
favoritesListViewAdapter = new AsyncListViewAdapter<StockQuote>() {
@Override
@@ -126,7 +126,7 @@
update();
}
};
- favoritesListViewAdapter.setKeyProvider(StockQuote.KEY_PROVIDER);
+ favoritesListViewAdapter.setKeyProvider(StockQuote.PROVIDES_KEY);
playerScoresListViewAdapter = new AsyncListViewAdapter<PlayerInfo>() {
@Override
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StocksMobile.java b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StocksMobile.java
index 9c3c8f5..51d7e2f 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StocksMobile.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StocksMobile.java
@@ -79,7 +79,7 @@
update();
}
};
- favoritesListViewAdapter.setKeyProvider(StockQuote.KEY_PROVIDER);
+ favoritesListViewAdapter.setKeyProvider(StockQuote.PROVIDES_KEY);
// Now create the UI.
RootPanel.get().add(binder.createAndBindUi(this));
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/TransactionTreeViewModel.java b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/TransactionTreeViewModel.java
index 790800d..83bb928 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/TransactionTreeViewModel.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/TransactionTreeViewModel.java
@@ -44,7 +44,7 @@
public SectorListViewAdapter(String sector) {
this.sector = sector;
- setKeyProvider(StockQuote.KEY_PROVIDER);
+ setKeyProvider(StockQuote.PROVIDES_KEY);
}
public String getSector() {
@@ -96,10 +96,10 @@
public <T> NodeInfo<?> getNodeInfo(T value, final TreeNode<T> treeNode) {
if (value == null) {
return new TreeViewModel.DefaultNodeInfo<String>(topLevelListViewAdapter,
- TextCell.getInstance());
+ TextCell.getInstance(), false);
} else if ("Favorites".equals(value)) {
return new TreeViewModel.DefaultNodeInfo<StockQuote>(stockQuoteListViewAdapter,
- STOCK_QUOTE_CELL);
+ STOCK_QUOTE_CELL, false);
} else if ("History".equals(value)) {
String ticker = ((StockQuote) treeNode.getParentNode().getValue()).getTicker();
ListViewAdapter<Transaction> adapter = transactionListViewAdaptersByTicker.get(ticker);
@@ -108,14 +108,14 @@
transactionListViewAdaptersByTicker.put(ticker, adapter);
}
return new TreeViewModel.DefaultNodeInfo<Transaction>(adapter,
- TRANSACTION_CELL);
+ TRANSACTION_CELL, false);
} else if ("Actions".equals(value)) {
ListViewAdapter<String> adapter = new ListViewAdapter<String>();
List<String> list = adapter.getList();
list.add("Buy");
list.add("Sell");
return new TreeViewModel.DefaultNodeInfo<String>(adapter,
- ButtonCell.getInstance(), new ValueUpdater<String, Void>() {
+ ButtonCell.getInstance(), false, new ValueUpdater<String, Void>() {
public void update(String value, Void viewData) {
StockQuote stockQuote = (StockQuote) treeNode.getParentNode().getValue();
if ("Buy".equals(value)) {
@@ -129,14 +129,14 @@
SectorListViewAdapter adapter = new SectorListViewAdapter((String) value);
sectorListViewAdapters.put((String) value, adapter);
return new TreeViewModel.DefaultNodeInfo<StockQuote>(adapter,
- STOCK_QUOTE_CELL);
+ STOCK_QUOTE_CELL, false);
} else if (value instanceof StockQuote) {
ListViewAdapter<String> adapter = new ListViewAdapter<String>();
List<String> list = adapter.getList();
list.add("Actions");
list.add("History");
return new TreeViewModel.DefaultNodeInfo<String>(adapter,
- TextCell.getInstance());
+ TextCell.getInstance(), false);
}
throw new IllegalArgumentException(value.toString());
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/shared/StockQuote.java b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/shared/StockQuote.java
index 91c3249..ac49dac 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/shared/StockQuote.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/shared/StockQuote.java
@@ -27,7 +27,7 @@
/**
* Provides the key for {@link StockQuote}.
*/
- public static final ProvidesKey<StockQuote> KEY_PROVIDER = new ProvidesKey<StockQuote>() {
+ public static final ProvidesKey<StockQuote> PROVIDES_KEY = new ProvidesKey<StockQuote>() {
public Object getKey(StockQuote item) {
return item.getTicker();
}