Revision: 7916
Author: r...@google.com
Date: Tue Apr 13 08:09:30 2010
Log: Implement selection on trees
Rename 'onDataChange' -> 'setData', etc.
Minor stylistic fixes

Review at http://gwt-code-reviews.appspot.com/333802

Review by: j...@google.com
http://code.google.com/p/google-web-toolkit/source/detail?r=7916

Added:
 /trunk/bikeshed/src/com/google/gwt/bikeshed/list/shared/DataChanged.java
Deleted:
 /trunk/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListEvent.java
/trunk/bikeshed/src/com/google/gwt/bikeshed/list/shared/SizeChangeEvent.java
Modified:
 /trunk/bikeshed/src/com/google/gwt/bikeshed/list/client/HasCell.java
 /trunk/bikeshed/src/com/google/gwt/bikeshed/list/client/ListView.java
/trunk/bikeshed/src/com/google/gwt/bikeshed/list/client/PagingTableListView.java
 /trunk/bikeshed/src/com/google/gwt/bikeshed/list/client/SimpleCellList.java
/trunk/bikeshed/src/com/google/gwt/bikeshed/list/shared/AbstractListViewAdapter.java /trunk/bikeshed/src/com/google/gwt/bikeshed/list/shared/DefaultSelectionModel.java
 /trunk/bikeshed/src/com/google/gwt/bikeshed/list/shared/SelectionModel.java
/trunk/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeNodeView.java /trunk/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeView.java /trunk/bikeshed/src/com/google/gwt/bikeshed/tree/client/StandardTreeNodeView.java
 /trunk/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeNodeView.java
 /trunk/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeView.java
 /trunk/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeViewModel.java
/trunk/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/BasicTreeRecipe.java /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/Cookbook.java /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MailRecipe.java /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MultiSelectionModel.java /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MyTreeViewModel.java /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StocksDesktop.java /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StocksMobile.java /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/TransactionTreeViewModel.java /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/shared/StockQuote.java

=======================================
--- /dev/null
+++ /trunk/bikeshed/src/com/google/gwt/bikeshed/list/shared/DataChanged.java Tue Apr 13 08:09:30 2010
@@ -0,0 +1,70 @@
+/*
+ * 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;
+
+import java.util.List;
+
+/**
+ * Represents a list event.
+ *
+ * @param <T> the type of data in the list
+ */
+public class DataChanged<T> {
+
+  private final int length;
+  private final int start;
+  private final List<T> values;
+
+  /**
+   * 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 DataChanged(int start, int length, List<T> values) {
+    this.start = start;
+    this.length = length;
+    this.values = values;
+  }
+
+  /**
+   * Get the length of the changed data set.
+   *
+   * @return the length of the data set
+   */
+  public int getLength() {
+    return length;
+  }
+
+  /**
+   * Get the start index of the changed data.
+   *
+   * @return the start index
+   */
+  public int getStart() {
+    return start;
+  }
+
+  /**
+   * Gets the value.
+   *
+   * @return the value
+   */
+  public List<T> getValues() {
+    return values;
+  }
+}
=======================================
--- /trunk/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListEvent.java Fri Apr 9 11:12:18 2010
+++ /dev/null
@@ -1,70 +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;
-
-import java.util.List;
-
-/**
- * Represents a list event.
- *
- * @param <T> the type of data in the list
- */
-public class ListEvent<T> {
-
-  private final int length;
-  private final int start;
-  private final List<T> values;
-
-  /**
-   * Creates a {...@link ListEvent}.
-   *
-   * @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) {
-    this.start = start;
-    this.length = length;
-    this.values = values;
-  }
-
-  /**
-   * Get the length of the changed data set.
-   *
-   * @return the length of the data set
-   */
-  public int getLength() {
-    return length;
-  }
-
-  /**
-   * Get the start index of the changed data.
-   *
-   * @return the start index
-   */
-  public int getStart() {
-    return start;
-  }
-
-  /**
-   * Gets the value.
-   *
-   * @return the value
-   */
-  public List<T> getValues() {
-    return values;
-  }
-}
=======================================
--- /trunk/bikeshed/src/com/google/gwt/bikeshed/list/shared/SizeChangeEvent.java Fri Apr 9 11:12:18 2010
+++ /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;
-  }
-}
=======================================
--- /trunk/bikeshed/src/com/google/gwt/bikeshed/list/client/HasCell.java Fri Apr 9 11:25:51 2010 +++ /trunk/bikeshed/src/com/google/gwt/bikeshed/list/client/HasCell.java Tue Apr 13 08:09:30 2010
@@ -28,6 +28,8 @@
  * @param <V> the view data type
  */
 public interface HasCell<T, C, V> {
+
+  boolean dependsOnSelection();

   Cell<C, V> getCell();

=======================================
--- /trunk/bikeshed/src/com/google/gwt/bikeshed/list/client/ListView.java Fri Apr 9 11:12:18 2010 +++ /trunk/bikeshed/src/com/google/gwt/bikeshed/list/client/ListView.java Tue Apr 13 08:09:30 2010
@@ -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.
@@ -34,14 +33,13 @@
   public interface Delegate<T> {
     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);
-
-  // TODO - rename to setDataSize, don't use event?
-  void onSizeChanged(SizeChangeEvent event);
-}
+  void setData(DataChanged<T> event);
+
+  void setDelegate(Delegate<T> delegate);
+
+  void setSize(int size, boolean exact);
+}
=======================================
--- /trunk/bikeshed/src/com/google/gwt/bikeshed/list/client/PagingTableListView.java Fri Apr 9 11:12:18 2010 +++ /trunk/bikeshed/src/com/google/gwt/bikeshed/list/client/PagingTableListView.java Tue Apr 13 08:09:30 2010
@@ -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;
@@ -178,20 +177,6 @@
           providesKey);
     }
   }
