Add a HasKey interface and a maxColumns param for SideBySideTreeView
Note: the location of the getKey() method needs further thought
Review at http://gwt-code-reviews.appspot.com/277801
Review by: jgw@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7805 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/client/Column.java b/bikeshed/src/com/google/gwt/bikeshed/list/client/Column.java
index e2d9d41..730427c 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/list/client/Column.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/client/Column.java
@@ -36,18 +36,33 @@
*/
// TODO - when can we get rid of a view data object?
// TODO - should viewData implement some interface? (e.g., with commit/rollback/dispose)
-public abstract class Column<T, C, V> {
+public abstract class Column<T, C, V> implements HasKey<T> {
protected final Cell<C, V> cell;
- protected Map<T, V> viewDataMap = new HashMap<T, V>();
protected FieldUpdater<T, C, V> fieldUpdater;
+ protected Map<Object, V> viewDataMap = new HashMap<Object, V>();
public Column(Cell<C, V> cell) {
this.cell = cell;
}
+ public boolean consumesEvents() {
+ return cell.consumesEvents();
+ }
+
+ /**
+ * Returns a key to be used to associate view data with the given object.
+ * The default implementation simply returns the object.
+ */
+ public Object getKey(T object) {
+ return object;
+ }
+
+ public abstract C getValue(T object);
+
public void onBrowserEvent(Element elem, final int index, final T object,
NativeEvent event) {
- V viewData = viewDataMap.get(object);
+ Object key = getKey(object);
+ V viewData = viewDataMap.get(key);
V newViewData = cell.onBrowserEvent(elem,
getValue(object), viewData, event, fieldUpdater == null ? null
: new ValueUpdater<C, V>() {
@@ -56,7 +71,7 @@
}
});
if (newViewData != viewData) {
- viewDataMap.put(object, newViewData);
+ viewDataMap.put(key, newViewData);
}
}
@@ -76,6 +91,4 @@
protected FieldUpdater<T, C, V> getFieldUpdater() {
return fieldUpdater;
}
-
- protected abstract C getValue(T object);
}
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/client/HasKey.java b/bikeshed/src/com/google/gwt/bikeshed/list/client/HasKey.java
new file mode 100644
index 0000000..76eb2cf
--- /dev/null
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/client/HasKey.java
@@ -0,0 +1,35 @@
+/*
+ * 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.client;
+
+/**
+ * An interface for extracting a key from a value. The extracted key
+ * must contain suitable implementations of hashCode() and equals().
+ *
+ * @param <C> the value type for which keys are to be returned
+ */
+public interface HasKey<C> {
+
+ /**
+ * 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);
+}
\ No newline at end of file
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 04f0eb0..4a4c0da 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeNodeView.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeNodeView.java
@@ -20,6 +20,7 @@
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style;
+import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.user.client.ui.RequiresResize;
@@ -39,6 +40,8 @@
private int level;
+ private int maxColumns;
+
private String path;
/**
@@ -47,17 +50,19 @@
* @param tree the parent {@link TreeView}
* @param parent the parent {@link TreeNodeView}
* @param parentNodeInfo the {@link NodeInfo} of the parent
- * @param elem the outer element of this {@link TreeNodeView}.
+ * @param elem the outer element of this {@link TreeNodeView}
* @param value the value of this node
+ * @param maxColumns the maximum number of columns to display
*/
SideBySideTreeNodeView(final TreeView tree, final SideBySideTreeNodeView<?> parent,
NodeInfo<T> parentNodeInfo, Element elem, T value, int level, String path,
- int columnWidth) {
+ int columnWidth, int maxColumns) {
super(tree, parent, parentNodeInfo, value);
this.imageLeft = columnWidth - 16 - tree.getImageWidth();
this.level = level;
this.path = path;
this.columnWidth = columnWidth;
+ this.maxColumns = maxColumns;
setElement(elem);
}
@@ -66,7 +71,7 @@
protected <C> TreeNodeView<C> createTreeNodeView(NodeInfo<C> nodeInfo,
Element childElem, C childValue, Void viewData, int idx) {
return new SideBySideTreeNodeView<C>(getTree(), this, nodeInfo, childElem,
- childValue, level + 1, path + "-" + idx, columnWidth);
+ childValue, level + 1, path + "-" + idx, columnWidth, maxColumns);
}
@Override
@@ -188,7 +193,7 @@
private Element createContainer(int level) {
// Resize the root element
Element rootElement = getTree().getElement();
- rootElement.getStyle().setWidth((level + 1) * columnWidth, Unit.PX);
+ rootElement.getStyle().setWidth(Math.min(maxColumns, level + 1) * columnWidth, Unit.PX);
// Create children of the root container as needed.
int childCount = rootElement.getChildCount();
@@ -198,12 +203,26 @@
Style style = div.getStyle();
style.setPosition(Position.ABSOLUTE);
style.setTop(0, Unit.PX);
- style.setLeft(level * columnWidth, Unit.PX);
style.setWidth(columnWidth, Unit.PX);
childCount++;
}
+ Element child = rootElement.getFirstChild().cast();
+
+ int x = Math.min(0, maxColumns - (level + 1));
+ while (child != null) {
+ Style style = child.getStyle();
+ style.setLeft(x * columnWidth, Unit.PX);
+ if (x < 0) {
+ style.setDisplay(Display.NONE);
+ } else {
+ style.clearDisplay();
+ }
+ child = child.getNextSibling().cast();
+ x++;
+ }
+
return rootElement.getChild(level).cast();
}
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 0a6616c..f8c3b94 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeView.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeView.java
@@ -31,10 +31,13 @@
*/
public class SideBySideTreeView extends TreeView {
- protected int columnWidth = 100;
+ protected int columnWidth;
+
+ protected int maxColumns;
/**
- * Construct a new {@link TreeView}.
+ * Construct a new {@link TreeView} that will display as many columns as
+ * needed.
*
* @param <T> the type of data in the root node
* @param viewModel the {@link TreeViewModel} that backs the tree
@@ -43,9 +46,24 @@
*/
public <T> SideBySideTreeView(TreeViewModel viewModel, T rootValue,
int columnWidth) {
+ this(viewModel, rootValue, columnWidth, Integer.MAX_VALUE);
+ }
+
+ /**
+ * Construct a new {@link TreeView}.
+ *
+ * @param <T> the type of data in the root node
+ * @param viewModel the {@link TreeViewModel} that backs the tree
+ * @param rootValue the hidden root value of the tree
+ * @param columnWidth the width of each column
+ * @param maxColumns the maximum number of columns to display horizontally.
+ */
+ public <T> SideBySideTreeView(TreeViewModel viewModel, T rootValue,
+ int columnWidth, int maxColumns) {
super(viewModel);
this.columnWidth = columnWidth;
+ this.maxColumns = maxColumns;
Element rootElement = Document.get().createDivElement();
rootElement.setClassName("gwt-sstree");
@@ -59,7 +77,7 @@
// Associate a view with the item.
TreeNodeView<T> root = new SideBySideTreeNodeView<T>(this, null, null,
- rootElement, rootValue, 0, "gwt-sstree", columnWidth);
+ rootElement, rootValue, 0, "gwt-sstree", columnWidth, maxColumns);
setRootNode(root);
root.setState(true);
}
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 4b6393e..12cd722 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeViewModel.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeViewModel.java
@@ -17,6 +17,7 @@
import com.google.gwt.bikeshed.cells.client.Cell;
import com.google.gwt.bikeshed.cells.client.ValueUpdater;
+import com.google.gwt.bikeshed.list.client.HasKey;
import com.google.gwt.bikeshed.list.shared.ListModel;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
@@ -29,7 +30,7 @@
/**
* The info needed to create a {@link TreeNodeView}.
*/
- interface NodeInfo<C> {
+ interface NodeInfo<C> extends HasKey<C> {
/**
* Get the {@link Cell} used to render child nodes.
*
@@ -38,16 +39,6 @@
Cell<C, Void> 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
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/Columns.java b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/Columns.java
index 6e9b848..ae4ed2d 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/Columns.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/Columns.java
@@ -32,7 +32,7 @@
static Column<StockQuote, String, Void> buyColumn = new Column<StockQuote, String, Void>(
new ButtonCell()) {
@Override
- protected String getValue(StockQuote object) {
+ public String getValue(StockQuote object) {
return "Buy";
}
};
@@ -40,7 +40,7 @@
static Column<StockQuote, String, Void> changeColumn = new Column<StockQuote, String, Void>(
new ChangeCell()) {
@Override
- protected String getValue(StockQuote object) {
+ public String getValue(StockQuote object) {
return object.getChange();
}
};
@@ -48,7 +48,7 @@
static Column<StockQuote, Integer, Void> dollarsColumn = new Column<StockQuote, Integer, Void>(
new CurrencyCell()) {
@Override
- protected Integer getValue(StockQuote object) {
+ public Integer getValue(StockQuote object) {
return object.getPrice() * object.getSharesOwned();
}
};
@@ -56,7 +56,7 @@
static Column<StockQuote, Boolean, Void> favoriteColumn = new Column<StockQuote, Boolean, Void>(
new CheckboxCell()) {
@Override
- protected Boolean getValue(StockQuote object) {
+ public Boolean getValue(StockQuote object) {
return object.isFavorite();
}
};
@@ -67,7 +67,7 @@
static Column<StockQuote, String, Void> nameColumn = new Column<StockQuote, String, Void>(
nameCell) {
@Override
- protected String getValue(StockQuote object) {
+ public String getValue(StockQuote object) {
return object.getName();
}
};
@@ -75,7 +75,7 @@
static Column<StockQuote, Integer, Void> priceColumn = new Column<StockQuote, Integer, Void>(
new CurrencyCell()) {
@Override
- protected Integer getValue(StockQuote object) {
+ public Integer getValue(StockQuote object) {
return object.getPrice();
}
};
@@ -83,7 +83,7 @@
static Column<StockQuote, Integer, Void> profitLossColumn = new Column<StockQuote, Integer, Void>(
new ProfitLossCell()) {
@Override
- protected Integer getValue(StockQuote object) {
+ public Integer getValue(StockQuote object) {
return object.getValue() - object.getTotalPaid();
}
};
@@ -91,7 +91,7 @@
static Column<StockQuote, String, Void> sellColumn = new Column<StockQuote, String, Void>(
new ButtonCell()) {
@Override
- protected String getValue(StockQuote object) {
+ public String getValue(StockQuote object) {
return "Sell";
}
};
@@ -99,7 +99,7 @@
static Column<StockQuote, String, Void> sharesColumn = new Column<StockQuote, String, Void>(
new TextCell()) {
@Override
- protected String getValue(StockQuote object) {
+ public String getValue(StockQuote object) {
return "" + object.getSharesOwned();
}
};
@@ -107,7 +107,7 @@
static Column<Transaction, String, Void> subtotalColumn = new Column<Transaction, String, Void>(
new TextCell()) {
@Override
- protected String getValue(Transaction object) {
+ public String getValue(Transaction object) {
int price = object.getActualPrice() * object.getQuantity();
return (object.isBuy() ? " (" : " ")
+ StocksDesktop.getFormattedPrice(price) + (object.isBuy() ? ")" : "");
@@ -117,7 +117,7 @@
static Column<StockQuote, String, Void> tickerColumn = new Column<StockQuote, String, Void>(
new TextCell()) {
@Override
- protected String getValue(StockQuote object) {
+ public String getValue(StockQuote object) {
return object.getTicker();
}
};
@@ -125,7 +125,7 @@
static Column<Transaction, String, Void> transactionColumn = new Column<Transaction, String, Void>(
new TextCell()) {
@Override
- protected String getValue(Transaction object) {
+ public String getValue(Transaction object) {
return object.toString();
}
};
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/tree/client/TreeSample.java b/bikeshed/src/com/google/gwt/sample/bikeshed/tree/client/TreeSample.java
index 1476fe8..4f91d91 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/tree/client/TreeSample.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/tree/client/TreeSample.java
@@ -33,7 +33,7 @@
RootPanel.get().add(new HTML("<hr>"));
- SideBySideTreeView sstree = new SideBySideTreeView(new MyTreeViewModel(), "...", 100);
+ SideBySideTreeView sstree = new SideBySideTreeView(new MyTreeViewModel(), "...", 100, 4);
sstree.setHeight("200px");
RootPanel.get().add(sstree);
}
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/validation/client/Validation.java b/bikeshed/src/com/google/gwt/sample/bikeshed/validation/client/Validation.java
index 88addf7..cac83e6 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/validation/client/Validation.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/validation/client/Validation.java
@@ -85,7 +85,7 @@
Column<Address, String, Void> stateColumn = new Column<Address, String, Void>(
new TextCell()) {
@Override
- protected String getValue(Address object) {
+ public String getValue(Address object) {
return object.state;
}
};
@@ -94,7 +94,12 @@
new Column<Address, String, ValidatableField<String>>(
new ValidatableInputCell()) {
@Override
- protected String getValue(Address object) {
+ public Object getKey(Address object) {
+ return object.key;
+ }
+
+ @Override
+ public String getValue(Address object) {
return object.zip;
}
};
@@ -128,7 +133,7 @@
Column<Address, String, Void> messageColumn = new Column<Address, String, Void>(
new TextCell()) {
@Override
- protected String getValue(Address object) {
+ public String getValue(Address object) {
return object.zipInvalid ? "Please fix the zip code" : "";
}
};