| /******************************************************************************* |
| * 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 |
| ******************************************************************************/ |
| package org.eclipse.nebula.widgets.nattable.layer; |
| |
| import java.util.Collection; |
| import java.util.LinkedHashSet; |
| import java.util.Properties; |
| |
| import org.eclipse.nebula.widgets.nattable.NatTable; |
| import org.eclipse.nebula.widgets.nattable.command.ILayerCommand; |
| import org.eclipse.nebula.widgets.nattable.command.ILayerCommandHandler; |
| import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry; |
| import org.eclipse.nebula.widgets.nattable.coordinate.Range; |
| import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell; |
| import org.eclipse.nebula.widgets.nattable.layer.event.ILayerEvent; |
| import org.eclipse.nebula.widgets.nattable.layer.event.IVisualChangeEvent; |
| import org.eclipse.nebula.widgets.nattable.painter.cell.ICellPainter; |
| import org.eclipse.nebula.widgets.nattable.painter.layer.ILayerPainter; |
| import org.eclipse.nebula.widgets.nattable.persistence.IPersistable; |
| import org.eclipse.nebula.widgets.nattable.style.DisplayMode; |
| import org.eclipse.nebula.widgets.nattable.ui.binding.UiBindingRegistry; |
| import org.eclipse.nebula.widgets.nattable.util.IClientAreaProvider; |
| import org.eclipse.swt.graphics.Rectangle; |
| |
| /** |
| * <p> |
| * A Layer is a rectangular region of grid cells. A layer has methods to access |
| * its columns, rows, width and height. A layer can be stacked on top of another |
| * layer in order to expose a transformed view of its underlying layer's grid |
| * cell structure. |
| * </p> |
| * <p> |
| * Columns and rows in a layer are referenced either by <b>position</b> or |
| * <b>index</b>. The position of a column/row in a layer corresponds to the |
| * physical location of the column/row in the layer. The index of a column/row |
| * in a layer corresponds to the location of the column/row in the lowest level |
| * layer in the layer stack. These concepts are illustrated by the following |
| * example: |
| * </p> |
| * |
| * <pre> |
| * Hide Layer C |
| * 0 1 2 3 4 <- column positions |
| * 1 0 3 4 5 <- column indexes |
| * |
| * Reorder Layer B |
| * 0 1 2 3 4 5 <- column positions |
| * 2 1 0 3 4 5 <- column indexes |
| * |
| * Data Layer A |
| * 0 1 2 3 4 5 <- column positions |
| * 0 1 2 3 4 5 <- column indexes |
| * </pre> |
| * <p> |
| * In the above example, Hide Layer C is stacked on top of Reorder Layer B, |
| * which is in turn stacked on top of Data Layer A. The positions in Data Layer |
| * A are the same as its indexes, because it is the lowest level layer in the |
| * stack. Reorder Layer B reorders column 0 of its underlying layer (Data Layer |
| * A) after column 2 of its underlying layer. Hide Layer C hides the first |
| * column of its underlying layer (Reorder Layer B). |
| * </p> |
| * <p> |
| * Layers can also be laterally composed into larger layers. For instance, the |
| * standard grid layer is composed of a body layer, column header layer, row |
| * header layer, and corner layer: |
| * </p> |
| * <table border=1> |
| * <caption></caption> |
| * <tr> |
| * <td>corner</td> |
| * <td>column header</td> |
| * </tr> |
| * <tr> |
| * <td>row header</td> |
| * <td>body</td> |
| * </tr> |
| * </table> |
| * |
| * @see CompositeLayer |
| */ |
| public interface ILayer extends ILayerListener, IPersistable { |
| |
| // Dispose |
| |
| /** |
| * Dispose any resource allocated by this layer. |
| */ |
| public void dispose(); |
| |
| // Persistence |
| |
| /** |
| * Register an {@link IPersistable} that can write its state to the state |
| * {@link Properties} instance when the layer is persisted. |
| * |
| * @param persistable |
| * The persistable that should be registered. |
| */ |
| public void registerPersistable(IPersistable persistable); |
| |
| /** |
| * Unregister the given {@link IPersistable}. |
| * |
| * @param persistable |
| * The persistable to unregister. |
| */ |
| public void unregisterPersistable(IPersistable persistable); |
| |
| // Configuration |
| |
| /** |
| * Configure this layer, e.g. add any key/mouse bindings and other general |
| * configuration. |
| * <p> |
| * This method is triggered by {@link NatTable#configure()} and executed |
| * down the layer stack. |
| * </p> |
| * |
| * @param configRegistry |
| * The {@link IConfigRegistry} instance owned by the |
| * {@link NatTable} this layer is attached to. |
| * @param uiBindingRegistry |
| * The {@link UiBindingRegistry} instance owned by |
| * {@link NatTable} this layer is attached to. |
| * |
| * @since 2.0 |
| */ |
| public void configure(IConfigRegistry configRegistry, UiBindingRegistry uiBindingRegistry); |
| |
| // Region |
| |
| /** |
| * Return the {@link LabelStack} containing the region labels for the cell |
| * at the given pixel position. |
| * |
| * @param x |
| * the x pixel coordinate |
| * @param y |
| * the y pixel coordinate |
| * @return LabelStack containing the region labels for the cell at the given |
| * pixel position. |
| */ |
| public LabelStack getRegionLabelsByXY(int x, int y); |
| |
| // Commands |
| |
| /** |
| * Opportunity to respond to a command as it flows down the stack. If the |
| * layer is not interested in the command it should allow the command to |
| * keep traveling down the stack. |
| * <p> |
| * <b>Note:</b> Before the layer can process a command it <i>must</i> |
| * convert the command to its local coordinates using |
| * {@link ILayerCommand#convertToTargetLayer(ILayer)} |
| * |
| * @param command |
| * The command to execute. |
| * @return <code>true</code> if the command has been handled and was |
| * therefore consumed, <code>false</code> otherwise. |
| */ |
| public boolean doCommand(ILayerCommand command); |
| |
| /** |
| * Register an {@link ILayerCommandHandler} to handle a command in this |
| * layer. Only one {@link ILayerCommandHandler} per {@link ILayerCommand} |
| * can be registered per layer. |
| * |
| * @param commandHandler |
| * The command handler to register with this layer. |
| */ |
| public void registerCommandHandler(ILayerCommandHandler<?> commandHandler); |
| |
| /** |
| * Unregister the {@link ILayerCommandHandler} that is registered for the |
| * given {@link ILayerCommand} class. |
| * |
| * @param commandClass |
| * The {@link ILayerCommand} class for which the |
| * {@link ILayerCommandHandler} should be unregistered. |
| */ |
| public void unregisterCommandHandler(Class<? extends ILayerCommand> commandClass); |
| |
| // Events |
| |
| /** |
| * Events can be fired to notify other components of the grid. Events travel |
| * <i>up</i> the layer stack and may cause a repaint. |
| * <p> |
| * Example: When the contents of the grid change {@link IVisualChangeEvent} |
| * can be fired to notify other layers to refresh their caches etc. |
| * |
| * @param event |
| * the event to fire |
| */ |
| public void fireLayerEvent(ILayerEvent event); |
| |
| /** |
| * Add a general {@link ILayerListener} to handle {@link ILayerEvent}s on |
| * this layer. |
| * |
| * @param listener |
| * The {@link ILayerListener} to add. |
| */ |
| public void addLayerListener(ILayerListener listener); |
| |
| /** |
| * Remove the given {@link ILayerListener} from this layer. |
| * |
| * @param listener |
| * The {@link ILayerListener} to remove. |
| */ |
| public void removeLayerListener(ILayerListener listener); |
| |
| /** |
| * Check if an {@link ILayerListener} of the given type is registered on |
| * this layer or not. |
| * |
| * @param layerListenerClass |
| * The type of {@link ILayerListener} to check for. |
| * @return <code>true</code> if this {@link ILayer} has a |
| * {@link ILayerListener} of the specified type registered, |
| * <code>false</code> if there is no such listener registered. |
| */ |
| public boolean hasLayerListener(Class<? extends ILayerListener> layerListenerClass); |
| |
| /** |
| * |
| * @return The {@link ILayerPainter} used to render this layer. |
| */ |
| public ILayerPainter getLayerPainter(); |
| |
| // Client area |
| |
| /** |
| * |
| * @return The {@link IClientAreaProvider} that specifies the rectangular |
| * area available on this layer. |
| */ |
| public IClientAreaProvider getClientAreaProvider(); |
| |
| /** |
| * |
| * @param clientAreaProvider |
| * The {@link IClientAreaProvider} that specifies the rectangular |
| * area available on this layer. |
| */ |
| public void setClientAreaProvider(IClientAreaProvider clientAreaProvider); |
| |
| // Horizontal features |
| |
| // Columns |
| |
| /** |
| * @return The number of columns in this layer. |
| */ |
| public int getColumnCount(); |
| |
| public int getPreferredColumnCount(); |
| |
| /** |
| * Gets the underlying non-transformed column index for the given column |
| * position on this layer. |
| * |
| * @param columnPosition |
| * The column position relative to this layer. |
| * @return An underlying non-transformed column index, or -1 if the given |
| * column position does not exist within this coordinate system. |
| */ |
| public int getColumnIndexByPosition(int columnPosition); |
| |
| /** |
| * Convert a column position to the coordinates of the underlying layer. |
| * This is possible since each layer is aware of its underlying layer. |
| * |
| * @param localColumnPosition |
| * column position in local (the layer's own) coordinates |
| * @return column position in the underlying layer's coordinates |
| */ |
| public int localToUnderlyingColumnPosition(int localColumnPosition); |
| |
| /** |
| * Transforms the column position relative to the given underlying layer to |
| * this layer coordinates. |
| * |
| * @param sourceUnderlyingLayer |
| * The underlying layer to which the given column position |
| * matches. |
| * @param underlyingColumnPosition |
| * The column position in the given underlying layer that should |
| * be converted to a local column position. |
| * @return The given column position transformed to be local to this layer. |
| */ |
| public int underlyingToLocalColumnPosition( |
| ILayer sourceUnderlyingLayer, |
| int underlyingColumnPosition); |
| |
| /** |
| * Transforms the column position ranges relative to the given underlying |
| * layer to this layer coordinates. |
| * |
| * @param sourceUnderlyingLayer |
| * The underlying layer to which the given column positions |
| * match. |
| * @param underlyingColumnPositionRanges |
| * The column position ranges relative to the given underlying |
| * layer that should be converted to local column positions. |
| * @return The given column position ranges transformed to this layer. |
| */ |
| public Collection<Range> underlyingToLocalColumnPositions( |
| ILayer sourceUnderlyingLayer, |
| Collection<Range> underlyingColumnPositionRanges); |
| |
| // Width |
| |
| /** |
| * Returns the total width in pixels of this layer. |
| * |
| * @return The total width in pixels of this layer. |
| */ |
| public int getWidth(); |
| |
| public int getPreferredWidth(); |
| |
| /** |
| * Returns the width in pixels of the given column. |
| * |
| * The width of invisible and non-existing columns is 0. |
| * |
| * @param columnPosition |
| * The column position in this layer. |
| * |
| * @return The width of the column. |
| */ |
| public int getColumnWidthByPosition(int columnPosition); |
| |
| // Column resize |
| |
| /** |
| * Check if the column at the given position is resizable. |
| * |
| * @param columnPosition |
| * The column position to check. |
| * @return <code>true</code> if the column is resizable, <code>false</code> |
| * if not. |
| */ |
| public boolean isColumnPositionResizable(int columnPosition); |
| |
| // X |
| |
| /** |
| * Returns the column position that contains the given x coordinate. |
| * |
| * @param x |
| * A horizontal pixel location relative to the pixel boundary of |
| * this layer. |
| * @return A column position relative to the associated coordinate system, |
| * or -1 if there is no column that contains x. |
| */ |
| public int getColumnPositionByX(int x); |
| |
| /** |
| * Returns the x offset in pixels of the given column. |
| * |
| * @param columnPosition |
| * The column position in this layer. |
| * @return The x offset of the column, or -1. |
| */ |
| public int getStartXOfColumnPosition(int columnPosition); |
| |
| // Underlying |
| |
| /** |
| * Returns the layers that are directly below this layer for the given |
| * column position. For simple layers this collection will typically only |
| * have one entry. Layer compositions might return multiple values, e.g. in |
| * a default grid there will be 2 layers in the collection as there are two |
| * layers involved in a column. |
| * |
| * @param columnPosition |
| * The column position for which the underlying layers are |
| * requested. |
| * @return The layers that are directly below this layer for the given |
| * column position or <code>null</code> if this layer has no |
| * underlying layers. |
| */ |
| public Collection<ILayer> getUnderlyingLayersByColumnPosition(int columnPosition); |
| |
| // Vertical features |
| |
| // Rows |
| |
| /** |
| * @return The number of rows in this layer. |
| */ |
| public int getRowCount(); |
| |
| public int getPreferredRowCount(); |
| |
| /** |
| * Gets the underlying non-transformed row index for the given row position |
| * on this layer. |
| * |
| * @param rowPosition |
| * The row position relative to this layer. |
| * @return An underlying non-transformed row index, or -1 if the given row |
| * position does not exist within this coordinate system. |
| */ |
| public int getRowIndexByPosition(int rowPosition); |
| |
| /** |
| * Convert a row position to the coordinates of the underlying layer. This |
| * is possible since each layer is aware of its underlying layer. |
| * |
| * @param localRowPosition |
| * row position in local (the layer's own) coordinates |
| * @return row position in the underlying layer's coordinates |
| */ |
| public int localToUnderlyingRowPosition(int localRowPosition); |
| |
| /** |
| * Transforms the row position relative to the given underlying layer to |
| * this layer coordinates. |
| * |
| * @param sourceUnderlyingLayer |
| * The underlying layer to which the given row position matches. |
| * @param underlyingRowPosition |
| * The row position in the given underlying layer that should be |
| * converted to a local row position. |
| * @return The given row position transformed to be local to this layer. |
| */ |
| public int underlyingToLocalRowPosition( |
| ILayer sourceUnderlyingLayer, |
| int underlyingRowPosition); |
| |
| /** |
| * Transforms the row position ranges relative to the given underlying layer |
| * to this layer coordinates. |
| * |
| * @param sourceUnderlyingLayer |
| * The underlying layer to which the given row positions match. |
| * @param underlyingRowPositionRanges |
| * The row position ranges relative to the given underlying layer |
| * that should be converted to local row positions. |
| * @return The given row position ranges transformed to this layer. |
| */ |
| public Collection<Range> underlyingToLocalRowPositions( |
| ILayer sourceUnderlyingLayer, |
| Collection<Range> underlyingRowPositionRanges); |
| |
| // Height |
| |
| /** |
| * Returns the total height in pixels of this layer. |
| * |
| * @return The total height in pixels of this layer. |
| */ |
| public int getHeight(); |
| |
| public int getPreferredHeight(); |
| |
| /** |
| * Returns the height in pixels of the given row. |
| * |
| * The height of invisible and non-existing rows is 0. |
| * |
| * @param rowPosition |
| * The row position in this layer. |
| * |
| * @return The height of the row. |
| */ |
| public int getRowHeightByPosition(int rowPosition); |
| |
| // Row resize |
| |
| /** |
| * Check if the row at the given position is resizable. |
| * |
| * @param rowPosition |
| * The row position to check. |
| * @return <code>true</code> if the row is resizable, <code>false</code> if |
| * not. |
| */ |
| public boolean isRowPositionResizable(int rowPosition); |
| |
| // Y |
| |
| /** |
| * Returns the row position that contains the given y coordinate. |
| * |
| * @param y |
| * a vertical pixel location relative to the pixel boundary of |
| * this layer |
| * @return a row position relative to the associated coordinate system, or |
| * -1 if there is no row that contains y |
| */ |
| public int getRowPositionByY(int y); |
| |
| /** |
| * Returns the y offset in pixels of the given row. |
| * |
| * @param rowPosition |
| * the row position in this layer |
| * |
| * @return the y offset of the row, or -1 |
| */ |
| public int getStartYOfRowPosition(int rowPosition); |
| |
| // Underlying |
| |
| /** |
| * Returns the layers that are directly below this layer for the given row |
| * position. For simple layers this collection will typically only have one |
| * entry. Layer compositions might return multiple values, e.g. in a default |
| * grid there will be 2 layers in the collection as there are two layers |
| * involved in a row. |
| * |
| * @param rowPosition |
| * The row position for which the underlying layers are |
| * requested. |
| * @return The layers that are directly below this layer for the given row |
| * position or <code>null</code> if this layer has no underlying |
| * layers. |
| */ |
| public Collection<ILayer> getUnderlyingLayersByRowPosition(int rowPosition); |
| |
| // Cell features |
| |
| /** |
| * Returns the cell for the given coordinates on this layer. |
| * |
| * @param columnPosition |
| * The column position of the requested cell. |
| * @param rowPosition |
| * The row position of the requested cell. |
| * @return The {@link ILayerCell} for the given coordinates in this layer or |
| * <code>null</code> if the coordinates are invalid on this layer. |
| */ |
| public ILayerCell getCellByPosition(int columnPosition, int rowPosition); |
| |
| /** |
| * Calculates the bounds in pixel for the given cell position. |
| * |
| * @param columnPosition |
| * the column position of the cell |
| * @param rowPosition |
| * the row position of the cell |
| * |
| * @return the bounds, or <code>null</code> if there are no valid bounds |
| */ |
| public Rectangle getBoundsByPosition(int columnPosition, int rowPosition); |
| |
| /** |
| * Returns the active {@link DisplayMode} for the cell at the given |
| * coordinates. Needed to retrieve the corresponding configurations out of |
| * the {@link IConfigRegistry}. The default value is |
| * {@link DisplayMode#NORMAL}. The SelectionLayer for example overrides this |
| * to return {@link DisplayMode#SELECT} for cells that are currently |
| * selected. |
| * |
| * @param columnPosition |
| * The column position of the cell. |
| * @param rowPosition |
| * The row position of the cell. |
| * @return {@link DisplayMode} for the cell at the given coordinates. |
| */ |
| public String getDisplayModeByPosition(int columnPosition, int rowPosition); |
| |
| /** |
| * Returns the config labels for the cell at the given coordinates. Needed |
| * to retrieve the corresponding configurations out of the |
| * {@link IConfigRegistry}. |
| * |
| * @param columnPosition |
| * The column position of the cell. |
| * @param rowPosition |
| * The row position of the cell. |
| * @return The {@link LabelStack} with the config labels for the cell at the |
| * given coordinates. |
| */ |
| public LabelStack getConfigLabelsByPosition(int columnPosition, int rowPosition); |
| |
| /** |
| * Returns the data value for the cell at the given coordinates. |
| * |
| * @param columnPosition |
| * The column position of the cell. |
| * @param rowPosition |
| * The row position of the cell. |
| * @return The data value for the cell at the given coordinates. |
| */ |
| public Object getDataValueByPosition(int columnPosition, int rowPosition); |
| |
| /** |
| * Returns the layer that is directly below this layer for the given cell |
| * coordinate. |
| * |
| * @param columnPosition |
| * The column position for which the underlying layer is |
| * requested. |
| * @param rowPosition |
| * The row position for which the underlying layer is requested. |
| * @return The layer that is directly below this layer for the given cell |
| * coordinates or <code>null</code> if this layer has no underlying |
| * layers. |
| */ |
| public ILayer getUnderlyingLayerByPosition(int columnPosition, int rowPosition); |
| |
| /** |
| * Return the {@link ICellPainter} for the given {@link ILayerCell} at the |
| * given coordinates out of the given {@link IConfigRegistry}. |
| * |
| * @param columnPosition |
| * The column position of the cell. |
| * @param rowPosition |
| * The row position of the cell. |
| * @param cell |
| * The {@link ILayerCell} for which the {@link ICellPainter} is |
| * requested. |
| * @param configRegistry |
| * The {@link IConfigRegistry} to retrieve the painter from. |
| * @return The {@link ICellPainter} for the given cell at the given |
| * coordinates or <code>null</code> if no painter is configured. |
| */ |
| public ICellPainter getCellPainter( |
| int columnPosition, |
| int rowPosition, |
| ILayerCell cell, |
| IConfigRegistry configRegistry); |
| |
| /** |
| * @return <code>true</code> if the layer has a dynamic size (e.g. viewport) |
| * or a fixed size. |
| * @since 2.0 |
| */ |
| public default boolean isDynamicSizeLayer() { |
| return false; |
| } |
| |
| /** |
| * @return The collection of labels that are provided by this layer used |
| * e.g. for CSS styling. |
| * @since 2.0 |
| */ |
| public default Collection<String> getProvidedLabels() { |
| return new LinkedHashSet<String>(); |
| } |
| |
| } |