blob: 0a1592cb012a8e0c458210054572862d41f837ed [file] [log] [blame]
/*******************************************************************************
* 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 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);
}
}
}