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

Reply via email to