From 41f5328ef5600ce61bb323814f605cc6e77cbca2 Mon Sep 17 00:00:00 2001 From: Automerge Date: Tue, 15 May 2012 17:11:36 +0000 Subject: [PATCH] [merge from 6.7] Take viewport scrolling into account when calculating drop position (#6021) svn changeset:23749/svn branch:6.8 --- .../terminal/gwt/client/ui/dd/DDUtil.java | 17 +++-- .../tests/dd/ScrolledDropTarget.html.disabled | 0 .../vaadin/tests/dd/ScrolledDropTarget.java | 67 +++++++++++++++++++ 3 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 tests/testbench/com/vaadin/tests/dd/ScrolledDropTarget.html.disabled create mode 100644 tests/testbench/com/vaadin/tests/dd/ScrolledDropTarget.java diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/DDUtil.java b/src/com/vaadin/terminal/gwt/client/ui/dd/DDUtil.java index 02c1fe5061..225770b62b 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/DDUtil.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/DDUtil.java @@ -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 index 0000000000..e69de29bb2 diff --git a/tests/testbench/com/vaadin/tests/dd/ScrolledDropTarget.java b/tests/testbench/com/vaadin/tests/dd/ScrolledDropTarget.java new file mode 100644 index 0000000000..093e12f84a --- /dev/null +++ b/tests/testbench/com/vaadin/tests/dd/ScrolledDropTarget.java @@ -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); + } + +} -- 2.39.5