diff options
7 files changed, 326 insertions, 116 deletions
diff --git a/WebContent/VAADIN/themes/base/grid/grid.scss b/WebContent/VAADIN/themes/base/grid/grid.scss index d0bae911db..35024e27c0 100644 --- a/WebContent/VAADIN/themes/base/grid/grid.scss +++ b/WebContent/VAADIN/themes/base/grid/grid.scss @@ -14,6 +14,7 @@ $v-grid-row-focused-background-color: null !default; $v-grid-header-row-height: null !default; $v-grid-header-font-size: $v-font-size !default; $v-grid-header-background-color: $v-grid-row-background-color !default; +$v-grid-header-drag-marked-color: $v-grid-row-selected-background-color !default; $v-grid-footer-row-height: $v-grid-header-row-height !default; $v-grid-footer-font-size: $v-grid-header-font-size !default; @@ -61,12 +62,14 @@ $v-grid-editor-background-color: $v-grid-row-background-color !default; > .#{$primaryStyleName}-cell { border: $v-grid-border; + margin-top: -10px; opacity: 0.9; filter: alpha(opacity=90); // IE8 + z-index: 30000; } > .#{$primaryStyleName}-drop-marker { - background-color: #197de1; + background-color: $v-grid-header-drag-marked-color; position: absolute; width: 3px; } diff --git a/WebContent/VAADIN/themes/valo/components/_grid.scss b/WebContent/VAADIN/themes/valo/components/_grid.scss index 4cac9c5e43..0d6d2ff0a6 100644 --- a/WebContent/VAADIN/themes/valo/components/_grid.scss +++ b/WebContent/VAADIN/themes/valo/components/_grid.scss @@ -40,6 +40,15 @@ $v-grid-animations-enabled: $v-animations-enabled !default; text-shadow: valo-text-shadow($font-color: valo-font-color($v-grid-header-background-color), $background-color: $v-grid-header-background-color); } + .#{$primary-stylename}-header .#{$primary-stylename}-cell.dragged { + @include opacity(0.5, false); + @include transition (opacity .3s ease-in-out); + } + + .#{$primary-stylename}-header .#{$primary-stylename}-cell.dragged-column-header { + margin-top: round($v-grid-row-height/-2); + } + .#{$primary-stylename}-footer .#{$primary-stylename}-cell { @include valo-gradient($v-grid-footer-background-color); text-shadow: valo-text-shadow($font-color: valo-font-color($v-grid-footer-background-color), $background-color: $v-grid-footer-background-color); diff --git a/client/src/com/vaadin/client/widgets/Grid.java b/client/src/com/vaadin/client/widgets/Grid.java index 643f223068..d54c023e3d 100644 --- a/client/src/com/vaadin/client/widgets/Grid.java +++ b/client/src/com/vaadin/client/widgets/Grid.java @@ -2932,10 +2932,6 @@ public class Grid<T> extends ResizeComposite implements dropMarker.getStyle().setLeft(dropMarkerLeft, Unit.PX); } - private void resolveDragElementVerticalPosition() { - dragElement.getStyle().setTop(-10, Unit.PX); - } - private void resolveDragElementHorizontalPosition(final int clientX) { int left = clientX - table.getAbsoluteLeft(); left = Math.max(0, Math.min(left, table.getClientWidth())); @@ -2946,22 +2942,23 @@ public class Grid<T> extends ResizeComposite implements @Override public void showDragElement() { initHeaderDragElementDOM(); - // TODO this clones also some unwanted style names, should confirm - // with UX what we want to show (focus/sort indicator) + // needs to clone focus and sorting indicators too (UX) dragElement = DOM.clone(eventCell.getElement(), true); dragElement.getStyle().clearWidth(); dropMarker.getStyle().setProperty("height", dragElement.getStyle().getHeight()); tableHeader.appendChild(dragElement); - // might need to change this on fly once sorting with multiple - // header rows is possible - resolveDragElementVerticalPosition(); + // mark the column being dragged for styling + eventCell.getElement().addClassName("dragged"); + // mark the floating cell, for styling & testing + dragElement.addClassName("dragged-column-header"); } @Override public void removeDragElement() { table.removeFromParent(); dragElement.removeFromParent(); + eventCell.getElement().removeClassName("dragged"); } @Override @@ -2980,10 +2977,40 @@ public class Grid<T> extends ResizeComposite implements @SuppressWarnings("unchecked") Column<?, T>[] array = reordered.toArray(new Column[reordered .size()]); + transferCellFocusOnDrop(); setColumnOrder(array); } // else no reordering } + private void transferCellFocusOnDrop() { + final Cell focusedCell = cellFocusHandler.getFocusedCell(); + if (focusedCell != null) { + final int focusedCellColumnIndex = focusedCell.getColumn(); + final int focusedRowIndex = focusedCell.getRow(); + final int draggedColumnIndex = eventCell.getColumnIndex(); + // transfer focus if it was effected by the new column order + // FIXME if the dragged column is partly outside of the view + // port and the focused cell is +-1 of the dragged column, the + // grid scrolls to the right end. maybe fixed when the automatic + // scroll handling is implemented? + final RowContainer rowContainer = escalator + .findRowContainer(focusedCell.getElement()); + if (focusedCellColumnIndex == draggedColumnIndex) { + // move with the dragged column + cellFocusHandler.setCellFocus(focusedRowIndex, + latestColumnDropIndex, rowContainer); + } else if (latestColumnDropIndex <= focusedCellColumnIndex + && draggedColumnIndex > focusedCellColumnIndex) { + cellFocusHandler.setCellFocus(focusedRowIndex, + focusedCellColumnIndex + 1, rowContainer); + } else if (latestColumnDropIndex >= focusedCellColumnIndex + && draggedColumnIndex < focusedCellColumnIndex) { + cellFocusHandler.setCellFocus(focusedRowIndex, + focusedCellColumnIndex - 1, rowContainer); + } + } + } + @Override public void onDragCancel() { // cancel next click so that we may prevent column sorting if diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeaturesTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeaturesTest.java index 0e339ec0ae..e7fbc14d89 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeaturesTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeaturesTest.java @@ -15,6 +15,9 @@ */ package com.vaadin.tests.components.grid.basicfeatures; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import java.util.ArrayList; import java.util.List; @@ -132,4 +135,45 @@ public abstract class GridBasicFeaturesTest extends MultiBrowserTest { testUrl = testUrl.replace("?&", "?"); driver.get(testUrl); } + + protected void focusCell(int row, int column) { + getGridElement().getCell(row, column).click(); + } + + protected void assertColumnHeaderOrder(int... indices) { + List<TestBenchElement> headers = getGridHeaderRowCells(); + for (int i = 0; i < indices.length; i++) { + assertColumnHeader("Column " + indices[i], headers.get(i)); + } + } + + protected void assertColumnHeader(String expectedHeaderCaption, + TestBenchElement testBenchElement) { + assertEquals(expectedHeaderCaption.toLowerCase(), testBenchElement + .getText().toLowerCase()); + } + + protected WebElement getDefaultColumnHeader(int index) { + List<TestBenchElement> headerRowCells = getGridHeaderRowCells(); + return headerRowCells.get(index); + } + + protected void dragDefaultColumnHeader(int draggedColumnHeaderIndex, + int onTopOfColumnHeaderIndex, int xOffsetFromColumnTopLeftCorner) { + new Actions(getDriver()) + .clickAndHold(getDefaultColumnHeader(draggedColumnHeaderIndex)) + .moveToElement( + getDefaultColumnHeader(onTopOfColumnHeaderIndex), + xOffsetFromColumnTopLeftCorner, 0).release().perform(); + } + + protected void assertColumnIsSorted(int index) { + WebElement columnHeader = getDefaultColumnHeader(index); + assertTrue(columnHeader.getAttribute("class").contains("sort")); + } + + protected void assertFocusedCell(int row, int column) { + assertTrue(getGridElement().getCell(row, column).getAttribute("class") + .contains("focused")); + } } diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridColumnReorderEventTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridColumnReorderEventTest.java deleted file mode 100644 index eda064284c..0000000000 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridColumnReorderEventTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2000-2014 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.vaadin.tests.components.grid.basicfeatures; - -import static org.junit.Assert.assertEquals; - -import org.junit.Before; -import org.junit.Test; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -import com.vaadin.testbench.elements.GridElement.GridCellElement; -import com.vaadin.tests.annotations.TestCategory; - -/** - * - * @since - * @author Vaadin Ltd - */ -@TestCategory("grid") -public class GridColumnReorderEventTest extends GridBasicClientFeaturesTest { - - @Before - public void before() { - openTestURL(); - } - - @Test - public void columnReorderEventTriggered() { - final int firstIndex = 3; - final int secondIndex = 4; - final String firstHeaderText = getGridElement().getHeaderCell(0, - firstIndex).getText(); - final String secondHeaderText = getGridElement().getHeaderCell(0, - secondIndex).getText(); - selectMenuPath("Component", "Internals", "Listeners", - "Add ColumnReorder listener"); - selectMenuPath("Component", "Columns", "Column " + secondIndex, - "Move column left"); - // columns 3 and 4 should have swapped to 4 and 3 - GridCellElement headerCell = getGridElement().getHeaderCell(0, - firstIndex); - assertEquals(secondHeaderText, headerCell.getText()); - headerCell = getGridElement().getHeaderCell(0, secondIndex); - assertEquals(firstHeaderText, headerCell.getText()); - - // the reorder event should have typed the order to this label - WebElement columnReorderElement = findElement(By.id("columnreorder")); - int eventIndex = Integer.parseInt(columnReorderElement - .getAttribute("columns")); - assertEquals(1, eventIndex); - - // trigger another event - selectMenuPath("Component", "Columns", "Column " + secondIndex, - "Move column left"); - columnReorderElement = findElement(By.id("columnreorder")); - eventIndex = Integer.parseInt(columnReorderElement - .getAttribute("columns")); - assertEquals(2, eventIndex); - } -} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridColumnReorderTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridColumnReorderTest.java new file mode 100644 index 0000000000..9f43c39b1e --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridColumnReorderTest.java @@ -0,0 +1,233 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Before; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.tests.annotations.TestCategory; + +/** + * + * @since + * @author Vaadin Ltd + */ +@TestCategory("grid") +public class GridColumnReorderTest extends GridBasicClientFeaturesTest { + + @Before + public void before() { + openTestURL(); + } + + @Test + public void columnReorderEventTriggered() { + final int firstIndex = 3; + final int secondIndex = 4; + final String firstHeaderText = getGridElement().getHeaderCell(0, + firstIndex).getText(); + final String secondHeaderText = getGridElement().getHeaderCell(0, + secondIndex).getText(); + selectMenuPath("Component", "Internals", "Listeners", + "Add ColumnReorder listener"); + selectMenuPath("Component", "Columns", "Column " + secondIndex, + "Move column left"); + // columns 3 and 4 should have swapped to 4 and 3 + GridCellElement headerCell = getGridElement().getHeaderCell(0, + firstIndex); + assertEquals(secondHeaderText, headerCell.getText()); + headerCell = getGridElement().getHeaderCell(0, secondIndex); + assertEquals(firstHeaderText, headerCell.getText()); + + // the reorder event should have typed the order to this label + WebElement columnReorderElement = findElement(By.id("columnreorder")); + int eventIndex = Integer.parseInt(columnReorderElement + .getAttribute("columns")); + assertEquals(1, eventIndex); + + // trigger another event + selectMenuPath("Component", "Columns", "Column " + secondIndex, + "Move column left"); + columnReorderElement = findElement(By.id("columnreorder")); + eventIndex = Integer.parseInt(columnReorderElement + .getAttribute("columns")); + assertEquals(2, eventIndex); + } + + @Test + public void testColumnReorder_onReorder_columnReorderEventTriggered() { + final int firstIndex = 3; + final int secondIndex = 4; + final String firstHeaderText = getGridElement().getHeaderCell(0, + firstIndex).getText(); + final String secondHeaderText = getGridElement().getHeaderCell(0, + secondIndex).getText(); + selectMenuPath("Component", "Internals", "Listeners", + "Add ColumnReorder listener"); + selectMenuPath("Component", "Columns", "Column " + secondIndex, + "Move column left"); + // columns 3 and 4 should have swapped to 4 and 3 + GridCellElement headerCell = getGridElement().getHeaderCell(0, + firstIndex); + assertEquals(secondHeaderText, headerCell.getText()); + headerCell = getGridElement().getHeaderCell(0, secondIndex); + assertEquals(firstHeaderText, headerCell.getText()); + + // the reorder event should have typed the order to this label + WebElement columnReorderElement = findElement(By.id("columnreorder")); + int eventIndex = Integer.parseInt(columnReorderElement + .getAttribute("columns")); + assertEquals(1, eventIndex); + + // trigger another event + selectMenuPath("Component", "Columns", "Column " + secondIndex, + "Move column left"); + columnReorderElement = findElement(By.id("columnreorder")); + eventIndex = Integer.parseInt(columnReorderElement + .getAttribute("columns")); + assertEquals(2, eventIndex); + } + + @Test + public void testColumnReorder_draggingSortedColumn_sortIndicatorShownOnDraggedElement() { + // given + toggleColumnReorder(); + toggleSortableColumn(0); + sortColumn(0); + + // when + startDragButDontDropOnDefaultColumnHeader(0); + + // then + WebElement draggedElement = getDraggedHeaderElement(); + assertTrue(draggedElement.getAttribute("class").contains("sort")); + } + + @Test + public void testColumnReorder_draggingSortedColumn_sortStays() { + // given + toggleColumnReorder(); + toggleSortableColumn(0); + sortColumn(0); + + // when + dragDefaultColumnHeader(0, 2, 10); + + // then + assertColumnIsSorted(1); + } + + @Test + public void testColumnReorder_draggingFocusedHeader_focusShownOnDraggedElement() { + // given + toggleColumnReorder(); + focusDefaultHeader(0); + + // when + startDragButDontDropOnDefaultColumnHeader(0); + + // then + WebElement draggedElement = getDraggedHeaderElement(); + assertTrue(draggedElement.getAttribute("class").contains("focused")); + } + + @Test + public void testColumnReorder_draggingFocusedHeader_focusIsKeptOnHeader() { + // given + toggleColumnReorder(); + focusDefaultHeader(0); + + // when + dragDefaultColumnHeader(0, 3, 10); + + // then + WebElement defaultColumnHeader = getDefaultColumnHeader(2); + String attribute = defaultColumnHeader.getAttribute("class"); + assertTrue(attribute.contains("focused")); + } + + @Test + public void testColumnReorder_draggingFocusedCellColumn_focusIsKeptOnCell() { + // given + toggleColumnReorder(); + focusCell(2, 2); + + // when + dragDefaultColumnHeader(2, 0, 10); + + // then + assertFocusedCell(2, 0); + } + + @Test + public void testColumnReorder_dragColumnFromRightToLeftOfFocusedCellColumn_focusIsKept() { + // given + toggleColumnReorder(); + focusCell(1, 3); + + // when + dragDefaultColumnHeader(4, 1, 10); + + // then + assertFocusedCell(1, 4); + } + + @Test + public void testColumnReorder_dragColumnFromLeftToRightOfFocusedCellColumn_focusIsKept() { + // given + toggleColumnReorder(); + focusCell(4, 2); + + // when + dragDefaultColumnHeader(0, 4, 10); + + // then + assertFocusedCell(4, 1); + } + + private void toggleColumnReorder() { + selectMenuPath("Component", "State", "Column Reordering"); + } + + private void toggleSortableColumn(int index) { + selectMenuPath("Component", "Columns", "Column " + index, "Sortable"); + } + + private void startDragButDontDropOnDefaultColumnHeader(int index) { + new Actions(getDriver()) + .clickAndHold(getGridHeaderRowCells().get(index)) + .moveByOffset(100, 0).perform(); + } + + private void sortColumn(int index) { + getGridHeaderRowCells().get(index).click(); + } + + private void focusDefaultHeader(int index) { + getGridHeaderRowCells().get(index).click(); + } + + private WebElement getDraggedHeaderElement() { + return findElement(By.className("dragged-column-header")); + } +} 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 2f00071351..2cc8610209 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 @@ -15,18 +15,12 @@ */ package com.vaadin.tests.components.grid.basicfeatures.server; -import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import java.util.List; - import org.junit.Before; import org.junit.Test; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.interactions.Actions; -import com.vaadin.testbench.TestBenchElement; import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeaturesTest; /** @@ -212,30 +206,4 @@ public class GridColumnReorderTest extends GridBasicFeaturesTest { assertFalse(logRow.contains("Columns reordered")); } - private void assertColumnHeaderOrder(int... indices) { - List<TestBenchElement> headers = getGridHeaderRowCells(); - for (int i = 0; i < indices.length; i++) { - assertColumnHeader("Column " + indices[i], headers.get(i)); - } - } - - private void assertColumnHeader(String expectedHeaderCaption, - TestBenchElement testBenchElement) { - assertEquals(expectedHeaderCaption.toLowerCase(), testBenchElement - .getText().toLowerCase()); - } - - private WebElement getDefaultColumnHeader(int index) { - List<TestBenchElement> headerRowCells = getGridHeaderRowCells(); - return headerRowCells.get(index); - } - - private void dragDefaultColumnHeader(int draggedColumnHeaderIndex, - int onTopOfColumnHeaderIndex, int xOffsetFromColumnTopLeftCorner) { - new Actions(getDriver()) - .clickAndHold(getDefaultColumnHeader(draggedColumnHeaderIndex)) - .moveToElement( - getDefaultColumnHeader(onTopOfColumnHeaderIndex), - xOffsetFromColumnTopLeftCorner, 0).release().perform(); - } } |