/******************************************************************************* * <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); } } }