| /******************************************************************************* |
| * 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.draw2d.rap.swt.graphics.LineAttributes; |
| |
| |
| /** |
| * Provides abstract support for a variety of shapes. |
| * <p> |
| * When customizing shapes, you shouldn't override paintFigure(). Override |
| * fillShape() and outlineShape() methods instead. |
| */ |
| public abstract class Shape extends Figure { |
| |
| /** |
| * The width of this shape's outline. |
| */ |
| protected int lineWidth; |
| |
| /** |
| * Private copy of lineWidth field to track changes. We cannot compare to |
| * the float line width because rounding may make them seem equal when they |
| * have actually changed. |
| * |
| * e.g. someone sets int line width to 5, when float line width was already |
| * 5.4, float line width should change to 5.0, but comparing them as ints |
| * would suggest there's no change to synchronize. |
| */ |
| private int lastLineWidth; |
| |
| /** |
| * The line style to be used for this shape's outline. |
| */ |
| protected int lineStyle; |
| |
| private LineAttributes lineAttributes; |
| |
| private boolean fill; |
| private boolean outline; |
| private boolean xorFill; |
| private boolean xorOutline; |
| private Integer antialias; |
| private Integer alpha; |
| |
| /** |
| * Default constructor. |
| * |
| * @since 2.0 |
| */ |
| public Shape() { |
| lineAttributes = new LineAttributes(1.0f); |
| fill = true; |
| outline = true; |
| xorFill = false; |
| xorOutline = false; |
| antialias = null; |
| alpha = null; |
| |
| // synchronize parameters |
| lineWidth = (int) lineAttributes.width; |
| lineStyle = lineAttributes.style; |
| lastLineWidth = lineWidth; |
| } |
| |
| /** |
| * Fills the interior of the shape with the background color. |
| * |
| * @param graphics |
| * the graphics object |
| */ |
| protected abstract void fillShape(Graphics graphics); |
| |
| /** |
| * Outlines this shape using the foreground color. |
| * |
| * @param graphics |
| * the graphics object |
| */ |
| protected abstract void outlineShape(Graphics graphics); |
| |
| /** |
| * Paints the shape. Each shape has an outline to draw, and a region to fill |
| * within that outline. Disabled shapes must visually depict the disabled |
| * state. |
| * |
| * @see Figure#paintFigure(Graphics) |
| */ |
| public void paintFigure(Graphics graphics) { |
| if (antialias != null) { |
| graphics.setAntialias(antialias.intValue()); |
| } |
| if (alpha != null) { |
| graphics.setAlpha(alpha.intValue()); |
| } |
| // graphics.rotate(rotation); |
| |
| /* |
| * see bug #267397: paintFigure was historically not called, disabling |
| * setOpaque() behavior, and it was decided to defend the API's |
| * consistency. |
| */ |
| // paint background and border |
| // super.paintFigure(graphics); |
| |
| if (!isEnabled()) { |
| graphics.translate(1, 1); |
| graphics.setBackgroundColor(ColorConstants.buttonLightest); |
| graphics.setForegroundColor(ColorConstants.buttonLightest); |
| |
| if (fill) { |
| paintFill(graphics); |
| } |
| |
| if (outline) { |
| paintOutline(graphics); |
| } |
| |
| graphics.setBackgroundColor(ColorConstants.buttonDarker); |
| graphics.setForegroundColor(ColorConstants.buttonDarker); |
| graphics.translate(-1, -1); |
| } |
| |
| if (fill) { |
| paintFill(graphics); |
| } |
| |
| if (outline) { |
| paintOutline(graphics); |
| } |
| } |
| |
| private void paintOutline(Graphics graphics) { |
| // synchronize the line width and style attributes to the |
| // public fields which may have been assigned |
| // to without our knowledge |
| lineAttributes.width = getLineWidthFloat(); |
| lineAttributes.style = getLineStyle(); |
| |
| graphics.setLineAttributes(lineAttributes); |
| |
| if (xorOutline) { |
| /* |
| * XORMode is a non-advanced only feature (GDI, not in GDI+ on |
| * windows) |
| * |
| * Also, XORMode is deprecated in SWT, so this should really be |
| * removed completely at some point. XORMode isn't supported on Mac |
| * OSX at all. |
| */ |
| boolean oldAdv = graphics.getAdvanced(); |
| graphics.setAdvanced(false); |
| graphics.setXORMode(true); |
| outlineShape(graphics); |
| graphics.setAdvanced(oldAdv); |
| } else { |
| outlineShape(graphics); |
| } |
| } |
| |
| private void paintFill(Graphics graphics) { |
| if (xorFill) { |
| /* |
| * XORMode is a non-advanced only feature (GDI, not in GDI+ on |
| * windows) |
| * |
| * Also, XORMode is deprecated in SWT, so this should really be |
| * removed completely at some point. XORMode isn't supported on Mac |
| * OSX at all. |
| */ |
| boolean oldAdv = graphics.getAdvanced(); |
| graphics.setAdvanced(false); |
| graphics.setXORMode(true); |
| fillShape(graphics); |
| graphics.setAdvanced(oldAdv); |
| } else { |
| fillShape(graphics); |
| } |
| } |
| |
| /** |
| * Sets whether this shape should fill its region or not. It repaints this |
| * figure. |
| * |
| * @param b |
| * fill state |
| * @since 2.0 |
| */ |
| public void setFill(boolean b) { |
| if (fill != b) { |
| fill = b; |
| repaint(); |
| } |
| } |
| |
| /** |
| * Sets whether XOR based fill should be used by the shape. It repaints this |
| * figure. |
| * |
| * @param b |
| * XOR fill state |
| * @since 2.0 |
| */ |
| public void setFillXOR(boolean b) { |
| if (xorFill != b) { |
| xorFill = b; |
| repaint(); |
| } |
| } |
| |
| /** |
| * Sets whether the outline should be drawn for this shape. |
| * |
| * @param b |
| * <code>true</code> if the shape should be outlined |
| * @since 2.0 |
| */ |
| public void setOutline(boolean b) { |
| if (outline != b) { |
| outline = b; |
| repaint(); |
| } |
| } |
| |
| /** |
| * Sets whether XOR based outline should be used for this shape. |
| * |
| * @param b |
| * <code>true</code> if the outline should be XOR'ed |
| * @since 2.0 |
| */ |
| public void setOutlineXOR(boolean b) { |
| if (xorOutline != b) { |
| xorOutline = b; |
| repaint(); |
| } |
| } |
| |
| /** |
| * Sets whether XOR based fill and XOR based outline should be used for this |
| * shape. |
| * |
| * @param b |
| * <code>true</code> if the outline and fill should be XOR'ed |
| * @since 2.0 |
| */ |
| public void setXOR(boolean b) { |
| xorOutline = xorFill = b; |
| repaint(); |
| } |
| |
| /** |
| * @since 3.5 |
| */ |
| public Integer getAlpha() { |
| return alpha; |
| } |
| |
| /** |
| * @since 3.5 |
| */ |
| public Integer getAntialias() { |
| return antialias; |
| } |
| |
| /** |
| * Returns line attributes used when drawing this shape. |
| * |
| * @see org.eclipse.swt.graphics.LineAttributes |
| * |
| * Performance note: creates and returns a clone. |
| * |
| * @return current line attributes |
| * @since 3.5 |
| */ |
| public LineAttributes getLineAttributes() { |
| return SWTGraphics.clone(lineAttributes); |
| } |
| |
| /** |
| * Returns the line width of this shape's outline. |
| * |
| * @return the line width |
| */ |
| public int getLineWidth() { |
| // synchronize lineWidth field for |
| // backwards compatibility |
| if (lineWidth != lastLineWidth) { |
| lineAttributes.width = lineWidth; |
| lastLineWidth = lineWidth; |
| } |
| |
| return (int) lineAttributes.width; |
| } |
| |
| /** |
| * Returns the line width of this shape's outline. |
| * |
| * @see org.eclipse.swt.graphics.LineAttributes#width |
| * |
| * @since 3.5 |
| */ |
| public float getLineWidthFloat() { |
| // synchronize lineWidth field for |
| // backwards compatibility |
| if (lineWidth != lastLineWidth) { |
| lineAttributes.width = lineWidth; |
| lastLineWidth = lineWidth; |
| } |
| |
| return lineAttributes.width; |
| } |
| |
| /** |
| * Returns the line join style of this shape's outline. |
| * |
| * @see org.eclipse.swt.graphics.LineAttributes#join |
| * |
| * @since 3.5 |
| */ |
| public int getLineJoin() { |
| return lineAttributes.join; |
| } |
| |
| /** |
| * Returns the line cap style of this shape's outline. |
| * |
| * @see org.eclipse.swt.graphics.LineAttributes#cap |
| * |
| * @since 3.5 |
| */ |
| public int getLineCap() { |
| return lineAttributes.cap; |
| } |
| |
| /** |
| * Returns the line style of this shape's outline. |
| * |
| * @see org.eclipse.swt.graphics.LineAttributes#style |
| * |
| * @return the line style |
| */ |
| public int getLineStyle() { |
| // synchronize line style which may have been assigned |
| // to lineStyle field for backwards compatibility |
| lineAttributes.style = lineStyle; |
| |
| return lineAttributes.style; |
| } |
| |
| /** |
| * Returns the line dash style of this shape's outline. |
| * |
| * @see org.eclipse.swt.graphics.LineAttributes#dash |
| * |
| * @since 3.5 |
| */ |
| public float[] getLineDash() { |
| if (lineAttributes.dash != null) { |
| return (float[]) lineAttributes.dash.clone(); |
| } else { |
| return null; |
| } |
| } |
| |
| /** |
| * Returns the line dash offset of this shape's outline. |
| * |
| * @see org.eclipse.swt.graphics.LineAttributes#dashOffset |
| * |
| * @since 3.5 |
| */ |
| public float getLineDashOffset() { |
| return lineAttributes.dashOffset; |
| } |
| |
| /** |
| * Returns the line dash miter limit of this shape's outline. |
| * |
| * @see org.eclipse.swt.graphics.LineAttributes#miterLimit |
| * |
| * @since 3.5 |
| */ |
| public float getLineMiterLimit() { |
| return lineAttributes.miterLimit; |
| } |
| |
| /** |
| * @since 3.5 |
| */ |
| public void setAlpha(Integer value) { |
| if (alpha != null) { |
| if (!alpha.equals(value)) { |
| alpha = value; |
| repaint(); |
| } |
| } else if (value != null) { |
| alpha = value; |
| repaint(); |
| } |
| } |
| |
| /** |
| * @since 3.5 |
| */ |
| public void setAlpha(int value) { |
| if (alpha != null) { |
| if (alpha.intValue() != value) { |
| alpha = new Integer(value); |
| repaint(); |
| } |
| } else { |
| alpha = new Integer(value); |
| repaint(); |
| } |
| } |
| |
| /** |
| * @see org.eclipse.swt.graphics.GC#setAntialias(int) |
| * @param value |
| * @since 3.5 |
| */ |
| public void setAntialias(Integer value) { |
| if (antialias != null) { |
| if (!antialias.equals(value)) { |
| antialias = value; |
| repaint(); |
| } |
| } else if (value != null) { |
| antialias = value; |
| repaint(); |
| } |
| } |
| |
| /** |
| * @since 3.5 |
| */ |
| public void setAntialias(int value) { |
| if (antialias != null) { |
| if (antialias.intValue() != value) { |
| antialias = new Integer(value); |
| repaint(); |
| } |
| } else { |
| antialias = new Integer(value); |
| repaint(); |
| } |
| } |
| |
| /** |
| * Sets all line attributes at once. |
| * |
| * @see org.eclipse.swt.graphics.LineAttributes |
| * |
| * @param la |
| * @since 3.5 |
| */ |
| public void setLineAttributes(LineAttributes la) { |
| if (!lineAttributes.equals(la)) { |
| SWTGraphics.copyLineAttributes(lineAttributes, la); |
| repaint(); |
| } |
| } |
| |
| /** |
| * Sets the line width to be used to outline the shape. |
| * |
| * @param w |
| * the new width |
| * @since 2.0 |
| */ |
| public void setLineWidth(int w) { |
| float _w = w; |
| |
| if (lineAttributes.width != _w) { |
| lineAttributes.width = _w; |
| |
| // synchronize lineWidth fields for |
| // backwards compatibility |
| lineWidth = w; |
| lastLineWidth = w; |
| |
| repaint(); |
| } |
| } |
| |
| /** |
| * Sets the line width of this shape's outline. |
| * |
| * @see org.eclipse.swt.graphics.LineAttributes#width |
| * |
| * @param value |
| * @since 3.5 |
| */ |
| public void setLineWidthFloat(float value) { |
| if (lineAttributes.width != value) { |
| lineAttributes.width = value; |
| |
| // synchronize lineWidth fields for |
| // backwards compatibility |
| lineWidth = (int) value; |
| lastLineWidth = (int) value; |
| |
| repaint(); |
| } |
| } |
| |
| /** |
| * Sets the line join style of this shape's outline. |
| * |
| * @see org.eclipse.swt.graphics.LineAttributes#join |
| * |
| * @param join |
| * @since 3.5 |
| */ |
| public void setLineJoin(int join) { |
| if (lineAttributes.join != join) { |
| lineAttributes.join = join; |
| repaint(); |
| } |
| } |
| |
| /** |
| * Sets the line cap style of this shape's outline. |
| * |
| * @see org.eclipse.swt.graphics.LineAttributes#cap |
| * |
| * @param cap |
| * @since 3.5 |
| */ |
| public void setLineCap(int cap) { |
| if (lineAttributes.cap != cap) { |
| lineAttributes.cap = cap; |
| repaint(); |
| } |
| } |
| |
| /** |
| * Sets the line style of this shape's outline. |
| * |
| * @see org.eclipse.swt.graphics.LineAttributes#style |
| * |
| * @param style |
| * the new line style |
| * @since 2.0 |
| */ |
| public void setLineStyle(int style) { |
| if (lineAttributes.style != style) { |
| lineAttributes.style = style; |
| |
| // synchronize the lineStyle field |
| // to the lineStyle we actually use |
| lineStyle = style; |
| |
| repaint(); |
| } |
| } |
| |
| /** |
| * Sets the line dash style of this shape's outline. |
| * |
| * @see org.eclipse.swt.graphics.LineAttributes#dash |
| * |
| * @param dash |
| * @since 3.5 |
| */ |
| public void setLineDash(float[] dash) { |
| if ((dash != null) && !dash.equals(lineAttributes.dash)) { |
| lineAttributes.dash = (float[]) dash.clone(); |
| repaint(); |
| } else if ((dash == null) && (lineAttributes.dash != null)) { |
| lineAttributes.dash = null; |
| repaint(); |
| } |
| } |
| |
| /** |
| * Sets the line dash offset of this shape's outline. |
| * |
| * @see org.eclipse.swt.graphics.LineAttributes#dashOffset |
| * |
| * @param dashOffset |
| * @since 3.5 |
| */ |
| public void setLineDashOffset(float dashOffset) { |
| if (lineAttributes.dashOffset != dashOffset) { |
| lineAttributes.dashOffset = dashOffset; |
| repaint(); |
| } |
| } |
| |
| /** |
| * Sets the line dash miter limit of this shape's outline. |
| * |
| * @see org.eclipse.swt.graphics.LineAttributes#miterLimit |
| * |
| * @param miterLimit |
| * @since 3.5 |
| */ |
| public void setLineMiterLimit(float miterLimit) { |
| if (lineAttributes.miterLimit != miterLimit) { |
| lineAttributes.miterLimit = miterLimit; |
| repaint(); |
| } |
| } |
| |
| } |