blob: e4b877bb7c7f8223ddde027ca2758cbf00897a43 [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.ui.util;
import static org.eclipse.statet.ecommons.waltable.coordinate.Orientation.HORIZONTAL;
import static org.eclipse.statet.ecommons.waltable.coordinate.Orientation.VERTICAL;
import static org.eclipse.statet.ecommons.waltable.ui.util.CellEdgeEnum.BOTTOM;
import static org.eclipse.statet.ecommons.waltable.ui.util.CellEdgeEnum.LEFT;
import static org.eclipse.statet.ecommons.waltable.ui.util.CellEdgeEnum.NONE;
import static org.eclipse.statet.ecommons.waltable.ui.util.CellEdgeEnum.RIGHT;
import static org.eclipse.statet.ecommons.waltable.ui.util.CellEdgeEnum.TOP;
import static org.eclipse.statet.ecommons.waltable.util.GUIHelper.DEFAULT_RESIZE_HANDLE_SIZE;
import org.eclipse.statet.ecommons.waltable.coordinate.LPoint;
import org.eclipse.statet.ecommons.waltable.coordinate.LRectangle;
import org.eclipse.statet.ecommons.waltable.coordinate.Orientation;
import org.eclipse.statet.ecommons.waltable.layer.ILayer;
import org.eclipse.statet.ecommons.waltable.layer.cell.ILayerCell;
public class CellEdgeDetectUtil {
/**
* Calculate the column position to resize depending on the cursor's position
* on the left/right edges of the cell.
* Does <i>not</i> take into account columns which are not allowed to be resized.
*/
public static long getPositionToResize(final ILayer layer, final LPoint clickPoint,
final Orientation orientation) {
final ILayerCell cell= layer.getCellByPosition(
layer.getDim(HORIZONTAL).getPositionByPixel(clickPoint.x),
layer.getDim(VERTICAL).getPositionByPixel(clickPoint.y) );
if (cell != null) {
final long position= cell.getDim(orientation).getPosition();
final CellEdgeEnum edge= (orientation == HORIZONTAL) ?
getHorizontalCellEdge(cell.getBounds(), clickPoint, DEFAULT_RESIZE_HANDLE_SIZE) :
getVerticalCellEdge(cell.getBounds(), clickPoint, DEFAULT_RESIZE_HANDLE_SIZE);
switch (edge) {
case LEFT:
case TOP:
if (position == 1) { // can't resize left edge of first column/row
break;
}
return position - 1;
case RIGHT:
case BOTTOM:
return position;
default:
break;
}
}
return Long.MIN_VALUE;
}
public static CellEdgeEnum getHorizontalCellEdge(final ILayer layer, final LPoint clickPt) {
return getHorizontalCellEdge(layer, clickPt, -1);
}
public static CellEdgeEnum getHorizontalCellEdge(final ILayer layer, final LPoint clickPt,
final long handleWidth) {
final ILayerCell cell= layer.getCellByPosition(
layer.getColumnPositionByX(clickPt.x),
layer.getRowPositionByY(clickPt.y) );
if (cell != null) {
return getHorizontalCellEdge(cell.getBounds(), clickPt, handleWidth);
} else {
return NONE;
}
}
/**
* Figure out if the click point is closer to the left/right edge of the cell.
* @param cellBounds of the table cell containing the click
* @param clickPt
* @param distanceFromEdge distance from the edge to qualify as <i>close</i> to the cell edge
*/
private static CellEdgeEnum getHorizontalCellEdge(final LRectangle cellBounds, final LPoint clickPt,
long distanceFromEdge) {
if (distanceFromEdge < 0) {
distanceFromEdge= cellBounds.width / 2;
}
final LRectangle left= new LRectangle(cellBounds.x, cellBounds.y, distanceFromEdge, cellBounds.height);
final LRectangle right= new LRectangle(cellBounds.x + cellBounds.width - distanceFromEdge, cellBounds.y,
distanceFromEdge, cellBounds.height);
if (left.contains(clickPt)) {
return LEFT;
} else if (right.contains(clickPt)) {
return RIGHT;
} else {
return NONE;
}
}
public static CellEdgeEnum getVerticalCellEdge(final ILayer layer, final LPoint clickPt) {
return getVerticalCellEdge(layer, clickPt, -1);
}
public static CellEdgeEnum getVerticalCellEdge(final ILayer layer, final LPoint clickPt,
final long handleHeight) {
final ILayerCell cell= layer.getCellByPosition(
layer.getColumnPositionByX(clickPt.x),
layer.getRowPositionByY(clickPt.y) );
if (cell != null) {
return getVerticalCellEdge(cell.getBounds(), clickPt, handleHeight);
}
else {
return NONE;
}
}
private static CellEdgeEnum getVerticalCellEdge(final LRectangle cellBounds, final LPoint clickPt,
long distanceFromEdge) {
if (distanceFromEdge < 0) {
distanceFromEdge= cellBounds.height / 2;
}
final LRectangle top= new LRectangle(cellBounds.x, cellBounds.y, cellBounds.width, distanceFromEdge);
final LRectangle bottom= new LRectangle(cellBounds.x, cellBounds.y + cellBounds.height - distanceFromEdge, cellBounds.width, distanceFromEdge);
if (top.contains(clickPt)) {
return TOP;
} else if (bottom.contains(clickPt)) {
return BOTTOM;
} else {
return NONE;
}
}
}