/******************************************************************************* * Copyright (c) 2000, 2005 IBM Corporation 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: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.draw2d; import org.eclipse.swt.graphics.Color; import org.eclipse.draw2d.geometry.Insets; import org.eclipse.draw2d.geometry.Rectangle; /** * SchemeBorder allows the creation of borders based on * {@link SchemeBorder.Scheme Schemes}. A <i>Scheme</i> is a class whose only purpose is * to carry border specific information. SchemeBorder renders the border based on the * information given by the <i>Scheme</i> set to it. */ public class SchemeBorder extends AbstractBorder implements ColorConstants { /** The {@link SchemeBorder.Scheme} associated with this SchemeBorder **/ protected Scheme scheme = null; /** Arrays of Colors, used for shadow or highlight effects **/ protected static final Color DARKEST_DARKER[] = new Color[] {buttonDarkest, buttonDarker}, LIGHTER_DARKER[] = new Color[] {buttonLightest, buttonDarker}, DARKER_LIGHTER[] = new Color[] {buttonDarker, buttonLightest}; /** * Holds a set of information about a border, which can be changed to create a wide range * of schemes. Provides support for border opacity, size, highlight side and shadow side * colors. */ public static class Scheme { private Insets insets; private boolean isOpaque = false; /** Arrays of Colors, used for highlight and shadow effecsts */ protected Color highlight[], shadow[]; /** * Constructs a default border Scheme with no border sides. * @since 2.0 */ protected Scheme() { } /** * Constructs a border Scheme with the specified highlight and shadow colors. The size * of the border depends on the number of colors passed in for each parameter. * Hightlight colors are used in the top and left sides of the border, and Shadow * colors are used in the bottom and right sides of the border. * * @param highlight the hightlight colors * @param shadow the shadow colors * @since 2.0 */ public Scheme(Color[] highlight, Color[] shadow) { this.highlight = highlight; this.shadow = shadow; init(); } /** * Constructs a border scheme with the specified colors. The input colors serve as * both highlight and shadow colors. The size of the border is the number of colors * passed in as input. Hightlight colors are used in the top and left sides of the * border, and Shadow colors are used in the bottom and right sides of the border. * * @param colors the colors to be used for the border * @since 2.0 */ public Scheme(Color[] colors) { highlight = shadow = colors; init(); } /** * Calculates and returns the Insets for this border Scheme. The calculations depend * on the number of colors passed in as input. * * @return the Insets used by this border * @since 2.0 */ protected Insets calculateInsets() { int tl = getHighlight().length; int br = getShadow().length; return new Insets(tl, tl, br, br); } /** * Calculates and retuns the opaque state of this border scheme. Returns * <code>false</code> if any of the border colors are <code>null</code>. This is done * to prevent the appearance of underlying pixels since the border color is * <code>null</code>. * * @return <code>true</code> if this border is opaque * @since 2.0 */ protected boolean calculateOpaque() { Color colors [] = getHighlight(); for (int i = 0; i < colors.length; i++) if (colors[i] == null) return false; colors = getShadow(); for (int i = 0; i < colors.length; i++) if (colors[i] == null) return false; return true; } /** * Returns the highlight colors of this border scheme as an array of Colors. * * @return the highlight colors * @since 2.0 */ protected Color[] getHighlight() { return highlight; } /** * Returns the Insets required by this Scheme. * * @return the Insets * @since 2.0 */ protected Insets getInsets() { return insets; } /** * Returns the shadow colors of this border scheme as an array of Colors. * * @return the shadow colors * @since 2.0 */ protected Color[] getShadow() { return shadow; } /** * Calculates and initializes the properties of this border scheme. * * @since 2.0 */ protected void init() { insets = calculateInsets(); isOpaque = calculateOpaque(); } /** * Returns whether this border should be opaque or not. * * @return <code>true</code> if this border is opaque * @since 2.0 */ protected boolean isOpaque() { return isOpaque; } } /** * Interface which defines some commonly used schemes for the border. These schemes can be * given as input to the {@link SchemeBorder SchemeBorder} to generate appropriate borders. */ public static interface SCHEMES { /** Schemes used for shadow and highlight effects **/ Scheme BUTTON_CONTRAST = new Scheme( new Color[]{button, buttonLightest}, DARKEST_DARKER ), BUTTON_RAISED = new Scheme( new Color[]{buttonLightest}, DARKEST_DARKER ), BUTTON_PRESSED = new Scheme( DARKEST_DARKER, new Color[]{buttonLightest} ), RAISED = new Scheme( new Color[]{buttonLightest}, new Color[]{buttonDarkest} ), LOWERED = new Scheme( new Color[]{buttonDarkest}, new Color[]{buttonLightest} ), RIDGED = new Scheme(LIGHTER_DARKER, DARKER_LIGHTER), ETCHED = new Scheme(DARKER_LIGHTER, LIGHTER_DARKER); } /** * Constructs a default SchemeBorder with no scheme defined. * @since 2.0 */ protected SchemeBorder() { } /** * Constructs a SchemeBorder with the Scheme given as input. * * @param scheme the Scheme to be used by this border * @since 2.0 */ public SchemeBorder(Scheme scheme) { setScheme(scheme); } /** * @see Border#getInsets(IFigure) */ public Insets getInsets(IFigure figure) { return getScheme().getInsets(); } /** * Returns the scheme used by this border. * * @return the Scheme used by this border * @since 2.0 */ protected Scheme getScheme() { return scheme; } /** * Returns the opaque state of this border. Returns <code>true</code> indicating that this * will fill in the area enclosed by the border. * * @see Border#isOpaque() */ public boolean isOpaque() { return true; } /** * Sets the Scheme for this border to the Scheme given as input. * * @param scheme the Scheme for this border * @since 2.0 */ protected void setScheme(Scheme scheme) { this.scheme = scheme; } /** * @see Border#paint(IFigure, Graphics, Insets) */ public void paint(IFigure figure, Graphics g, Insets insets) { Color [] tl = scheme.getHighlight(); Color [] br = scheme.getShadow(); paint (g, figure, insets, tl, br); } /** * Paints the border using the information in the set Scheme and the inputs given. Side * widths are determined by the number of colors in the Scheme for each side. * * @param graphics the graphics object * @param fig the figure this border belongs to * @param insets the insets * @param tl the highlight (top/left) colors * @param br the shadow (bottom/right) colors */ protected void paint(Graphics graphics, IFigure fig, Insets insets, Color[] tl, Color[] br) { graphics.setLineWidth(1); graphics.setLineStyle(Graphics.LINE_SOLID); graphics.setXORMode(false); Rectangle rect = getPaintRectangle(fig, insets); int top = rect.y; int left = rect.x; int bottom = rect.bottom() - 1; int right = rect.right() - 1; Color color; for (int i = 0; i < br.length; i++) { color = br[i]; graphics.setForegroundColor(color); graphics.drawLine(right - i, bottom - i, right - i, top + i); graphics.drawLine(right - i, bottom - i, left + i, bottom - i); } right--; bottom--; for (int i = 0; i < tl.length; i++) { color = tl[i]; graphics.setForegroundColor(color); graphics.drawLine(left + i, top + i, right - i, top + i); graphics.drawLine(left + i, top + i, left + i, bottom - i); } } }