Revision: 10660
Author:   pengzhu...@google.com
Date:     Tue Sep 20 07:04:28 2011
Log: 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.

Review at http://gwt-code-reviews.appspot.com/1546803

Review by: jlaba...@google.com
http://code.google.com/p/google-web-toolkit/source/detail?r=10660

Modified:
 /trunk/user/src/com/google/gwt/user/cellview/client/AbstractCellTable.java
 /trunk/user/src/com/google/gwt/user/cellview/client/RowHoverEvent.java

=======================================
--- /trunk/user/src/com/google/gwt/user/cellview/client/AbstractCellTable.java Thu Sep 1 10:10:30 2011 +++ /trunk/user/src/com/google/gwt/user/cellview/client/AbstractCellTable.java Tue Sep 20 07:04:28 2011
@@ -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);
   }

   /**
=======================================
--- /trunk/user/src/com/google/gwt/user/cellview/client/RowHoverEvent.java Tue Aug 30 06:42:56 2011 +++ /trunk/user/src/com/google/gwt/user/cellview/client/RowHoverEvent.java Tue Sep 20 07:04:28 2011
@@ -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.
@@ -55,7 +56,23 @@
    */
public static RowHoverEvent fire(HasHandlers source, TableRowElement hoveringRow,
       boolean isUnHover) {
-    RowHoverEvent event = new RowHoverEvent(hoveringRow, isUnHover);
+    return fire(source, hoveringRow, null, isUnHover);
+  }
+
+  /**
+   * 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
+   *          should be the previouly hovering {@link TableRowElement}
+   * @param browserEvent the original browser event
+   * @param isUnHover false 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);
     if (TYPE != null) {
       source.fireEvent(event);
     }
@@ -73,6 +90,8 @@
     }
     return TYPE;
   }
+
+  private Event browserEvent;

   private TableRowElement hoveringRow;

@@ -86,7 +105,20 @@
    * @param isUnHover false if this is an unhover event
    */
   protected RowHoverEvent(TableRowElement hoveringRow, boolean isUnHover) {
+    this(hoveringRow, null, isUnHover);
+  }
+
+  /**
+   * Construct a new {@link RowHoverEvent}.
+   *
+ * @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, Event browserEvent, boolean isUnHover) {
     this.hoveringRow = hoveringRow;
+    this.browserEvent = browserEvent;
     this.isUnHover = isUnHover;
   }

@@ -94,6 +126,14 @@
   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)})
+   */
+  public Event getBrowserEvent() {
+    return browserEvent;
+  }

   /**
* Return the {@link TableRowElement} that the user just hovered or unhovered.

--
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to