Checkpoint tree/list stuff:
No more DataSource interface
Added maxSize/increment to SimpleCellList constructor (not fully functional)
Fix tree node size 0 bug
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7748 8db76d5a-ed1c-0410-87a9-c151d255dfc7
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 aaef117..e0d3e43 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/list/client/SimpleCellList.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/client/SimpleCellList.java
@@ -22,9 +22,12 @@
import com.google.gwt.bikeshed.list.shared.ListModel;
import com.google.gwt.bikeshed.list.shared.ListRegistration;
import com.google.gwt.bikeshed.list.shared.SizeChangeEvent;
+import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Node;
+import com.google.gwt.dom.client.Style.Display;
+import com.google.gwt.dom.client.Style.Visibility;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.Widget;
@@ -40,48 +43,34 @@
private final Cell<T> cell;
private final ArrayList<T> data = new ArrayList<T>();
+ private int increment;
+ private int maxSize;
+ private ListModel<T> model;
+ private final Element showMoreElem;
private final Element tmpElem;
private ListRegistration reg;
private ValueUpdater<T> valueUpdater;
-
- public SimpleCellList(ListModel<T> model, Cell<T> cell) {
+
+ public SimpleCellList(ListModel<T> model, Cell<T> cell, int maxSize, int increment) {
+ this.maxSize = maxSize;
+ this.increment = increment;
+ this.model = model;
this.cell = cell;
+
tmpElem = Document.get().createDivElement();
+
+ showMoreElem = Document.get().createDivElement();
+ showMoreElem.setInnerHTML("<i>Show " + increment + " more</i>");
+ showMoreElem.getStyle().setDisplay(Display.NONE);
// TODO: find some way for cells to communicate what they're interested in.
- setElement(Document.get().createDivElement());
+ DivElement outerDiv = Document.get().createDivElement();
+ DivElement innerDiv = Document.get().createDivElement();
+ outerDiv.appendChild(innerDiv);
+ outerDiv.appendChild(showMoreElem);
+ setElement(outerDiv);
sinkEvents(Event.ONCLICK);
sinkEvents(Event.ONCHANGE);
-
- // Register for model events.
- reg = model.addListHandler(new ListHandler<T>() {
- public void onDataChanged(ListEvent<T> event) {
- int start = event.getStart(), len = event.getLength();
- List<T> values = event.getValues();
- for (int i = 0; i < len; ++i) {
- data.set(start + i, values.get(i));
- }
- render(start, len, values);
- }
-
- public void onSizeChanged(SizeChangeEvent event) {
- int size = event.getSize();
-
- // Is there no better way than this mess?
- data.ensureCapacity(size);
- while (data.size() < size) {
- data.add(null);
- }
- // TODO: This only grows. It needs to shrink as well.
-
- gc(size);
- reg.setRangeOfInterest(0, size);
- }
- });
-
- // Start with no range of interest. This will be updated as soon as the
- // list size changes.
- reg.setRangeOfInterest(0, 0);
}
@Override
@@ -97,11 +86,63 @@
cell.onBrowserEvent(target, data.get(idx), event, valueUpdater);
}
}
-
+
public void setValueUpdater(ValueUpdater<T> valueUpdater) {
this.valueUpdater = valueUpdater;
}
+ @Override
+ protected void onLoad() {
+ super.onLoad();
+
+ // Register for model events.
+ this.reg = model.addListHandler(new ListHandler<T>() {
+ public void onDataChanged(ListEvent<T> event) {
+ int start = event.getStart(), len = event.getLength();
+ List<T> values = event.getValues();
+ for (int i = 0; i < len; ++i) {
+ data.set(start + i, values.get(i));
+ }
+ render(start, len, values);
+ }
+
+ public void onSizeChanged(SizeChangeEvent event) {
+ int size = event.getSize();
+ if (size > maxSize) {
+ showMoreElem.getStyle().clearDisplay();
+ } else {
+ showMoreElem.getStyle().setDisplay(Display.NONE);
+ }
+
+ int dataSize = data.size();
+ if (size < dataSize) {
+ while (size < dataSize) {
+ data.remove(dataSize - 1);
+ dataSize--;
+ }
+ } else {
+ data.ensureCapacity(size);
+ while (dataSize < size) {
+ data.add(null);
+ dataSize++;
+ }
+ }
+
+ // TODO: This only grows. It needs to shrink as well.
+ gc(size);
+ }
+ });
+
+ // Request up to maxSize elements
+ reg.setRangeOfInterest(0, maxSize);
+ }
+
+ @Override
+ protected void onUnload() {
+ this.reg.removeHandler();
+ this.reg = null;
+ }
+
private void gc(int size) {
// Remove unused children if the size shrinks.
int childCount = getElement().getChildCount();
@@ -111,7 +152,7 @@
}
private void render(int start, int len, List<T> values) {
- Element parent = getElement();
+ Element parent = getElement().getFirstChildElement();
int childCount = parent.getChildCount();
// Create innerHTML for the new items.
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/shared/AbstractListModel.java b/bikeshed/src/com/google/gwt/bikeshed/list/shared/AbstractListModel.java
index f46dba0..43fdca2 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/list/shared/AbstractListModel.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/shared/AbstractListModel.java
@@ -82,7 +82,7 @@
public void setRangeOfInterest(int start, int length) {
this.start = start;
this.length = length;
- onRangeChanged();
+ onRangeChanged(start, length);
}
protected ListHandler<T> getHandler() {
@@ -126,7 +126,7 @@
/**
* Called when a view changes its range of interest.
*/
- protected abstract void onRangeChanged();
+ protected abstract void onRangeChanged(int start, int length);
/**
* Inform the views of the total number of items that are available.
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/shared/AsyncListModel.java b/bikeshed/src/com/google/gwt/bikeshed/list/shared/AsyncListModel.java
index 7631110..4c5f6f7 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/list/shared/AsyncListModel.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/shared/AsyncListModel.java
@@ -18,55 +18,31 @@
import java.util.List;
/**
- * Asynchronous version of a {@link ListModel}.
+ * An implementation of {@link AbstractListModel} that allows the data to be
+ * modified.
*
- * @param <T> the data type
+ * @param <T> the data type of records in the list
*/
-public class AsyncListModel<T> extends AbstractListModel<T> {
-
+public abstract class AsyncListModel<T> extends AbstractListModel<T> {
+
/**
- * The source of data for the list model.
+ * Inform the views of the total number of items that are available.
*
- * @param <T> the data type
+ * @param size the new size
+ * @param exact true if the size is exact, false if it is a guess
*/
- public static interface DataSource<T> {
-
- /**
- * Request that the data source pushes new data to the client. The data
- * source should call {@link #updateViewData} and/or {@link #updateDataSize}
- * when the data is available.
- *
- * @param listModel the model requesting the data
- */
- void requestData(AsyncListModel<T> listModel);
- }
-
- /**
- * The data source.
- */
- private DataSource<T> dataSource;
-
- /**
- * Construct a new {@link AsyncListModel}.
- *
- * @param dataSource the data source
- */
- public AsyncListModel(DataSource<T> dataSource) {
- this.dataSource = dataSource;
- }
-
- @Override
public void updateDataSize(int size, boolean exact) {
super.updateDataSize(size, exact);
}
- @Override
+ /**
+ * Inform the views of the new data.
+ *
+ * @param start the start index
+ * @param length the length of the data
+ * @param values the data values
+ */
public void updateViewData(int start, int length, List<T> values) {
super.updateViewData(start, length, values);
}
-
- @Override
- protected void onRangeChanged() {
- dataSource.requestData(this);
- }
}
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 74e8977..574230f 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListListModel.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListListModel.java
@@ -222,7 +222,9 @@
}
@Override
- protected void onRangeChanged() {
+ protected void onRangeChanged(int start, int length) {
+ // TODO - update size only when needed
+ // TODO - update only relevant range of data
updateDataSize(listWrapper.size(), true);
updateViewData(0, listWrapper.size(), listWrapper);
}
diff --git a/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/PlayerScoresWidget.java b/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/PlayerScoresWidget.java
index 14a0067..49c1be2 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/PlayerScoresWidget.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/PlayerScoresWidget.java
@@ -75,6 +75,6 @@
@UiFactory
SimpleCellList<PlayerInfo> createListView() {
- return new SimpleCellList<PlayerInfo>(model, new PlayerInfoCell());
+ return new SimpleCellList<PlayerInfo>(model, new PlayerInfoCell(), 1, 1);
}
}
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 6aa5f9f..ab01470 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
@@ -19,7 +19,6 @@
import com.google.gwt.bikeshed.list.shared.AsyncListModel;
import com.google.gwt.bikeshed.list.shared.ListListModel;
import com.google.gwt.bikeshed.list.shared.Range;
-import com.google.gwt.bikeshed.list.shared.AsyncListModel.DataSource;
import com.google.gwt.bikeshed.sample.stocks.client.TransactionTreeViewModel.SectorListModel;
import com.google.gwt.bikeshed.sample.stocks.shared.PlayerInfo;
import com.google.gwt.bikeshed.sample.stocks.shared.StockQuote;
@@ -111,26 +110,25 @@
public void onModuleLoad() {
// Create the various models. Do this before binding the UI, because some
// of the UiFactories need the models to instantiate their widgets.
- searchListModel = new AsyncListModel<StockQuote>(
- new DataSource<StockQuote>() {
- public void requestData(AsyncListModel<StockQuote> listModel) {
- update();
- }
- });
+ searchListModel = new AsyncListModel<StockQuote>() {
+ @Override
+ protected void onRangeChanged(int start, int length) {
+ update();
+ }
+ };
- favoritesListModel = new AsyncListModel<StockQuote>(
- new DataSource<StockQuote>() {
- public void requestData(AsyncListModel<StockQuote> listModel) {
- update();
- }
- });
+ favoritesListModel = new AsyncListModel<StockQuote>() {
+ @Override
+ protected void onRangeChanged(int start, int length) {
+ update();
+ }
+ };
- playerScoresListModel = new AsyncListModel<PlayerInfo>(
- new DataSource<PlayerInfo>() {
- public void requestData(AsyncListModel<PlayerInfo> listModel) {
- // Player cannot request data from this view.
- }
- });
+ playerScoresListModel = new AsyncListModel<PlayerInfo>() {
+ @Override
+ protected void onRangeChanged(int start, int length) {
+ }
+ };
treeModel = new TransactionTreeViewModel(this, favoritesListModel,
transactionListListModelsByTicker);
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 4983262..039ee98 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
@@ -42,18 +42,18 @@
String sector;
- public SectorListModel(final Updater updater, String sector) {
- super(new DataSource<StockQuote>() {
- public void requestData(AsyncListModel<StockQuote> listModel) {
- updater.update();
- }
- });
+ public SectorListModel(String sector) {
this.sector = sector;
}
public String getSector() {
return sector;
}
+
+ @Override
+ protected void onRangeChanged(int start, int length) {
+ updater.update();
+ }
}
static class TransactionCell extends Cell<Transaction> {
@@ -131,7 +131,7 @@
}
});
} else if (value instanceof String) {
- SectorListModel listModel = new SectorListModel(updater, (String) value);
+ SectorListModel listModel = new SectorListModel((String) value);
sectorListModels.put((String) value, listModel);
return new TreeViewModel.DefaultNodeInfo<StockQuote>(listModel, STOCK_QUOTE_CELL) {
@Override
diff --git a/bikeshed/src/com/google/gwt/bikeshed/sample/tree/client/MyTreeViewModel.java b/bikeshed/src/com/google/gwt/bikeshed/sample/tree/client/MyTreeViewModel.java
index a4ed1da..61596c3 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/sample/tree/client/MyTreeViewModel.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/sample/tree/client/MyTreeViewModel.java
@@ -18,7 +18,7 @@
import com.google.gwt.bikeshed.cells.client.ButtonCell;
import com.google.gwt.bikeshed.cells.client.Cell;
import com.google.gwt.bikeshed.cells.client.ValueUpdater;
-import com.google.gwt.bikeshed.list.shared.AsyncListModel;
+import com.google.gwt.bikeshed.list.shared.AbstractListModel;
import com.google.gwt.bikeshed.list.shared.ListModel;
import com.google.gwt.bikeshed.tree.client.TreeNode;
import com.google.gwt.bikeshed.tree.client.TreeViewModel;
@@ -35,47 +35,53 @@
*/
public class MyTreeViewModel implements TreeViewModel {
- private static class IntegerListModel extends AsyncListModel<Integer> {
- public IntegerListModel(final int length) {
- super(new DataSource<Integer>() {
- public void requestData(AsyncListModel<Integer> listModel) {
- listModel.updateDataSize(1, true);
- List<Integer> values = new ArrayList<Integer>(1);
- values.add(length);
- listModel.updateViewData(0, 1, values);
- }
- });
+ private static class IntegerListModel extends AbstractListModel<Integer> {
+ int wordLength;
+
+ public IntegerListModel(int wordLength) {
+ this.wordLength = wordLength;
+ }
+
+ @Override
+ protected void onRangeChanged(int start, int length) {
+ List<Integer> values = new ArrayList<Integer>(1);
+ values.add(wordLength);
+ updateDataSize(1, true);
+ updateViewData(0, 1, values);
}
}
- private static class StringListModel extends AsyncListModel<String> {
+ private static class StringListModel extends AbstractListModel<String> {
+ String value;
+
public StringListModel(final String value) {
- super(new DataSource<String>() {
- public void requestData(final AsyncListModel<String> listModel) {
- String prefix = value.endsWith("...") ? value.substring(0,
- value.length() - 3) : value;
- dataService.getNext(prefix, new AsyncCallback<List<String>>() {
- public void onFailure(Throwable caught) {
- String message = caught.getMessage();
- if (message.contains("Not logged in")) {
- // Force the user to login.
- Window.Location.reload();
- } else {
- Window.alert("ERROR: " + caught.getMessage());
- }
- }
+ this.value = value;
+ }
+
+ @Override
+ protected void onRangeChanged(int start, int length) {
+ String prefix = value.endsWith("...") ? value.substring(0,
+ value.length() - 3) : value;
+ dataService.getNext(prefix, new AsyncCallback<List<String>>() {
+ public void onFailure(Throwable caught) {
+ String message = caught.getMessage();
+ if (message.contains("Not logged in")) {
+ // Force the user to login.
+ Window.Location.reload();
+ } else {
+ Window.alert("ERROR: " + caught.getMessage());
+ }
+ }
- public void onSuccess(final List<String> result) {
- // Use a timer to simulate network delay.
- new Timer() {
- @Override
- public void run() {
- listModel.updateDataSize(result.size(), true);
- listModel.updateViewData(0, result.size(), result);
- }
- }.schedule(500);
+ public void onSuccess(final List<String> result) {
+ // Use a timer to simulate network delay.
+ new Timer() {
+ @Override
+ public void run() {
+ updateDataSize(result.size(), true);
+ updateViewData(0, result.size(), result);
}
- });
+ }.schedule(500);
}
});
}
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 4502c97..3e25271 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeNodeView.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeNodeView.java
@@ -426,8 +426,13 @@
public void onSizeChanged(SizeChangeEvent event) {
if (event.getSize() == 0 && event.isExact()) {
- // Close the node
- setState(false, false);
+ ensureChildContainer().setInnerHTML("<i>no data</i>");
+ if (children != null) {
+ for (TreeNodeView<?> child : children) {
+ child.cleanup();
+ }
+ children = null;
+ }
}
}
});