blob: e870dffe3d0bbddd97372d746320252acdca8f98 [file] [log] [blame]
/*******************************************************************************
* 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 462459
******************************************************************************/
package org.eclipse.nebula.widgets.nattable.layer;
public class LayerUtil {
/**
* Modifier that is used by layers if they add additional columns or rows.
* By using this modifier layers can mark an added position to tell the
* conversion that it can handle the negative index to position conversion.
* For example, the HierarchicalTreeLayer adds structural columns to
* separate levels, these columns do not have an index as they are added. As
* some layers need the local column position, a conversion is performed
* first getting the column index and then get back the local position by
* index. Each added column is multiplied with this modifier and an
* identifier so the returned index is greater than -1, to tell the
* index-position transformation that calculation back to position is
* possible, and via the identifier the concrete position in the
* HierarchicalTreeLayer can be retrieved.
*
* @since 1.6
*/
public static final int ADDITIONAL_POSITION_MODIFIER = -13;
public static final int getColumnPositionByX(ILayer layer, int x) {
int width = layer.getWidth();
if (x < 0 || x >= width) {
return -1;
}
return findColumnPosition(0, 0, layer, x, width, layer.getColumnCount());
}
protected static final int findColumnPosition(
int xOffset, int columnOffset, ILayer layer, int x, int totalWidth, int columnCount) {
if (columnOffset == columnCount) {
return columnCount;
}
double size = (double) (totalWidth - xOffset) / (columnCount - columnOffset);
int columnPosition = columnOffset + (int) ((x - xOffset) / size);
int startX = layer.getStartXOfColumnPosition(columnPosition);
int endX = startX + layer.getColumnWidthByPosition(columnPosition);
if (x < startX) {
if (startX == totalWidth && startX != endX) {
return columnCount;
}
return findColumnPosition(xOffset, columnOffset, layer, x, startX, columnPosition);
} else if (x >= endX) {
return findColumnPosition(endX, columnPosition + 1, layer, x, totalWidth, columnCount);
} else {
return columnPosition;
}
}
public static final int getRowPositionByY(ILayer layer, int y) {
int height = layer.getHeight();
if (y < 0 || y >= height) {
return -1;
}
return findRowPosition(0, 0, layer, y, height, layer.getRowCount());
}
protected static final int findRowPosition(
int yOffset, int rowOffset, ILayer layer, int y, int totalHeight, int rowCount) {
if (rowOffset == rowCount) {
return rowCount;
}
double size = (double) (totalHeight - yOffset) / (rowCount - rowOffset);
int rowPosition = rowOffset + (int) ((y - yOffset) / size);
int startY = layer.getStartYOfRowPosition(rowPosition);
int endY = startY + layer.getRowHeightByPosition(rowPosition);
if (y < startY) {
if (startY == totalHeight && startY != endY) {
return rowCount;
}
return findRowPosition(yOffset, rowOffset, layer, y, startY, rowPosition);
} else if (y >= endY) {
return findRowPosition(endY, rowPosition + 1, layer, y, totalHeight, rowCount);
} else {
return rowPosition;
}
}
/**
* Convert column position from the source layer to the target layer
*
* @param sourceLayer
* source layer
* @param sourceColumnPosition
* column position in the source layer
* @param targetLayer
* layer to convert the from position to
* @return converted column position, or -1 if conversion not possible
*/
public static final int convertColumnPosition(
ILayer sourceLayer, int sourceColumnPosition, IUniqueIndexLayer targetLayer) {
if (targetLayer == sourceLayer) {
return sourceColumnPosition;
}
int columnIndex = sourceLayer.getColumnIndexByPosition(sourceColumnPosition);
if (columnIndex < 0) {
// if the negative index is multiplied with the additional position
// modifier we assume that the back conversion is possible
if (columnIndex % ADDITIONAL_POSITION_MODIFIER != 0) {
return -1;
}
}
return targetLayer.getColumnPositionByIndex(columnIndex);
}
/**
* Convert row position from the source layer to the target layer
*
* @param sourceLayer
* source layer
* @param sourceRowPosition
* position in the source layer
* @param targetLayer
* layer to convert the from position to
* @return converted row position, or -1 if conversion not possible
*/
public static final int convertRowPosition(
ILayer sourceLayer, int sourceRowPosition, IUniqueIndexLayer targetLayer) {
if (targetLayer == sourceLayer) {
return sourceRowPosition;
}
int rowIndex = sourceLayer.getRowIndexByPosition(sourceRowPosition);
if (rowIndex < 0) {
// if the negative index is multiplied with the additional position
// modifier we assume that the back conversion is possible
if (rowIndex % ADDITIONAL_POSITION_MODIFIER != 0) {
return -1;
}
}
return targetLayer.getRowPositionByIndex(rowIndex);
}
}