/* ******************************************************************************
* Copyright (c) 2006-2012 XMind Ltd. and others.
*
* This file is a part of XMind 3. XMind releases 3 and
* above are dual-licensed under the Eclipse Public License (EPL),
* which is available at http://www.eclipse.org/legal/epl-v10.html
* and the GNU Lesser General Public License (LGPL),
* which is available at http://www.gnu.org/licenses/lgpl.html
* See http://www.xmind.net/license.html for details.
*
* Contributors:
* XMind Ltd. - initial API and implementation
*******************************************************************************/
package org.xmind.gef.draw2d.decoration;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Pattern;
import org.eclipse.swt.widgets.Display;
import org.xmind.gef.GEF;
import org.xmind.gef.draw2d.graphics.GradientPattern;
public abstract class AbstractShapeDecoration extends AbstractDecoration
implements IShapeDecoration {
protected final static Rectangle NO_OWNER_BOX = new Rectangle();
private Color fillColor = null;
private int fillAlpha = 0xFF;
private int lineAlpha = 0xFF;
private Color lineColor = null;
private int lineWidth = 1;
private int lineStyle = SWT.LINE_SOLID;
private boolean gradient = false;
protected AbstractShapeDecoration() {
super();
}
protected AbstractShapeDecoration(String id) {
super(id);
}
/**
* @see org.xmind.gef.draw2d.decoration.IShapeDecoration#isGradient()
*/
public boolean isGradient() {
return gradient;
}
/**
* @return the fillColor
*/
public Color getFillColor() {
return fillColor;
}
/**
* @see org.xmind.gef.draw2d.decoration.IShapeDecoration#getLineAlpha()
*/
public int getLineAlpha() {
return lineAlpha;
}
/**
* @return the outlineColor
*/
public Color getLineColor() {
return lineColor;
}
/**
* @see org.xmind.gef.draw2d.decoration.IShapeDecoration#getLineStyle()
*/
public int getLineStyle() {
return lineStyle;
}
/**
* @return the lineWidth
*/
public int getLineWidth() {
return lineWidth;
}
/**
* @see org.xmind.gef.draw2d.decoration.IShapeDecoration#getFillAlpha()
*/
public int getFillAlpha() {
return fillAlpha;
}
/**
* @see org.xmind.gef.draw2d.decoration.IShapeDecoration#setFillAlpha(int)
*/
public void setFillAlpha(IFigure figure, int alpha) {
if (alpha == this.fillAlpha)
return;
this.fillAlpha = alpha;
if (figure != null) {
repaint(figure);
}
}
/**
* @param c
* the fillColor to set
*/
public void setFillColor(IFigure figure, Color c) {
if (c == this.fillColor || (c != null && c.equals(this.fillColor)))
return;
this.fillColor = c;
if (figure != null) {
repaint(figure);
}
}
/**
* @see org.xmind.gef.draw2d.decoration.IShapeDecoration#setGradient(boolean)
*/
public void setGradient(IFigure figure, boolean gradient) {
gradient = gradient && GEF.IS_PLATFORM_SUPPORT_GRADIENT;
if (gradient == this.gradient)
return;
this.gradient = gradient;
if (figure != null) {
repaint(figure);
}
}
/**
* @see org.xmind.gef.draw2d.decoration.IShapeDecoration#setLineAlpha(int)
*/
public void setLineAlpha(IFigure figure, int alpha) {
if (alpha == this.lineAlpha)
return;
this.lineAlpha = alpha;
if (figure != null) {
repaint(figure);
}
}
/**
* @param c
* the outlineColor to set
*/
public void setLineColor(IFigure figure, Color c) {
if (c == this.lineColor || (c != null && c.equals(this.lineColor)))
return;
this.lineColor = c;
if (figure != null) {
repaint(figure);
}
}
/**
* @see org.xmind.gef.draw2d.decoration.IShapeDecoration#setLineStyle(int)
*/
public void setLineStyle(IFigure figure, int lineStyle) {
if (lineStyle == this.lineStyle)
return;
this.lineStyle = lineStyle;
if (figure != null) {
repaint(figure);
}
}
/**
* @param lineWidth
* the lineWidth to set
*/
public void setLineWidth(IFigure figure, int lineWidth) {
if (lineWidth == this.lineWidth)
return;
this.lineWidth = lineWidth;
if (figure != null) {
figure.revalidate();
repaint(figure);
}
invalidate();
}
protected void performPaint(IFigure figure, Graphics g) {
if (isFillVisible(figure)) {
fill(figure, g);
g.restoreState();
}
if (isLineVisible(figure)) {
outline(figure, g);
g.restoreState();
}
}
protected void outline(IFigure figure, Graphics g) {
g.setAlpha(getAppliedLineAlpha());
g.setForegroundColor(getLineColor(figure));
g.setLineWidth(getLineWidth());
g.setLineStyle(getLineStyle());
paintOutline(figure, g);
}
protected void fill(IFigure figure, Graphics g) {
Pattern bgPattern = null;
int appliedAlpha = getAppliedFillAlpha();
Color bgColor = getFillColor(figure);
if (isGradient()) {
bgPattern = createGradientPattern(figure, appliedAlpha, bgColor);
g.setBackgroundPattern(bgPattern);
} else {
g.setAlpha(appliedAlpha);
g.setBackgroundColor(bgColor);
}
paintFill(figure, g);
if (bgPattern != null) {
g.setBackgroundPattern(null);
bgPattern.dispose();
}
}
protected int getAppliedLineAlpha() {
return (int) Math.floor(getLineAlpha() * 1.0 * getAlpha() / 0xFF);
}
protected int getAppliedFillAlpha() {
return (int) Math.floor(getFillAlpha() * 1.0 * getAlpha() / 0xFF);
}
protected Color getFillColor(IFigure figure) {
Color c = getFillColor();
return c == null ? figure.getBackgroundColor() : c;
}
protected Color getLineColor(IFigure figure) {
Color c = getLineColor();
return c == null ? figure.getForegroundColor() : c;
}
protected Pattern createGradientPattern(IFigure figure, int alpha,
Color bgColor) {
Rectangle r = getFillBox(figure);
int delta = (int) (r.height * 0.4);
Pattern p = new GradientPattern(Display.getCurrent(), //
r.x, r.y - delta, //
r.x, r.y + r.height, //
ColorConstants.white, alpha, //
bgColor, alpha);
return p;
}
protected abstract void paintFill(IFigure figure, Graphics graphics);
protected abstract void paintOutline(IFigure figure, Graphics graphics);
protected Rectangle getFillBox(IFigure figure) {
return getFillBox(figure.getBounds());
}
protected Rectangle getFillBox(Rectangle box) {
Rectangle ret = box.getCopy();
int w = Math.min(ret.width - 1, Math
.min(ret.height - 1, getLineWidth()));
int half = w - w / 2;
return ret.shrink(half, half);
}
protected Rectangle getOutlineBox(IFigure figure) {
return getOutlineBox(figure.getBounds());
}
/**
* @return
*/
protected Rectangle getOutlineBox(Rectangle box) {
Rectangle ret = box.getCopy();
int w = Math.min(ret.width - 1, Math
.min(ret.height - 1, getLineWidth()));
int half = w - w / 2;
return ret.shrink(half, half).resize(-1, -1);
}
/**
* @param figure
* @return the fillVisible
*/
protected boolean isFillVisible(IFigure figure) {
return getFillColor() != null;
}
/**
* @param figure
* @return the outlineVisible
*/
protected boolean isLineVisible(IFigure figure) {
return getLineColor() != null;
}
}