diff options
author | Pekka Hyvönen <pekka@vaadin.com> | 2015-02-26 16:23:32 +0200 |
---|---|---|
committer | Pekka Hyvönen <pekka@vaadin.com> | 2015-02-27 10:21:22 +0200 |
commit | 31b188e370b60832ecc05df8ddd41a6884996aad (patch) | |
tree | fb4288a11a152da9045fcb0a3a89b596d04f189d /client/src | |
parent | fa50ea28870436c5dedb459e364d24f14f7ab001 (diff) | |
download | vaadin-framework-31b188e370b60832ecc05df8ddd41a6884996aad.tar.gz vaadin-framework-31b188e370b60832ecc05df8ddd41a6884996aad.zip |
Handle spanned header cells when dnd reordering columns in grid. (#16643)
Prevents dragging columns from outside spanned cells to inside them, on any row.
Currently prevents dragging columns inside spanned cells. Will change this later.
Change-Id: Ie832b3c404a3afbcce0374f8b5088dc8cb124fb8
Diffstat (limited to 'client/src')
-rw-r--r-- | client/src/com/vaadin/client/widget/grid/AutoScroller.java | 1 | ||||
-rw-r--r-- | client/src/com/vaadin/client/widgets/Grid.java | 129 |
2 files changed, 106 insertions, 24 deletions
diff --git a/client/src/com/vaadin/client/widget/grid/AutoScroller.java b/client/src/com/vaadin/client/widget/grid/AutoScroller.java index 60c9535ca7..71851d67c8 100644 --- a/client/src/com/vaadin/client/widget/grid/AutoScroller.java +++ b/client/src/com/vaadin/client/widget/grid/AutoScroller.java @@ -669,6 +669,7 @@ public class AutoScroller { } private double getFrozenColumnsWidth() { + // TODO handle the case where the checkbox column is present double value = 0; for (int i = 0; i < grid.getFrozenColumnCount(); i++) { value += grid.getColumn(i).getWidthActual(); diff --git a/client/src/com/vaadin/client/widgets/Grid.java b/client/src/com/vaadin/client/widgets/Grid.java index ebc2fcf97e..3fd119d9ea 100644 --- a/client/src/com/vaadin/client/widgets/Grid.java +++ b/client/src/com/vaadin/client/widgets/Grid.java @@ -25,7 +25,9 @@ import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; +import java.util.TreeMap; import java.util.logging.Level; import java.util.logging.Logger; @@ -37,7 +39,6 @@ import com.google.gwt.dom.client.DivElement; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.EventTarget; import com.google.gwt.dom.client.NativeEvent; -import com.google.gwt.dom.client.NodeList; import com.google.gwt.dom.client.Style; import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.dom.client.TableCellElement; @@ -416,6 +417,16 @@ public class Grid<T> extends ResizeComposite implements } /** + * Returns <code>true</code> if this row contains spanned cells. + * + * @since + * @return does this row contain spanned cells + */ + public boolean hasSpannedCells() { + return !cellGroups.isEmpty(); + } + + /** * Merges columns cells in a row * * @param columns @@ -2907,6 +2918,11 @@ public class Grid<T> extends ResizeComposite implements /** Tracks index of the column whose left side the drop would occur */ private int latestColumnDropIndex; /** + * Map of possible drop positions for the column and the corresponding + * column index. + */ + private final TreeMap<Double, Integer> possibleDropPositions = new TreeMap<Double, Integer>(); + /** * Makes sure that drag cancel doesn't cause anything unwanted like sort */ private HandlerRegistration columnSortPreventRegistration; @@ -2952,33 +2968,33 @@ public class Grid<T> extends ResizeComposite implements } private void updateDragDropMarker(final int clientX) { - RowContainer header = escalator.getHeader(); - NodeList<TableCellElement> cells = header.getRowElement( - eventCell.getRowIndex()).getCells(); - double dropMarkerLeft = 0 - escalator.getScrollLeft(); - latestColumnDropIndex = 0; - for (int i = 0; i < cells.getLength(); i++, latestColumnDropIndex++) { - TableCellElement cellElement = cells.getItem(i); - int cellX = cellElement.getAbsoluteLeft(); - int cellWidth = cellElement.getOffsetWidth(); - if (clientX < cellX || clientX < cellX + (cellWidth / 2)) { - break; - } else { - dropMarkerLeft += cellWidth; - } + final double scrollLeft = getScrollLeft(); + final double cursorXCoordinate = clientX + - escalator.getHeader().getElement().getAbsoluteLeft(); + final Entry<Double, Integer> cellEdgeOnRight = possibleDropPositions + .ceilingEntry(cursorXCoordinate); + final Entry<Double, Integer> cellEdgeOnLeft = possibleDropPositions + .floorEntry(cursorXCoordinate); + final double diffToRightEdge = cellEdgeOnRight == null ? Double.MAX_VALUE + : cellEdgeOnRight.getKey() - cursorXCoordinate; + final double diffToLeftEdge = cellEdgeOnLeft == null ? Double.MAX_VALUE + : cursorXCoordinate - cellEdgeOnLeft.getKey(); + + double dropMarkerLeft = 0 - scrollLeft; + if (diffToRightEdge > diffToLeftEdge) { + latestColumnDropIndex = cellEdgeOnLeft.getValue(); + dropMarkerLeft += cellEdgeOnLeft.getKey(); + } else { + latestColumnDropIndex = cellEdgeOnRight.getValue(); + dropMarkerLeft += cellEdgeOnRight.getKey(); } + dropMarkerLeft += autoScrollX; final double frozenColumnsWidth = getFrozenColumnsWidth(); - if (dropMarkerLeft < frozenColumnsWidth) { - latestColumnDropIndex = getFrozenColumnCount(); - if (getScrollLeft() == 0) { - dropMarkerLeft = frozenColumnsWidth; - } else { - dropMarkerLeft = -10000000; - } - } else if (dropMarkerLeft > header.getElement().getOffsetWidth() - || dropMarkerLeft < 0) { + if (dropMarkerLeft < frozenColumnsWidth + || dropMarkerLeft > escalator.getHeader().getElement() + .getOffsetWidth() || dropMarkerLeft < 0) { dropMarkerLeft = -10000000; } dropMarker.getStyle().setLeft(dropMarkerLeft, Unit.PX); @@ -3009,6 +3025,9 @@ public class Grid<T> extends ResizeComposite implements eventCell.getElement().addClassName("dragged"); // mark the floating cell, for styling & testing dragElement.addClassName("dragged-column-header"); + + calculatePossibleDropPositions(); + // start the auto scroll handler autoScroller.setScrollAreaPX(60); autoScroller.start(startingEvent, ScrollAxis.HORIZONTAL, @@ -3099,6 +3118,58 @@ public class Grid<T> extends ResizeComposite implements } return result; } + + private void calculatePossibleDropPositions() { + possibleDropPositions.clear(); + + if (!calculatePossibleDropPositionInsideSpannedHeader()) { + HashMap<Integer, Double> columnIndexToDropPositionMap = new HashMap<Integer, Double>(); + + final int frozenColumns = Math.max(0, getFrozenColumnCount()); + double position = getFrozenColumnsWidth(); + // add all columns except frozen columns + // TODO handle the case where the checkbox column is present + for (int i = frozenColumns; i < getColumnCount(); i++) { + columnIndexToDropPositionMap.put(i, position); + position += getColumn(i).getWidthActual(); + } + // add the right side of the last column as columns.size() + columnIndexToDropPositionMap.put(getColumnCount(), position); + + // can't drop inside a spanned header from outside it + // -> remove all column indexes that are inside a spanned cell + // in any header row + for (int c = frozenColumns; c < getColumnCount(); c++) { + for (int r = 0; r < getHeaderRowCount(); r++) { + HeaderRow headerRow = getHeaderRow(r); + if (headerRow.hasSpannedCells()) { + HeaderCell cell = headerRow.getCell(getColumn(c)); + assert cell != null : "Somehow got a null cell for row:cell " + + r + ":" + c; + int colspan = cell.getColspan(); + while (colspan > 1) { + c++; + colspan--; + columnIndexToDropPositionMap.remove(Integer + .valueOf(c)); + } + } + } + } + // finally lets flip the map, because while dragging we want the + // column index matching the X-coordinate + for (Entry<Integer, Double> entry : columnIndexToDropPositionMap + .entrySet()) { + possibleDropPositions.put(entry.getValue(), entry.getKey()); + } + } + } + + private boolean calculatePossibleDropPositionInsideSpannedHeader() { + // TODO if the dragged column is inside a spanned header on any row, + // then dragging is limited to inside that spanned cell + return false; + } }; /** @@ -5392,6 +5463,16 @@ public class Grid<T> extends ResizeComposite implements .getFrozenColumnCount()) { return false; } + // for now prevent dragging of spanned cells + if (eventCell.getElement().getColSpan() > 1) { + return false; + } + // for now prevent dragging of columns belonging to a spanned cell + for (int r = 0; r < getHeaderRowCount(); r++) { + if (getHeaderRow(r).getCell(eventCell.getColumn()).getColspan() > 1) { + return false; + } + } if (event.getTypeInt() == Event.ONMOUSEDOWN && event.getButton() == NativeEvent.BUTTON_LEFT || event.getTypeInt() == Event.ONTOUCHSTART) { |