A previous change broke some backward-compatibility with RowHoverEvent
(events did not fire when expected). This change fixes the compatibility
issue, clarifies the event's scope and introduces a new field in the event
(hovering scope).
Clients can use this field to differentiate between hover events on the same
row and hovering between different rows, allowing more control on the event's
processing.
Review at http://gwt-code-reviews.appspot.com/1637803
Review by: jlabanca@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10867 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/cellview/client/AbstractCellTable.java b/user/src/com/google/gwt/user/cellview/client/AbstractCellTable.java
index 90f163e..d7baff6 100644
--- a/user/src/com/google/gwt/user/cellview/client/AbstractCellTable.java
+++ b/user/src/com/google/gwt/user/cellview/client/AbstractCellTable.java
@@ -1921,14 +1921,15 @@
int relRow = absRow - getPageStart();
int subrow = tableBuilder.getSubrowValueIndex(targetTableRow);
- if (!skipRowHoverCheck && hoveringRow != targetTableRow) {
+ if (!skipRowHoverCheck) {
+ boolean isRowChange = hoveringRow != targetTableRow;
if (BrowserEvents.MOUSEOVER.equals(eventType)) {
// Unstyle the old row if it is still part of the table.
if (hoveringRow != null && getTableBodyElement().isOrHasChild(hoveringRow)) {
- setRowHover(hoveringRow, event, false);
+ setRowHover(hoveringRow, event, false, isRowChange);
}
hoveringRow = targetTableRow;
- setRowHover(hoveringRow, event, true);
+ setRowHover(hoveringRow, event, true, isRowChange);
} else if (BrowserEvents.MOUSEOUT.equals(eventType) && hoveringRow != null) {
boolean unhover = true;
if (!skipRowHoverFloatElementCheck) {
@@ -1946,7 +1947,7 @@
unhover = clientX < rowLeft || clientX > rowRight || clientY < rowTop || clientY > rowBottom;
}
if (unhover) {
- setRowHover(hoveringRow, event, false);
+ setRowHover(hoveringRow, event, false, isRowChange);
hoveringRow = null;
}
}
@@ -2574,18 +2575,23 @@
/**
* Set a row's hovering style and fire a {@link RowHoverEvent}
- *
+ *
* @param tr the row element
* @param event the original event
* @param isHovering false if this is an unhover event
+ * @param isRowChange true if the hover event is a full row change, false if it is a hover on a
+ * cell. Row style update is called only on full row change.
*/
- private void setRowHover(TableRowElement tr, Event event, boolean isHovering) {
+ private void setRowHover(TableRowElement tr, Event event, boolean isHovering,
+ boolean isRowChange) {
if (!skipRowHoverStyleUpdate) {
setRowStyleName(tr, style.hoveredRow(), style.hoveredRowCell(), isHovering);
}
- RowHoverEvent.fire(this, tr, event, !isHovering);
+ RowHoverEvent.fire(this, tr, event, !isHovering,
+ isRowChange ? RowHoverEvent.HoveringScope.ROW_HOVER
+ : RowHoverEvent.HoveringScope.CELL_HOVER);
}
-
+
/**
* Apply a style to a row and all cells in the row.
*
diff --git a/user/src/com/google/gwt/user/cellview/client/RowHoverEvent.java b/user/src/com/google/gwt/user/cellview/client/RowHoverEvent.java
index 43d1ea8..ff8f78e 100644
--- a/user/src/com/google/gwt/user/cellview/client/RowHoverEvent.java
+++ b/user/src/com/google/gwt/user/cellview/client/RowHoverEvent.java
@@ -22,7 +22,9 @@
import com.google.gwt.user.client.Event;
/**
- * Represents a row hover event.
+ * Represents a row hover event. The event includes change in the hovering
+ * row (e.g. the mouse moves over another row) and cell hover events (e.g.
+ * the mouse moves over another cell within the actual row).
*/
public class RowHoverEvent extends GwtEvent<RowHoverEvent.Handler> {
@@ -33,12 +35,34 @@
/**
* Called when {@link RowHoverEvent} is fired.
- *
+ *
* @param event the {@link ColumnSortEvent} that was fired
*/
void onRowHover(RowHoverEvent event);
}
-
+
+ /**
+ * Indicates the scope/area of the hover event
+ */
+ public static enum HoveringScope {
+ /**
+ * Backward-compatibility parameter to handle the rare case where we don't
+ * know the event's context, because it is outside of CellTable. Clients
+ * should not limit features (e.g. event processing) if the scope is unknown.
+ */
+ UNKNOWN,
+
+ /**
+ * Change in the hovering row, the mouse is moving over different rows
+ */
+ ROW_HOVER,
+
+ /**
+ * Cell-only hover event, the mouse remains on the same row
+ */
+ CELL_HOVER
+ }
+
/**
* Handler type.
*/
@@ -47,32 +71,49 @@
/**
* Fires a row hover event on all registered handlers in the handler
* manager. If no such handlers exist, this implementation will do nothing.
- *
+ *
* @param source the source of the event
- * @param hoveringRow the currently hovering {@link TableRowElement}. If isUnHover is false, this
+ * @param hoveringRow the currently hovering {@link TableRowElement}. If isUnHover is true, this
* should be the previouly hovering {@link TableRowElement}
- * @param isUnHover false if this is an unhover event
+ * @param isUnHover true if this is an unhover event
* @return the {@link RowHoverEvent} that was fired
*/
public static RowHoverEvent fire(HasHandlers source, TableRowElement hoveringRow,
boolean isUnHover) {
- return fire(source, hoveringRow, null, isUnHover);
+ return fire(source, hoveringRow, null, isUnHover, HoveringScope.UNKNOWN);
}
-
+
/**
* Fires a row hover event on all registered handlers in the handler
* manager. If no such handlers exist, this implementation will do nothing.
- *
+ *
* @param source the source of the event
- * @param hoveringRow the currently hovering {@link TableRowElement}. If isUnHover is false, this
+ * @param hoveringRow the currently hovering {@link TableRowElement}. If isUnHover is true, this
* should be the previouly hovering {@link TableRowElement}
* @param browserEvent the original browser event
- * @param isUnHover false if this is an unhover event
+ * @param isUnHover true if this is an unhover event
* @return the {@link RowHoverEvent} that was fired
*/
public static RowHoverEvent fire(HasHandlers source, TableRowElement hoveringRow,
Event browserEvent, boolean isUnHover) {
- RowHoverEvent event = new RowHoverEvent(hoveringRow, browserEvent, isUnHover);
+ return fire(source, hoveringRow, browserEvent, isUnHover, HoveringScope.UNKNOWN);
+ }
+
+ /**
+ * Fires a row hover event on all registered handlers in the handler
+ * manager. If no such handlers exist, this implementation will do nothing.
+ *
+ * @param source the source of the event
+ * @param hoveringRow the currently hovering {@link TableRowElement}. If isUnHover is true, this
+ * should be the previouly hovering {@link TableRowElement}
+ * @param browserEvent the original browser event
+ * @param isUnHover true if this is an unhover event
+ * @param hoveringScope the scope/area of the hover event
+ * @return the {@link RowHoverEvent} that was fired
+ */
+ public static RowHoverEvent fire(HasHandlers source, TableRowElement hoveringRow,
+ Event browserEvent, boolean isUnHover, HoveringScope hoveringScope) {
+ RowHoverEvent event = new RowHoverEvent(hoveringRow, browserEvent, isUnHover, hoveringScope);
if (TYPE != null) {
source.fireEvent(event);
}
@@ -81,7 +122,7 @@
/**
* Gets the type associated with this event.
- *
+ *
* @return returns the handler type
*/
public static Type<Handler> getType() {
@@ -92,41 +133,58 @@
}
private Event browserEvent;
-
+
private TableRowElement hoveringRow;
-
+
private boolean isUnHover;
-
+
+ private HoveringScope hoveringScope;
+
/**
* Construct a new {@link RowHoverEvent}.
- *
- * @param hoveringRow the currently hovering {@link TableRowElement}. If isUnHover is false, this
+ *
+ * @param hoveringRow the currently hovering {@link TableRowElement}. If isUnHover is true, this
* should be the previouly hovering {@link TableRowElement}
- * @param isUnHover false if this is an unhover event
+ * @param isUnHover true if this is an unhover event
*/
protected RowHoverEvent(TableRowElement hoveringRow, boolean isUnHover) {
- this(hoveringRow, null, isUnHover);
+ this(hoveringRow, null, isUnHover, HoveringScope.UNKNOWN);
}
-
+
/**
* Construct a new {@link RowHoverEvent}.
- *
- * @param hoveringRow the currently hovering {@link TableRowElement}. If isUnHover is false, this
+ *
+ * @param hoveringRow the currently hovering {@link TableRowElement}. If isUnHover is true, this
* should be the previouly hovering {@link TableRowElement}
* @param browserEvent the original browser event
- * @param isUnHover false if this is an unhover event
+ * @param isUnHover true if this is an unhover event
*/
protected RowHoverEvent(TableRowElement hoveringRow, Event browserEvent, boolean isUnHover) {
+ this(hoveringRow, browserEvent, isUnHover, HoveringScope.UNKNOWN);
+ }
+
+ /**
+ * Construct a new {@link RowHoverEvent}.
+ *
+ * @param hoveringRow the currently hovering {@link TableRowElement}. If isUnHover is true, this
+ * should be the previouly hovering {@link TableRowElement}
+ * @param browserEvent the original browser event
+ * @param isUnHover true if this is an unhover event
+ * @param hoveringScope the scope/area of the hover event
+ */
+ protected RowHoverEvent(TableRowElement hoveringRow, Event browserEvent, boolean isUnHover,
+ HoveringScope hoveringScope) {
this.hoveringRow = hoveringRow;
this.browserEvent = browserEvent;
this.isUnHover = isUnHover;
+ this.hoveringScope = hoveringScope;
}
-
+
@Override
public Type<Handler> getAssociatedType() {
return TYPE;
}
-
+
/**
* Return the original browser {@link Event}. The browser event could be null if the event is
* fired without one (e.g., by calling {@link #fire(HasHandler, TableRowElement, isUnHover)})
@@ -134,21 +192,28 @@
public Event getBrowserEvent() {
return browserEvent;
}
-
+
/**
* Return the {@link TableRowElement} that the user just hovered or unhovered.
*/
public TableRowElement getHoveringRow() {
return hoveringRow;
}
-
+
+ /**
+ * Return the scope/area of the hover event.
+ */
+ public HoveringScope getHoveringScope() {
+ return hoveringScope;
+ }
+
/**
* Return whether this is an unhover event.
*/
public boolean isUnHover() {
return isUnHover;
}
-
+
@Override
protected void dispatch(Handler handler) {
handler.onRowHover(this);