| /******************************************************************************* |
| * Copyright (c) 2012, 2020 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.painter.cell.decorator; |
| |
| import org.eclipse.nebula.widgets.nattable.config.CellConfigAttributes; |
| 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.BorderStyle; |
| import org.eclipse.nebula.widgets.nattable.style.BorderStyle.LineStyleEnum; |
| import org.eclipse.nebula.widgets.nattable.style.CellStyleAttributes; |
| import org.eclipse.nebula.widgets.nattable.style.CellStyleUtil; |
| import org.eclipse.nebula.widgets.nattable.style.DisplayMode; |
| import org.eclipse.nebula.widgets.nattable.style.IStyle; |
| import org.eclipse.swt.graphics.Color; |
| import org.eclipse.swt.graphics.GC; |
| import org.eclipse.swt.graphics.Rectangle; |
| |
| public class LineBorderDecorator extends CellPainterWrapper { |
| |
| private final BorderStyle defaultBorderStyle; |
| |
| public LineBorderDecorator(ICellPainter interiorPainter) { |
| this(interiorPainter, null); |
| } |
| |
| public LineBorderDecorator(ICellPainter interiorPainter, BorderStyle defaultBorderStyle) { |
| super(interiorPainter); |
| this.defaultBorderStyle = defaultBorderStyle; |
| } |
| |
| @Override |
| public int getPreferredWidth(ILayerCell cell, GC gc, IConfigRegistry configRegistry) { |
| BorderStyle borderStyle = getBorderStyle(cell, configRegistry); |
| int borderThickness = borderStyle != null ? borderStyle.getThickness() : 0; |
| |
| return super.getPreferredWidth(cell, gc, configRegistry) + (borderThickness * 2); |
| } |
| |
| @Override |
| public int getPreferredHeight(ILayerCell cell, GC gc, IConfigRegistry configRegistry) { |
| BorderStyle borderStyle = getBorderStyle(cell, configRegistry); |
| int borderThickness = borderStyle != null ? borderStyle.getThickness() : 0; |
| |
| return super.getPreferredHeight(cell, gc, configRegistry) + (borderThickness * 2); |
| } |
| |
| private BorderStyle getBorderStyle(ILayerCell cell, IConfigRegistry configRegistry) { |
| IStyle cellStyle = CellStyleUtil.getCellStyle(cell, configRegistry); |
| BorderStyle borderStyle = cellStyle.getAttributeValue(CellStyleAttributes.BORDER_STYLE); |
| if (borderStyle == null) { |
| borderStyle = this.defaultBorderStyle; |
| } |
| return borderStyle; |
| } |
| |
| @Override |
| public void paintCell(ILayerCell cell, GC gc, Rectangle rectangle, IConfigRegistry configRegistry) { |
| BorderStyle borderStyle = getBorderStyle(cell, configRegistry); |
| int borderThickness = borderStyle != null ? borderStyle.getThickness() : 0; |
| |
| Rectangle interiorBounds = new Rectangle( |
| rectangle.x + borderThickness, |
| rectangle.y + borderThickness, |
| rectangle.width - (borderThickness * 2), |
| rectangle.height - (borderThickness * 2)); |
| super.paintCell(cell, gc, interiorBounds, configRegistry); |
| |
| if (borderStyle == null || borderThickness <= 0) { |
| return; |
| } |
| |
| // Save GC settings |
| Color originalForeground = gc.getForeground(); |
| int originalLineWidth = gc.getLineWidth(); |
| int originalLineStyle = gc.getLineStyle(); |
| |
| Integer gridLineWidth = configRegistry.getConfigAttribute( |
| CellConfigAttributes.GRID_LINE_WIDTH, |
| DisplayMode.NORMAL, |
| cell.getConfigLabels()); |
| int adjustment = (gridLineWidth == null || gridLineWidth == 1) |
| ? 0 |
| : Math.round(gridLineWidth.floatValue() / 2); |
| |
| gc.setLineWidth(borderThickness); |
| |
| Rectangle borderArea = new Rectangle( |
| rectangle.x, |
| rectangle.y, |
| rectangle.width, |
| rectangle.height); |
| if (borderThickness >= 1) { |
| int shift = 0; |
| int areaShift = 0; |
| if ((borderThickness % 2) == 0) { |
| shift = borderThickness / 2; |
| areaShift = (shift * 2); |
| } else { |
| shift = borderThickness / 2; |
| areaShift = (shift * 2) + 1; |
| } |
| borderArea.x += (shift + adjustment); |
| borderArea.y += (shift + adjustment); |
| borderArea.width -= (areaShift + adjustment); |
| borderArea.height -= (areaShift + adjustment); |
| } |
| |
| gc.setLineStyle(LineStyleEnum.toSWT(borderStyle.getLineStyle())); |
| gc.setForeground(borderStyle.getColor()); |
| gc.drawRectangle(borderArea); |
| |
| // Restore GC settings |
| gc.setForeground(originalForeground); |
| gc.setLineWidth(originalLineWidth); |
| gc.setLineStyle(originalLineStyle); |
| } |
| |
| } |