diff options
author | John Ahlroos <john@vaadin.com> | 2014-05-22 16:23:52 +0300 |
---|---|---|
committer | John Ahlroos <john@vaadin.com> | 2014-05-27 15:04:38 +0300 |
commit | dbde68ef3d26e830cfb93e0667cedf8bf9ff8520 (patch) | |
tree | 93c1e7ed23ea91e224fafd4cae00ebe37bae96d9 | |
parent | 61b04537b350c39f06310b55089f259f2bdab3d8 (diff) | |
download | vaadin-framework-dbde68ef3d26e830cfb93e0667cedf8bf9ff8520.tar.gz vaadin-framework-dbde68ef3d26e830cfb93e0667cedf8bf9ff8520.zip |
Allow listening to events from cells via renderer #13334
Change-Id: Id89deab9e19db67ab547d914fd11ade890663c45
-rw-r--r-- | client/src/com/vaadin/client/ui/grid/Escalator.java | 60 | ||||
-rw-r--r-- | client/src/com/vaadin/client/ui/grid/Grid.java | 103 | ||||
-rw-r--r-- | client/src/com/vaadin/client/ui/grid/RowContainer.java | 16 |
3 files changed, 176 insertions, 3 deletions
diff --git a/client/src/com/vaadin/client/ui/grid/Escalator.java b/client/src/com/vaadin/client/ui/grid/Escalator.java index 2f1535ccd4..cc3ee55182 100644 --- a/client/src/com/vaadin/client/ui/grid/Escalator.java +++ b/client/src/com/vaadin/client/ui/grid/Escalator.java @@ -1750,6 +1750,47 @@ public class Escalator extends Widget { } }); } + + @Override + public Cell getCell(Element element) { + if (element == null) { + throw new IllegalArgumentException("Element cannot be null"); + } + + /* + * Ensure that element is not root nor the direct descendant of root + * (a row) and ensure the element is inside the dom hierarchy of the + * root element. If not, return. + */ + if (root == element || element.getParentElement() == root + || !root.isOrHasChild(element)) { + return null; + } + + /* + * Ensure element is the cell element by iterating up the DOM + * hierarchy until reaching cell element. + */ + while (element.getParentElement().getParentElement() != root) { + element = element.getParentElement(); + } + + // Find dom column + int domColumnIndex = -1; + for (Element e = element; e != null; e = e + .getPreviousSiblingElement()) { + domColumnIndex++; + } + + // Find dom row + int domRowIndex = -1; + for (Element e = element.getParentElement(); e != null; e = e + .getPreviousSiblingElement()) { + domRowIndex++; + } + + return new Cell(domRowIndex, domColumnIndex, element); + } } private abstract class AbstractStaticRowContainer extends @@ -2898,9 +2939,9 @@ public class Escalator extends Widget { } } - private int getLogicalRowIndex(final Element element) { - assert element.getParentNode() == root : "The given element isn't a row element in the body"; - int internalIndex = visualRowOrder.indexOf(element); + private int getLogicalRowIndex(final Element tr) { + assert tr.getParentNode() == root : "The given element isn't a row element in the body"; + int internalIndex = visualRowOrder.indexOf(tr); return getTopRowLogicalIndex() + internalIndex; } @@ -3328,6 +3369,19 @@ public class Escalator extends Widget { return activeRow; } + + @Override + public Cell getCell(Element element) { + Cell cell = super.getCell(element); + if (cell == null) { + return null; + } + + // Convert DOM coordinates to logical coordinates for rows + Element rowElement = cell.getElement().getParentElement(); + return new Cell(getLogicalRowIndex(rowElement), cell.getColumn(), + cell.getElement()); + } } private class ColumnConfigurationImpl implements ColumnConfiguration { diff --git a/client/src/com/vaadin/client/ui/grid/Grid.java b/client/src/com/vaadin/client/ui/grid/Grid.java index d1e299ba5a..25186ae80a 100644 --- a/client/src/com/vaadin/client/ui/grid/Grid.java +++ b/client/src/com/vaadin/client/ui/grid/Grid.java @@ -16,17 +16,24 @@ package com.vaadin.client.ui.grid; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.logging.Logger; import com.google.gwt.core.shared.GWT; +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.event.shared.HandlerRegistration; +import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HasVisibility; import com.vaadin.client.data.DataChangeHandler; import com.vaadin.client.data.DataSource; +import com.vaadin.client.ui.grid.renderers.ComplexRenderer; import com.vaadin.client.ui.grid.renderers.TextRenderer; import com.vaadin.shared.ui.grid.GridConstants; import com.vaadin.shared.ui.grid.HeightMode; @@ -817,6 +824,33 @@ public class Grid<T> extends Composite { .findIndexOfColumn() < index) { refreshFrozenColumns(); } + + // Sink all renderer events + Set<String> events = new HashSet<String>(); + events.addAll(getConsumedEventsForRenderer(column.getHeaderRenderer())); + events.addAll(getConsumedEventsForRenderer(column.getRenderer())); + events.addAll(getConsumedEventsForRenderer(column.getFooterRenderer())); + + sinkEvents(events); + } + + private void sinkEvents(Collection<String> events) { + assert events != null; + + int eventsToSink = 0; + for (String typeName : events) { + int typeInt = Event.getTypeInt(typeName); + if (typeInt < 0) { + // Type not recognized by typeInt + sinkBitlessEvent(typeName); + } else { + eventsToSink |= typeInt; + } + } + + if (eventsToSink > 0) { + sinkEvents(eventsToSink); + } } private int findVisibleColumnIndex(GridColumn<?, T> column) { @@ -1382,4 +1416,73 @@ public class Grid<T> extends Composite { public HeightMode getHeightMode() { return escalator.getHeightMode(); } + + /** + * Returns the events that the {@link Grid} listens for. This includes all + * events for columns and renderers. + * <p> + * + * @See {@link BrowserEvents} for available events. + * + * @return events consumed by the Grid. + */ + protected Set<String> getConsumedEvents() { + Set<String> events = new HashSet<String>(); + for (GridColumn<?, T> column : columns) { + events.addAll(getConsumedEventsForRenderer(column + .getHeaderRenderer())); + events.addAll(getConsumedEventsForRenderer(column.getRenderer())); + events.addAll(getConsumedEventsForRenderer(column + .getFooterRenderer())); + } + return events; + } + + private Set<String> getConsumedEventsForRenderer(Renderer<?> renderer) { + Set<String> events = new HashSet<String>(); + if (renderer instanceof ComplexRenderer) { + Collection<String> consumedEvents = ((ComplexRenderer<?>) renderer) + .getConsumedEvents(); + if (consumedEvents != null) { + events.addAll(consumedEvents); + } + } + return events; + } + + @Override + public void onBrowserEvent(Event event) { + super.onBrowserEvent(event); + EventTarget target = event.getEventTarget(); + if (Element.is(target)) { + Element e = Element.as(target); + + /* + * FIXME This is an ugly way to resolve if the event comes from the + * header, footer or body. But it is currently the only way since + * RowContainer doesn't provide the root element or a method to + * check if the element is inside the row container externally. + */ + Cell cell = escalator.getHeader().getCell(e); + Renderer renderer = null; + if (cell == null) { + cell = escalator.getBody().getCell(e); + if (cell == null) { + cell = escalator.getFooter().getCell(e); + if (cell != null) { + renderer = columns.get(cell.getColumn()) + .getFooterRenderer(); + } + } else { + renderer = columns.get(cell.getColumn()).getRenderer(); + } + } else { + renderer = columns.get(cell.getColumn()).getHeaderRenderer(); + } + + if (renderer instanceof ComplexRenderer) { + ((ComplexRenderer) renderer).onBrowserEvent(cell, event); + } + } + } } diff --git a/client/src/com/vaadin/client/ui/grid/RowContainer.java b/client/src/com/vaadin/client/ui/grid/RowContainer.java index abf08c4393..9cf5d02742 100644 --- a/client/src/com/vaadin/client/ui/grid/RowContainer.java +++ b/client/src/com/vaadin/client/ui/grid/RowContainer.java @@ -16,6 +16,8 @@ package com.vaadin.client.ui.grid; +import com.google.gwt.dom.client.Element; + /** * A representation of the rows in each of the sections (header, body and * footer) in an {@link Escalator}. @@ -153,4 +155,18 @@ public interface RowContainer { * @see #setDefaultRowHeight(int) */ public int getDefaultRowHeight(); + + /** + * Returns the cell object which contains information about the cell the + * element is in. + * + * @param element + * The element to get the cell for. If element is not present in + * row container then <code>null</code> is returned. + * + * @return the cell of the element, or <code>null</code> if element is not + * present in the {@link RowContainer}. + */ + public Cell getCell(Element element); + } |