]> source.dussan.org Git - vaadin-framework.git/commitdiff
[merge from 6.7] Take viewport scrolling into account when calculating drop position...
authorAutomerge <automerge@vaadin.com>
Tue, 15 May 2012 17:11:36 +0000 (17:11 +0000)
committerAutomerge <automerge@vaadin.com>
Tue, 15 May 2012 17:11:36 +0000 (17:11 +0000)
svn changeset:23749/svn branch:6.8

src/com/vaadin/terminal/gwt/client/ui/dd/DDUtil.java
tests/testbench/com/vaadin/tests/dd/ScrolledDropTarget.html.disabled [new file with mode: 0644]
tests/testbench/com/vaadin/tests/dd/ScrolledDropTarget.java [new file with mode: 0644]

index 02c1fe5061659dab258dfc67782d7c03385c9cd6..225770b62be066514defb35ae2bdeb7e91858c89 100644 (file)
@@ -5,6 +5,7 @@ package com.vaadin.terminal.gwt.client.ui.dd;
 
 import com.google.gwt.dom.client.NativeEvent;
 import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Window;
 import com.vaadin.terminal.gwt.client.Util;
 
 public class DDUtil {
@@ -43,8 +44,11 @@ public class DDUtil {
     public static VerticalDropLocation getVerticalDropLocation(Element element,
             int offsetHeight, int clientY, double topBottomRatio) {
 
-        int absoluteTop = element.getAbsoluteTop();
-        int fromTop = clientY - absoluteTop;
+        // Event coordinates are relative to the viewport, element absolute
+        // position is relative to the document. Make element position relative
+        // to viewport by adjusting for viewport scrolling. See #6021
+        int elementTop = element.getAbsoluteTop() - Window.getScrollTop();
+        int fromTop = clientY - elementTop;
 
         float percentageFromTop = (fromTop / (float) offsetHeight);
         if (percentageFromTop < topBottomRatio) {
@@ -74,11 +78,14 @@ public class DDUtil {
     public static HorizontalDropLocation getHorizontalDropLocation(
             Element element, int clientX, double leftRightRatio) {
 
-        int absoluteLeft = element.getAbsoluteLeft();
+        // Event coordinates are relative to the viewport, element absolute
+        // position is relative to the document. Make element position relative
+        // to viewport by adjusting for viewport scrolling. See #6021
+        int elementLeft = element.getAbsoluteLeft() - Window.getScrollLeft();
         int offsetWidth = element.getOffsetWidth();
-        int fromTop = clientX - absoluteLeft;
+        int fromLeft = clientX - elementLeft;
 
-        float percentageFromTop = (fromTop / (float) offsetWidth);
+        float percentageFromTop = (fromLeft / (float) offsetWidth);
         if (percentageFromTop < leftRightRatio) {
             return HorizontalDropLocation.LEFT;
         } else if (percentageFromTop > 1 - leftRightRatio) {
diff --git a/tests/testbench/com/vaadin/tests/dd/ScrolledDropTarget.html.disabled b/tests/testbench/com/vaadin/tests/dd/ScrolledDropTarget.html.disabled
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/testbench/com/vaadin/tests/dd/ScrolledDropTarget.java b/tests/testbench/com/vaadin/tests/dd/ScrolledDropTarget.java
new file mode 100644 (file)
index 0000000..093e12f
--- /dev/null
@@ -0,0 +1,67 @@
+package com.vaadin.tests.dd;
+
+import com.vaadin.event.dd.DragAndDropEvent;
+import com.vaadin.event.dd.DropHandler;
+import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
+import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation;
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.tests.util.Log;
+import com.vaadin.ui.AbstractSelect.AbstractSelectTargetDetails;
+import com.vaadin.ui.AbstractSelect.VerticalLocationIs;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.Table.TableDragMode;
+
+public class ScrolledDropTarget extends TestBase {
+    private final Log log = new Log(5);
+
+    @Override
+    protected void setup() {
+
+        Table table = new Table();
+        table.addContainerProperty("A", String.class, "");
+        for (int i = 0; i < 100; i++) {
+            table.addItem(new Object[] { Integer.toString(i) },
+                    Integer.valueOf(i));
+        }
+
+        table.setDragMode(TableDragMode.ROW);
+        table.setDropHandler(new DropHandler() {
+            public AcceptCriterion getAcceptCriterion() {
+                return VerticalLocationIs.MIDDLE;
+            }
+
+            public void drop(DragAndDropEvent event) {
+                AbstractSelectTargetDetails targetDetails = (AbstractSelectTargetDetails) event
+                        .getTargetDetails();
+                VerticalDropLocation dropLocation = targetDetails
+                        .getDropLocation();
+                log.log("Drop at " + dropLocation + " relative to "
+                        + targetDetails.getItemIdOver());
+            }
+        });
+
+        addComponent(table);
+        addComponent(new Button("Scroll body", new Button.ClickListener() {
+            public void buttonClick(ClickEvent event) {
+                getMainWindow().executeJavaScript(
+                        "document.body.style.overflow = 'auto';"
+                                + "document.body.style.height = '200%';"
+                                + "window.scrollTo(0,18)");
+            }
+        }));
+        addComponent(log);
+    }
+
+    @Override
+    protected String getDescription() {
+        return "Vertical location for drags should work even when the browser window is scrolled";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return Integer.valueOf(6021);
+    }
+
+}