aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Ahlroos <john@vaadin.com>2014-05-22 16:23:52 +0300
committerJohn Ahlroos <john@vaadin.com>2014-05-27 15:04:38 +0300
commitdbde68ef3d26e830cfb93e0667cedf8bf9ff8520 (patch)
tree93c1e7ed23ea91e224fafd4cae00ebe37bae96d9
parent61b04537b350c39f06310b55089f259f2bdab3d8 (diff)
downloadvaadin-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.java60
-rw-r--r--client/src/com/vaadin/client/ui/grid/Grid.java103
-rw-r--r--client/src/com/vaadin/client/ui/grid/RowContainer.java16
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);
+
}