]> source.dussan.org Git - vaadin-framework.git/commitdiff
#8724 Preliminary native touch scroll support for Table
authorJohannes Dahlström <johannes.dahlstrom@vaadin.com>
Fri, 11 May 2012 15:38:58 +0000 (15:38 +0000)
committerJohannes Dahlström <johannes.dahlstrom@vaadin.com>
Fri, 11 May 2012 15:38:58 +0000 (15:38 +0000)
svn changeset:23724/svn branch:6.8

src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java

index f0874a5d18489d64859e8541e01081e020549b66..0ab200ccf4a53350016c145d9a9f3cc302ecb1a5 100644 (file)
@@ -44,8 +44,6 @@ import com.google.gwt.event.dom.client.KeyUpEvent;
 import com.google.gwt.event.dom.client.KeyUpHandler;
 import com.google.gwt.event.dom.client.ScrollEvent;
 import com.google.gwt.event.dom.client.ScrollHandler;
-import com.google.gwt.event.dom.client.TouchStartEvent;
-import com.google.gwt.event.dom.client.TouchStartHandler;
 import com.google.gwt.event.logical.shared.CloseEvent;
 import com.google.gwt.event.logical.shared.CloseHandler;
 import com.google.gwt.user.client.Command;
@@ -212,6 +210,9 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
 
     private boolean enableDebug = false;
 
+    private final static boolean requiresTouchScrollDelegate = BrowserInfo
+            .get().requiresTouchScrollDelegate();
+
     /**
      * Represents a select range of rows
      */
