diff options
author | Dirk Fauth | 2017-03-06 20:26:13 +0000 |
---|---|---|
committer | Dirk Fauth | 2017-03-06 20:26:13 +0000 |
commit | 67d691930fe0d53b267f4e58f58f9f33e0040c64 (patch) | |
tree | 644ea2e0637730d141cd9d5c86faab4fe7ce2428 | |
parent | 30b608ad1895725567b2c6d0cd948f3a1bafdc43 (diff) | |
download | org.eclipse.nebula.widgets.nattable-67d691930fe0d53b267f4e58f58f9f33e0040c64.tar.gz org.eclipse.nebula.widgets.nattable-67d691930fe0d53b267f4e58f58f9f33e0040c64.tar.xz org.eclipse.nebula.widgets.nattable-67d691930fe0d53b267f4e58f58f9f33e0040c64.zip |
Bug 512951 - Auto scrolling during column reordering
Change-Id: Ia17817d9c94480c3dfece63e0d778b0ee5069f71
Signed-off-by: Dirk Fauth <dirk.fauth@googlemail.com>
5 files changed, 401 insertions, 214 deletions
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/fillhandle/action/FillHandleDragMode.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/fillhandle/action/FillHandleDragMode.java index 2cd523d5..57e5188a 100644 --- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/fillhandle/action/FillHandleDragMode.java +++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/fillhandle/action/FillHandleDragMode.java @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2015, 2016 CEA LIST. + * Copyright (c) 2015, 2017 CEA LIST and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -28,7 +28,7 @@ import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer; import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer.MoveDirectionEnum; import org.eclipse.nebula.widgets.nattable.style.DisplayMode; import org.eclipse.nebula.widgets.nattable.ui.action.IDragMode; -import org.eclipse.nebula.widgets.nattable.viewport.command.ViewportDragCommand; +import org.eclipse.nebula.widgets.nattable.viewport.action.AutoScrollDragMode; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; @@ -49,7 +49,7 @@ import org.eclipse.swt.widgets.MenuItem; * * @since 1.4 */ -public class FillHandleDragMode implements IDragMode { +public class FillHandleDragMode extends AutoScrollDragMode { protected MouseEvent startEvent; protected Point startIndex; @@ -73,6 +73,8 @@ public class FillHandleDragMode implements IDragMode { * & paste operation triggered by using the fill handle. */ public FillHandleDragMode(SelectionLayer selectionLayer, InternalCellClipboard clipboard) { + super(true, true); + if (selectionLayer == null) { throw new IllegalArgumentException("SelectionLayer can not be null"); //$NON-NLS-1$ } @@ -97,106 +99,84 @@ public class FillHandleDragMode implements IDragMode { } @Override - public void mouseMove(NatTable natTable, MouseEvent event) { - Rectangle clientArea = natTable.getClientAreaProvider().getClientArea(); - - int x = event.x; - int y = event.y; - - MoveDirectionEnum horizontal = MoveDirectionEnum.NONE; - if (event.x < 0) { - horizontal = MoveDirectionEnum.LEFT; - x = 0; - } else if (event.x > clientArea.width) { - horizontal = MoveDirectionEnum.RIGHT; - x = clientArea.width; - } - - MoveDirectionEnum vertical = MoveDirectionEnum.NONE; - if (event.y < 0) { - vertical = MoveDirectionEnum.UP; - y = 0; - } else if (event.y > clientArea.height) { - vertical = MoveDirectionEnum.DOWN; - y = clientArea.height; - } - - if (natTable.doCommand(new ViewportDragCommand(horizontal, vertical))) { - - int selectedColumnPosition = natTable.getColumnPositionByX(x); - int selectedRowPosition = natTable.getRowPositionByY(y); - - int selectedColumnIndex = natTable.getColumnIndexByPosition(selectedColumnPosition); - int selectedRowIndex = natTable.getRowIndexByPosition(selectedRowPosition); - - if (selectedColumnPosition > -1 && selectedRowPosition > -1) { - Rectangle actionBounds = null; - - int xStart = this.startIndex.x; - int yStart = this.startIndex.y; - - Rectangle region = this.selectionLayer.getLastSelectedRegion(); - - // only increase range in one direction - int xDiff = calculateIncreasedPositiveDiff( - event.x, - (event.x < this.startEvent.x) ? this.selectionCell.getBounds().x : this.startEvent.x); - int yDiff = calculateIncreasedPositiveDiff( - event.y, - (event.y < this.startEvent.y) ? this.selectionCell.getBounds().y : this.startEvent.y); - if (selectedColumnIndex >= region.x && selectedColumnIndex < (region.x + region.width)) { - xDiff = 0; - } - if (selectedRowIndex >= region.y && selectedRowIndex < (region.y + region.height)) { - yDiff = 0; - } + protected void performDragAction( + NatTable natTable, + int x, int y, + MoveDirectionEnum horizontal, MoveDirectionEnum vertical) { + + int selectedColumnPosition = natTable.getColumnPositionByX(x); + int selectedRowPosition = natTable.getRowPositionByY(y); + + int selectedColumnIndex = natTable.getColumnIndexByPosition(selectedColumnPosition); + int selectedRowIndex = natTable.getRowIndexByPosition(selectedRowPosition); + + if (selectedColumnPosition > -1 && selectedRowPosition > -1) { + Rectangle actionBounds = null; + + int xStart = this.startIndex.x; + int yStart = this.startIndex.y; + + Rectangle region = this.selectionLayer.getLastSelectedRegion(); + + // only increase range in one direction + int xDiff = calculateIncreasedPositiveDiff( + x, + (x < this.startEvent.x) ? this.selectionCell.getBounds().x : this.startEvent.x); + int yDiff = calculateIncreasedPositiveDiff( + y, + (y < this.startEvent.y) ? this.selectionCell.getBounds().y : this.startEvent.y); + if (selectedColumnIndex >= region.x && selectedColumnIndex < (region.x + region.width)) { + xDiff = 0; + } + if (selectedRowIndex >= region.y && selectedRowIndex < (region.y + region.height)) { + yDiff = 0; + } - int width = -1; - int height = -1; + int width = -1; + int height = -1; - // check if only drag operations in one direction are supported - Direction direction = natTable.getConfigRegistry().getConfigAttribute( - FillHandleConfigAttributes.ALLOWED_FILL_DIRECTION, - DisplayMode.NORMAL, - this.selectionCell.getConfigLabels().getLabels()); + // check if only drag operations in one direction are supported + Direction direction = natTable.getConfigRegistry().getConfigAttribute( + FillHandleConfigAttributes.ALLOWED_FILL_DIRECTION, + DisplayMode.NORMAL, + this.selectionCell.getConfigLabels().getLabels()); - if (direction == null) { - direction = Direction.BOTH; - } + if (direction == null) { + direction = Direction.BOTH; + } - if (direction != Direction.NONE) { - if (direction == Direction.VERTICAL - || (direction == Direction.BOTH && yDiff >= xDiff)) { - int diff = calculateIncreasedPositiveDiff(selectedRowIndex, this.startIndex.y); - height = Math.max(diff, this.selectionLayer.getSelectedRowCount()); - width = this.selectionLayer.getSelectedColumnPositions().length; - this.direction = MoveDirectionEnum.DOWN; - if ((selectedRowIndex - this.startIndex.y) < 0) { - yStart = selectedRowIndex; - height = diff + this.selectionLayer.getSelectedRowCount() - 1; - this.direction = MoveDirectionEnum.UP; - } - } else { - int diff = calculateIncreasedPositiveDiff(selectedColumnIndex, this.startIndex.x); - height = this.selectionLayer.getSelectedRowCount(); - width = Math.max(diff, this.selectionLayer.getSelectedColumnPositions().length); - this.direction = MoveDirectionEnum.RIGHT; - if ((selectedColumnIndex - this.startIndex.x) < 0) { - xStart = selectedColumnIndex; - width = diff + this.selectionLayer.getSelectedColumnPositions().length - 1; - this.direction = MoveDirectionEnum.LEFT; - } + if (direction != Direction.NONE) { + if (direction == Direction.VERTICAL + || (direction == Direction.BOTH && yDiff >= xDiff)) { + int diff = calculateIncreasedPositiveDiff(selectedRowIndex, this.startIndex.y); + height = Math.max(diff, this.selectionLayer.getSelectedRowCount()); + width = this.selectionLayer.getSelectedColumnPositions().length; + this.direction = MoveDirectionEnum.DOWN; + if ((selectedRowIndex - this.startIndex.y) < 0) { + yStart = selectedRowIndex; + height = diff + this.selectionLayer.getSelectedRowCount() - 1; + this.direction = MoveDirectionEnum.UP; + } + } else { + int diff = calculateIncreasedPositiveDiff(selectedColumnIndex, this.startIndex.x); + height = this.selectionLayer.getSelectedRowCount(); + width = Math.max(diff, this.selectionLayer.getSelectedColumnPositions().length); + this.direction = MoveDirectionEnum.RIGHT; + if ((selectedColumnIndex - this.startIndex.x) < 0) { + xStart = selectedColumnIndex; + width = diff + this.selectionLayer.getSelectedColumnPositions().length - 1; + this.direction = MoveDirectionEnum.LEFT; } + } - actionBounds = new Rectangle( - xStart, - yStart, - width, - height); + actionBounds = new Rectangle( + xStart, + yStart, + width, + height); - this.selectionLayer.setFillHandleRegion(actionBounds); - natTable.redraw(); - } + this.selectionLayer.setFillHandleRegion(actionBounds); + natTable.redraw(); } } } @@ -222,6 +202,9 @@ public class FillHandleDragMode implements IDragMode { @Override public void mouseUp(final NatTable natTable, MouseEvent event) { + // Cancel any active viewport drag + super.mouseUp(natTable, event); + if (natTable.doCommand( new CopyDataToClipboardCommand( "\t", //$NON-NLS-1$ diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/reorder/action/ColumnReorderDragMode.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/reorder/action/ColumnReorderDragMode.java index 7e238c20..2332308b 100644 --- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/reorder/action/ColumnReorderDragMode.java +++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/reorder/action/ColumnReorderDragMode.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012, 2013 Original authors and others. + * Copyright (c) 2012, 2017 Original authors and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -22,7 +22,7 @@ import org.eclipse.nebula.widgets.nattable.ui.util.CellEdgeDetectUtil; import org.eclipse.nebula.widgets.nattable.ui.util.CellEdgeEnum; import org.eclipse.nebula.widgets.nattable.ui.util.MouseEventHelper; import org.eclipse.nebula.widgets.nattable.util.GUIHelper; -import org.eclipse.nebula.widgets.nattable.viewport.command.ViewportDragCommand; +import org.eclipse.nebula.widgets.nattable.viewport.action.AutoScrollDragMode; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; @@ -37,7 +37,7 @@ import org.eclipse.swt.graphics.Rectangle; * <li>Overlays a black line indicating the new column position</li> * </ol> */ -public class ColumnReorderDragMode implements IDragMode { +public class ColumnReorderDragMode extends AutoScrollDragMode { protected NatTable natTable; protected MouseEvent initialEvent; @@ -46,6 +46,10 @@ public class ColumnReorderDragMode implements IDragMode { protected ColumnReorderOverlayPainter targetOverlayPainter = new ColumnReorderOverlayPainter(); + public ColumnReorderDragMode() { + super(true, false); + } + @Override public void mouseDown(NatTable natTable, MouseEvent event) { this.natTable = natTable; @@ -62,15 +66,18 @@ public class ColumnReorderDragMode implements IDragMode { @Override public void mouseMove(NatTable natTable, MouseEvent event) { - this.currentEvent = event; + super.mouseMove(natTable, event); - natTable.doCommand(new ViewportDragCommand(event.x, -1)); + this.currentEvent = event; natTable.redraw(); } @Override public void mouseUp(NatTable natTable, MouseEvent event) { + // Cancel any active viewport drag + super.mouseUp(natTable, event); + natTable.removeOverlayPainter(this.targetOverlayPainter); // only trigger column reordering in case there is a real drag operation @@ -79,17 +86,13 @@ public class ColumnReorderDragMode implements IDragMode { getMoveDirection(event.x), natTable.getColumnPositionByX(event.x)); - if (!isValidTargetColumnPosition(natTable, this.dragFromGridColumnPosition, - dragToGridColumnPosition)) { + if (!isValidTargetColumnPosition(natTable, this.dragFromGridColumnPosition, dragToGridColumnPosition)) { dragToGridColumnPosition = -1; } fireMoveEndCommand(natTable, dragToGridColumnPosition); } - // Cancel any active viewport drag - natTable.doCommand(new ViewportDragCommand(-1, -1)); - natTable.redraw(); } @@ -97,8 +100,7 @@ public class ColumnReorderDragMode implements IDragMode { return this.natTable.getColumnPositionByX(this.initialEvent.x); } - protected int getDragToGridColumnPosition(CellEdgeEnum moveDirection, - int gridColumnPosition) { + protected int getDragToGridColumnPosition(CellEdgeEnum moveDirection, int gridColumnPosition) { int dragToGridColumnPosition = -1; if (moveDirection != null) { @@ -119,8 +121,7 @@ public class ColumnReorderDragMode implements IDragMode { ILayerCell cell = getColumnCell(x); if (cell != null) { Rectangle selectedColumnHeaderRect = cell.getBounds(); - return CellEdgeDetectUtil.getHorizontalCellEdge( - selectedColumnHeaderRect, new Point(x, this.initialEvent.y)); + return CellEdgeDetectUtil.getHorizontalCellEdge(selectedColumnHeaderRect, new Point(x, this.initialEvent.y)); } return null; @@ -132,21 +133,16 @@ public class ColumnReorderDragMode implements IDragMode { return this.natTable.getCellByPosition(gridColumnPosition, gridRowPosition); } - protected boolean isValidTargetColumnPosition(ILayer natLayer, - int dragFromGridColumnPosition, int dragToGridColumnPosition) { + protected boolean isValidTargetColumnPosition(ILayer natLayer, int dragFromGridColumnPosition, int dragToGridColumnPosition) { return dragFromGridColumnPosition >= 0 && dragToGridColumnPosition >= 0; } - protected void fireMoveStartCommand(NatTable natTable, - int dragFromGridColumnPosition) { - natTable.doCommand(new ColumnReorderStartCommand(natTable, - dragFromGridColumnPosition)); + protected void fireMoveStartCommand(NatTable natTable, int dragFromGridColumnPosition) { + natTable.doCommand(new ColumnReorderStartCommand(natTable, dragFromGridColumnPosition)); } - protected void fireMoveEndCommand(NatTable natTable, - int dragToGridColumnPosition) { - natTable.doCommand(new ColumnReorderEndCommand(natTable, - dragToGridColumnPosition)); + protected void fireMoveEndCommand(NatTable natTable, int dragToGridColumnPosition) { + natTable.doCommand(new ColumnReorderEndCommand(natTable, dragToGridColumnPosition)); } private class ColumnReorderOverlayPainter implements IOverlayPainter { @@ -164,21 +160,20 @@ public class ColumnReorderDragMode implements IDragMode { moveDirection, ColumnReorderDragMode.this.natTable.getColumnPositionByX(ColumnReorderDragMode.this.currentEvent.x)); - if (isValidTargetColumnPosition(ColumnReorderDragMode.this.natTable, + if (isValidTargetColumnPosition( + ColumnReorderDragMode.this.natTable, dragFromGridColumnPosition, dragToGridColumnPosition)) { int dragToColumnHandleX = -1; if (moveDirection != null) { - Rectangle selectedColumnHeaderRect = getColumnCell( - ColumnReorderDragMode.this.currentEvent.x).getBounds(); + Rectangle selectedColumnHeaderRect = getColumnCell(ColumnReorderDragMode.this.currentEvent.x).getBounds(); switch (moveDirection) { case LEFT: dragToColumnHandleX = selectedColumnHeaderRect.x; break; case RIGHT: - dragToColumnHandleX = selectedColumnHeaderRect.x - + selectedColumnHeaderRect.width; + dragToColumnHandleX = selectedColumnHeaderRect.x + selectedColumnHeaderRect.width; break; } } @@ -186,15 +181,10 @@ public class ColumnReorderDragMode implements IDragMode { if (dragToColumnHandleX > 0) { Color orgBgColor = gc.getBackground(); gc.setBackground(GUIHelper.COLOR_DARK_GRAY); - - gc.fillRectangle(dragToColumnHandleX - 1, 0, 2, - layer.getHeight()); - + gc.fillRectangle(dragToColumnHandleX - 1, 0, 2, layer.getHeight()); gc.setBackground(orgBgColor); } } } - } - } diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/reorder/action/RowReorderDragMode.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/reorder/action/RowReorderDragMode.java index ac28e6b2..52b11b95 100644 --- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/reorder/action/RowReorderDragMode.java +++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/reorder/action/RowReorderDragMode.java @@ -1,12 +1,12 @@ /******************************************************************************* - * Copyright (c) 2013 Dirk Fauth and others. + * Copyright (c) 2013, 2017 Dirk Fauth and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Dirk Fauth <dirk.fauth@gmail.com> - initial API and implementation + * Dirk Fauth <dirk.fauth@googlemail.com> - initial API and implementation *******************************************************************************/ package org.eclipse.nebula.widgets.nattable.reorder.action; @@ -21,7 +21,7 @@ import org.eclipse.nebula.widgets.nattable.ui.action.IDragMode; import org.eclipse.nebula.widgets.nattable.ui.util.CellEdgeDetectUtil; import org.eclipse.nebula.widgets.nattable.ui.util.CellEdgeEnum; import org.eclipse.nebula.widgets.nattable.util.GUIHelper; -import org.eclipse.nebula.widgets.nattable.viewport.command.ViewportDragCommand; +import org.eclipse.nebula.widgets.nattable.viewport.action.AutoScrollDragMode; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; @@ -36,7 +36,7 @@ import org.eclipse.swt.graphics.Rectangle; * <li>Overlays a black line indicating the new row position</li> * </ol> */ -public class RowReorderDragMode implements IDragMode { +public class RowReorderDragMode extends AutoScrollDragMode { protected NatTable natTable; protected MouseEvent initialEvent; @@ -45,6 +45,10 @@ public class RowReorderDragMode implements IDragMode { protected RowReorderOverlayPainter targetOverlayPainter = new RowReorderOverlayPainter(); + public RowReorderDragMode() { + super(false, true); + } + @Override public void mouseDown(NatTable natTable, MouseEvent event) { this.natTable = natTable; @@ -61,31 +65,30 @@ public class RowReorderDragMode implements IDragMode { @Override public void mouseMove(NatTable natTable, MouseEvent event) { - this.currentEvent = event; + super.mouseMove(natTable, event); - natTable.doCommand(new ViewportDragCommand(-1, event.y)); + this.currentEvent = event; natTable.redraw(); } @Override public void mouseUp(NatTable natTable, MouseEvent event) { + // Cancel any active viewport drag + super.mouseUp(natTable, event); + natTable.removeOverlayPainter(this.targetOverlayPainter); int dragToGridRowPosition = getDragToGridRowPosition( - getMoveDirection(event.y), natTable.getRowPositionByY(event.y)); + getMoveDirection(event.y), + natTable.getRowPositionByY(event.y)); - if (!isValidTargetRowPosition(natTable, this.dragFromGridRowPosition, - dragToGridRowPosition)) { + if (!isValidTargetRowPosition(natTable, this.dragFromGridRowPosition, dragToGridRowPosition)) { dragToGridRowPosition = -1; } fireMoveEndCommand(natTable, dragToGridRowPosition); - natTable.doCommand(new ViewportDragCommand(-1, -1)); // Cancel any - // active viewport - // drag - natTable.redraw(); } @@ -104,8 +107,7 @@ public class RowReorderDragMode implements IDragMode { * The row position at which the drop was performed * @return The row position where the dragged row should be dropped */ - protected int getDragToGridRowPosition(CellEdgeEnum moveDirection, - int gridRowPosition) { + protected int getDragToGridRowPosition(CellEdgeEnum moveDirection, int gridRowPosition) { int dragToGridRowPosition = -1; if (moveDirection != null) { @@ -132,8 +134,7 @@ public class RowReorderDragMode implements IDragMode { ILayerCell cell = getRowCell(y); if (cell != null) { Rectangle selectedRowHeaderRect = cell.getBounds(); - return CellEdgeDetectUtil.getVerticalCellEdge( - selectedRowHeaderRect, new Point(this.initialEvent.x, y)); + return CellEdgeDetectUtil.getVerticalCellEdge(selectedRowHeaderRect, new Point(this.initialEvent.x, y)); } return null; @@ -161,8 +162,7 @@ public class RowReorderDragMode implements IDragMode { * @return <code>true</code> if the drop position is valid, * <code>false</code> if not */ - protected boolean isValidTargetRowPosition(ILayer natLayer, - int dragFromGridRowPosition, int dragToGridRowPosition) { + protected boolean isValidTargetRowPosition(ILayer natLayer, int dragFromGridRowPosition, int dragToGridRowPosition) { return dragFromGridRowPosition >= 0 && dragToGridRowPosition >= 0; } @@ -174,10 +174,8 @@ public class RowReorderDragMode implements IDragMode { * @param dragFromGridRowPosition * The row position of the row that is dragged */ - protected void fireMoveStartCommand(NatTable natTable, - int dragFromGridRowPosition) { - natTable.doCommand(new RowReorderStartCommand(natTable, - dragFromGridRowPosition)); + protected void fireMoveStartCommand(NatTable natTable, int dragFromGridRowPosition) { + natTable.doCommand(new RowReorderStartCommand(natTable, dragFromGridRowPosition)); } /** @@ -189,10 +187,8 @@ public class RowReorderDragMode implements IDragMode { * The position of the row to which the dragged row should be * dropped */ - protected void fireMoveEndCommand(NatTable natTable, - int dragToGridRowPosition) { - natTable.doCommand(new RowReorderEndCommand(natTable, - dragToGridRowPosition)); + protected void fireMoveEndCommand(NatTable natTable, int dragToGridRowPosition) { + natTable.doCommand(new RowReorderEndCommand(natTable, dragToGridRowPosition)); } /** @@ -209,24 +205,26 @@ public class RowReorderDragMode implements IDragMode { } CellEdgeEnum moveDirection = getMoveDirection(RowReorderDragMode.this.currentEvent.y); - int dragToGridRowPosition = getDragToGridRowPosition(moveDirection, + int dragToGridRowPosition = getDragToGridRowPosition( + moveDirection, RowReorderDragMode.this.natTable.getRowPositionByY(RowReorderDragMode.this.currentEvent.y)); - if (isValidTargetRowPosition(RowReorderDragMode.this.natTable, dragFromGridRowPosition, + if (isValidTargetRowPosition( + RowReorderDragMode.this.natTable, + dragFromGridRowPosition, dragToGridRowPosition)) { int dragToRowHandleY = -1; if (moveDirection != null) { - Rectangle selectedRowHeaderRect = getRowCell(RowReorderDragMode.this.currentEvent.y) - .getBounds(); + Rectangle selectedRowHeaderRect = + getRowCell(RowReorderDragMode.this.currentEvent.y).getBounds(); switch (moveDirection) { case TOP: dragToRowHandleY = selectedRowHeaderRect.y; break; case BOTTOM: - dragToRowHandleY = selectedRowHeaderRect.y - + selectedRowHeaderRect.height; + dragToRowHandleY = selectedRowHeaderRect.y + selectedRowHeaderRect.height; break; } } @@ -234,15 +232,10 @@ public class RowReorderDragMode implements IDragMode { if (dragToRowHandleY > 0) { Color orgBgColor = gc.getBackground(); gc.setBackground(GUIHelper.COLOR_DARK_GRAY); - - gc.fillRectangle(0, dragToRowHandleY - 1, layer.getWidth(), - 2); - + gc.fillRectangle(0, dragToRowHandleY - 1, layer.getWidth(), 2); gc.setBackground(orgBgColor); } } } - } - } diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/selection/action/CellSelectionDragMode.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/selection/action/CellSelectionDragMode.java index c34d1c57..6beaec20 100644 --- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/selection/action/CellSelectionDragMode.java +++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/selection/action/CellSelectionDragMode.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012, 2013, 2015 Original authors and others. + * Copyright (c) 2012, 2017 Original authors and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -14,20 +14,22 @@ package org.eclipse.nebula.widgets.nattable.selection.action; import org.eclipse.nebula.widgets.nattable.NatTable; import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer.MoveDirectionEnum; import org.eclipse.nebula.widgets.nattable.selection.command.SelectCellCommand; -import org.eclipse.nebula.widgets.nattable.ui.action.IDragMode; -import org.eclipse.nebula.widgets.nattable.viewport.command.ViewportDragCommand; +import org.eclipse.nebula.widgets.nattable.viewport.action.AutoScrollDragMode; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; /** * Fires commands to select a range of cells when the mouse is dragged in the * viewport. */ -public class CellSelectionDragMode implements IDragMode { +public class CellSelectionDragMode extends AutoScrollDragMode { private Point lastDragInCellPosition = null; + public CellSelectionDragMode() { + super(true, true); + } + @Override public void mouseDown(NatTable natTable, MouseEvent event) { natTable.forceFocus(); @@ -37,64 +39,69 @@ public class CellSelectionDragMode implements IDragMode { } @Override - public void mouseMove(NatTable natTable, MouseEvent event) { - - Rectangle clientArea = natTable.getClientAreaProvider().getClientArea(); - - int x = event.x; - int y = event.y; - - MoveDirectionEnum horizontal = MoveDirectionEnum.NONE; - if (event.x < 0) { - horizontal = MoveDirectionEnum.LEFT; - x = 0; - } - else if (event.x > clientArea.width) { - horizontal = MoveDirectionEnum.RIGHT; - x = clientArea.width; - } - - MoveDirectionEnum vertical = MoveDirectionEnum.NONE; - if (event.y < 0) { - vertical = MoveDirectionEnum.UP; - y = 0; - } - else if (event.y > clientArea.height) { - vertical = MoveDirectionEnum.DOWN; - y = clientArea.height; - } + protected void performDragAction( + NatTable natTable, + int x, int y, + MoveDirectionEnum horizontal, MoveDirectionEnum vertical) { if (!MoveDirectionEnum.NONE.equals(horizontal) || !MoveDirectionEnum.NONE.equals(vertical)) { this.lastDragInCellPosition = null; } - if (natTable.doCommand(new ViewportDragCommand(horizontal, vertical))) { - - int selectedColumnPosition = natTable.getColumnPositionByX(x); - int selectedRowPosition = natTable.getRowPositionByY(y); + int selectedColumnPosition = natTable.getColumnPositionByX(x); + int selectedRowPosition = natTable.getRowPositionByY(y); - if (selectedColumnPosition > -1 && selectedRowPosition > -1) { - Point dragInCellPosition = new Point(selectedColumnPosition, selectedRowPosition); - if (this.lastDragInCellPosition == null - || !dragInCellPosition.equals(this.lastDragInCellPosition)) { - this.lastDragInCellPosition = dragInCellPosition; + if (selectedColumnPosition > -1 && selectedRowPosition > -1) { + Point dragInCellPosition = new Point(selectedColumnPosition, selectedRowPosition); + if (this.lastDragInCellPosition == null + || !dragInCellPosition.equals(this.lastDragInCellPosition)) { + this.lastDragInCellPosition = dragInCellPosition; - fireSelectionCommand(natTable, selectedColumnPosition, selectedRowPosition, true, false); - } + fireSelectionCommand(natTable, selectedColumnPosition, selectedRowPosition, true, false); } } } - public void fireSelectionCommand(NatTable natTable, int columnPosition, int rowPosition, + /** + * Execute a command to trigger selection. + * + * @param natTable + * The NatTable to execute the command on. + * @param columnPosition + * The column position of the cell to select. + * @param rowPosition + * The row position of the cell to select. + * @param shiftMask + * Flag to configure whether the SHIFT mask is activated or not. + * @param controlMask + * Flag to configure whether the CTRL mask is activated or not. + */ + public void fireSelectionCommand( + NatTable natTable, + int columnPosition, int rowPosition, boolean shiftMask, boolean controlMask) { - natTable.doCommand( + boolean result = natTable.doCommand( new SelectCellCommand(natTable, columnPosition, rowPosition, shiftMask, controlMask)); + + // If the command execution fails for cell coordinates pointing to + // position 0 try again with increased positions. Needed in case of grid + // compositions where position 0 in NatTable are typically the headers. + if (!result && columnPosition == 0) { + natTable.doCommand( + new SelectCellCommand(natTable, columnPosition + 1, rowPosition, shiftMask, controlMask)); + } else if (!result && rowPosition == 0) { + natTable.doCommand( + new SelectCellCommand(natTable, columnPosition, rowPosition + 1, shiftMask, controlMask)); + } } @Override public void mouseUp(NatTable natTable, MouseEvent event) { + // Cancel any active viewport drag + super.mouseUp(natTable, event); + this.lastDragInCellPosition = null; } diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/viewport/action/AutoScrollDragMode.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/viewport/action/AutoScrollDragMode.java new file mode 100644 index 00000000..038b0663 --- /dev/null +++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/viewport/action/AutoScrollDragMode.java @@ -0,0 +1,214 @@ +/******************************************************************************* + * Copyright (c) 2017 Dirk Fauth. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Dirk Fauth <dirk.fauth@googlemail.com> - initial API and implementation + ******************************************************************************/ +package org.eclipse.nebula.widgets.nattable.viewport.action; + +import org.eclipse.nebula.widgets.nattable.NatTable; +import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer.MoveDirectionEnum; +import org.eclipse.nebula.widgets.nattable.ui.action.IDragMode; +import org.eclipse.nebula.widgets.nattable.viewport.command.ViewportDragCommand; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Display; + +/** + * Abstract {@link IDragMode} implementation to support auto-scrolling on + * dragging. + * + * @since 1.5 + */ +public abstract class AutoScrollDragMode implements IDragMode { + + private final boolean horizontal; + private final boolean vertical; + + private AutoScrollRunnable runnable; + + /** + * + * @param horizontal + * <code>true</code> to support horizontal auto-scrolling. + * @param vertical + * <code>true</code> to support vertical auto-scrolling. + */ + public AutoScrollDragMode(boolean horizontal, boolean vertical) { + this.horizontal = horizontal; + this.vertical = vertical; + } + + @Override + public void mouseMove(NatTable natTable, MouseEvent event) { + Rectangle clientArea = natTable.getClientAreaProvider().getClientArea(); + + int x = event.x; + int y = event.y; + + int horizontalDiff = 0; + MoveDirectionEnum horizontal = MoveDirectionEnum.NONE; + if (this.horizontal) { + if (event.x < 0) { + horizontal = MoveDirectionEnum.LEFT; + x = 0; + horizontalDiff = -event.x; + } else if (event.x > clientArea.width) { + horizontal = MoveDirectionEnum.RIGHT; + x = clientArea.width - 1; + horizontalDiff = event.x - clientArea.width; + } + } + + int verticalDiff = 0; + MoveDirectionEnum vertical = MoveDirectionEnum.NONE; + if (this.vertical) { + if (event.y < 0) { + vertical = MoveDirectionEnum.UP; + y = 0; + verticalDiff = -event.y; + } else if (event.y > clientArea.height) { + vertical = MoveDirectionEnum.DOWN; + y = clientArea.height - 1; + verticalDiff = event.y - clientArea.height; + } + } + + if ((!MoveDirectionEnum.NONE.equals(horizontal) + || !MoveDirectionEnum.NONE.equals(vertical)) && this.runnable == null) { + this.runnable = new AutoScrollRunnable(natTable, x, y, horizontal, vertical); + this.runnable.schedule(); + } else if (MoveDirectionEnum.NONE.equals(horizontal) + && MoveDirectionEnum.NONE.equals(vertical) + && this.runnable != null) { + this.runnable.cancel(); + this.runnable = null; + } else if (this.runnable != null) { + this.runnable.calculateRepeatDelay(horizontalDiff, verticalDiff); + } + + performDragAction(natTable, x, y, horizontal, vertical); + } + + @Override + public void mouseUp(NatTable natTable, MouseEvent event) { + if (this.runnable != null) { + this.runnable.cancel(); + this.runnable = null; + } + } + + /** + * + * @param natTable + * The NatTable instance the drag operation is currently + * performed on. + * @param x + * The x coordinate of the mouse pointer on mouse move. Corrected + * to be inside the NatTable client area. + * @param y + * The y coordinate of the mouse pointer on mouse move. Corrected + * to be inside the NatTable client area. + * @param horizontal + * The horizontal direction where the auto-scroll should be + * performed to. + * @param vertical + * The vertical direction where the auto-scroll should be + * performed to. + */ + protected void performDragAction( + NatTable natTable, + int x, int y, + MoveDirectionEnum horizontal, MoveDirectionEnum vertical) { + // do nothing by default + } + + /** + * Runnable that continuously scrolls the viewport. + */ + protected class AutoScrollRunnable implements Runnable { + + private final NatTable natTable; + private final Display display; + + private final MoveDirectionEnum horizontal; + private final MoveDirectionEnum vertical; + + private final int x, y; + + private int repeatDelay = 500; + + private boolean active = true; + + public AutoScrollRunnable(NatTable natTable, + int x, int y, + MoveDirectionEnum horizontal, MoveDirectionEnum vertical) { + this.natTable = natTable; + this.display = natTable.getDisplay(); + this.horizontal = horizontal; + this.vertical = vertical; + this.x = x; + this.y = y; + } + + /** + * Schedule this runnable to start with a delay of 500 ms. + */ + public void schedule() { + if (this.display != null) { + this.display.timerExec(500, this); + } + } + + /** + * Calculates the delay of the repeated auto-scroll execution based on + * the difference between the NatTable borders and the mouse cursor and + * the move direction that is currently active. + * + * @param horizontalDiff + * The horizontal difference between the NatTable border and + * the mouse cursor. + * @param verticalDiff + * The vertical difference between the NatTable border and + * the mouse cursor. + */ + public void calculateRepeatDelay(int horizontalDiff, int verticalDiff) { + if (!MoveDirectionEnum.NONE.equals(this.horizontal)) { + int factor = horizontalDiff / 5; + factor = Math.min(factor, 10); + this.repeatDelay = 500 - (factor * 49); + } + + if (!MoveDirectionEnum.NONE.equals(this.vertical)) { + int factor = verticalDiff / 5; + factor = Math.min(factor, 10); + this.repeatDelay = 500 - (factor * 49); + } + } + + /** + * Cancels the repeated execution. + */ + public void cancel() { + this.active = false; + } + + @Override + public void run() { + if (this.active) { + if (!MoveDirectionEnum.NONE.equals(this.horizontal) + || !MoveDirectionEnum.NONE.equals(this.vertical)) { + if (this.natTable.doCommand(new ViewportDragCommand(this.horizontal, this.vertical))) { + performDragAction(this.natTable, this.x, this.y, this.horizontal, this.vertical); + } + } + + this.display.timerExec(this.repeatDelay, this); + } + } + } +} |