| /****************************************************************************** |
| * Copyright (c) 2002, 2006 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.gmf.runtime.draw2d.ui.figures; |
| |
| import org.eclipse.draw2d.Graphics; |
| import org.eclipse.draw2d.IFigure; |
| import org.eclipse.draw2d.PositionConstants; |
| import org.eclipse.draw2d.geometry.Dimension; |
| import org.eclipse.draw2d.geometry.Point; |
| import org.eclipse.draw2d.geometry.Rectangle; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.graphics.Color; |
| import org.eclipse.swt.graphics.RGB; |
| |
| /** |
| * A set of methods that are useful when manipulating figures. These are often |
| * used in the paint routines or locators of IFigure implementors to do complex |
| * geometry calculations that may be common across different parts of a hierarchy. |
| * |
| * @author sshaw |
| * @canBeSeenBy %partners |
| */ |
| public class FigureUtilities extends org.eclipse.draw2d.FigureUtilities { |
| |
| /** |
| * Method colorToInteger. |
| * converts from a Color to an Integer representation |
| * @param c |
| * @return Integer |
| */ |
| public static Integer colorToInteger(Color c) { |
| return new Integer( |
| (c.getBlue() << 16) | (c.getGreen() << 8) | c.getRed()); |
| } |
| |
| /** |
| * Method integerToColor. |
| * converts from an Integer to a Color representation |
| * |
| * Note: Normally, colors should be instantiated |
| * using the AbstractResourceManager. |
| * |
| * @param i |
| * @return Color |
| */ |
| public static Color integerToColor(Integer i) { |
| if (i == null) |
| return null; |
| int color = i.intValue(); |
| return new Color( |
| null, |
| (color & 0x000000FF), |
| (color & 0x0000FF00) >> 8, |
| (color & 0x00FF0000) >> 16); |
| } |
| |
| /** |
| * Method RGBToInteger |
| * converts from an RGB to an Integer representation |
| * @param rgb |
| * @return Integer |
| */ |
| public static Integer RGBToInteger(RGB rgb) { |
| return new Integer((rgb.blue << 16) | (rgb.green << 8) | rgb.red); |
| } |
| |
| |
| /** |
| * Method integerToRGB |
| * converts from an Integer to an RGB representation |
| * @param color |
| * @return RGB |
| */ |
| public static RGB integerToRGB(Integer color) { |
| int n = color.intValue(); |
| return new RGB( |
| (n & 0x000000FF), |
| (n & 0x0000FF00) >> 8, |
| (n & 0x00FF0000) >> 16); |
| } |
| |
| /** |
| * Return the location within the supplied constraint the supplied rectangle requires to be |
| * positioned according to the alignment parameter <i>pos</i>. |
| * |
| * <pre> |
| * NW-----N------NE |
| * | | |
| * W NS/EW E |
| * | | |
| * SW-----S------SE |
| * |
| * </pre> |
| * <P> |
| * @param pos a geographic PositionConstant (N,E,W,S,NW,NW,NS,EW) |
| * @param topos the rectangle to be (re)positioned. |
| * @param constraint the containing bounds. |
| * @return a new location. |
| */ |
| public static Point getLocation( |
| int pos, |
| final Rectangle topos, |
| final Rectangle constraint) { |
| Rectangle b = constraint.getCopy(); |
| Point svb = new Point(b.x, b.y); |
| |
| switch (pos) { |
| case PositionConstants.NORTH : |
| svb.x += b.width / 2; |
| break; |
| |
| case PositionConstants.SOUTH : |
| svb.x += b.width / 2; |
| svb.y += b.height; |
| break; |
| |
| case PositionConstants.WEST : |
| svb.y += b.height / 2 - topos.height / 2; |
| break; |
| |
| case PositionConstants.EAST : |
| svb.x += b.width; |
| svb.y += b.height / 2 - topos.height / 2; |
| break; |
| |
| case PositionConstants.NORTH_EAST : //top right |
| svb.x += b.width - topos.width; |
| break; |
| |
| case PositionConstants.SOUTH_EAST : //bottom right |
| svb.x += b.width - topos.width; |
| svb.y += b.height - topos.height; |
| break; |
| |
| case PositionConstants.SOUTH_WEST : //bottom left |
| svb.x += b.width; |
| svb.y += topos.height; |
| break; |
| |
| case PositionConstants.NORTH_SOUTH : // center of bounds area |
| case PositionConstants.EAST_WEST : |
| svb.x += b.width / 2 - topos.width / 2; |
| svb.y += b.height / 2 - topos.height / 2; |
| break; |
| |
| case PositionConstants.NORTH_WEST : //top left |
| default : |
| break; |
| } |
| return svb; |
| } |
| |
| /** |
| * Return the location within the supplied constraint of an object of dimension <i>dim</i> |
| * according to the alignment parameter. |
| * @see #getLocation(int, Rectangle, Rectangle) |
| * @param pos a geographic PositionConstant (N,E,W,S,NW,NW,NS,EW) |
| * @param dim some dimension. |
| * @param constraint the containing bounds. |
| * @return a new location. |
| */ |
| public static Point getLocation( |
| int pos, |
| final Dimension dim, |
| final Rectangle constraint) { |
| return getLocation( |
| pos, |
| new Rectangle(0, 0, dim.width, dim.height), |
| constraint); |
| } |
| |
| |
| /** |
| * Helper method to paint a grid. Painting is optimized as it is restricted to the |
| * Graphics' clip. |
| * |
| * @param g The Graphics object to be used for painting |
| * @param f The figure in which the grid is to be painted |
| * @param origin Any point where the grid lines are expected to intersect |
| * @param distanceX Distance between vertical grid lines; if 0 or less, vertical grid |
| * lines will not be drawn |
| * @param distanceY Distance between horizontal grid lines; if 0 or less, horizontal |
| * grid lines will not be drawn |
| * @param lineStyle Line style to be used for painting the grid lines |
| * @param dashes Dash pattern to be used for the grid line (ignored if lineStyle != LINE_CUSTOM) |
| * |
| */ |
| public static void paintGridWithStyle(Graphics g, IFigure f, |
| org.eclipse.draw2d.geometry.Point origin, int distanceX, int distanceY, int lineStyle, int[] dashes) { |
| Rectangle clip = g.getClip(Rectangle.SINGLETON); |
| |
| int origLineStyle = g.getLineStyle(); |
| |
| if (distanceX > 0) { |
| if (origin.x >= clip.x) |
| while (origin.x - distanceX >= clip.x) |
| origin.x -= distanceX; |
| else |
| while (origin.x < clip.x) |
| origin.x += distanceX; |
| for (int i = origin.x; i < clip.x + clip.width; i += distanceX) { |
| g.setLineStyle(lineStyle); |
| if ((dashes != null) && (lineStyle == SWT.LINE_CUSTOM)) g.setLineDash(dashes); |
| g.drawLine(i, clip.y, i, clip.y + clip.height); |
| g.setLineStyle(origLineStyle); |
| } |
| } |
| |
| if (distanceY > 0) { |
| if (origin.y >= clip.y) |
| while (origin.y - distanceY >= clip.y) |
| origin.y -= distanceY; |
| else |
| while (origin.y < clip.y) |
| origin.y += distanceY; |
| for (int i = origin.y; i < clip.y + clip.height; i += distanceY) { |
| g.setLineStyle(lineStyle); |
| if ((dashes != null) && (lineStyle == SWT.LINE_CUSTOM)) g.setLineDash(dashes); |
| g.drawLine(clip.x, i, clip.x + clip.width, i); |
| g.setLineStyle(origLineStyle); |
| } |
| } |
| } |
| |
| /** |
| * Calculates the anchorable figure bounds. There could be cases that a figure |
| * implements both <code>IOvalAnchorableFigure</code> and <code>IPolygonAnchorableFigure</code> |
| * interfaces. The latter interface is more popular because any figure can be approximated |
| * with line segments including ellipse. Therefore, we need to check first if it's an |
| * ellipse like figure and then if it's some kind of a polygon. |
| * |
| * @param figure the figure |
| * @return the bounding <code>Rectangle</code> of the anchorable part of the figure |
| */ |
| public static Rectangle getAnchorableFigureBounds(IFigure figure) { |
| if (figure instanceof IOvalAnchorableFigure) { |
| return ((IOvalAnchorableFigure)figure).getOvalBounds().getCopy(); |
| } else if (figure instanceof IPolygonAnchorableFigure) { |
| return ((IPolygonAnchorableFigure)figure).getPolygonPoints().getBounds(); |
| } else if (figure instanceof IFigure) { |
| return figure.getBounds().getCopy(); |
| } |
| return null; |
| } |
| |
| } |