summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Ahlroos <john@vaadin.com>2014-08-07 16:04:17 +0300
committerJohn Ahlroos <john@vaadin.com>2014-08-19 10:37:58 +0300
commit5dfdd40d00dc0f7a2eea19f8c77485f1afcf77ad (patch)
tree30b92381f2bce518697d2ead721d12cb97ceb6c5
parentc1a873bc9e47b98c58b298aa6935ab0853e6963f (diff)
downloadvaadin-framework-5dfdd40d00dc0f7a2eea19f8c77485f1afcf77ad.tar.gz
vaadin-framework-5dfdd40d00dc0f7a2eea19f8c77485f1afcf77ad.zip
Removed SortableColumnHeaderRenderer #13334
Change-Id: I3f15765228428049febfe3a8d5966c3631d010a9
-rw-r--r--client/src/com/vaadin/client/ui/grid/Grid.java524
-rw-r--r--client/src/com/vaadin/client/ui/grid/GridHeader.java28
-rw-r--r--client/src/com/vaadin/client/ui/grid/GridStaticSection.java19
-rw-r--r--shared/src/com/vaadin/shared/ui/grid/GridConstants.java10
4 files changed, 260 insertions, 321 deletions
diff --git a/client/src/com/vaadin/client/ui/grid/Grid.java b/client/src/com/vaadin/client/ui/grid/Grid.java
index aae7f046b6..a407038917 100644
--- a/client/src/com/vaadin/client/ui/grid/Grid.java
+++ b/client/src/com/vaadin/client/ui/grid/Grid.java
@@ -30,6 +30,7 @@ import com.google.gwt.dom.client.BrowserEvents;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.EventTarget;
import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.dom.client.TableCellElement;
import com.google.gwt.dom.client.Touch;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.shared.HandlerRegistration;
@@ -464,6 +465,83 @@ public class Grid<T> extends Composite implements
}
/**
+ * Class for sorting at a later time
+ */
+ private class LazySorter extends Timer {
+
+ private Cell cell;
+
+ private boolean multisort;
+
+ @Override
+ public void run() {
+ SortOrder sortingOrder = getSortOrder(getColumnFromVisibleIndex(cell
+ .getColumn()));
+ if (sortingOrder == null) {
+ /*
+ * No previous sorting, sort Ascending
+ */
+ sort(cell, SortDirection.ASCENDING, multisort);
+
+ } else {
+ // Toggle sorting
+ SortDirection direction = sortingOrder.getDirection();
+ if (direction == SortDirection.ASCENDING) {
+ sort(cell, SortDirection.DESCENDING, multisort);
+ } else {
+ sort(cell, SortDirection.ASCENDING, multisort);
+ }
+ }
+ }
+
+ /**
+ * Set the cell reference to the primary cell that sorting should be
+ * done for.
+ *
+ * @param cell
+ *
+ */
+ public void setCellReference(Cell cell) {
+ this.cell = cell;
+ }
+
+ /**
+ * Is multiple column sorting is enabled/disabled
+ *
+ * @param multisort
+ * true if multiple column sorting is enabled
+ */
+ public void setMultisort(boolean multisort) {
+ this.multisort = multisort;
+ }
+
+ /**
+ * Sorts the column in a direction
+ */
+ private void sort(Cell cell, SortDirection direction, boolean multisort) {
+ TableCellElement th = TableCellElement.as(cell.getElement());
+
+ // Apply primary sorting on clicked column
+ GridColumn<?, ?> columnInstance = getColumnFromVisibleIndex(cell
+ .getColumn());
+ Sort sorting = Sort.by(columnInstance, direction);
+
+ // Re-apply old sorting to the sort order
+ if (multisort) {
+ for (SortOrder order : getSortOrder()) {
+ if (order.getColumn() != columnInstance) {
+ sorting = sorting.then(order.getColumn(),
+ order.getDirection());
+ }
+ }
+ }
+
+ // Perform sorting
+ Grid.this.sort(sorting);
+ }
+ }
+
+ /**
* Escalator used internally by grid to render the rows
*/
private Escalator escalator = GWT.create(Escalator.class);
@@ -511,6 +589,8 @@ public class Grid<T> extends Composite implements
private final ActiveCellHandler activeCellHandler;
+ private final LazySorter lazySorter = new LazySorter();
+
/**
* Enumeration for easy setting of selection mode.
*/
@@ -552,13 +632,6 @@ public class Grid<T> extends Composite implements
protected abstract <T> SelectionModel<T> createModel();
}
- class SortableColumnHeaderRenderer extends
- AbstractGridColumn.SortableColumnHeaderRenderer {
- SortableColumnHeaderRenderer(Renderer<String> cellRenderer) {
- super(Grid.this, cellRenderer);
- }
- }
-
/**
* Base class for grid columns internally used by the Grid. The user should
* use {@link GridColumn} when creating new columns.
@@ -572,274 +645,7 @@ public class Grid<T> extends Composite implements
static abstract class AbstractGridColumn<C, T> implements HasVisibility {
/**
- * Renderer for columns which are sortable
- *
- * FIXME Currently assumes multisorting
- */
- static class SortableColumnHeaderRenderer extends
- ComplexRenderer<String> {
-
- private Grid<?> grid;
-
- /**
- * Delay before a long tap action is triggered. Number in
- * milliseconds.
- */
- private static final int LONG_TAP_DELAY = 500;
-
- /**
- * The threshold in pixels a finger can move while long tapping.
- */
- private static final int LONG_TAP_THRESHOLD = 3;
-
- /**
- * Class for sorting at a later time
- */
- private class LazySorter extends Timer {
-
- private Cell cell;
-
- private boolean multisort;
-
- @Override
- public void run() {
- SortOrder sortingOrder = getSortingOrder(grid
- .getColumnFromVisibleIndex(cell.getColumn()));
- if (sortingOrder == null) {
- /*
- * No previous sorting, sort Ascending
- */
- sort(cell, SortDirection.ASCENDING, multisort);
-
- } else {
- // Toggle sorting
- SortDirection direction = sortingOrder.getDirection();
- if (direction == SortDirection.ASCENDING) {
- sort(cell, SortDirection.DESCENDING, multisort);
- } else {
- sort(cell, SortDirection.ASCENDING, multisort);
- }
- }
- }
-
- public void setCurrentCell(Cell cell) {
- this.cell = cell;
- }
-
- public void setMultisort(boolean multisort) {
- this.multisort = multisort;
- }
- }
-
- private final LazySorter lazySorter = new LazySorter();
-
- private Renderer<String> cellRenderer;
-
- private Point touchStartPoint;
-
- /**
- * Creates column renderer with sort indicators
- *
- * @param cellRenderer
- * The actual cell renderer
- */
- public SortableColumnHeaderRenderer(Grid<?> grid,
- Renderer<String> cellRenderer) {
- this.grid = grid;
- this.cellRenderer = cellRenderer;
- }
-
- @Override
- public void render(FlyweightCell cell, String data) {
-
- // Render cell
- this.cellRenderer.render(cell, data);
-
- /*
- * FIXME This grid null check is needed since Grid.addColumns()
- * is invoking Escalator.insertColumn() before the grid instance
- * for the column is set resulting in the first render() being
- * done without a grid instance. Remove the if statement when
- * this is fixed.
- */
- if (grid != null) {
- GridColumn<?, ?> column = grid
- .getColumnFromVisibleIndex(cell.getColumn());
- SortOrder sortingOrder = getSortingOrder(column);
- Element cellElement = cell.getElement();
- if (column.isSortable()) {
- if (sortingOrder != null) {
- if (SortDirection.ASCENDING == sortingOrder
- .getDirection()) {
- cellElement.replaceClassName("sort-desc",
- "sort-asc");
- } else {
- cellElement.replaceClassName("sort-asc",
- "sort-desc");
- }
-
- int sortIndex = grid.getSortOrder().indexOf(
- sortingOrder);
- if (sortIndex > -1
- && grid.getSortOrder().size() > 1) {
- // Show sort order indicator if column is sorted
- // and other sorted columns also exists.
- cellElement.setAttribute("sort-order",
- String.valueOf(sortIndex + 1));
-
- } else {
- cellElement.removeAttribute("sort-order");
- }
- } else {
- cleanup(cell);
- }
- } else {
- cleanup(cell);
- }
- }
- }
-
- private void cleanup(FlyweightCell cell) {
- Element cellElement = cell.getElement();
- cellElement.removeAttribute("sort-order");
- cellElement.removeClassName("sort-desc");
- cellElement.removeClassName("sort-asc");
- }
-
- @Override
- public Collection<String> getConsumedEvents() {
- return Arrays.asList(BrowserEvents.TOUCHSTART,
- BrowserEvents.TOUCHMOVE, BrowserEvents.TOUCHEND,
- BrowserEvents.TOUCHCANCEL, BrowserEvents.CLICK);
- }
-
- @Override
- public boolean onBrowserEvent(final Cell cell, NativeEvent event) {
-
- // Handle sorting events if column is sortable
- if (grid.getColumn(cell.getColumn()).isSortable()) {
-
- if (BrowserEvents.TOUCHSTART.equals(event.getType())) {
- if (event.getTouches().length() > 1) {
- return false;
- }
-
- event.preventDefault();
-
- Touch touch = event.getChangedTouches().get(0);
- touchStartPoint = new Point(touch.getClientX(),
- touch.getClientY());
-
- lazySorter.setCurrentCell(cell);
- lazySorter.setMultisort(true);
- lazySorter.schedule(LONG_TAP_DELAY);
-
- } else if (BrowserEvents.TOUCHMOVE.equals(event.getType())) {
- if (event.getTouches().length() > 1) {
- return false;
- }
-
- event.preventDefault();
-
- Touch touch = event.getChangedTouches().get(0);
- double diffX = Math.abs(touch.getClientX()
- - touchStartPoint.getX());
- double diffY = Math.abs(touch.getClientY()
- - touchStartPoint.getY());
-
- // Cancel long tap if finger strays too far from
- // starting point
- if (diffX > LONG_TAP_THRESHOLD
- || diffY > LONG_TAP_THRESHOLD) {
- lazySorter.cancel();
- }
-
- } else if (BrowserEvents.TOUCHEND.equals(event.getType())) {
- if (event.getTouches().length() > 0) {
- return false;
- }
-
- if (lazySorter.isRunning()) {
- // Not a long tap yet, perform single sort
- lazySorter.cancel();
- lazySorter.setMultisort(false);
- lazySorter.run();
- }
-
- } else if (BrowserEvents.TOUCHCANCEL
- .equals(event.getType())) {
- if (event.getChangedTouches().length() > 1) {
- return false;
- }
-
- lazySorter.cancel();
-
- } else if (BrowserEvents.CLICK.equals(event.getType())) {
- lazySorter.setCurrentCell(cell);
- lazySorter.setMultisort(event.getShiftKey());
- lazySorter.run();
-
- // Active cell handling is also monitoring the click
- // event so we allow event to propagate for it
- return false;
- }
- return true;
- }
- return false;
-
- }
-
- protected void removeFromRow(HeaderRow row) {
- row.setRenderer(new Renderer<String>() {
- @Override
- public void render(FlyweightCell cell, String data) {
- cleanup(cell);
- }
- });
- grid.refreshHeader();
- row.setRenderer(cellRenderer);
- grid.refreshHeader();
- }
-
- /**
- * Sorts the column in a direction
- */
- private void sort(Cell cell, SortDirection direction,
- boolean multisort) {
- // Apply primary sorting on clicked column
- GridColumn<?, ?> columnInstance = grid
- .getColumnFromVisibleIndex(cell.getColumn());
- Sort sorting = Sort.by(columnInstance, direction);
-
- // Re-apply old sorting to the sort order
- if (multisort) {
- for (SortOrder order : grid.getSortOrder()) {
- if (order.getColumn() != columnInstance) {
- sorting = sorting.then(order.getColumn(),
- order.getDirection());
- }
- }
- }
-
- // Perform sorting
- grid.sort(sorting);
- }
-
- /**
- * Finds the sorting order for this column
- */
- private SortOrder getSortingOrder(GridColumn<?, ?> column) {
- for (SortOrder order : grid.getSortOrder()) {
- if (order.getColumn() == column) {
- return order;
- }
- }
- return null;
- }
- }
-
- /**
- * The grid the column is associated with
+ * the column is associated with
*/
private Grid<T> grid;
@@ -1187,13 +993,14 @@ public class Grid<T> extends Composite implements
int index = columnIndices.get(cell.getColumn());
final StaticCell metadata = staticRow.getCell(index);
+ // Decorate default row with sorting indicators
+ if (staticRow instanceof HeaderRow) {
+ addSortingIndicatorsToHeaderRow((HeaderRow) staticRow, cell);
+ }
+
// Assign colspan to cell before rendering
cell.setColSpan(metadata.getColspan());
- // Decorates cell with possible indicators onto the cell.
- // Actual content is rendered below.
- staticRow.getRenderer().render(cell, null);
-
switch (metadata.getType()) {
case TEXT:
cell.getElement().setInnerText(metadata.getText());
@@ -1212,6 +1019,57 @@ public class Grid<T> extends Composite implements
}
}
+ private void addSortingIndicatorsToHeaderRow(HeaderRow headerRow,
+ FlyweightCell cell) {
+
+ cleanup(cell);
+
+ GridColumn<?, ?> column = getColumnFromVisibleIndex(cell
+ .getColumn());
+ SortOrder sortingOrder = getSortOrder(column);
+ if (!headerRow.isDefault() || !column.isSortable()
+ || sortingOrder == null) {
+ // Only apply sorting indicators to sortable header columns in
+ // the default header row
+ return;
+ }
+
+ Element cellElement = cell.getElement();
+
+ if (SortDirection.ASCENDING == sortingOrder.getDirection()) {
+ cellElement.addClassName("sort-asc");
+ } else {
+ cellElement.addClassName("sort-desc");
+ }
+
+ int sortIndex = Grid.this.getSortOrder().indexOf(sortingOrder);
+ if (sortIndex > -1 && Grid.this.getSortOrder().size() > 1) {
+ // Show sort order indicator if column is
+ // sorted and other sorted columns also exists.
+ cellElement.setAttribute("sort-order",
+ String.valueOf(sortIndex + 1));
+ }
+ }
+
+ /**
+ * Finds the sort order for this column
+ */
+ private SortOrder getSortOrder(GridColumn<?, ?> column) {
+ for (SortOrder order : Grid.this.getSortOrder()) {
+ if (order.getColumn() == column) {
+ return order;
+ }
+ }
+ return null;
+ }
+
+ private void cleanup(FlyweightCell cell) {
+ Element cellElement = cell.getElement();
+ cellElement.removeAttribute("sort-order");
+ cellElement.removeClassName("sort-desc");
+ cellElement.removeClassName("sort-asc");
+ }
+
@Override
public void preAttach(Row row, Iterable<FlyweightCell> cellsToAttach) {
}
@@ -1333,6 +1191,9 @@ public class Grid<T> extends Composite implements
refreshBody();
}
});
+
+ // Sink header events
+ sinkEvents(getHeader().getConsumedEvents());
}
@Override
@@ -1371,7 +1232,7 @@ public class Grid<T> extends Composite implements
* The updater is invoked when body rows or columns are added or removed,
* the content of body cells is changed, or the body is scrolled to expose
* previously hidden content.
- *
+ *
* @return the new body updater instance
*/
protected EscalatorUpdater createBodyUpdater() {
@@ -1997,17 +1858,15 @@ public class Grid<T> extends Composite implements
// FIXME getFromVisibleIndex???
GridColumn<?, T> gridColumn = columns.get(cell.getColumn());
- Renderer<?> renderer;
if (container == escalator.getHeader()) {
- renderer = header.getRow(cell.getRow()).getRenderer();
+ if (getHeader().getRow(cell.getRow()).isDefault()) {
+ handleDefaultRowEvent(cell, event);
+ }
} else if (container == escalator.getFooter()) {
- renderer = footer.getRow(cell.getRow()).getRenderer();
- } else {
- renderer = gridColumn.getRenderer();
- }
-
- if (renderer instanceof ComplexRenderer) {
- ComplexRenderer<?> cplxRenderer = (ComplexRenderer<?>) renderer;
+ // NOP
+ } else if (gridColumn.getRenderer() instanceof ComplexRenderer) {
+ ComplexRenderer<?> cplxRenderer = (ComplexRenderer<?>) gridColumn
+ .getRenderer();
if (cplxRenderer.getConsumedEvents().contains(
event.getType())) {
if (cplxRenderer.onBrowserEvent(cell, event)) {
@@ -2027,6 +1886,81 @@ public class Grid<T> extends Composite implements
}
}
+ private Point rowEventTouchStartingPoint;
+
+ private boolean handleDefaultRowEvent(final Cell cell, NativeEvent event) {
+ if (!getColumn(cell.getColumn()).isSortable()) {
+ // Only handle sorting events if the column is sortable
+ return false;
+ }
+
+ if (BrowserEvents.TOUCHSTART.equals(event.getType())) {
+ if (event.getTouches().length() > 1) {
+ return false;
+ }
+
+ event.preventDefault();
+
+ Touch touch = event.getChangedTouches().get(0);
+ rowEventTouchStartingPoint = new Point(touch.getClientX(),
+ touch.getClientY());
+
+ lazySorter.setCellReference(cell);
+ lazySorter.setMultisort(true);
+ lazySorter.schedule(GridConstants.LONG_TAP_DELAY);
+
+ } else if (BrowserEvents.TOUCHMOVE.equals(event.getType())) {
+ if (event.getTouches().length() > 1) {
+ return false;
+ }
+
+ event.preventDefault();
+
+ Touch touch = event.getChangedTouches().get(0);
+ double diffX = Math.abs(touch.getClientX()
+ - rowEventTouchStartingPoint.getX());
+ double diffY = Math.abs(touch.getClientY()
+ - rowEventTouchStartingPoint.getY());
+
+ // Cancel long tap if finger strays too far from
+ // starting point
+ if (diffX > GridConstants.LONG_TAP_THRESHOLD
+ || diffY > GridConstants.LONG_TAP_THRESHOLD) {
+ lazySorter.cancel();
+ }
+
+ } else if (BrowserEvents.TOUCHEND.equals(event.getType())) {
+ if (event.getTouches().length() > 0) {
+ return false;
+ }
+
+ if (lazySorter.isRunning()) {
+ // Not a long tap yet, perform single sort
+ lazySorter.cancel();
+ lazySorter.setMultisort(false);
+ lazySorter.run();
+ }
+
+ } else if (BrowserEvents.TOUCHCANCEL.equals(event.getType())) {
+ if (event.getChangedTouches().length() > 1) {
+ return false;
+ }
+
+ lazySorter.cancel();
+
+ } else if (BrowserEvents.CLICK.equals(event.getType())) {
+ lazySorter.setCellReference(cell);
+ lazySorter.setMultisort(event.getShiftKey());
+ lazySorter.run();
+
+ // Active cell handling is also monitoring the click
+ // event so we allow event to propagate for it
+ return false;
+ }
+
+ return true;
+ }
+
@Override
public com.google.gwt.user.client.Element getSubPartElement(String subPart) {
// Parse SubPart string to type and indices
@@ -2359,6 +2293,18 @@ public class Grid<T> extends Composite implements
}
/**
+ * Finds the sorting order for this column
+ */
+ private SortOrder getSortOrder(GridColumn<?, ?> column) {
+ for (SortOrder order : getSortOrder()) {
+ if (order.getColumn() == column) {
+ return order;
+ }
+ }
+ return null;
+ }
+
+ /**
* Register a GWT event handler for a sorting event. This handler gets
* called whenever this Grid needs its data source to provide data sorted in
* a specific order.
diff --git a/client/src/com/vaadin/client/ui/grid/GridHeader.java b/client/src/com/vaadin/client/ui/grid/GridHeader.java
index f714848618..2867ae4d1c 100644
--- a/client/src/com/vaadin/client/ui/grid/GridHeader.java
+++ b/client/src/com/vaadin/client/ui/grid/GridHeader.java
@@ -15,8 +15,11 @@
*/
package com.vaadin.client.ui.grid;
+import java.util.Arrays;
+import java.util.Collection;
+
import com.google.gwt.core.client.Scheduler;
-import com.vaadin.client.ui.grid.Grid.AbstractGridColumn.SortableColumnHeaderRenderer;
+import com.google.gwt.dom.client.BrowserEvents;
/**
* Represents the header section of a Grid. A header consists of a single header
@@ -89,21 +92,9 @@ public class GridHeader extends GridStaticSection<GridHeader.HeaderRow> {
"Cannot set a default row that does not exist in the container");
}
if (defaultRow != null) {
- assert defaultRow.getRenderer() instanceof SortableColumnHeaderRenderer;
-
- // Eclipse is wrong about this warning - javac does not accept the
- // parameterized version
- ((Grid.SortableColumnHeaderRenderer) defaultRow.getRenderer())
- .removeFromRow(defaultRow);
-
defaultRow.setDefault(false);
}
if (row != null) {
- assert !(row.getRenderer() instanceof SortableColumnHeaderRenderer);
-
- row.setRenderer(getGrid().new SortableColumnHeaderRenderer(row
- .getRenderer()));
-
row.setDefault(true);
}
defaultRow = row;
@@ -145,4 +136,15 @@ public class GridHeader extends GridStaticSection<GridHeader.HeaderRow> {
}
});
}
+
+ /**
+ * Returns the events consumed by the header
+ *
+ * @return a collection of BrowserEvents
+ */
+ public Collection<String> getConsumedEvents() {
+ return Arrays.asList(BrowserEvents.TOUCHSTART, BrowserEvents.TOUCHMOVE,
+ BrowserEvents.TOUCHEND, BrowserEvents.TOUCHCANCEL,
+ BrowserEvents.CLICK);
+ }
}
diff --git a/client/src/com/vaadin/client/ui/grid/GridStaticSection.java b/client/src/com/vaadin/client/ui/grid/GridStaticSection.java
index 1be0a92b8f..8c9ada46d0 100644
--- a/client/src/com/vaadin/client/ui/grid/GridStaticSection.java
+++ b/client/src/com/vaadin/client/ui/grid/GridStaticSection.java
@@ -187,17 +187,6 @@ abstract class GridStaticSection<ROWTYPE extends GridStaticSection.StaticRow<?>>
private List<CELLTYPE> cells = new ArrayList<CELLTYPE>();
- private Renderer<String> renderer = new Renderer<String>() {
-
- @Override
- public void render(FlyweightCell cell, String data) {
- /*
- * The rendering into the cell is done directly from the updater
- * since it needs to handle multiple types of data.
- */
- }
- };
-
private GridStaticSection<?> section;
private Collection<List<CELLTYPE>> cellGroups = new HashSet<List<CELLTYPE>>();
@@ -359,14 +348,6 @@ abstract class GridStaticSection<ROWTYPE extends GridStaticSection.StaticRow<?>>
cells.remove(index);
}
- protected void setRenderer(Renderer<String> renderer) {
- this.renderer = renderer;
- }
-
- protected Renderer<String> getRenderer() {
- return renderer;
- }
-
protected abstract CELLTYPE createCell();
protected GridStaticSection<?> getSection() {
diff --git a/shared/src/com/vaadin/shared/ui/grid/GridConstants.java b/shared/src/com/vaadin/shared/ui/grid/GridConstants.java
index 346e85b994..1ee79a5d37 100644
--- a/shared/src/com/vaadin/shared/ui/grid/GridConstants.java
+++ b/shared/src/com/vaadin/shared/ui/grid/GridConstants.java
@@ -31,4 +31,14 @@ public final class GridConstants implements Serializable {
* explicitly defined padding value.
*/
public static final int DEFAULT_PADDING = 0;
+
+ /**
+ * Delay before a long tap action is triggered. Number in milliseconds.
+ */
+ public static final int LONG_TAP_DELAY = 500;
+
+ /**
+ * The threshold in pixels a finger can move while long tapping.
+ */
+ public static final int LONG_TAP_THRESHOLD = 3;
}