/*******************************************************************************
* Copyright (c) 2012, 2013, 2015 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Original authors and others - initial API and implementation
******************************************************************************/
package org.eclipse.nebula.widgets.nattable.ui.util;
import static org.eclipse.nebula.widgets.nattable.ui.util.CellEdgeEnum.BOTTOM;
import static org.eclipse.nebula.widgets.nattable.ui.util.CellEdgeEnum.LEFT;
import static org.eclipse.nebula.widgets.nattable.ui.util.CellEdgeEnum.NONE;
import static org.eclipse.nebula.widgets.nattable.ui.util.CellEdgeEnum.RIGHT;
import static org.eclipse.nebula.widgets.nattable.ui.util.CellEdgeEnum.TOP;
import static org.eclipse.nebula.widgets.nattable.util.GUIHelper.DEFAULT_RESIZE_HANDLE_SIZE;
import org.eclipse.nebula.widgets.nattable.layer.ILayer;
import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
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 int getColumnPositionToResize(ILayer layer, Point clickPoint) {
int columnPosition = layer.getColumnPositionByX(clickPoint.x);
if (columnPosition >= 0) {
switch (getHorizontalCellEdge(layer, clickPoint, DEFAULT_RESIZE_HANDLE_SIZE)) {
case LEFT:
if (columnPosition == 1) {
// can't resize left edge of first column
break;
}
return columnPosition - 1;
case RIGHT:
return columnPosition;
}
}
return -1;
}
/**
* Calculate the row position to resize depending on the cursor's position
* on the top/bottom edges of the cell. Does not take into account rows
* which are not allowed to be resized.
*/
public static int getRowPositionToResize(ILayer layer, Point clickPt) {
int rowPosition = layer.getRowPositionByY(clickPt.y);
if (rowPosition >= 0) {
switch (getVerticalCellEdge(layer, clickPt, DEFAULT_RESIZE_HANDLE_SIZE)) {
case TOP:
if (rowPosition == 1) {
// can't resize top edge of first row
break;
}
return rowPosition - 1;
case BOTTOM:
return rowPosition;
}
}
return -1;
}
/**
* Gets the edge (left/right) of the cell which is closer to the click
* point.
*
* @param cellBounds
* bounds of the cell containing the click
* @param clickPt
* usually the coordinates of a mouse click
*/
public static CellEdgeEnum getHorizontalCellEdge(Rectangle cellBounds, Point clickPt) {
return getHorizontalCellEdge(cellBounds, clickPt, -1);
}
public static CellEdgeEnum getHorizontalCellEdge(ILayer layer, Point clickPt) {
return getHorizontalCellEdge(layer, clickPt, -1);
}
public static CellEdgeEnum getHorizontalCellEdge(ILayer layer, Point clickPt, int handleWidth) {
ILayerCell cell = layer.getCellByPosition(
layer.getColumnPositionByX(clickPt.x),
layer.getRowPositionByY(clickPt.y));
if (cell != null) {
return getHorizontalCellEdge(cell.getBounds(), clickPt, handleWidth);
} else {
return CellEdgeEnum.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
*/
public static CellEdgeEnum getHorizontalCellEdge(Rectangle cellBounds, Point clickPt, int distanceFromEdge) {
if (distanceFromEdge < 0) {
distanceFromEdge = cellBounds.width / 2;
}
Rectangle left = new Rectangle(
cellBounds.x,
cellBounds.y,
distanceFromEdge,
cellBounds.height);
Rectangle right = new Rectangle(
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;
}
}
/**
* Gets the edge (top/bottom) of the cell which is closer to the click
* point.
*
* @param cellBounds
* bounds of the cell containing the click
* @param clickPt
* usually the coordinates of a mouse click
*/
public static CellEdgeEnum getVerticalCellEdge(Rectangle cellBounds, Point clickPt) {
return getVerticalCellEdge(cellBounds, clickPt, -1);
}
public static CellEdgeEnum getVerticalCellEdge(ILayer layer, Point clickPt) {
return getVerticalCellEdge(layer, clickPt, -1);
}
public static CellEdgeEnum getVerticalCellEdge(ILayer layer, Point clickPt, int handleHeight) {
ILayerCell cell = layer.getCellByPosition(
layer.getColumnPositionByX(clickPt.x),
layer.getRowPositionByY(clickPt.y));
if (cell != null) {
return getVerticalCellEdge(cell.getBounds(), clickPt, handleHeight);
} else {
return CellEdgeEnum.NONE;
}
}
/**
* @see CellEdgeDetectUtil#getHorizontalCellEdge(Rectangle, Point, int)
*/
private static CellEdgeEnum getVerticalCellEdge(Rectangle cellBounds, Point clickPt, int distanceFromEdge) {
if (distanceFromEdge < 0) {
distanceFromEdge = cellBounds.height / 2;
}
Rectangle top = new Rectangle(
cellBounds.x,
cellBounds.y,
cellBounds.width,
distanceFromEdge);
Rectangle bottom = new Rectangle(
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;
}
}
}