Reviewers: jlabanca,
Description:
During row mouseout events, only consider it as row unhovering if the
event coordinates are outside the hovering row. Previously, if there's a
popup
dialog floating on top of a table row, moving into this element will
cause a row unhover event. This is particularly a problem if the element
is shown/dismissed based on row hovering (causing a flickring effect).
Also include the original browser event in the RowHoverEvent in case the
user needs more information about the original event.
Please review this at http://gwt-code-reviews.appspot.com/1546803/
Affected files:
M user/src/com/google/gwt/user/cellview/client/AbstractCellTable.java
M user/src/com/google/gwt/user/cellview/client/RowHoverEvent.java
Index: user/src/com/google/gwt/user/cellview/client/AbstractCellTable.java
===================================================================
--- user/src/com/google/gwt/user/cellview/client/AbstractCellTable.java
(revision 10636)
+++ user/src/com/google/gwt/user/cellview/client/AbstractCellTable.java
(working copy)
@@ -44,6 +44,7 @@
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.Window;
import
com.google.gwt.user.client.ui.HasHorizontalAlignment.HorizontalAlignmentConstant;
import
com.google.gwt.user.client.ui.HasVerticalAlignment.VerticalAlignmentConstant;
import com.google.gwt.user.client.ui.Widget;
@@ -1777,13 +1778,26 @@
if ("mouseover".equals(eventType)) {
// Unstyle the old row if it is still part of the table.
if (hoveringRow != null &&
getTableBodyElement().isOrHasChild(hoveringRow)) {
- setRowHover(hoveringRow, false);
+ setRowHover(hoveringRow, event, false);
}
hoveringRow = targetTableRow;
- setRowHover(hoveringRow, true);
+ setRowHover(hoveringRow, event, true);
} else if ("mouseout".equals(eventType) && hoveringRow != null) {
- setRowHover(hoveringRow, false);
- hoveringRow = null;
+ // Ignore events happening directly over the hovering row. If
there are floating element
+ // on top of the row, mouseout event should not be triggered. This
is to avoid the flickring
+ // effect if the floating element is shown/hide based on hover
event.
+ int clientX = event.getClientX() + Window.getScrollLeft();
+ int clientY = event.getClientY() + Window.getScrollTop();
+ int rowLeft = hoveringRow.getAbsoluteLeft();
+ int rowTop = hoveringRow.getAbsoluteTop();
+ int rowWidth = hoveringRow.getOffsetWidth();
+ int rowHeight = hoveringRow.getOffsetHeight();
+ int rowBottom = rowTop + rowHeight;
+ int rowRight = rowLeft + rowWidth;
+ if (clientX < rowLeft || clientX > rowRight || clientY < rowTop ||
clientY > rowBottom) {
+ setRowHover(hoveringRow, event, false);
+ hoveringRow = null;
+ }
}
// If the event causes us to page, then the physical index will be
out
@@ -2410,11 +2424,12 @@
* 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
*/
- private void setRowHover(TableRowElement tr, boolean isHovering) {
+ private void setRowHover(TableRowElement tr, Event event, boolean
isHovering) {
setRowStyleName(tr, style.hoveredRow(), style.hoveredRowCell(),
isHovering);
- RowHoverEvent.fire(this, tr, !isHovering);
+ RowHoverEvent.fire(this, tr, event, !isHovering);
}
/**
Index: user/src/com/google/gwt/user/cellview/client/RowHoverEvent.java
===================================================================
--- user/src/com/google/gwt/user/cellview/client/RowHoverEvent.java
(revision 10636)
+++ user/src/com/google/gwt/user/cellview/client/RowHoverEvent.java
(working copy)
@@ -19,6 +19,7 @@
import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.event.shared.HasHandlers;
+import com.google.gwt.user.client.Event;
/**
* Represents a row hover event.
@@ -54,8 +55,8 @@
* @return the {@link RowHoverEvent} that was fired
*/
public static RowHoverEvent fire(HasHandlers source, TableRowElement
hoveringRow,
- boolean isUnHover) {
- RowHoverEvent event = new RowHoverEvent(hoveringRow, isUnHover);
+ Event browserEvent, boolean isUnHover) {
+ RowHoverEvent event = new RowHoverEvent(hoveringRow, browserEvent,
isUnHover);
if (TYPE != null) {
source.fireEvent(event);
}
@@ -73,6 +74,8 @@
}
return TYPE;
}
+
+ private Event browserEvent;
private TableRowElement hoveringRow;
@@ -83,10 +86,12 @@
*
* @param hoveringRow the currently hovering {@link TableRowElement}. If
isUnHover is false, this
* should be the previouly hovering {@link TableRowElement}
+ * @param browserEvent the original browser event
* @param isUnHover false if this is an unhover event
*/
- protected RowHoverEvent(TableRowElement hoveringRow, boolean isUnHover) {
+ protected RowHoverEvent(TableRowElement hoveringRow, Event browserEvent,
boolean isUnHover) {
this.hoveringRow = hoveringRow;
+ this.browserEvent = browserEvent;
this.isUnHover = isUnHover;
}
@@ -103,6 +108,13 @@
}
/**
+ * Return the original browser {@link Event}.
+ */
+ public Event getBrowserEvent() {
+ return browserEvent;
+ }
+
+ /**
* Return whether this is an unhover event.
*/
public boolean isUnHover() {
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors