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 {
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) {
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) {
--- /dev/null
+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);
+ }
+
+}