-
-  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);
@@ -228,6 +213,10 @@
       }
     }
   }
+
+  public void setData(DataChanged<T> event) {
+    render(event.getStart(), event.getLength(), event.getValues());
+  }

   public void setDelegate(Delegate<T> delegate) {
     this.delegate = delegate;
@@ -283,6 +272,15 @@
selectionHandler = selectionModel.addSelectionChangeHandler(new TableSelectionHandler());
     }
   }
+
+  public void setSize(int size, boolean exact) {
+    if (size <= 0) {
+      numPages = 0;
+    } else {
+      numPages = 1 + (size - 1) / pageSize;
+    }
+    setPage(curPage);
+  }

   @Override
   protected void onLoad() {
=======================================
--- /trunk/bikeshed/src/com/google/gwt/bikeshed/list/client/SimpleCellList.java Fri Apr 9 11:12:18 2010 +++ /trunk/bikeshed/src/com/google/gwt/bikeshed/list/client/SimpleCellList.java Tue Apr 13 08:09:30 2010
@@ -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();
@@ -136,11 +135,6 @@
       }
     }
   }
-
-  public void onSizeChanged(SizeChangeEvent event) {
-    size = event.getSize();
-    sizeChanged();
-  }

   public void setDelegate(Delegate<T> delegate) {
     this.delegate = delegate;
@@ -148,6 +142,11 @@
       delegate.onRangeChanged(this);
     }
   }
+
+  public void setSize(int size, boolean exact) {
+    this.size = size;
+    sizeChanged();
+  }

   public void setValueUpdater(ValueUpdater<T, Void> valueUpdater) {
     this.valueUpdater = valueUpdater;
=======================================
--- /trunk/bikeshed/src/com/google/gwt/bikeshed/list/shared/AbstractListViewAdapter.java Fri Apr 9 11:12:18 2010 +++ /trunk/bikeshed/src/com/google/gwt/bikeshed/list/shared/AbstractListViewAdapter.java Tue Apr 13 08:09:30 2010
@@ -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);
     }
   }
 }
=======================================
--- /trunk/bikeshed/src/com/google/gwt/bikeshed/list/shared/DefaultSelectionModel.java Thu Apr 8 11:13:17 2010 +++ /trunk/bikeshed/src/com/google/gwt/bikeshed/list/shared/DefaultSelectionModel.java Tue Apr 13 08:09:30 2010
@@ -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);
   }
 }
