blob: 8efdc468aeb1606a5956cb7ddf57635e3b80c471 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2012, 2021 Original NatTable 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 NatTable authors and others - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.ecommons.waltable.resize;
import static org.eclipse.statet.ecommons.waltable.coordinate.Orientation.HORIZONTAL;
import static org.eclipse.statet.ecommons.waltable.painter.cell.GraphicsUtils.check;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.statet.ecommons.waltable.NatTable;
import org.eclipse.statet.ecommons.waltable.NatTableDim;
import org.eclipse.statet.ecommons.waltable.coordinate.LPoint;
import org.eclipse.statet.ecommons.waltable.coordinate.LRange;
import org.eclipse.statet.ecommons.waltable.coordinate.LRangeList;
import org.eclipse.statet.ecommons.waltable.coordinate.Orientation;
import org.eclipse.statet.ecommons.waltable.layer.ILayer;
import org.eclipse.statet.ecommons.waltable.layer.ILayerDim;
import org.eclipse.statet.ecommons.waltable.painter.IOverlayPainter;
import org.eclipse.statet.ecommons.waltable.swt.SWTUtil;
import org.eclipse.statet.ecommons.waltable.ui.action.IDragMode;
import org.eclipse.statet.ecommons.waltable.ui.util.CellEdgeDetectUtil;
import org.eclipse.statet.ecommons.waltable.util.GUIHelper;
/**
* Drag mode that will implement the column/row resizing process.
*/
public class PositionResizeDragMode implements IDragMode {
private static final int DEFAULT_WIDTH_MINIMUM= 25;
private static final int RESIZE_OVERLAY_SIZE= 2;
private static void addPositions(final long pixel, final ILayerDim dim, final LRangeList positions) {
final long startPixel= Math.max(pixel - RESIZE_OVERLAY_SIZE / 2, 0);
final long endPixel= Math.min(pixel + RESIZE_OVERLAY_SIZE / 2, dim.getSize() - 1);
if (startPixel < endPixel) {
positions.add(new LRange(dim.getPositionByPixel(startPixel), dim.getPositionByPixel(endPixel) + 1));
}
}
private class ColumnResizeOverlayPainter implements IOverlayPainter {
@Override
public void paintOverlay(final GC gc, final ILayer layer) {
final Color originalBackgroundColor= gc.getBackground();
gc.setBackground(GUIHelper.COLOR_DARK_GRAY);
gc.fillRectangle(PositionResizeDragMode.this.currentPixel - (RESIZE_OVERLAY_SIZE / 2), 0, RESIZE_OVERLAY_SIZE, check(layer.getHeight()));
gc.setBackground(originalBackgroundColor);
}
}
private class RowResizeOverlayPainter implements IOverlayPainter {
@Override
public void paintOverlay(final GC gc, final ILayer layer) {
final Color originalBackgroundColor= gc.getBackground();
gc.setBackground(GUIHelper.COLOR_DARK_GRAY);
gc.fillRectangle(0, PositionResizeDragMode.this.currentPixel - (RESIZE_OVERLAY_SIZE / 2), check(layer.getWidth()), RESIZE_OVERLAY_SIZE);
gc.setBackground(originalBackgroundColor);
}
}
private final Orientation orientation;
private long positionToResize;
private int positionStart;
private int positionSize;
private int startPixel;
private int currentPixel;
private int lastPixel= -1;
private final IOverlayPainter overlayPainter;
public PositionResizeDragMode(final Orientation orientation) {
this.orientation= orientation;
this.overlayPainter= (orientation == HORIZONTAL) ?
new ColumnResizeOverlayPainter() :
new RowResizeOverlayPainter();
}
// XXX: This method must ask the layer what it's minimum width is!
private int getMinPositionSize() {
return DEFAULT_WIDTH_MINIMUM;
}
@Override
public void mouseDown(final NatTable natTable, final MouseEvent event) {
natTable.forceFocus();
this.positionToResize= CellEdgeDetectUtil.getPositionToResize(natTable,
new LPoint(event.x, event.y), this.orientation );
if (this.positionToResize >= 0) {
final ILayerDim dim= natTable.getDim(this.orientation);
this.positionStart= check(dim.getPositionStart(this.positionToResize));
this.positionSize= dim.getPositionSize(this.positionToResize);
this.startPixel= SWTUtil.get(event, this.orientation);
natTable.addOverlayPainter(this.overlayPainter);
}
}
@Override
public void mouseMove(final NatTable natTable, final MouseEvent event) {
final NatTableDim dim= natTable.getDim(this.orientation);
final int pixel= SWTUtil.get(event, this.orientation);
if (pixel > dim.getSize()) {
return;
}
if (pixel < this.positionStart + getMinPositionSize()) {
this.currentPixel= this.positionStart + getMinPositionSize();
}
else {
this.currentPixel= pixel;
final LRangeList positionsToRepaint= new LRangeList();
addPositions(this.currentPixel, dim, positionsToRepaint);
if (this.lastPixel >= 0) {
addPositions(this.lastPixel, dim, positionsToRepaint);
}
for (final LRange positions : positionsToRepaint) {
dim.repaintPositions(positions);
}
this.lastPixel= this.currentPixel;
}
}
@Override
public void mouseUp(final NatTable natTable, final MouseEvent event) {
final NatTableDim dim= natTable.getDim(this.orientation);
natTable.removeOverlayPainter(this.overlayPainter);
updatePositionSize(dim, SWTUtil.get(event, this.orientation));
}
private void updatePositionSize(final ILayerDim dim, final int pixel) {
final int dragSize= pixel - this.startPixel;
int newSize= this.positionSize + dragSize;
if (newSize < getMinPositionSize()) {
newSize= getMinPositionSize();
}
dim.getLayer().doCommand(new DimPositionResizeCommand(dim, this.positionToResize, newSize));
}
}