]> source.dussan.org Git - vaadin-framework.git/commitdiff
Fix touching Grid column header on Android (#9196)
authorMartin Vysny <vysny@baka.sk>
Tue, 8 Aug 2017 12:39:15 +0000 (15:39 +0300)
committerHenri Sara <henri.sara@gmail.com>
Tue, 8 Aug 2017 12:39:15 +0000 (15:39 +0300)
The fix allows both column-reorder handler and column-sort handlers to run
in parallel; on touchend it is decided whether we will perform sort or
reodering. This will enable user to sort on touch screens even with column
reordering enabled.

Fixes #8632

client/src/main/java/com/vaadin/client/widgets/Grid.java

index 9a5674e86e2dc63606d7d68481bc640173451870..9f70a63f5e94298ee36f7af9f43d0677918a8af0 100755 (executable)
@@ -3119,7 +3119,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
 
                 @Override
                 public void run() {
-                    UserSorter.this.sort(column, scheduledMultisort);
+                    scheduledMultisort = true;
                 }
             };
         }
@@ -3185,32 +3185,44 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
         }
 
         /**
-         * Perform a sort after a delay.
+         * Invoked on touchstart, marks itself that we will perform sorting on
+         * touchend. By default single sort is performed, however on long touch
+         * we will perform multitouch.
+         *
+         * Actual sorting is only performed after {@link #onTouchEnd()} is
+         * invoked.
          *
          * @param delay
          *            delay, in milliseconds
          */
-        public void sortAfterDelay(int delay, boolean multisort) {
+        public void awaitForTouchEnd(int delay) {
+            cancelAwaitForTouchEnd();
             column = eventCell.getColumn();
-            scheduledMultisort = multisort;
+            scheduledMultisort = false;
             timer.schedule(delay);
         }
 
         /**
-         * Check if a delayed sort command has been issued but not yet carried
-         * out.
+         * Notifies that the finger has been lifted from the tablet/mobile.
+         * Depending on how much time has passed, we need to perform singlesort
+         * or multisort.
          *
-         * @return a boolean value
+         * Does nothing if the await has been canceled by a call to
+         * {@link #cancelAwaitForTouchEnd()}.
          */
-        public boolean isDelayedSortScheduled() {
-            return timer.isRunning();
+        public void onTouchEnd() {
+            if (column != null) {
+                sort(column, scheduledMultisort);
+                cancelAwaitForTouchEnd();
+            }
         }
 
         /**
          * Cancel a scheduled sort.
          */
-        public void cancelDelayedSort() {
+        public void cancelAwaitForTouchEnd() {
             timer.cancel();
+            column = null;
         }
 
     }
@@ -7651,7 +7663,14 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
                         headerCellDndCallback);
                 event.getDomEvent().preventDefault();
                 event.getDomEvent().stopPropagation();
-                event.setHandled(true);
+
+                // fixes https://github.com/vaadin/framework/issues/8632
+                // don't mark the event as handled, in order for the next handler
+                // in the handler chain (HeaderDefaultRowEventHandler) to be able to
+                // receive it. This should be safe since the next handlers in the
+                // chain (RendererEventHandler and CellFocusEventHandler) do not
+                // react to header touches/clicks.
+//                event.setHandled(true);
             }
         }
     };
@@ -7697,7 +7716,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
                 rowEventTouchStartingPoint = new Point(touch.getClientX(),
                         touch.getClientY());
 
-                sorter.sortAfterDelay(GridConstants.LONG_TAP_DELAY, true);
+                sorter.awaitForTouchEnd(GridConstants.LONG_TAP_DELAY);
 
                 event.setHandled(true);
             } else if (BrowserEvents.TOUCHMOVE
@@ -7706,6 +7725,10 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
                     return;
                 }
 
+                if (rowEventTouchStartingPoint == null) {
+                    return;
+                }
+
                 event.getDomEvent().preventDefault();
 
                 Touch touch = event.getDomEvent().getChangedTouches().get(0);
@@ -7718,7 +7741,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
                 // starting point
                 if (diffX > GridConstants.LONG_TAP_THRESHOLD
                         || diffY > GridConstants.LONG_TAP_THRESHOLD) {
-                    sorter.cancelDelayedSort();
+                    sorter.cancelAwaitForTouchEnd();
                 }
 
                 event.setHandled(true);
@@ -7728,12 +7751,12 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
                     return;
                 }
 
-                if (sorter.isDelayedSortScheduled()) {
-                    // Not a long tap yet, perform single sort
-                    sorter.cancelDelayedSort();
-                    sorter.sort(event.getCell().getColumn(), false);
+                if (rowEventTouchStartingPoint == null) {
+                    return;
                 }
 
+                sorter.onTouchEnd();
+
                 event.setHandled(true);
             } else if (BrowserEvents.TOUCHCANCEL
                     .equals(event.getDomEvent().getType())) {
@@ -7741,7 +7764,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
                     return;
                 }
 
-                sorter.cancelDelayedSort();
+                sorter.cancelAwaitForTouchEnd();
 
                 event.setHandled(true);
             } else if (BrowserEvents.CLICK