=======================================
--- /trunk/bikeshed/src/com/google/gwt/bikeshed/list/shared/SelectionModel.java Fri Apr 9 04:13:29 2010 +++ /trunk/bikeshed/src/com/google/gwt/bikeshed/list/shared/SelectionModel.java Tue Apr 13 08:09:30 2010
@@ -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.
=======================================
--- /trunk/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeNodeView.java Thu Apr 1 12:13:45 2010 +++ /trunk/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeNodeView.java Tue Apr 13 08:09:30 2010
@@ -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);
-  }
-}
+}
=======================================
--- /trunk/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeView.java Fri Apr 9 11:12:18 2010 +++ /trunk/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeView.java Tue Apr 13 08:09:30 2010
@@ -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());
             }
=======================================
--- /trunk/bikeshed/src/com/google/gwt/bikeshed/tree/client/StandardTreeNodeView.java Fri Apr 9 11:12:18 2010 +++ /trunk/bikeshed/src/com/google/gwt/bikeshed/tree/client/StandardTreeNodeView.java Tue Apr 13 08:09:30 2010
@@ -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);
-  }
-}
+}
=======================================
--- /trunk/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeNodeView.java Fri Apr 9 11:12:18 2010 +++ /trunk/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeNodeView.java Tue Apr 13 08:09:30 2010
@@ -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;
@@ -41,6 +40,16 @@
  * @param <T> the type that this {...@link TreeNodeView} contains
  */
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.
@@ -92,6 +101,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.
    */
@@ -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,8 +380,20 @@
         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<?>>();
@@ -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;
@@ -462,6 +494,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++;
+    }
+  }
+}
=======================================
--- /trunk/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeView.java Fri Apr 9 11:12:18 2010 +++ /trunk/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeView.java Tue Apr 13 08:09:30 2010
@@ -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}.
    */
@@ -76,6 +78,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;
   }
@@ -155,6 +167,13 @@
   public boolean isAnimationEnabled() {
     return isAnimationEnabled;
   }
+
+  /**
+ * 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
@@ -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);
+      }
+    }
+  }
+}
=======================================
--- /trunk/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeViewModel.java Fri Apr 9 11:12:18 2010 +++ /trunk/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeViewModel.java Tue Apr 13 08:09:30 2010
@@ -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 = "";
=======================================
--- /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/BasicTreeRecipe.java Fri Apr 9 11:12:18 2010 +++ /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/BasicTreeRecipe.java Tue Apr 13 08:09:30 2010
@@ -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());
       }
     });

=======================================
--- /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/Cookbook.java Fri Apr 9 11:12:18 2010 +++ /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/Cookbook.java Tue Apr 13 08:09:30 2010
@@ -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;
     }
=======================================
--- /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MailRecipe.java Fri Apr 9 11:12:18 2010 +++ /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MailRecipe.java Tue Apr 13 08:09:30 2010
@@ -69,7 +69,7 @@
     private Type type = Type.NONE;

     @Override
-    public ProvidesKey<Message> getKeyProvider() {
+    public ProvidesKey<Message> getProvidesKey() {
       return keyProvider;
     }

=======================================
--- /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MultiSelectionModel.java Fri Apr 9 11:12:18 2010 +++ /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MultiSelectionModel.java Tue Apr 13 08:09:30 2010
@@ -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
  */
=======================================
--- /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MyTreeViewModel.java Fri Apr 9 11:12:18 2010 +++ /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MyTreeViewModel.java Tue Apr 13 08:09:30 2010
@@ -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);
             }
=======================================
--- /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StocksDesktop.java Fri Apr 9 11:12:18 2010 +++ /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StocksDesktop.java Tue Apr 13 08:09:30 2010
@@ -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
=======================================
--- /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StocksMobile.java Fri Apr 9 11:12:18 2010 +++ /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StocksMobile.java Tue Apr 13 08:09:30 2010
@@ -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));
=======================================
--- /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/TransactionTreeViewModel.java Fri Apr 9 11:12:18 2010 +++ /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/TransactionTreeViewModel.java Tue Apr 13 08:09:30 2010
@@ -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());
=======================================
--- /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/shared/StockQuote.java Fri Apr 9 11:25:51 2010 +++ /trunk/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/shared/StockQuote.java Tue Apr 13 08:09:30 2010
@@ -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();
     }

--
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to