@@ -467,12 +468,12 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
     public VScrollTable() {
         setMultiSelectMode(MULTISELECT_MODE_DEFAULT);
 
-        scrollBodyPanel.setStyleName(CLASSNAME + "-body-wrapper");
+        scrollBodyPanel.addStyleName(CLASSNAME + "-body-wrapper");
         scrollBodyPanel.addFocusHandler(this);
         scrollBodyPanel.addBlurHandler(this);
 
         scrollBodyPanel.addScrollHandler(this);
-        scrollBodyPanel.setStyleName(CLASSNAME + "-body");
+        scrollBodyPanel.addStyleName(CLASSNAME + "-body");
 
         /*
          * Firefox auto-repeat works correctly only if we use a key press
@@ -487,11 +488,6 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
         scrollBodyPanel.addKeyUpHandler(navKeyUpHandler);
 
         scrollBodyPanel.sinkEvents(Event.TOUCHEVENTS);
-        scrollBodyPanel.addDomHandler(new TouchStartHandler() {
-            public void onTouchStart(TouchStartEvent event) {
-                getTouchScrollDelegate().onTouchStart(event);
-            }
-        }, TouchStartEvent.getType());
 
         scrollBodyPanel.sinkEvents(Event.ONCONTEXTMENU);
         scrollBodyPanel.addDomHandler(new ContextMenuHandler() {
@@ -509,16 +505,6 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
         rowRequestHandler = new RowRequestHandler();
     }
 
-    protected TouchScrollDelegate getTouchScrollDelegate() {
-        if (touchScrollDelegate == null) {
-            touchScrollDelegate = new TouchScrollDelegate(
-                    scrollBodyPanel.getElement());
-            touchScrollDelegate.setScrollHandler(this);
-        }
-        return touchScrollDelegate;
-
-    }
-
     private void handleBodyContextMenu(ContextMenuEvent event) {
         if (enabled && bodyActionKeys != null) {
             int left = Util.getTouchOrMouseClientX(event.getNativeEvent());
@@ -4068,7 +4054,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
             DOM.appendChild(container, preSpacer);
             DOM.appendChild(container, table);
             DOM.appendChild(container, postSpacer);
-            if (BrowserInfo.get().isTouchDevice()) {
+            if (BrowserInfo.get().requiresTouchScrollDelegate()) {
                 NodeList<Node> childNodes = container.getChildNodes();
                 for (int i = 0; i < childNodes.getLength(); i++) {
                     Element item = (Element) childNodes.getItem(i);
@@ -4638,6 +4624,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                     + "-row-odd";
             private static final int TOUCH_CONTEXT_MENU_TIMEOUT = 500;
             private Timer contextTouchTimeout;
+            private Timer dragTouchTimeout;
             private int touchStartY;
             private int touchStartX;
 
@@ -5050,11 +5037,198 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                 }
             }
 
+            private boolean wasSignificantMove = false;
+            private boolean isDragging = false;
+
+            /**
+             * Special handler for touch devices
+             * 
+             * @param event
+             */
+            public void onTouchBrowserEvent(final Event event) {
+                VConsole.log("-- START ONTOUCHBROWSEREVENT");
+                if (enabled) {
+                    final Element targetTdOrTr = getEventTargetTdOrTr(event);
+                    final int type = event.getTypeInt();
+
+                    switch (type) {
+                    case Event.ONCONTEXTMENU:
+                        showContextMenu(event);
+                        if (enabled
+                                && (actionKeys != null || client
+                                        .hasEventListeners(VScrollTable.this,
+                                                ITEM_CLICK_EVENT_ID))) {
+                            /*
+                             * Prevent browser context menu only if there are
+                             * action handlers or item click listeners
+                             * registered
+                             */
+                            event.stopPropagation();
+                            event.preventDefault();
+                        }
+                        break;
+                    case Event.ONTOUCHSTART:
+                        touchStart = event;
+                        isDragging = false;
+                        wasSignificantMove = false;
+                        Touch touch = event.getChangedTouches().get(0);
+                        // save position to fields, touches in events are same
+                        // instance during the operation.
+                        touchStartX = touch.getClientX();
+                        touchStartY = touch.getClientY();
+
+                        if (dragmode != 0) {
+                            if (dragTouchTimeout == null) {
+                                dragTouchTimeout = new Timer() {
+                                    @Override
+                                    public void run() {
+                                        if (touchStart != null) {
+                                            VConsole.log("DRAGGING");
+                                            isDragging = true;
+                                        }
+                                    }
+                                };
+                                VConsole.log("START DRAG TIMEOUT");
+                                dragTouchTimeout.schedule(TOUCHSCROLL_TIMEOUT);
+                            }
+                        }
+
+                        if (actionKeys != null) {
+                            if (contextTouchTimeout == null) {
+                                contextTouchTimeout = new Timer() {
+                                    @Override
+                                    public void run() {
+                                        if (touchStart != null) {
+                                            VConsole.log("SHOW CONTEXT");
+                                            showContextMenu(touchStart);
+                                            event.preventDefault();
+                                            touchStart = null;
+
+                                        }
+                                    }
+                                };
+                                VConsole.log("START CONTEXT TIMEOUT");
+
+                                contextTouchTimeout.cancel();
+                                contextTouchTimeout
+                                        .schedule(TOUCH_CONTEXT_MENU_TIMEOUT);
+                            }
+                        }
+                        break;
+                    case Event.ONTOUCHMOVE:
+                        if (isSignificantMove(event)) {
+                            wasSignificantMove = true;
+                            if (contextTouchTimeout != null) {
+                                contextTouchTimeout.cancel();
+                            }
+                            if (!isDragging && dragTouchTimeout != null) {
+                                VConsole.log("CANCEL DRAG TIMEOUT");
+                                dragTouchTimeout.cancel();
+                                dragTouchTimeout = null;
+                            }
+                            if (isDragging) {
+                                if (dragmode != 0 && touchStart != null) {
+                                    event.preventDefault();
+                                    event.stopPropagation();
+                                    VConsole.log("START DRAG");
+                                    startRowDrag(touchStart, type, targetTdOrTr);
+                                }
+                                isDragging = false;
+                            }
+                            touchStart = null;
+                        }
+                        break;
+                    case Event.ONTOUCHEND:
+                    case Event.ONTOUCHCANCEL:
+                        VConsole.log("ONTOUCHEND");
+                        if (contextTouchTimeout != null) {
+                            VConsole.log("CANCEL CONTEXT TIMEOUT");
+                            contextTouchTimeout.cancel();
+                        }
+                        if (dragTouchTimeout != null) {
+                            VConsole.log("CANCEL DRAG TIMEOUT");
+                            dragTouchTimeout.cancel();
+                        }
+                        if (touchStart != null) {
+                            event.preventDefault();
+                            event.stopPropagation();
+                            touchStart = null;
+                        }
+                        isDragging = false;
+                        VConsole.log("END ONTOUCHEND");
+                        break;
+                    case Event.ONMOUSEDOWN:
+                        VConsole.log("ONMOUSEDOWN");
+                        if (targetTdOrTr != null) {
+                            setRowFocus(this);
+                            ensureFocus();
+                            if (dragmode != 0
+                                    && (event.getButton() == NativeEvent.BUTTON_LEFT)) {
+                                startRowDrag(event, event.getTypeInt(),
+                                        targetTdOrTr);
+                            } else {
+                                event.stopPropagation();
+                            }
+
+                            event.preventDefault();
+                        }
+                        break;
+                    case Event.ONMOUSEOUT:
+                        VConsole.log("ONMOUSEOUT");
+                        break;
+                    case Event.ONMOUSEUP:
+                        VConsole.log("ONMOUSEUP");
+                        if (targetTdOrTr != null) {
+                            if (isSelectable()) {
+                                boolean currentlyJustThisRowSelected = selectedRowKeys
+                                        .size() == 1
+                                        && selectedRowKeys.contains(getKey());
+
+                                if (!currentlyJustThisRowSelected) {
+                                    if (isSingleSelectMode()
+                                            || isMultiSelectModeDefault()) {
+                                        deselectAll();
+                                    }
+                                    toggleSelection();
+                                } else if ((isSingleSelectMode() || isMultiSelectModeSimple())
+                                        && nullSelectionAllowed) {
+                                    toggleSelection();
+                                }
+
+                                selectionRangeStart = this;
+                                setRowFocus(this);
+
+                                event.preventDefault();
+                                event.stopPropagation();
+                            }
+                        }
+
+                        break;
+                    case Event.ONDBLCLICK:
+                        if (targetTdOrTr != null) {
+                            handleClickEvent(event, targetTdOrTr, true);
+                        }
+                        break;
+                    default:
+                    }
+                }
+                VConsole.log("-- SUPER ONBROWSEREVENT");
+
+                super.onBrowserEvent(event);
+                VConsole.log("-- END ONTOUCHBROWSEREVENT");
+            }
+
             /*
              * React on click that occur on content cells only
              */
             @Override
             public void onBrowserEvent(final Event event) {
+
+                if (!requiresTouchScrollDelegate) {
+                    onTouchBrowserEvent(event);
+                    return;
+                }
+
                 if (enabled) {
                     final int type = event.getTypeInt();
                     final Element targetTdOrTr = getEventTargetTdOrTr(event);