From 69714e4251b3ef16ef18d96282996f9f452ec3fe Mon Sep 17 00:00:00 2001 From: =?utf8?q?Pekka=20Hyv=C3=B6nen?= Date: Thu, 7 May 2015 12:30:41 +0300 Subject: [PATCH] DND-drop-marker should not be on top of sidebar opening button #17692 When sidebar opening button is visible, the column dnd-drop marker should not be on top of it. Change-Id: I67428bc5f49ce08c8df11ad84b529e17ad2bc2da --- .../src/com/vaadin/client/widgets/Grid.java | 60 +++++++++++++++++-- .../server/GridColumnReorderTest.java | 25 ++++++++ 2 files changed, 79 insertions(+), 6 deletions(-) diff --git a/client/src/com/vaadin/client/widgets/Grid.java b/client/src/com/vaadin/client/widgets/Grid.java index fa74b16317..079207a999 100644 --- a/client/src/com/vaadin/client/widgets/Grid.java +++ b/client/src/com/vaadin/client/widgets/Grid.java @@ -3541,6 +3541,9 @@ public class Grid extends ResizeComposite implements /** Captures the value of the focused column before reordering */ private int focusedColumnIndex; + /** Offset caused by the drag and drop marker width */ + private double dropMarkerWidthOffset; + private void initHeaderDragElementDOM() { if (table == null) { tableHeader = DOM.createTHead(); @@ -3563,6 +3566,9 @@ public class Grid extends ResizeComposite implements tableHeader.getStyle().setTop(topOffset, Unit.PX); getElement().appendChild(table); + + dropMarkerWidthOffset = WidgetUtil + .getRequiredWidthBoundingClientRectDouble(dropMarker) / 2; } @Override @@ -3601,9 +3607,25 @@ public class Grid extends ResizeComposite implements dropMarkerLeft += autoScrollX; final double frozenColumnsWidth = getFrozenColumnsWidth(); - if (dropMarkerLeft < frozenColumnsWidth - || dropMarkerLeft > escalator.getHeader().getElement() - .getOffsetWidth() || dropMarkerLeft < 0) { + final double rightBoundaryForDrag = getSidebarBoundaryComparedTo(dropMarkerLeft); + final int visibleColumns = getVisibleColumns().size(); + + // First check if the drop marker should move left because of the + // sidebar opening button. this only the case if the grid is + // scrolled to the right + if (latestColumnDropIndex == visibleColumns + && rightBoundaryForDrag < dropMarkerLeft + && dropMarkerLeft <= escalator.getHeader().getElement() + .getOffsetWidth()) { + dropMarkerLeft = rightBoundaryForDrag - dropMarkerWidthOffset; + } + + // Check if the drop marker shouldn't be shown at all + else if (dropMarkerLeft < frozenColumnsWidth + || dropMarkerLeft > Math + .min(rightBoundaryForDrag, escalator.getHeader() + .getElement().getOffsetWidth()) + || dropMarkerLeft < 0) { dropMarkerLeft = -10000000; } dropMarker.getStyle().setLeft(dropMarkerLeft, Unit.PX); @@ -3624,18 +3646,44 @@ public class Grid extends ResizeComposite implements } // Do not show the drag element beyond the grid - final int bodyOffsetWidth = getEscalator().getBody().getElement() + final double sidebarBoundary = getSidebarBoundaryComparedTo(left); + final int gridBoundary = escalator.getHeader().getElement() .getOffsetWidth(); + final double rightBoundary = Math + .min(sidebarBoundary, gridBoundary); + // Do not show on left of the frozen columns (even if scrolled) final int frozenColumnsWidth = (int) getFrozenColumnsWidth(); - left = Math - .max(frozenColumnsWidth, Math.min(left, bodyOffsetWidth)); + left = Math.max(frozenColumnsWidth, Math.min(left, rightBoundary)); left -= dragElement.getClientWidth() / 2; dragElement.getStyle().setLeft(left, Unit.PX); } + private boolean isSidebarOnDraggedRow() { + return eventCell.getRowIndex() == 0 && getSidebar().isInDOM() + && !getSidebar().isOpen(); + } + + /** + * Returns the sidebar left coordinate, in relation to the grid. Or + * Double.MAX_VALUE if it doesn't cause a boundary. + */ + private double getSidebarBoundaryComparedTo(double left) { + if (isSidebarOnDraggedRow()) { + double absoluteLeft = left + getElement().getAbsoluteLeft(); + double sidebarLeft = getSidebar().getElement() + .getAbsoluteLeft(); + double diff = absoluteLeft - sidebarLeft; + + if (diff > 0) { + return left - diff; + } + } + return Double.MAX_VALUE; + } + @Override public boolean onDragStart(NativeEvent startingEvent) { calculatePossibleDropPositions(); diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridColumnReorderTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridColumnReorderTest.java index 1714cdaaf3..3ccca105de 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridColumnReorderTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridColumnReorderTest.java @@ -348,6 +348,31 @@ public class GridColumnReorderTest extends GridBasicFeaturesTest { + " was " + realLeft, Math.abs(expectedLeft - realLeft) < 5); } + @Test + public void testDropMarker_sidebarOpenButtonVisible_dropMarkerOnCorrectPosition() { + // using runo since there the sidebar opening button is wider than the + // scroll deco, and because using Valo has some TB issues + openTestURL("theme=runo"); + + selectMenuPath("Component", "Size", "Width", "100%"); + selectMenuPath("Component", "Columns", "All columns hidable"); + toggleColumnReordering(); + scrollGridHorizontallyTo(100000); + + new Actions(getDriver()).clickAndHold(getDefaultColumnHeader(10)) + .moveByOffset(800, 0).build().perform(); + + WebElement dragDropMarker = findElement(By + .className("v-grid-drop-marker")); + WebElement sidebar = findElement(By.className("v-grid-sidebar")); + + int dragDropMarkerX = dragDropMarker.getLocation().getX(); + int sidebarX = sidebar.getLocation().getX(); + assertTrue("Drop marker misplaced " + dragDropMarkerX + + " compared to sidebar open button " + sidebarX, + dragDropMarkerX <= sidebarX); + } + private void toggleColumnReordering() { selectMenuPath(COLUMN_REORDERING_PATH); } -- 2.39.5