| /****************************************************************************** |
| * Copyright (c) 2006, 2008 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.internal.routers; |
| |
| import java.util.Collections; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.ListIterator; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.WeakHashMap; |
| |
| import org.eclipse.draw2d.Bendpoint; |
| import org.eclipse.draw2d.Connection; |
| import org.eclipse.draw2d.ConnectionAnchor; |
| import org.eclipse.draw2d.FigureUtilities; |
| import org.eclipse.draw2d.IFigure; |
| import org.eclipse.draw2d.ShortestPathConnectionRouter; |
| import org.eclipse.draw2d.XYLayout; |
| import org.eclipse.draw2d.geometry.Dimension; |
| import org.eclipse.draw2d.geometry.Point; |
| import org.eclipse.draw2d.geometry.PointList; |
| import org.eclipse.draw2d.geometry.PrecisionPoint; |
| import org.eclipse.draw2d.geometry.Ray; |
| import org.eclipse.draw2d.geometry.Rectangle; |
| import org.eclipse.gmf.runtime.draw2d.ui.figures.PolylineConnectionEx; |
| import org.eclipse.gmf.runtime.draw2d.ui.geometry.PointListUtilities; |
| import org.eclipse.gmf.runtime.draw2d.ui.mapmode.MapModeUtil; |
| |
| /** |
| * Manager class which determines which shortest path connection router to use |
| * for a given <code>Connection</code>. |
| * |
| * @author sshaw |
| * |
| */ |
| |
| class RouterHelper { |
| |
| static private RouterHelper sprm = new RouterHelper(true); |
| |
| /** |
| * @return the <code>RouterHelper</code> singleton instance |
| */ |
| static public RouterHelper getInstance() { |
| return sprm; |
| } |
| |
| private boolean useGEFRouter = true; |
| |
| private RouterHelper(boolean useGEFRouter) { |
| super(); |
| this.useGEFRouter = useGEFRouter; |
| } |
| |
| protected boolean getUseGEFRouter() { |
| return useGEFRouter; |
| } |
| /*************************************************************************** |
| * Following section is supporting useGEFRouter = true option |
| ***************************************************************************/ |
| |
| // if useGEFRouter = true, holds one router for each container that has at least |
| // one connection with avoid obstacles on |
| private Map<IFigure, ShortestPathConnectionRouter> routers = new WeakHashMap<IFigure, ShortestPathConnectionRouter>(); |
| |
| // if useGEFRouter = true, keeps track of the last GEF router used |
| // for routing each connection with avoid obstacles on |
| private Map<Connection, ShortestPathConnectionRouter> lastUsedRouter = new WeakHashMap<Connection, ShortestPathConnectionRouter>(); |
| |
| /** |
| * Added to support GEF's router. |
| */ |
| public void setConstraint(Connection conn, Object constraint) { |
| if (useGEFRouter && isAvoidingObstructions(conn)) { |
| ShortestPathConnectionRouter spcr = getConnRouter(conn, false); |
| if (spcr != null) { |
| setConstraint(spcr, conn, constraint); |
| } |
| } |
| } |
| |
| /** |
| * Sets constraint for GEF router. |
| * |
| * @param spcr |
| * GEF router |
| * @param conn |
| * <code>Connection</code> whose constraint is being set |
| * @param constraint |
| * New constraint |
| */ |
| public void setConstraint(ShortestPathConnectionRouter spcr, |
| Connection conn, Object constraint) { |
| spcr.setConstraint(conn, null); |
| } |
| |
| /** |
| * Added to support GEF's router. |
| * |
| * @param conn |
| * the <code>Connection</code> to be removed from GEF's router, |
| * if applicable. |
| */ |
| public void remove(Connection conn) { |
| if (useGEFRouter && isAvoidingObstructions(conn)) { |
| ShortestPathConnectionRouter spcr = getConnRouter(conn, false); |
| if (spcr != null) { |
| cleanUpAvoidObstaclesRouter(spcr, conn); |
| } |
| } |
| } |
| |
| /** |
| * Removes conn from router and cleans up routers and lastUSedRouter appropriately |
| */ |
| private void cleanUpAvoidObstaclesRouter(ShortestPathConnectionRouter router, Connection conn) { |
| if (router != null) { |
| router.remove(conn); |
| if (!router.hasMoreConnections()) { |
| routers.remove(router.getContainer()); |
| } |
| lastUsedRouter.remove(conn); |
| } |
| } |
| |
| /** |
| * Added to support GEF's router. |
| * |
| * @param conn |
| * the <code>Connection</code> to be potentially invalidated. |
| */ |
| public void invalidate(Connection conn) { |
| if (useGEFRouter && isAvoidingObstructions(conn)) { |
| ShortestPathConnectionRouter spcr = getConnRouter(conn, false); |
| if (spcr != null) { |
| spcr.invalidate(conn); |
| } |
| } |
| } |
| |
| /** |
| * Retrieves GEF's router for given figContainer |
| * @param figContainer |
| * @param createNew If true, new router will be created if one doesn't already exist |
| * @return |
| */ |
| private ShortestPathConnectionRouter getRouter(IFigure figContainer, boolean createNew) { |
| ShortestPathConnectionRouter shortestPathRouter = routers.get(figContainer); |
| if (shortestPathRouter == null && createNew) { |
| shortestPathRouter = new ShortestPathConnectionRouter(figContainer); |
| shortestPathRouter.setSpacing(MapModeUtil.getMapMode(figContainer) |
| .DPtoLP(10)); |
| routers.put(figContainer, shortestPathRouter); |
| } |
| |
| return shortestPathRouter; |
| } |
| |
| /** |
| * Retrieves GEF's router for routing conn, if both source and target of the connection |
| * belong to the same container. |
| * @param conn the <code>Connection</code> whose router is to be retrieved. |
| * @param forRouting Indicates if this call is made in order to route the connection. |
| * is no router for conn. If yes, and there is no apporpriate router for this connection, then new |
| * router will be created. |
| * @return the router to use for routing conn |
| */ |
| protected ShortestPathConnectionRouter getConnRouter(Connection conn, boolean forRouting) { |
| ShortestPathConnectionRouter lur = lastUsedRouter.get(conn); |
| // First, get the container for this connection |
| // Rule: both source and target figures have to belong to the same container. |
| IFigure container = null; |
| IFigure sourcefigContainer = getSourceContainer(conn); |
| IFigure targetfigContainer = getTargetContainer(conn); |
| if (sourcefigContainer == null || targetfigContainer == null ) { |
| // this may happen when source or target anchors are being moved outside of all figures, |
| // or if source or target of conn is another connection |
| if (lur != null) { |
| // Route using the last router, if any, otherwise don't route using GEF |
| return lur; |
| } else { |
| container = null; |
| } |
| } else if (sourcefigContainer != targetfigContainer) { |
| container = null; |
| } else { |
| container = sourcefigContainer; |
| } |
| |
| if (container == null) { |
| // conn spans between two different containers in which case we don't support |
| // avoid obstacles. If there was a router for this connection (conn used to belong |
| // to one container), remove it from previous router. |
| if (lur != null) { |
| cleanUpAvoidObstaclesRouter(lur, conn); |
| } |
| return null; |
| } |
| ShortestPathConnectionRouter spcr = getRouter(container, forRouting); |
| |
| if (spcr != null && forRouting) { |
| if (lur != spcr) { |
| if (lur != null) { |
| // conn changed container. Remove it from previous router. |
| cleanUpAvoidObstaclesRouter(lur, conn); |
| } |
| lastUsedRouter.put(conn, spcr); |
| } |
| } |
| return spcr; |
| } |
| |
| |
| /*************************************************************************** |
| * end of section supporting useGEFRouter = true option |
| ***************************************************************************/ |
| |
| |
| |
| /** |
| * @param conn the <code>Connection</code> that is to be check if it is a feedback |
| * connection or not. |
| * @return <code>true</code> is it is a feedback connection, <code>false</code> otherwise. |
| */ |
| public boolean isFeedback(Connection conn) { |
| Dimension dim = new Dimension(100, 100); |
| Dimension dimCheck = dim.getCopy(); |
| conn.translateToRelative(dimCheck); |
| return dim.equals(dimCheck); |
| } |
| |
| /** |
| * @param conn the <code>Connection</code> that is to be routed. |
| * @return the <code>PointList</code> that is the list of points that are |
| * a direct mapping of the constraint points. |
| */ |
| public PointList routeFromConstraint(Connection conn) { |
| if (useGEFRouter && lastUsedRouter.get(conn) != null) { |
| // User just unselected Avoid obstacles options for this connection, clean up. |
| cleanUpAvoidObstaclesRouter(lastUsedRouter.get(conn), conn); |
| } |
| List bendpoints = (List)conn.getConnectionRouter().getConstraint(conn); |
| if (bendpoints == null) |
| bendpoints = Collections.EMPTY_LIST; |
| |
| PointList points = new PointList(bendpoints.size()); |
| |
| for (int i = 0; i < bendpoints.size(); i++) { |
| Bendpoint bp = (Bendpoint) bendpoints.get(i); |
| points.addPoint(bp.getLocation()); |
| } |
| |
| if (bendpoints.size() == 0) { |
| Point r1 = conn.getSourceAnchor().getReferencePoint().getCopy(); |
| conn.translateToRelative(r1); |
| points.addPoint(r1); |
| |
| Point r2 = conn.getTargetAnchor().getReferencePoint().getCopy(); |
| conn.translateToRelative(r2); |
| points.addPoint(r2); |
| } |
| |
| return points; |
| } |
| |
| /** |
| * @param conn the <code>Connection</code> that is to be routed. |
| * @return the <code>PointList</code> that is the list of points that represent |
| * the closest distance possible to route the line. |
| */ |
| public PointList routeClosestDistance(Connection conn) { |
| if (useGEFRouter && lastUsedRouter.get(conn) != null) { |
| // User just unselected Avoid obstacles options for this connection, clean up. |
| cleanUpAvoidObstaclesRouter(lastUsedRouter.get(conn), conn); |
| } |
| PointList newLine = routeFromConstraint(conn); |
| |
| Point ptOrig = new Point(newLine.getFirstPoint()); |
| Point ptTerm = new Point(newLine.getLastPoint()); |
| |
| newLine.removeAllPoints(); |
| newLine.addPoint(ptOrig); |
| newLine.addPoint(ptTerm); |
| |
| return newLine; |
| } |
| |
| /** |
| * @param conn |
| * the <code>Connection</code> that is to be routed. |
| * @return the <code>PointList</code> that is the list of points that are |
| * avoiding all the possible obstructions in the container for the |
| * connection. |
| */ |
| public PointList routeAroundObstructions(Connection conn) { |
| PointList newLine = null; |
| newLine = routeClosestDistance(conn); |
| |
| Point infimumPoint = PointListUtilities.getPointsInfimum(newLine); |
| Point supremumPoint = PointListUtilities.getPointsSupremum(newLine); |
| |
| Ray diameter = new Ray(infimumPoint, supremumPoint); |
| Rectangle rPoly = new Rectangle(infimumPoint.x, infimumPoint.y, |
| diameter.x, diameter.y); |
| |
| List collectObstructs = new LinkedList(); |
| |
| IFigure parent = getRouterContainerFigure(conn); |
| |
| // don't bother routing if there is no attachments |
| if (parent == null) |
| return routeFromConstraint(conn); |
| |
| // set the end points back to the reference points - this will avoid |
| // errors, where |
| // an edge point is erroneously aligned with a specific edge, even |
| // though the avoid |
| // obstructions would suggest attachment to another edge is more |
| // appropriate |
| Point ptRef = conn.getSourceAnchor().getReferencePoint(); |
| conn.translateToRelative(ptRef); |
| newLine.setPoint(ptRef, 0); |
| ptRef = conn.getTargetAnchor().getReferencePoint(); |
| conn.translateToRelative(ptRef); |
| newLine.setPoint(ptRef, newLine.size() - 1); |
| |
| // TBD - optimize this |
| // increase connect view rect by width or height of diagram |
| // to maximize views included in the obstruction calculation |
| // without including all views in the diagram |
| Rectangle rBoundingRect = new Rectangle(parent.getBounds()); |
| parent.translateToAbsolute(rBoundingRect); |
| conn.translateToRelative(rBoundingRect); |
| |
| if (rPoly.width > rPoly.height) { |
| rPoly.y = rBoundingRect.y; |
| rPoly.setSize(rPoly.width, rBoundingRect.height); |
| } else { |
| rPoly.x = rBoundingRect.x; |
| rPoly.setSize(rBoundingRect.width, rPoly.height); |
| } |
| |
| collectObstructions(conn, rPoly, collectObstructs); |
| |
| // parse through obstruction collect and combine rectangle that |
| // intersect with each other |
| if (collectObstructs.size() > 0) { |
| Dimension buffer = new Dimension(ROUTER_OBSTRUCTION_BUFFER + 1, 0); |
| if (!isFeedback(conn)) |
| buffer = (Dimension) MapModeUtil.getMapMode(conn) |
| .DPtoLP(buffer); |
| final int inflate = buffer.width; |
| |
| List collapsedRects = collapseRects(collectObstructs, inflate); |
| collectObstructs.clear(); |
| |
| // Loop through the collapsedRects list until there are no more |
| // intersections |
| boolean bRouted = true; |
| while (bRouted && !collapsedRects.isEmpty()) { |
| ListIterator listIter = collapsedRects.listIterator(); |
| bRouted = false; |
| |
| while (listIter.hasNext()) { |
| Rectangle rObstruct = (Rectangle) listIter.next(); |
| PointList routedPoly = PointListUtilities.routeAroundRect( |
| newLine, rObstruct, 0, false, inflate); |
| |
| if (routedPoly != null) { |
| bRouted = true; |
| newLine.removeAllPoints(); |
| newLine.addAll(routedPoly); |
| } else |
| collectObstructs.add(rObstruct); |
| } |
| |
| List tempList = collapsedRects; |
| collapsedRects = collectObstructs; |
| tempList.clear(); |
| collectObstructs = tempList; |
| |
| if (bRouted && !collapsedRects.isEmpty()) |
| resetEndPointsToEdge(conn, newLine); |
| } |
| } |
| |
| return newLine; |
| } |
| |
| /** |
| * Finds all the children shapes of the parent figure passed in that are in |
| * the way of the connection. This method will dig into children of |
| * container shapes if one of the connection ends is also in that container. |
| * |
| * @param connection |
| * the connection being routed |
| * @param connectionRect |
| * the rectangle representing the connection bounds that is used |
| * to determine if a shape intersects with the connection |
| * @param obstructionsToReturn |
| * the list of figures that the connection should be routed |
| * around |
| */ |
| protected void collectObstructions(Connection connection, |
| Rectangle connectionRect, List obstructionsToReturn) { |
| |
| Set containerFiguresToSearch = new HashSet(); |
| Set figuresToExclude = new HashSet(); |
| |
| IFigure figure = connection.getSourceAnchor().getOwner(); |
| figuresToExclude.add(figure); |
| figure = figure.getParent(); |
| while (figure != null) { |
| if (figure.getLayoutManager() instanceof XYLayout) { |
| containerFiguresToSearch.add(figure); |
| } |
| figuresToExclude.add(figure); |
| figure = figure.getParent(); |
| } |
| |
| figure = connection.getTargetAnchor().getOwner(); |
| figuresToExclude.add(figure); |
| figure = figure.getParent(); |
| while (figure != null) { |
| if (figure.getLayoutManager() instanceof XYLayout) { |
| containerFiguresToSearch.add(figure); |
| } |
| figuresToExclude.add(figure); |
| figure = figure.getParent(); |
| } |
| |
| for (Iterator iter = containerFiguresToSearch.iterator(); iter |
| .hasNext();) { |
| IFigure containerFigure = (IFigure) iter.next(); |
| |
| for (Iterator iterator = containerFigure.getChildren().iterator(); iterator |
| .hasNext();) { |
| IFigure childFigure = (IFigure) iterator.next(); |
| |
| if (!figuresToExclude.contains(childFigure)) { |
| |
| Rectangle rObstruct = new Rectangle(childFigure.getBounds()); |
| childFigure.translateToAbsolute(rObstruct); |
| connection.translateToRelative(rObstruct); |
| |
| // inflate slightly |
| rObstruct.expand(1, 1); |
| |
| if (connectionRect.intersects(rObstruct)) { |
| obstructionsToReturn.add(rObstruct); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * @param conn |
| * the <code>Connection</code> that is to have used to |
| * determine the end points for reseting the <code>newLine</code> |
| * parameter. |
| * @param newLine |
| * the <code>PointList</code> to reset the end points of to be |
| * on the edge of the connection source and target nodes. |
| */ |
| public void resetEndPointsToEdge(Connection conn, PointList newLine) { |
| if (newLine.size() < 2) { |
| /* |
| * Connection must have at least 2 points in the list: the source |
| * and target anchor points. Otherwise it's invalid connection. |
| * Invalid connection case: add a dumb point at the start of the |
| * list and at the end of the list. The first and the last point in |
| * the list are replaced by the new source and target anchor points |
| * in this method |
| */ |
| newLine.addPoint(0, 0); |
| newLine.insertPoint(new Point(), 0); |
| } |
| |
| PrecisionPoint sourceAnchorPoint, targetAnchorPoint; |
| if (newLine.size() > 2) { |
| /* |
| * First bend point is the outside reference point for the source anchor. |
| * Last bend point is the outside reference point for the target anchor. |
| */ |
| PrecisionPoint sourceReference = new PrecisionPoint(newLine.getPoint(1)); |
| PrecisionPoint targetReference = new PrecisionPoint(newLine.getPoint(newLine.size() - 2)); |
| conn.translateToAbsolute(sourceReference); |
| conn.translateToAbsolute(targetReference); |
| sourceAnchorPoint = getAnchorLocation(conn.getSourceAnchor(), sourceReference); |
| targetAnchorPoint = getAnchorLocation(conn.getTargetAnchor(), targetReference); |
| } else { |
| /* |
| * We need to take target anchor reference point as an outside reference point |
| * for the source anchor location. The outside reference point for the target |
| * anchor would the source anchor location. |
| */ |
| PrecisionPoint sourceReference = getAnchorReference(conn.getTargetAnchor()); |
| sourceAnchorPoint = getAnchorLocation(conn.getSourceAnchor(), sourceReference); |
| targetAnchorPoint = getAnchorLocation(conn.getTargetAnchor(), sourceAnchorPoint); |
| } |
| |
| |
| conn.translateToRelative(sourceAnchorPoint); |
| conn.translateToRelative(targetAnchorPoint); |
| |
| newLine.setPoint(sourceAnchorPoint,0); |
| newLine.setPoint(targetAnchorPoint,newLine.size() - 1); |
| } |
| |
| private final static int ROUTER_OBSTRUCTION_BUFFER = 12; |
| |
| /** |
| * This method will collapse all the rectangles together that intersect in |
| * the given List. It utilizes a recursive implementation. |
| */ |
| private List collapseRects(List collectRect, int inflate) { |
| if (collectRect.size() == 0) |
| return new LinkedList(); |
| |
| Rectangle rCompare = new Rectangle((Rectangle) collectRect.remove(0)); |
| List collapsedRects = collapseRects(rCompare, collectRect, inflate); |
| collapsedRects.add(rCompare); |
| |
| return collapsedRects; |
| } |
| |
| /** |
| * Recursively called method called by collapseRects(List collectRect). |
| */ |
| private List collapseRects(Rectangle rCompare, List collectRect, int inflate) { |
| List newCollect = new LinkedList(); |
| Rectangle rCompare1 = new Rectangle(rCompare); |
| |
| // compare rectangle with each rectangle in the rest of the list |
| boolean intersectionOccurred = false; |
| ListIterator listIter = collectRect.listIterator(); |
| while (listIter.hasNext()) { |
| Rectangle rCompare2 = new Rectangle((Rectangle) listIter.next()); |
| |
| Rectangle rExpandRect1 = new Rectangle(rCompare1); |
| Rectangle rExpandRect2 = new Rectangle(rCompare2); |
| |
| // inflate the rect by the obstruction buffer for the intersection |
| // calculation so that we won't try to route through a space smaller |
| // then necessary |
| rExpandRect1.expand(inflate, inflate); |
| rExpandRect2.expand(inflate, inflate); |
| |
| if (rExpandRect1.intersects(rExpandRect2)) { |
| rCompare1.union(rCompare2); |
| intersectionOccurred = true; |
| } else { |
| newCollect.add(rCompare2); |
| } |
| } |
| |
| rCompare.setBounds(rCompare1); |
| |
| if (newCollect.size() > 0) { |
| if (intersectionOccurred) { |
| return collapseRects(rCompare, newCollect, inflate); |
| } else { |
| Rectangle rFirst = new Rectangle((Rectangle) newCollect |
| .remove(0)); |
| List finalCollapse = collapseRects(rFirst, newCollect, inflate); |
| finalCollapse.add(rFirst); |
| |
| return finalCollapse; |
| } |
| } else { |
| return newCollect; |
| } |
| } |
| |
| |
| /** |
| * @param conn |
| * @return |
| */ |
| private IFigure getRouterContainerFigure(Connection conn) { |
| IFigure sourcefigContainer = getSourceContainer(conn); |
| IFigure targetfigContainer = getTargetContainer(conn); |
| IFigure commonFig = FigureUtilities.findCommonAncestor( |
| sourcefigContainer, targetfigContainer); |
| |
| IFigure routerContainer = null; |
| |
| if (sourcefigContainer == null || targetfigContainer == null) |
| return null; |
| |
| if (sourcefigContainer == targetfigContainer) { |
| routerContainer = sourcefigContainer; |
| } else if (commonFig != sourcefigContainer |
| && commonFig != targetfigContainer) { |
| routerContainer = commonFig; |
| } else { |
| // find the end that isn't the common ancestor and use it's bounds |
| // to find |
| // the optimal end for the avoid obstructions algorithm |
| IFigure checkFig = sourcefigContainer; |
| if (commonFig == sourcefigContainer) |
| checkFig = targetfigContainer; |
| |
| // decide which end of the connection exists more in it's container |
| // relative |
| // to the other end, and use that container to determine which |
| // router to |
| // return. |
| Rectangle checkRect = checkFig.getBounds().getCopy(); |
| checkFig.translateToAbsolute(checkRect); |
| conn.translateToRelative(checkRect); |
| int sourceDistance = findDistanceToEndRect(conn.getPoints(), |
| checkRect); |
| int targetDistance = (int) PointListUtilities.getPointsLength(conn |
| .getPoints()) |
| - sourceDistance; |
| |
| if (sourceDistance > targetDistance) |
| routerContainer = sourcefigContainer; |
| else |
| routerContainer = targetfigContainer; |
| } |
| |
| return routerContainer; |
| } |
| |
| |
| protected IFigure getSourceContainer(Connection conn) { |
| if (conn.getSourceAnchor() != null) |
| return findContainerFigure(conn.getSourceAnchor().getOwner()); |
| |
| return null; |
| } |
| |
| protected IFigure getTargetContainer(Connection conn) { |
| if (conn.getTargetAnchor() != null) |
| return findContainerFigure(conn.getTargetAnchor().getOwner()); |
| |
| return null; |
| } |
| |
| /** |
| * findContainerFigure Recursive method to find the figure that owns the |
| * children the connection is connecting to. |
| * |
| * @param fig |
| * IFigure to find the shape container figure parent of. |
| * @return Container figure |
| */ |
| private IFigure findContainerFigure(IFigure fig) { |
| if (fig == null) |
| return null; |
| |
| if (fig.getLayoutManager() instanceof XYLayout) |
| return fig; |
| |
| return findContainerFigure(fig.getParent()); |
| } |
| |
| private int findDistanceToEndRect(PointList points, Rectangle endRect) { |
| PointList intersections = new PointList(); |
| PointList distances = new PointList(); |
| boolean foundSourceDistance = PointListUtilities.findIntersections( |
| points, PointListUtilities.createPointsFromRect(endRect), |
| intersections, distances); |
| |
| int sourceDistance = foundSourceDistance ? distances.getFirstPoint().x |
| : 0; |
| return sourceDistance; |
| } |
| |
| |
| /** |
| * Returns anchor location as <code>PrecisionPoint</code> |
| * |
| * @param anchor connection anchor object |
| * @param reference outside reference point |
| * @return <code>PrecisionPoint</code> for anchor location |
| */ |
| private PrecisionPoint getAnchorLocation(ConnectionAnchor anchor, Point reference) { |
| return new PrecisionPoint(anchor.getLocation(reference)); |
| } |
| |
| /** |
| * Returns anchor reference point as <code>PrecisionPoint</code> |
| * |
| * @param anchor connection anchor object |
| * @return <code>PrecisionPoint</code> for anchor reference |
| */ |
| private PrecisionPoint getAnchorReference(ConnectionAnchor anchor) { |
| return new PrecisionPoint(anchor.getReferencePoint()); |
| } |
| |
| /** |
| * Determines whether the router is going to avoid obstructions during the |
| * routing algorithm. |
| */ |
| public boolean isAvoidingObstructions(Connection conn) { |
| if (conn instanceof PolylineConnectionEx) { |
| return ((PolylineConnectionEx) conn).isAvoidObstacleRouting(); |
| } |
| |
| return false; |
| } |
| |
| |
| } |