blob: 65b8db1ddb3ddd39ac70637bd27739d7e2078d95 [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 (DimensionallyDependentLayer)
* Stephan Wahlbrink - initial API and implementation
******************************************************************************/
package org.eclipse.nebula.widgets.nattable.grid.layer;
import org.eclipse.nebula.widgets.nattable.command.ILayerCommand;
import org.eclipse.nebula.widgets.nattable.layer.AbstractIndexLayerTransform;
import org.eclipse.nebula.widgets.nattable.layer.ILayer;
import org.eclipse.nebula.widgets.nattable.layer.IUniqueIndexLayer;
import org.eclipse.nebula.widgets.nattable.layer.LayerUtil;
/**
* <p>
* A DimensionallyDependentIndexLayer is a layer whose horizontal and vertical
* dimensions are dependent on the horizontal and vertical dimensions of other
* layers. A DimensionallyDependentIndexLayer takes three constructor
* parameters: the horizontal layer that the DimensionallyDependentIndexLayer's
* horizontal dimension is linked to, the vertical layer that the
* DimensionallyDependentIndexLayer is linked to, and a base layer to which all
* non-dimensionally related ILayer method calls will be delegated to (e.g.
* command, event methods)
* </p>
* <p>
* Prime examples of dimensionally dependent layers are the column header and
* row header layers. For example, the column header layer's horizontal
* dimension is linked to the body layer's horizontal dimension. This means that
* whatever columns are shown in the body area will also be shown in the column
* header area, and vice versa. Note that the column header layer maintains its
* own vertical dimension, however, so it's vertical layer dependency would be a
* separate data layer. The same is true for the row header layer, only with the
* vertical instead of the horizontal dimension. The constructors for the column
* header and row header layers would therefore look something like this:
* </p>
*
* <pre>
* ILayer columnHeaderLayer = new DimensionallyDependentIndexLayer(
* columnHeaderRowDataLayer, bodyLayer, columnHeaderRowDataLayer);
* ILayer rowHeaderLayer = new DimensionallyDependentIndexLayer(
* rowHeaderColumnDataLayer, bodyLayer, rowHeaderColumnDataLayer);
* </pre>
* <p>
* In contrast to {@link DimensionallyDependentLayer}, this class:
* </p>
* <ul>
* <li>implements {@link IUniqueIndexLayer};</li>
* <li>provides conversion of local and underlying positions based on the unique
* index (reliable);</li>
* <li>provides an implementation of {@link #getCellByPosition(int, int)} which
* e.g. fully supports spanned cells;</li>
* <li>requires that the layers, the horizontal and vertical dimension are
* linked to, implements {@link IUniqueIndexLayer} too.</li>
* </ul>
*/
public class DimensionallyDependentIndexLayer extends
AbstractIndexLayerTransform {
private IUniqueIndexLayer horizontalLayerDependency;
private IUniqueIndexLayer verticalLayerDependency;
/**
* Creates a new DimensionallyDependentIndexLayer.
*
* @param baseLayer
* the underlying base layer
* @param horizontalLayerDependency
* the layer, the horizontal dimension is linked to
* @param verticalLayerDependency
* the layer, the vertical dimension is linked to
*/
public DimensionallyDependentIndexLayer(IUniqueIndexLayer baseLayer,
IUniqueIndexLayer horizontalLayerDependency,
IUniqueIndexLayer verticalLayerDependency) {
super(baseLayer);
setHorizontalLayerDependency(horizontalLayerDependency);
setVerticalLayerDependency(verticalLayerDependency);
}
/**
* Creates a new DimensionallyDependentIndexLayer.
*
* @param baseLayer
* the underlying base layer
*/
protected DimensionallyDependentIndexLayer(IUniqueIndexLayer baseLayer) {
super(baseLayer);
}
// Dependent layer accessors
protected void setHorizontalLayerDependency(
IUniqueIndexLayer horizontalLayerDependency) {
this.horizontalLayerDependency = horizontalLayerDependency;
// horizontalLayerDependency.addLayerListener(new ILayerListener() {
//
// public void handleLayerEvent(ILayerEvent event) {
// if (event instanceof IStructuralChangeEvent) {
// // TODO refresh horizontal structure
// }
// }
//
// });
}
protected void setVerticalLayerDependency(
IUniqueIndexLayer verticalLayerDependency) {
this.verticalLayerDependency = verticalLayerDependency;
// verticalLayerDependency.addLayerListener(new ILayerListener() {
//
// public void handleLayerEvent(ILayerEvent event) {
// if (event instanceof IStructuralChangeEvent) {
// // TODO refresh vertical structure
// }
// }
//
// });
}
public ILayer getHorizontalLayerDependency() {
return this.horizontalLayerDependency;
}
public ILayer getVerticalLayerDependency() {
return this.verticalLayerDependency;
}
public IUniqueIndexLayer getBaseLayer() {
return getUnderlyingLayer();
}
// Commands
@Override
public boolean doCommand(ILayerCommand command) {
// Invoke command handler(s) on the Dimensionally dependent layer
ILayerCommand clonedCommand = command.cloneCommand();
if (super.doCommand(command)) {
return true;
}
clonedCommand = command.cloneCommand();
if (this.horizontalLayerDependency.doCommand(clonedCommand)) {
return true;
}
clonedCommand = command.cloneCommand();
if (this.verticalLayerDependency.doCommand(clonedCommand)) {
return true;
}
return false;
}
// Horizontal features
// Columns
@Override
public int getColumnCount() {
return this.horizontalLayerDependency.getColumnCount();
}
@Override
public int getPreferredColumnCount() {
return this.horizontalLayerDependency.getPreferredColumnCount();
}
@Override
public int getColumnIndexByPosition(int columnPosition) {
return this.horizontalLayerDependency
.getColumnIndexByPosition(columnPosition);
}
@Override
public int getColumnPositionByIndex(int columnIndex) {
return this.horizontalLayerDependency.getColumnPositionByIndex(columnIndex);
}
@Override
public int localToUnderlyingColumnPosition(int localColumnPosition) {
return LayerUtil.convertColumnPosition(this, localColumnPosition,
getUnderlyingLayer());
}
@Override
public int underlyingToLocalColumnPosition(ILayer sourceUnderlyingLayer,
int underlyingColumnPosition) {
return LayerUtil.convertColumnPosition(sourceUnderlyingLayer,
underlyingColumnPosition, this);
}
// Width
@Override
public int getWidth() {
return this.horizontalLayerDependency.getWidth();
}
@Override
public int getPreferredWidth() {
return this.horizontalLayerDependency.getPreferredWidth();
}
@Override
public int getColumnWidthByPosition(int columnPosition) {
return this.horizontalLayerDependency
.getColumnWidthByPosition(columnPosition);
}
// Column resize
@Override
public boolean isColumnPositionResizable(int columnPosition) {
return this.horizontalLayerDependency
.isColumnPositionResizable(columnPosition);
}
// X
@Override
public int getColumnPositionByX(int x) {
return this.horizontalLayerDependency.getColumnPositionByX(x);
}
@Override
public int getStartXOfColumnPosition(int columnPosition) {
return this.horizontalLayerDependency
.getStartXOfColumnPosition(columnPosition);
}
// Vertical features
// Rows
@Override
public int getRowCount() {
return this.verticalLayerDependency.getRowCount();
}
@Override
public int getPreferredRowCount() {
return this.verticalLayerDependency.getPreferredRowCount();
}
@Override
public int getRowIndexByPosition(int rowPosition) {
return this.verticalLayerDependency.getRowIndexByPosition(rowPosition);
}
@Override
public int getRowPositionByIndex(int rowIndex) {
return this.verticalLayerDependency.getRowPositionByIndex(rowIndex);
}
@Override
public int localToUnderlyingRowPosition(int localRowPosition) {
return LayerUtil.convertRowPosition(this, localRowPosition,
getUnderlyingLayer());
}
@Override
public int underlyingToLocalRowPosition(ILayer sourceUnderlyingLayer,
int underlyingRowPosition) {
return LayerUtil.convertRowPosition(sourceUnderlyingLayer,
underlyingRowPosition, this);
}
// Height
@Override
public int getHeight() {
return this.verticalLayerDependency.getHeight();
}
@Override
public int getPreferredHeight() {
return this.verticalLayerDependency.getPreferredHeight();
}
@Override
public int getRowHeightByPosition(int rowPosition) {
return this.verticalLayerDependency.getRowHeightByPosition(rowPosition);
}
// Row resize
@Override
public boolean isRowPositionResizable(int rowPosition) {
return this.verticalLayerDependency.isRowPositionResizable(rowPosition);
}
// Y
@Override
public int getRowPositionByY(int y) {
return this.verticalLayerDependency.getRowPositionByY(y);
}
@Override
public int getStartYOfRowPosition(int rowPosition) {
return this.verticalLayerDependency.getStartYOfRowPosition(rowPosition);
}
}