| /******************************************************************************* |
| * Copyright (c) 2000, 2010 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 { |
| |
| /** 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() { return new Color[] { |
| ColorConstants.buttonDarkest(), ColorConstants.buttonDarker() };} |
| protected static final Color[] LIGHTER_DARKER() { return new Color[] { |
| ColorConstants.buttonLightest(), ColorConstants.buttonDarker() };} |
| protected static final Color[] DARKER_LIGHTER() { return new Color[] { |
| ColorConstants.buttonDarker(), ColorConstants.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 class SCHEMES { |
| |
| /** Schemes used for shadow and highlight effects **/ |
| public static Scheme BUTTON_CONTRAST() { return new Scheme(new Color[] { ColorConstants.button(), |
| ColorConstants.buttonLightest() }, DARKEST_DARKER());} |
| public static Scheme BUTTON_RAISED() { return new Scheme( |
| new Color[] { ColorConstants.buttonLightest() }, DARKEST_DARKER());} |
| public static Scheme BUTTON_PRESSED() { return new Scheme(DARKEST_DARKER(), |
| new Color[] { ColorConstants.buttonLightest() });} |
| public static Scheme RAISED() { return new Scheme( |
| new Color[] { ColorConstants.buttonLightest() }, |
| new Color[] { ColorConstants.buttonDarkest() });} |
| public static Scheme LOWERED() { return new Scheme( |
| new Color[] { ColorConstants.buttonDarkest() }, |
| new Color[] { ColorConstants.buttonLightest() });} |
| public static Scheme RIDGED() { return new Scheme( |
| LIGHTER_DARKER(), DARKER_LIGHTER());} |
| public static Scheme ETCHED() { return 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); |
| } |
| } |
| |
| } |