| /******************************************************************************* |
| * 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.painter.cell.decorator; |
| |
| import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry; |
| import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell; |
| import org.eclipse.nebula.widgets.nattable.painter.cell.CellPainterWrapper; |
| import org.eclipse.nebula.widgets.nattable.painter.cell.ICellPainter; |
| import org.eclipse.nebula.widgets.nattable.style.CellStyleAttributes; |
| import org.eclipse.nebula.widgets.nattable.style.CellStyleUtil; |
| import org.eclipse.nebula.widgets.nattable.style.HorizontalAlignmentEnum; |
| import org.eclipse.nebula.widgets.nattable.style.IStyle; |
| import org.eclipse.nebula.widgets.nattable.style.VerticalAlignmentEnum; |
| import org.eclipse.nebula.widgets.nattable.util.GUIHelper; |
| import org.eclipse.swt.graphics.Color; |
| import org.eclipse.swt.graphics.GC; |
| import org.eclipse.swt.graphics.Rectangle; |
| |
| /** |
| * CellPainterWrapper that adds a padding between the cell border and the |
| * interior painter. |
| */ |
| public class PaddingDecorator extends CellPainterWrapper { |
| |
| private final int topPadding; |
| private final int rightPadding; |
| private final int bottomPadding; |
| private final int leftPadding; |
| |
| private final boolean paintBg; |
| |
| /** |
| * Create a PaddingDecorator around the given interior painter, adding a |
| * padding of 2 pixels on every side.<br> |
| * If will paint the background color to fill the resulting gaps, in case |
| * the PaddingDecorator wraps e.g. a TextPainter but is itself not wrapped |
| * by a BackgroundPainter. |
| * |
| * @param interiorPainter |
| * The painter that should be wrapped. |
| */ |
| public PaddingDecorator(ICellPainter interiorPainter) { |
| this(interiorPainter, 2); |
| } |
| |
| /** |
| * Create a PaddingDecorator around the given interior painter, adding a |
| * padding of 2 pixels on every side.<br> |
| * This constructor allows to configure whether the PaddingDecorator should |
| * itself paint the background to avoid gaps or not. In case the |
| * PaddingDecorator is wrapped in another background painter, e.g. |
| * BackgroundImagePainter or GradientBackroundPainter, the paintBg parameter |
| * needs to be <code>false</code> to avoid rendering issues. |
| * |
| * @param interiorPainter |
| * The painter that should be wrapped. |
| * @param paintBg |
| * <code>true</code> if the PaddingDecorator should paint the |
| * background, <code>false</code> if not. |
| */ |
| public PaddingDecorator(ICellPainter interiorPainter, boolean paintBg) { |
| this(interiorPainter, 2, paintBg); |
| } |
| |
| /** |
| * Create a PaddingDecorator around the given interior painter, adding a |
| * padding of the given number of pixels on every side.<br> |
| * If will paint the background color to fill the resulting gaps, in case |
| * the PaddingDecorator wraps e.g. a TextPainter but is itself not wrapped |
| * by a BackgroundPainter. |
| * |
| * @param interiorPainter |
| * The painter that should be wrapped. |
| * @param padding |
| * The number of pixels that should be used as padding on every |
| * side. |
| */ |
| public PaddingDecorator(ICellPainter interiorPainter, int padding) { |
| this(interiorPainter, padding, padding, padding, padding); |
| } |
| |
| /** |
| * Create a PaddingDecorator around the given interior painter, adding a |
| * padding of the given number of pixels on every side.<br> |
| * This constructor allows to configure whether the PaddingDecorator should |
| * itself paint the background to avoid gaps or not. In case the |
| * PaddingDecorator is wrapped in another background painter, e.g. |
| * BackgroundImagePainter or GradientBackroundPainter, the paintBg parameter |
| * needs to be <code>false</code> to avoid rendering issues. |
| * |
| * @param interiorPainter |
| * The painter that should be wrapped. |
| * @param padding |
| * The number of pixels that should be used as padding on every |
| * side. |
| * @param paintBg |
| * <code>true</code> if the PaddingDecorator should paint the |
| * background, <code>false</code> if not. |
| */ |
| public PaddingDecorator(ICellPainter interiorPainter, int padding, boolean paintBg) { |
| this(interiorPainter, padding, padding, padding, padding, paintBg); |
| } |
| |
| /** |
| * Create a PaddingDecorator around the given interior painter, adding the |
| * padding specified for each side.<br> |
| * If will paint the background color to fill the resulting gaps, in case |
| * the PaddingDecorator wraps e.g. a TextPainter but is itself not wrapped |
| * by a BackgroundPainter. |
| * |
| * @param interiorPainter |
| * The painter that should be wrapped. |
| * @param topPadding |
| * The number of pixels that should be used as padding on top. |
| * @param rightPadding |
| * The number of pixels that should be used as padding to the |
| * right. |
| * @param bottomPadding |
| * The number of pixels that should be used as padding at the |
| * bottom. |
| * @param leftPadding |
| * The number of pixels that should be used as padding to the |
| * left. |
| */ |
| public PaddingDecorator(ICellPainter interiorPainter, |
| int topPadding, int rightPadding, int bottomPadding, int leftPadding) { |
| this(interiorPainter, topPadding, rightPadding, bottomPadding, leftPadding, true); |
| } |
| |
| /** |
| * Create a PaddingDecorator around the given interior painter, adding the |
| * padding specified for each side.<br> |
| * This constructor allows to configure whether the PaddingDecorator should |
| * itself paint the background to avoid gaps or not. In case the |
| * PaddingDecorator is wrapped in another background painter, e.g. |
| * BackgroundImagePainter or GradientBackroundPainter, the paintBg parameter |
| * needs to be <code>false</code> to avoid rendering issues. |
| * |
| * @param interiorPainter |
| * The painter that should be wrapped. |
| * @param topPadding |
| * The number of pixels that should be used as padding on top. |
| * @param rightPadding |
| * The number of pixels that should be used as padding to the |
| * right. |
| * @param bottomPadding |
| * The number of pixels that should be used as padding at the |
| * bottom. |
| * @param leftPadding |
| * The number of pixels that should be used as padding to the |
| * left. |
| * @param paintBg |
| * <code>true</code> if the PaddingDecorator should paint the |
| * background, <code>false</code> if not. |
| */ |
| public PaddingDecorator(ICellPainter interiorPainter, |
| int topPadding, int rightPadding, int bottomPadding, int leftPadding, boolean paintBg) { |
| super(interiorPainter); |
| this.topPadding = topPadding; |
| this.rightPadding = rightPadding; |
| this.bottomPadding = bottomPadding; |
| this.leftPadding = leftPadding; |
| this.paintBg = paintBg; |
| } |
| |
| @Override |
| public int getPreferredWidth(ILayerCell cell, GC gc, IConfigRegistry configRegistry) { |
| return GUIHelper.convertHorizontalPixelToDpi(this.leftPadding, configRegistry) |
| + super.getPreferredWidth(cell, gc, configRegistry) |
| + GUIHelper.convertHorizontalPixelToDpi(this.rightPadding, configRegistry); |
| } |
| |
| @Override |
| public int getPreferredHeight(ILayerCell cell, GC gc, IConfigRegistry configRegistry) { |
| return GUIHelper.convertVerticalPixelToDpi(this.topPadding, configRegistry) |
| + super.getPreferredHeight(cell, gc, configRegistry) |
| + GUIHelper.convertVerticalPixelToDpi(this.bottomPadding, configRegistry); |
| } |
| |
| @Override |
| public void paintCell(ILayerCell cell, GC gc, Rectangle adjustedCellBounds, IConfigRegistry configRegistry) { |
| Rectangle interiorBounds = getInteriorBounds(adjustedCellBounds, configRegistry); |
| |
| if (this.paintBg) { |
| Color originalBg = gc.getBackground(); |
| Color cellStyleBackground = getBackgroundColor(cell, configRegistry); |
| gc.setBackground(cellStyleBackground != null ? cellStyleBackground : originalBg); |
| gc.fillRectangle(adjustedCellBounds); |
| gc.setBackground(originalBg); |
| } |
| |
| if (interiorBounds.width > 0 && interiorBounds.height > 0) { |
| super.paintCell(cell, gc, interiorBounds, configRegistry); |
| } |
| } |
| |
| /** |
| * Calculates the cell bounds that should be used for the internal painter |
| * out of the available bounds for this PaddingDecorator and the configured |
| * padding. |
| * |
| * @param adjustedCellBounds |
| * The cell bounds of the cell to render. |
| * @param configRegistry |
| * The {@link IConfigRegistry} needed for accessing the dpi |
| * converter. |
| * @return The cell bounds that are available for the interior painter. |
| * @since 2.0 |
| */ |
| public Rectangle getInteriorBounds(Rectangle adjustedCellBounds, IConfigRegistry configRegistry) { |
| return new Rectangle( |
| adjustedCellBounds.x + GUIHelper.convertHorizontalPixelToDpi(this.leftPadding, configRegistry), |
| adjustedCellBounds.y + GUIHelper.convertVerticalPixelToDpi(this.topPadding, configRegistry), |
| adjustedCellBounds.width |
| - GUIHelper.convertHorizontalPixelToDpi(this.leftPadding, configRegistry) |
| - GUIHelper.convertHorizontalPixelToDpi(this.rightPadding, configRegistry), |
| adjustedCellBounds.height |
| - GUIHelper.convertVerticalPixelToDpi(this.topPadding, configRegistry) |
| - GUIHelper.convertVerticalPixelToDpi(this.bottomPadding, configRegistry)); |
| } |
| |
| /** |
| * Extract the background color that is registered for the given ILayerCell. |
| * |
| * @param cell |
| * The cell for which the background color is requested. |
| * @param configRegistry |
| * The IConfigRegistry which contains the style configurations. |
| * @return The background color that should be used to render the background |
| * of the given cell. |
| */ |
| protected Color getBackgroundColor(ILayerCell cell, IConfigRegistry configRegistry) { |
| return CellStyleUtil.getCellStyle(cell, configRegistry) |
| .getAttributeValue(CellStyleAttributes.BACKGROUND_COLOR); |
| } |
| |
| @Override |
| public ICellPainter getCellPainterAt( |
| int x, int y, |
| ILayerCell cell, GC gc, |
| Rectangle adjustedCellBounds, IConfigRegistry configRegistry) { |
| |
| // need to take the alignment into account |
| IStyle cellStyle = CellStyleUtil.getCellStyle(cell, configRegistry); |
| |
| HorizontalAlignmentEnum horizontalAlignment = |
| cellStyle.getAttributeValue(CellStyleAttributes.HORIZONTAL_ALIGNMENT); |
| int horizontalAlignmentPadding = 0; |
| if (horizontalAlignment == HorizontalAlignmentEnum.LEFT) { |
| horizontalAlignmentPadding = GUIHelper.convertHorizontalPixelToDpi(this.leftPadding, configRegistry); |
| } else if (horizontalAlignment == HorizontalAlignmentEnum.CENTER) { |
| horizontalAlignmentPadding = GUIHelper.convertHorizontalPixelToDpi(this.leftPadding, configRegistry) / 2; |
| } |
| |
| VerticalAlignmentEnum verticalAlignment = |
| cellStyle.getAttributeValue(CellStyleAttributes.VERTICAL_ALIGNMENT); |
| int verticalAlignmentPadding = 0; |
| if (verticalAlignment == VerticalAlignmentEnum.TOP) { |
| verticalAlignmentPadding = GUIHelper.convertVerticalPixelToDpi(this.topPadding, configRegistry); |
| } else if (verticalAlignment == VerticalAlignmentEnum.MIDDLE) { |
| verticalAlignmentPadding = GUIHelper.convertVerticalPixelToDpi(this.topPadding, configRegistry) / 2; |
| } |
| |
| return super.getCellPainterAt( |
| x - horizontalAlignmentPadding, |
| y - verticalAlignmentPadding, |
| cell, |
| gc, |
| adjustedCellBounds, |
| configRegistry); |
| } |
| |
| /** |
| * |
| * @return The top padding added by this {@link PaddingDecorator}. |
| * |
| * @since 1.4 |
| */ |
| public int getTopPadding() { |
| return this.topPadding; |
| } |
| |
| /** |
| * |
| * @return The right padding added by this {@link PaddingDecorator}. |
| * |
| * @since 1.4 |
| */ |
| public int getRightPadding() { |
| return this.rightPadding; |
| } |
| |
| /** |
| * |
| * @return The bottom padding added by this {@link PaddingDecorator}. |
| * |
| * @since 1.4 |
| */ |
| public int getBottomPadding() { |
| return this.bottomPadding; |
| } |
| |
| /** |
| * |
| * @return The left padding added by this {@link PaddingDecorator}. |
| * |
| * @since 1.4 |
| */ |
| public int getLeftPadding() { |
| return this.leftPadding; |
| } |
| } |