diff options
Diffstat (limited to 'plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/helper/PapyrusLabelHelper.java')
-rw-r--r-- | plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/helper/PapyrusLabelHelper.java | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/helper/PapyrusLabelHelper.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/helper/PapyrusLabelHelper.java new file mode 100644 index 00000000000..a2b47c95f5d --- /dev/null +++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/helper/PapyrusLabelHelper.java @@ -0,0 +1,290 @@ +/****************************************************************************** + * Copyright (c) 2005, 2009 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.papyrus.infra.gmfdiag.common.helper; + + +import org.eclipse.draw2d.Connection; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.PointList; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.gmf.runtime.draw2d.ui.geometry.LineSeg; +import org.eclipse.gmf.runtime.draw2d.ui.geometry.PointListUtilities; + +/** + * Helper class to convert the label coordinates from an offset value + * from a keypoint to real draw2d coordinate + * + * @author sshaw + * + */ +public class PapyrusLabelHelper { + + /** + * Calculates the label offset from the reference point given the label bounds. + * + * @param label + * the <code>IFigure</code> to calculate the offset for + * @param bounds + * the <code>Rectangle</code> that is the bounding box of the label. + * @param ref + * the <code>Point</code> that is the reference point that the offset + * is based on. + * @return a <code>Point</code> which represents a value offset from the <code>ref</code> point oriented based on the nearest line segment. + */ + static public Point offsetFromRelativeCoordinate(IFigure label, Rectangle bounds, Point ref) { + return offsetFromRelativeCoordinate(label, bounds, getParentPointList(label), ref); + } + + /** + * Calculates the label offset from the reference point given the label bounds and a points list. + * + * @param label + * the <code>IFigure</code> to calculate the offset for + * @param bounds + * the <code>Rectangle</code> that is the bounding box of the label. + * @param points + * the <code>PointList</code> that contains that the label offset is relative to. + * @param ref + * the <code>Point</code> that is the reference point that the offset + * is based on. + * @return a <code>Point</code> which represents a value offset from the <code>ref</code> point oriented based on the nearest line segment. + */ + static public Point offsetFromRelativeCoordinate(IFigure label, Rectangle bounds, PointList points, Point ref) { + Rectangle rect = new Rectangle(bounds); + + // Componsate for the fact that we are using the + // figure center + rect.translate(rect.width / 2, rect.height / 2); + + Point normalPoint = normalizeRelativePointToPointOnLine(points, ref, + new Point(rect.x - ref.x, rect.y - ref.y)); + + return normalPoint; + } + + /** + * Calculates the relative coordinate that is equivalent to the offset from the reference + * point, that can be used to set the label location. + * + * @param label + * the <code>IFigure</code> to calculate the relative coordinate for + * @param ref + * a <code>Point</code> located on the parent which the offset value + * is relative to. + * @param offset + * a <code>Point</code> which represents a value offset from the <code>ref</code> point oriented based on the nearest line segment. + * @return a <code>Point</code> that is the relative coordinate of the label that can be + * used to set it's location. + */ + static public Point relativeCoordinateFromOffset(IFigure label, Point ref, Point offset) { + return relativeCoordinateFromOffset(label, getParentPointList(label), ref, offset); + } + + /** + * Calculates the relative coordinate that is equivalent to the offset from the reference + * point, that can be used to set the label location. + * + * @param label + * the <code>IFigure</code> to calculate the relative coordinate for + * @param points + * the <code>PointList</code> that contains that the label offset is relative to. + * @param ref + * a <code>Point</code> located on the parent which the offset value + * is relative to. + * @param offset + * a <code>Point</code> which represents a value offset from the <code>ref</code> point oriented based on the nearest line segment. + * @return a <code>Point</code> that is the relative coordinate of the label that can be + * used to set it's location. + */ + static private Point relativeCoordinateFromOffset(IFigure label, PointList points, Point ref, Point offset) { + Point location = calculatePointRelativeToPointOnLine(points, ref, offset); + int dx = 0; + int dy = 0; + + // switch (textAlignment) { + // case PositionConstants.LEFT: + // dx = 0; + // break; + // case PositionConstants.RIGHT: + // dx = -label.getBounds().width; + // break; + // case PositionConstants.MIDDLE: + // dx = -1 * label.getBounds().width / 2; + // break; + // default: + // dx = label.getBounds().width / 2; + // break; + // } + dx = -1 * label.getBounds().width / 2; + dy = -1 * label.getBounds().height / 2; + location.translate(dx, dy); + + return location; + } + + /** + * gets the point list using the passed figure to get the parent + * + * @param label + * the <code>IFigure</code> to use to retrieve the parent points + * @return List of points + */ + static public PointList getParentPointList(IFigure label) { + IFigure parent = label.getParent(); + if (parent instanceof Connection) { + return ((Connection) parent).getPoints(); + } else { + PointList ptList = new PointList(); + ptList.addPoint(parent.getBounds().getLocation()); + return ptList; + } + } + + /** + * Returns a point located relative to the line by the given offset. + * + * @param ptLst + * the point + * @param ptOnLine + * @param offset + * @return the relative point given the line angle + */ + protected static Point calculatePointRelativeToPointOnLine(PointList ptLst, Point ptOnLine, Point offset) { + // Calculate slope of line + if (ptLst.size() == 1) { + // This is a node... + return ptLst.getFirstPoint().getTranslated(offset); + } else if (ptLst.size() >= 2) { + // This is a edge... + int index = PointListUtilities.findNearestLineSegIndexOfPoint(ptLst, ptOnLine); + if (index < 1) { + return ptLst.getFirstPoint().getTranslated(offset); + } + LineSeg segment = (LineSeg) PointListUtilities.getLineSegments(ptLst).get(index - 1); + Point relativeOffset = null; + if (segment != null) { + if (segment.isHorizontal()) { + if (segment.getOrigin().x > segment.getTerminus().x) { + relativeOffset = ptOnLine.getTranslated(offset.getNegated()); + // System.out.println("1. Relative offset: " + relativeOffset);//$NON-NLS-1$ + return relativeOffset; + } else { + relativeOffset = ptOnLine.getTranslated(offset); + // System.out.println("2. Relative offset: " + relativeOffset);//$NON-NLS-1$ + return relativeOffset; + } + } else if (segment.isVertical()) { + if (segment.getOrigin().y > segment.getTerminus().y) { + relativeOffset = ptOnLine.getTranslated(offset.getCopy().scale(-1, 1).transpose()); + // System.out.println("3. Relative offset: " + relativeOffset);//$NON-NLS-1$ + return relativeOffset; + } else { + relativeOffset = ptOnLine.getTranslated(offset.getCopy().scale(1, -1).transpose()); + // System.out.println("4. Relative offset: " + relativeOffset);//$NON-NLS-1$ + return relativeOffset; + } + } else { + double slope = segment.slope(); + double theta = Math.atan(slope); + Point normalizedOffset = new Point(offset); + Point calculatedOffset = new Point(); + if (segment.getOrigin().x > segment.getTerminus().x) { + normalizedOffset = offset.getCopy().scale(-1, -1); + } + + calculatedOffset = new Point(normalizedOffset.x + * Math.cos(theta) - normalizedOffset.y + * Math.sin(theta), normalizedOffset.x * Math.sin(theta) + + normalizedOffset.y * Math.cos(theta)); + relativeOffset = ptOnLine.getTranslated(calculatedOffset); + // System.out.println("5. Relative offset: " + relativeOffset);//$NON-NLS-1$ + return relativeOffset; + } + } + } + return null; + } + + /** + * Calculates the normalized offset from a point on a <code>Connection</code>'s point list to an point. + * + * @param ptLst + * @param ptOnLine + * @param offset + * @return the normalized offset + */ + private static Point normalizeRelativePointToPointOnLine(PointList ptLst, Point ptOnLine, Point offset) { + // Calculate slope of line + if (ptLst.size() == 1) { + // This is a node... + return offset; + } else if (ptLst.size() >= 2) { + // This is a edge... + int index = PointListUtilities.findNearestLineSegIndexOfPoint(ptLst, ptOnLine); + LineSeg segment = (LineSeg) PointListUtilities.getLineSegments(ptLst).get(index - 1); + Point normalOffset = null; + if (segment != null) { + if (segment.isHorizontal()) { + if (segment.getOrigin().x > segment.getTerminus().x) { + normalOffset = offset.getNegated(); + //System.out.println("1. Normal offset: " + normalOffset);//$NON-NLS-1$ + return normalOffset; + } else { + normalOffset = offset; + //System.out.println("2. Normal offset: " + normalOffset);//$NON-NLS-1$ + return normalOffset; + } + } else if (segment.isVertical()) { + if (segment.getOrigin().y < segment.getTerminus().y) { + normalOffset = offset.scale(-1, 1).transpose(); + //System.out.println("3. Normal offset: " + normalOffset);//$NON-NLS-1$ + return normalOffset; + } else { + normalOffset = offset.scale(1, -1).transpose(); + //System.out.println("4. Normal offset: " + normalOffset);//$NON-NLS-1$ + return normalOffset; + } + } else { + Point p = ptOnLine.getTranslated(offset); + normalOffset = getOrthogonalDistances(segment, ptOnLine, p); + //System.out.println("5. Normal offset: " + normalOffset);//$NON-NLS-1$ + return normalOffset; + } + } + } + return null; + + } + + /** + * Calculates distances from a <code>Point</code> on a <code>LineSeg</code> to + * another <code>Point</code>. The sign of the distances indicate direction. + * + * @param lineSeg + * @param ptOnLine + * @param refPoint + * @return the distance from <code>Point</code> on a <code>LineSeg</code> to another <code>Point</code> + */ + private static Point getOrthogonalDistances(LineSeg lineSeg, Point ptOnLine, Point refPoint) { + LineSeg parallelSeg = lineSeg.getParallelLineSegThroughPoint(refPoint); + Point p1 = parallelSeg.perpIntersect(ptOnLine.x, ptOnLine.y); + double dx = p1.getDistance(refPoint) * ((p1.x > refPoint.x) ? -1 : 1); + double dy = p1.getDistance(ptOnLine) * ((p1.y < ptOnLine.y) ? -1 : 1); + Point orth = new Point(dx, dy); + // Reflection in the y axis + if (lineSeg.getOrigin().x > lineSeg.getTerminus().x) { + orth = orth.scale(-1, -1); + } + return orth; + } +} |