Detect partial changes in the ListModel associated with a TreeNodeView.
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7626 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListListModel.java b/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListListModel.java
index 1327de5..5eaf458 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListListModel.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListListModel.java
@@ -31,8 +31,6 @@
*/
public class ListListModel<T> extends AbstractListModel<T> {
- public int insertIndex;
-
/**
* A wrapper around a list that updates the model on any change.
*/
@@ -77,7 +75,6 @@
public void add(int index, T element) {
list.add(index, element);
- // insert(index);
flush();
}
diff --git a/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/BuySellPopup.java b/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/BuySellPopup.java
index c313777..2e7b341 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/BuySellPopup.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/BuySellPopup.java
@@ -112,6 +112,10 @@
layout.setWidget(6, 1, cancelButton);
}
+ public StockQuote getStockQuote() {
+ return quote;
+ }
+
/**
* Get the last transaction.
*
diff --git a/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/StockSample.java b/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/StockSample.java
index c7f2be2..5539171 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/StockSample.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/StockSample.java
@@ -168,8 +168,6 @@
private AsyncListModel<StockQuote> searchListModel;
- private ListListModel<String> tickersListModel = new ListListModel<String>();
-
private Map<String, ListListModel<Transaction>> transactionListListModelsByTicker =
new HashMap<String, ListListModel<Transaction>>();
@@ -181,8 +179,6 @@
private TreeView transactionTree;
- private List<String> transactionTreeTickers = tickersListModel.getList();
-
/**
* The timer used to update the stock quotes.
*/
@@ -248,8 +244,9 @@
transactionTable.addColumn(Columns.subtotalColumn);
// Create the transactions tree.
- transactionTree = new TreeView(new TransactionTreeViewModel(tickersListModel,
+ transactionTree = new TreeView(new TransactionTreeViewModel(favoritesListModel,
transactionListListModelsByTicker), null);
+ transactionTree.setAnimationEnabled(true);
Columns.favoriteColumn.setFieldUpdater(new FieldUpdater<StockQuote, Boolean>() {
public void update(StockQuote object, Boolean value) {
@@ -293,25 +290,7 @@
*/
private void recordTransaction(Transaction result) {
transactions.add(0, result);
-
- // Add ticker in alphebetical order
String ticker = result.getTicker();
- int index = 0;
- for (String s : transactionTreeTickers) {
- int compare = s.compareTo(ticker);
- if (compare == 0) {
- // Already have the ticker
- index = -1;
- break;
- } else if (compare > 0) {
- break;
- }
-
- index++;
- }
- if (index != -1) {
- transactionTreeTickers.add(index, ticker);
- }
// Update the next level of the transaction tree
// for the given ticker
diff --git a/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/TransactionTreeViewModel.java b/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/TransactionTreeViewModel.java
index 6f95667..fcaf4b2 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/TransactionTreeViewModel.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/TransactionTreeViewModel.java
@@ -32,36 +32,43 @@
class TransactionTreeViewModel implements TreeViewModel {
static class TransactionCell extends Cell<Transaction> {
-
@Override
public void render(Transaction value, StringBuilder sb) {
sb.append(value.toString());
}
}
- private static final Cell<String> TEXT_CELL = new TextCell();
+ private static final Cell<StockQuote> STOCK_QUOTE_CELL = new Cell<StockQuote>() {
+ @Override
+ public void render(StockQuote value, StringBuilder sb) {
+ sb.append(value.getTicker() + " - " + value.getDisplayPrice());
+ }
+ };
private static final Cell<Transaction> TRANSACTION_CELL =
new TransactionCell();
- private ListListModel<String> tickersListModel;
+ private ListModel<StockQuote> stockQuoteListModel;
private Map<String, ListListModel<Transaction>> transactionListListModelsByTicker;
- public TransactionTreeViewModel(ListListModel<String> tickersListModel,
+ public TransactionTreeViewModel(ListModel<StockQuote> stockQuoteListModel,
Map<String, ListListModel<Transaction>> transactionListListModelsByTicker) {
- this.tickersListModel = tickersListModel;
+ this.stockQuoteListModel = stockQuoteListModel;
this.transactionListListModelsByTicker = transactionListListModelsByTicker;
}
public <T> NodeInfo<?> getNodeInfo(T value, TreeNodeView<T> treeNodeView) {
if (value == null) {
- return new TreeViewModel.DefaultNodeInfo<String>(tickersListModel,
- TEXT_CELL);
- } else if (value instanceof String) {
+ return new TreeViewModel.DefaultNodeInfo<StockQuote>(stockQuoteListModel,
+ STOCK_QUOTE_CELL) {
+ @Override
+ public Object getKey(StockQuote value) {
+ return value.getTicker();
+ }
+ };
+ } else if (value instanceof StockQuote) {
return new TreeViewModel.DefaultNodeInfo<Transaction>(
- transactionListListModelsByTicker.get(value), TRANSACTION_CELL);
- } else if (value instanceof Transaction) {
- return null;
+ transactionListListModelsByTicker.get(((StockQuote) value).getTicker()), TRANSACTION_CELL);
}
throw new IllegalArgumentException(value.toString());
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 c82a8f3..ab35216 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeNodeView.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeNodeView.java
@@ -31,7 +31,9 @@
import com.google.gwt.user.client.ui.Composite;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* A view of a tree node.
@@ -45,6 +47,8 @@
*/
private static final String LEAF_IMAGE = "<div style='position:absolute;display:none;'></div>";
+ private boolean animate;
+
/**
* The children of this {@link TreeNodeView}.
*/
@@ -183,6 +187,7 @@
return;
}
+ this.animate = true;
this.open = open;
if (open) {
if (!nodeInfoLoaded) {
@@ -203,6 +208,12 @@
updateImage();
}
+ boolean consumeAnimate() {
+ boolean hasAnimate = animate;
+ animate = false;
+ return hasAnimate;
+ }
+
/**
* Fire an event to the {@link Cell}.
*
@@ -282,6 +293,10 @@
return childContainer;
}
+ private Object getValueKey() {
+ return parentNodeInfo.getKey(getValue());
+ }
+
/**
* Check if this is a root node at the top of the tree.
*
@@ -292,7 +307,7 @@
}
/**
- * Setup the node when it is opened.
+ * Set up the node when it is opened.
*
* @param nodeInfo the {@link NodeInfo} that provides information about the
* child values
@@ -309,6 +324,18 @@
public void onDataChanged(ListEvent<C> event) {
// TODO - handle event start and length
+ // Construct a map of former child views based on their value keys.
+ Map<Object, TreeNodeView<?>> map = new HashMap<Object, TreeNodeView<?>>();
+ if (children != null) {
+ for (TreeNodeView<?> child : children) {
+ // Ignore child nodes that are closed
+ if (child.getState()) {
+ Object key = child.getValueKey();
+ map.put(key, child);
+ }
+ }
+ }
+
// Hide the child container so we can animate it.
ensureAnimationFrame().getStyle().setDisplay(Display.NONE);
@@ -317,12 +344,21 @@
int imageWidth = tree.getImageWidth();
Cell<C> theCell = nodeInfo.getCell();
StringBuilder sb = new StringBuilder();
- children = new ArrayList<TreeNodeView<?>>();
+
for (C childValue : event.getValues()) {
+ // Remove any child elements that correspond to prior children
+ // so the call to setInnerHtml will not destroy them
+ TreeNodeView<?> savedView = map.get(nodeInfo.getKey(childValue));
+ if (savedView != null) {
+ savedView.getElement().removeFromParent();
+ }
+
sb.append("<div style=\"position:relative;padding-left:");
sb.append(imageWidth);
sb.append("px;\">");
- if (model.isLeaf(childValue)) {
+ if (savedView != null) {
+ sb.append(tree.getOpenImageHtml());
+ } else if (model.isLeaf(childValue)) {
sb.append(LEAF_IMAGE);
} else {
sb.append(tree.getClosedImageHtml());
@@ -338,8 +374,21 @@
children = new ArrayList<TreeNodeView<?>>();
Element childElem = childContainer.getFirstChildElement();
for (C childValue : event.getValues()) {
- TreeNodeView<C> child = new TreeNodeView<C>(tree, TreeNodeView.this,
- nodeInfo, childElem, childValue);
+ TreeNodeView<C> child = new TreeNodeView<C>(tree, TreeNodeView.this, nodeInfo, childElem, childValue);
+ TreeNodeView<?> savedChild = map.get(nodeInfo.getKey(childValue));
+ // Copy the saved child's state into the new child
+ if (savedChild != null) {
+ child.children = savedChild.children;
+ child.childContainer = savedChild.childContainer;
+ child.listReg = savedChild.listReg;
+ child.nodeInfo = savedChild.nodeInfo;
+ child.nodeInfoLoaded = savedChild.nodeInfoLoaded;
+ child.open = savedChild.open;
+
+ // Copy the animation frame element to the new child
+ child.getElement().appendChild(savedChild.childContainer.getParentElement());
+ }
+
children.add(child);
childElem = childElem.getNextSiblingElement();
}
@@ -349,17 +398,6 @@
}
public void onSizeChanged(SizeChangeEvent event) {
- if (children == null) {
- return;
- }
-
- // Shrink the list based on the new size.
- int size = event.getSize();
- int currentSize = children.size();
- for (int i = currentSize - 1; i >= size; i--) {
- childContainer.getLastChild().removeFromParent();
- children.remove(i);
- }
}
});
listReg.setRangeOfInterest(0, 100);
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 62b128b..529ccba 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeView.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeView.java
@@ -444,7 +444,7 @@
* @param node the node to animate
*/
void maybeAnimateTreeNode(TreeNodeView<?> node) {
- animation.animate(node, isAnimationEnabled);
+ animation.animate(node, node.consumeAnimate() && isAnimationEnabled);
}
/**
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 78dc7e1..b3ae963 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeViewModel.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeViewModel.java
@@ -38,6 +38,16 @@
Cell<C> getCell();
/**
+ * Return a key that may be used to identify values that should
+ * be treated as the same in UI views.
+ *
+ * @param value a value of type C.
+ * @return an Object that implements appropriate hashCode() and equals()
+ * methods.
+ */
+ Object getKey(C value);
+
+ /**
* Get the {@link ListModel} used to retrieve child node values.
*
* @return the list model
@@ -91,6 +101,10 @@
return cell;
}
+ public Object getKey(C value) {
+ return value;
+ }
+
public ListModel<C> getListModel() {
return listModel;
}