| /******************************************************************************* |
| * <copyright> |
| * |
| * Copyright (c) 2005, 2010 SAP AG. |
| * 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: |
| * SAP AG - initial API, implementation and documentation |
| * |
| * </copyright> |
| * |
| *******************************************************************************/ |
| package org.eclipse.graphiti.testtool.sketch; |
| |
| import org.eclipse.draw2d.ColorConstants; |
| import org.eclipse.draw2d.Graphics; |
| import org.eclipse.draw2d.Label; |
| import org.eclipse.draw2d.RectangleFigure; |
| import org.eclipse.draw2d.geometry.Insets; |
| import org.eclipse.draw2d.geometry.Rectangle; |
| import org.eclipse.graphiti.platform.ga.IGraphicsAlgorithmRenderer; |
| import org.eclipse.graphiti.platform.ga.IVisualState; |
| import org.eclipse.graphiti.platform.ga.IVisualStateChangeListener; |
| import org.eclipse.graphiti.platform.ga.IVisualStateHolder; |
| import org.eclipse.graphiti.platform.ga.VisualState; |
| import org.eclipse.graphiti.platform.ga.VisualStateChangedEvent; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.graphics.Color; |
| import org.eclipse.swt.graphics.Image; |
| |
| /** |
| * The Class CanFigure. |
| */ |
| public class CanFigure extends RectangleFigure implements IGraphicsAlgorithmRenderer, IVisualStateHolder, IVisualStateChangeListener { |
| |
| private static final int SELECTION_LINE_WIDTH_PRIMARY = 4; |
| |
| private static final int SELECTION_LINE_WIDTH_SECONDARY = 3; |
| |
| private static final Color SELECTION_BACKGROUND_PRIMARY = ColorConstants.blue; |
| |
| private static final Color SELECTION_BACKGROUND_SECONDARY = ColorConstants.lightBlue; |
| |
| private static final boolean ADVANCED_GRAPHIC = true; |
| |
| private static final int DEFAULT_ELLIPSE_PROPORTION = 4; |
| |
| private static final Color DEFAULT_TEXT_COLOR = ColorConstants.black; |
| |
| private Insets defaultFigureInsets = new Insets(2); |
| |
| private boolean dropShadow = true; |
| |
| private Image icon; |
| |
| private String label = ""; |
| |
| private int mProportion = DEFAULT_ELLIPSE_PROPORTION; |
| |
| private boolean ovalTop; |
| |
| private Color storeColor; |
| |
| private String storeText; |
| |
| private Color textColor = DEFAULT_TEXT_COLOR; |
| |
| boolean highlight = false; |
| |
| private VisualState visualState; |
| |
| private int storeLineWidth = -1; |
| |
| /** |
| * Instantiates a new can figure. |
| * |
| * @param ovalTop |
| * the oval top |
| */ |
| public CanFigure(boolean ovalTop) { |
| this(ovalTop, DEFAULT_ELLIPSE_PROPORTION); |
| } |
| |
| /** |
| * Instantiates a new can figure. |
| * |
| * @param ovalTop |
| * the oval top |
| * @param ellipseProportion |
| * the ellipse proportion |
| */ |
| public CanFigure(boolean ovalTop, int ellipseProportion) { |
| super(); |
| if (ellipseProportion > 0) { |
| mProportion = ellipseProportion; |
| } |
| this.ovalTop = ovalTop; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.draw2d.Figure#containsPoint(int, int) |
| */ |
| @Override |
| public boolean containsPoint(int x, int y) { |
| if (!super.containsPoint(x, y)) |
| return false; |
| |
| Rectangle ell = getInnerBounds().getCopy(); |
| ell.height /= mProportion; |
| |
| Rectangle topEll = ell; |
| if (containsPoint(topEll, x, y)) |
| return true; |
| |
| Rectangle bottomEll = ell.getCopy().translate(0, getHeight(ell)); |
| if (containsPoint(bottomEll, x, y)) |
| return true; |
| return new Rectangle(topEll.getLeft(), bottomEll.getRight()).contains(x, y); |
| } |
| |
| /** |
| * Gets the figure insets. |
| * |
| * @return the figure insets |
| */ |
| public Insets getFigureInsets() { |
| return defaultFigureInsets; |
| } |
| |
| /** |
| * Returns the visual state of this shape. |
| * |
| * @return The visual state of this shape. |
| */ |
| public IVisualState getVisualState() { |
| if (visualState == null) { |
| visualState = new VisualState(); |
| visualState.addChangeListener(this); |
| } |
| return visualState; |
| } |
| |
| /** |
| * Is called after the visual state changed. |
| */ |
| public void visualStateChanged(VisualStateChangedEvent e) { |
| int selectionFeedback = getVisualState().getSelectionFeedback(); |
| if (selectionFeedback == IVisualState.SELECTION_PRIMARY) { |
| // text |
| if (storeText == null) { |
| storeText = getCaption(); |
| } |
| setCaption("primary select"); |
| |
| // text color |
| setTextColor(ColorConstants.white); |
| |
| // background color |
| if (storeColor == null) { |
| storeColor = getBackgroundColor(); |
| } |
| setBackgroundColor(SELECTION_BACKGROUND_PRIMARY); |
| |
| // line width |
| if (storeLineWidth < 0) { |
| storeLineWidth = getLineWidth(); |
| } |
| setLineWidth(SELECTION_LINE_WIDTH_PRIMARY); |
| } else if (selectionFeedback == IVisualState.SELECTION_SECONDARY) { |
| // text |
| if (storeText == null) { |
| storeText = getCaption(); |
| } |
| setCaption("secondary select"); |
| |
| // text color |
| setTextColor(ColorConstants.white); |
| |
| // background color |
| if (storeColor == null) { |
| storeColor = getBackgroundColor(); |
| } |
| setBackgroundColor(SELECTION_BACKGROUND_SECONDARY); |
| |
| // line width |
| if (storeLineWidth < 0) { |
| storeLineWidth = getLineWidth(); |
| } |
| setLineWidth(SELECTION_LINE_WIDTH_SECONDARY); |
| } else if (selectionFeedback == IVisualState.SELECTION_FEEDBACK_OFF) { |
| // text color |
| if (storeText != null) { |
| setCaption(storeText); |
| storeText = null; |
| } |
| |
| // text color |
| setTextColor(DEFAULT_TEXT_COLOR); |
| |
| // background color |
| if (storeColor != null) { |
| setBackgroundColor(storeColor); |
| storeColor = null; |
| } |
| |
| // line width |
| if (storeLineWidth >= 0) { |
| setLineWidth(storeLineWidth); |
| storeLineWidth = -1; |
| } |
| } |
| } |
| |
| /** |
| * Sets the caption. |
| * |
| * @param label |
| * the new caption |
| */ |
| public void setCaption(String label) { |
| this.label = label; |
| setToolTip(new Label(" " + label + " ")); |
| repaint(); |
| } |
| |
| /** |
| * Sets the drop shadow. |
| * |
| * @param dropShadow |
| * the new drop shadow |
| */ |
| public void setDropShadow(boolean dropShadow) { |
| this.dropShadow = dropShadow; |
| } |
| |
| /** |
| * Sets the highlight. |
| * |
| * @param highlight |
| * the new highlight |
| */ |
| public void setHighlight(boolean highlight) { |
| this.highlight = highlight; |
| repaint(); |
| } |
| |
| /** |
| * Sets the icon. |
| * |
| * @param icon |
| * the new icon |
| */ |
| public void setIcon(Image icon) { |
| this.icon = icon; |
| repaint(); |
| } |
| |
| /** |
| * Sets the text color. |
| * |
| * @param textColor |
| * the new text color |
| */ |
| public void setTextColor(Color textColor) { |
| this.textColor = textColor; |
| } |
| |
| private boolean containsPoint(Rectangle el, int x, int y) { |
| |
| long ux = x - el.x - el.width / 2; |
| long uy = y - el.y - el.height / 2; |
| return ((ux * ux) << 10) / (el.width * el.width) + ((uy * uy) << 10) / (el.height * el.height) <= 256; |
| } |
| |
| private String getCaption() { |
| return label; |
| } |
| |
| private int getHeight(Rectangle topEllipse) { |
| return getInnerBounds().height - topEllipse.height; |
| } |
| |
| private Rectangle getInnerBounds() { |
| return getBounds().getCopy().getShrinked(defaultFigureInsets); |
| } |
| |
| @Override |
| protected void fillShape(Graphics g) { |
| if (ADVANCED_GRAPHIC) |
| g.setAntialias(SWT.ON); |
| Rectangle upperArc = getInnerBounds(); |
| upperArc.height /= mProportion; |
| |
| Rectangle lowerArc = upperArc.getCopy().translate(0, getHeight(upperArc)); |
| if (highlight) { |
| g.setBackgroundColor(ColorConstants.blue); |
| g.fillRectangle(getBounds()); |
| } else if (dropShadow) { |
| |
| for (int i = 0; i < 3; i++) { |
| switch (i) { |
| case 0: |
| g.setBackgroundColor(ColorConstants.lightGray); |
| break; |
| case 1: |
| g.setBackgroundColor(ColorConstants.gray); |
| break; |
| case 2: |
| g.setBackgroundColor(ColorConstants.darkGray); |
| break; |
| } |
| |
| g.fillRectangle(new Rectangle(upperArc.getLeft(), lowerArc.getRight()).getTranslated(3, 3).getExpanded(-i, 1)); |
| g.fillArc(new Rectangle(upperArc.getLocation(), upperArc.getBottomRight()).getTranslated(3, 2).getExpanded(-i, -i), 0, 180); |
| g.fillArc(new Rectangle(lowerArc.getLocation(), lowerArc.getBottomRight()).getTranslated(3, 3).getExpanded(-i, -i), 180, |
| 180); |
| |
| } |
| |
| } |
| g.setBackgroundColor(getBackgroundColor()); |
| |
| g.fillRectangle(new Rectangle(upperArc.getLeft(), lowerArc.getRight())); |
| g.fillArc(new Rectangle(upperArc.getLocation(), upperArc.getBottomRight().getTranslated(0, 1)), 0, 180); |
| g.fillArc(new Rectangle(lowerArc.getLocation(), lowerArc.getBottomRight()), 180, 180); |
| } |
| |
| @Override |
| protected void outlineShape(Graphics g) { |
| |
| Rectangle innerBounds = getInnerBounds(); |
| |
| Rectangle ovalBounds = innerBounds.getCopy(); |
| |
| ovalBounds.height /= mProportion; |
| |
| // Rectangle ovalBounds = ellipseBounds.getCopy().shrink((lineWidth - 1) |
| // / 2, (lineWidth - 1) / 2); |
| if (ovalTop) { |
| g.drawOval(ovalBounds); |
| } else { |
| g.drawArc(ovalBounds, 0, 180); |
| } |
| |
| Rectangle arcBounds = ovalBounds.getCopy().translate(0, getHeight(ovalBounds)); |
| g.drawLine(ovalBounds.getLeft(), arcBounds.getLeft()); |
| g.drawLine(ovalBounds.getRight(), arcBounds.getRight()); |
| g.drawArc(new Rectangle(arcBounds.getLocation(), arcBounds.getBottomRight().translate(-2, -1)), 180, 180); |
| |
| int maxChars = (innerBounds.width - 40) / g.getFontMetrics().getAverageCharWidth(); |
| if (maxChars < 3) |
| maxChars = 3; |
| |
| if (label != null) { |
| String newCaption = label; |
| if (label.length() > maxChars) |
| newCaption = label.substring(0, maxChars - 3) + "..."; |
| |
| g.setForegroundColor(textColor); |
| g.drawText(newCaption, innerBounds.x + 25, innerBounds.y + innerBounds.height / 2 - 6); |
| if (icon != null) |
| g.drawImage(icon, innerBounds.x + 5, innerBounds.y + innerBounds.height / 2 - 8); |
| } |
| } |
| } |