| /******************************************************************************* |
| * Copyright (c) 2012, 2020 Original authors and others. |
| * |
| * This program and the accompanying materials are made |
| * available under the terms of the Eclipse Public License 2.0 |
| * which is available at https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Original authors and others - initial API and implementation |
| * Dirk Fauth <dirk.fauth@googlemail.com - Bug 449764 |
| * Dirk Fauth <dirk.fauth@googlemail.com> - Bug 460077 |
| ******************************************************************************/ |
| package org.eclipse.nebula.widgets.nattable.resize.mode; |
| |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| import org.eclipse.nebula.widgets.nattable.NatTable; |
| import org.eclipse.nebula.widgets.nattable.layer.ILayer; |
| import org.eclipse.nebula.widgets.nattable.painter.IOverlayPainter; |
| import org.eclipse.nebula.widgets.nattable.resize.command.ColumnResizeCommand; |
| import org.eclipse.nebula.widgets.nattable.ui.action.IDragMode; |
| import org.eclipse.nebula.widgets.nattable.ui.util.CellEdgeDetectUtil; |
| import org.eclipse.nebula.widgets.nattable.util.GUIHelper; |
| import org.eclipse.swt.events.MouseEvent; |
| import org.eclipse.swt.graphics.Color; |
| import org.eclipse.swt.graphics.GC; |
| import org.eclipse.swt.graphics.Point; |
| |
| /** |
| * Drag mode that will implement the column resizing process. |
| */ |
| public class ColumnResizeDragMode implements IDragMode { |
| |
| private static final int DEFAULT_COLUMN_WIDTH_MINIMUM = 25; |
| |
| protected int columnPositionToResize; |
| protected int originalColumnWidth; |
| protected int startX; |
| protected int currentX; |
| protected int lastX = -1; |
| protected int gridColumnStartX; |
| |
| protected boolean checkMinimumWidth = true; |
| |
| protected final IOverlayPainter overlayPainter = new ColumnResizeOverlayPainter(); |
| |
| @Override |
| public void mouseDown(NatTable natTable, MouseEvent event) { |
| natTable.forceFocus(); |
| this.columnPositionToResize = CellEdgeDetectUtil.getColumnPositionToResize(natTable, new Point(event.x, event.y)); |
| if (this.columnPositionToResize >= 0) { |
| this.gridColumnStartX = natTable.getStartXOfColumnPosition(this.columnPositionToResize); |
| this.originalColumnWidth = natTable.getColumnWidthByPosition(this.columnPositionToResize); |
| this.startX = event.x; |
| natTable.addOverlayPainter(this.overlayPainter); |
| } |
| } |
| |
| @Override |
| public void mouseMove(NatTable natTable, MouseEvent event) { |
| this.currentX = event.x; |
| // redraw the space to the right of the last column |
| // to be able to render the resize drag indicator |
| natTable.repaintHorizontalLeftOver(); |
| |
| if (this.checkMinimumWidth |
| && this.currentX < this.gridColumnStartX + getColumnWidthMinimum()) { |
| this.currentX = this.gridColumnStartX + getColumnWidthMinimum(); |
| } else { |
| int overlayExtent = ColumnResizeOverlayPainter.COLUMN_RESIZE_OVERLAY_WIDTH / 2; |
| |
| Set<Integer> columnsToRepaint = new HashSet<>(); |
| |
| columnsToRepaint.add(natTable.getColumnPositionByX(this.currentX - overlayExtent)); |
| columnsToRepaint.add(natTable.getColumnPositionByX(this.currentX + overlayExtent)); |
| |
| if (this.lastX >= 0) { |
| columnsToRepaint.add(natTable.getColumnPositionByX(this.lastX - overlayExtent)); |
| columnsToRepaint.add(natTable.getColumnPositionByX(this.lastX + overlayExtent)); |
| } |
| |
| for (Integer columnToRepaint : columnsToRepaint) { |
| if (columnToRepaint >= 0) { |
| natTable.repaintColumn(columnToRepaint.intValue()); |
| } |
| } |
| |
| this.lastX = this.currentX; |
| } |
| } |
| |
| @Override |
| public void mouseUp(NatTable natTable, MouseEvent event) { |
| natTable.removeOverlayPainter(this.overlayPainter); |
| updateColumnWidth(natTable, event); |
| } |
| |
| private void updateColumnWidth(ILayer natLayer, MouseEvent e) { |
| int dragWidth = e.x - this.startX; |
| int newColumnWidth = this.originalColumnWidth + dragWidth; |
| if (newColumnWidth < getColumnWidthMinimum()) { |
| newColumnWidth = getColumnWidthMinimum(); |
| } |
| // trigger the ColumnResizeCommand with downScaling enabled |
| // as the user performed a drag operation the newColumnWidth is the |
| // value on the screen, which needs to be down scaled in the DataLayer |
| natLayer.doCommand( |
| new ColumnResizeCommand( |
| natLayer, |
| this.columnPositionToResize, |
| newColumnWidth, |
| true)); |
| } |
| |
| // XXX: This method must ask the layer what it's minimum width is! |
| /** |
| * @since 1.3 |
| */ |
| protected int getColumnWidthMinimum() { |
| return DEFAULT_COLUMN_WIDTH_MINIMUM; |
| } |
| |
| private class ColumnResizeOverlayPainter implements IOverlayPainter { |
| |
| static final int COLUMN_RESIZE_OVERLAY_WIDTH = 2; |
| |
| @Override |
| public void paintOverlay(GC gc, ILayer layer) { |
| Color originalBackgroundColor = gc.getBackground(); |
| gc.setBackground(GUIHelper.COLOR_DARK_GRAY); |
| gc.fillRectangle( |
| ColumnResizeDragMode.this.currentX - (COLUMN_RESIZE_OVERLAY_WIDTH / 2), |
| 0, |
| COLUMN_RESIZE_OVERLAY_WIDTH, |
| layer.getHeight()); |
| gc.setBackground(originalBackgroundColor); |
| } |
| } |
| } |