blob: 9e807ed40288ac03036a77d84a81538362bcf37d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2012 Red Hat, Inc.
* All rights reserved.
* This program is 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:
* Red Hat, Inc. - initial API and implementation
*
* @author Bob Brodt
******************************************************************************/
package org.eclipse.bpmn2.modeler.core.features;
import org.eclipse.bpmn2.BoundaryEvent;
import org.eclipse.bpmn2.modeler.core.di.DIUtils;
import org.eclipse.bpmn2.modeler.core.utils.AnchorSite;
import org.eclipse.bpmn2.modeler.core.utils.AnchorType;
import org.eclipse.bpmn2.modeler.core.utils.AnchorUtil;
import org.eclipse.bpmn2.modeler.core.utils.BoundaryEventPositionHelper;
import org.eclipse.bpmn2.modeler.core.utils.BoundaryEventPositionHelper.PositionOnLine;
import org.eclipse.bpmn2.modeler.core.utils.BusinessObjectUtil;
import org.eclipse.bpmn2.modeler.core.utils.GraphicsUtil;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.graphiti.datatypes.IDimension;
import org.eclipse.graphiti.datatypes.ILocation;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.mm.algorithms.styles.Point;
import org.eclipse.graphiti.mm.pictograms.Connection;
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
import org.eclipse.graphiti.mm.pictograms.FixPointAnchor;
import org.eclipse.graphiti.mm.pictograms.FreeFormConnection;
import org.eclipse.graphiti.mm.pictograms.Shape;
import org.eclipse.graphiti.services.Graphiti;
/**
* Router for connections that can have user-settable bendpoints.
*/
public class BendpointConnectionRouter extends DefaultConnectionRouter {
/** The connection, must be a {@code FreeFormConnection}. */
protected FreeFormConnection ffc;
/** The moved or added bendpoint (if any). */
protected Point movedBendpoint;
/** The removed bendpoint. */
protected Point removedBendpoint;
/** The list of old connection cuts (including the end cuts) for determining if a route has changed */
protected Point oldPoints[];
/** The list of allowable source shape edges which can serve as sites (top, left, bottom or right) */
AnchorSite sourceAnchorSites[];
/** The list of allowable target shape edges which can serve as sites */
AnchorSite targetAnchorSites[];
/**
* Instantiates a new bendpoint connection router.
*
* @param fp the Feature Provider
*/
public BendpointConnectionRouter(IFeatureProvider fp) {
super(fp);
}
/* (non-Javadoc)
* @see org.eclipse.bpmn2.modeler.core.features.IConnectionRouter#canRoute(org.eclipse.graphiti.mm.pictograms.Connection)
*/
@Override
public boolean canRoute(Connection connection) {
return super.canRoute(connection) && connection instanceof FreeFormConnection;
}
/* (non-Javadoc)
* @see org.eclipse.bpmn2.modeler.core.features.DefaultConnectionRouter#initialize(org.eclipse.graphiti.mm.pictograms.Connection)
*/
@Override
protected void initialize(Connection connection) {
// check if initialization needed?
if (oldPoints==null) {
super.initialize(connection);
ffc = (FreeFormConnection)connection;
movedBendpoint = getMovedBendpoint(ffc);
if (movedBendpoint==null)
movedBendpoint = getAddedBendpoint(ffc);
removedBendpoint = getRemovedBendpoint(ffc);
findAllShapes();
if (movedBendpoint!=null) {
for (ContainerShape shape : allShapes) {
if (GraphicsUtil.contains(shape, movedBendpoint)) {
movedBendpoint = null;
break;
}
}
}
/**
* Save the connection's start/end anchors, and their locations as well as
* the bendpoints. This is used to compare against the new ConnectionRoute
*/
oldPoints = new Point[ffc.getBendpoints().size() + 2];
int i = 0;
oldPoints[i++] = GraphicsUtil.createPoint(ffc.getStart());
for (Point p : ffc.getBendpoints()) {
oldPoints[i++] = GraphicsUtil.createPoint(p);
}
oldPoints[i++] = GraphicsUtil.createPoint(ffc.getEnd());
calculateAllowedAnchorSites();
}
}
/* (non-Javadoc)
* @see org.eclipse.bpmn2.modeler.core.features.DefaultConnectionRouter#route(org.eclipse.graphiti.mm.pictograms.Connection)
*/
@Override
public boolean route(Connection connection) {
initialize(connection);
boolean changed = false;
if (connection instanceof FreeFormConnection) {
ConnectionRoute route = calculateRoute();
if (route!=null) {
changed = isRouteChanged(route);
applyRoute(route);
}
dispose();
}
return changed;
}
/**
*
*/
protected void calculateAllowedAnchorSites() {
EObject bo = BusinessObjectUtil.getBusinessObjectForPictogramElement(source);
if (bo instanceof BoundaryEvent) {
sourceAnchorSites = calculateBoundaryEventAnchorSites(source);
}
bo = BusinessObjectUtil.getBusinessObjectForPictogramElement(target);
if (bo instanceof BoundaryEvent) {
targetAnchorSites = calculateBoundaryEventAnchorSites(target);
}
if (AnchorType.getType(source) == AnchorType.CONNECTION) {
sourceAnchorSites = new AnchorSite[1];
sourceAnchorSites[0] = AnchorSite.CENTER;
}
if (AnchorType.getType(target) == AnchorType.CONNECTION) {
targetAnchorSites = new AnchorSite[1];
targetAnchorSites[0] = AnchorSite.CENTER;
}
ILocation sPos = Graphiti.getPeService().getLocationRelativeToDiagram(source);
IDimension sSize = GraphicsUtil.calculateSize(source);
ILocation tPos = Graphiti.getPeService().getLocationRelativeToDiagram(target);
IDimension tSize = GraphicsUtil.calculateSize(target);
if (movedBendpoint!=null) {
Point sc = GraphicsUtil.getShapeCenter(source);
Point tc = GraphicsUtil.getShapeCenter(target);
double ds = GraphicsUtil.getLength(movedBendpoint, sc);
double dt = GraphicsUtil.getLength(movedBendpoint, tc);
boolean expandSourceSites = ds > 2*dt;
boolean expandTargetSites = dt > 2*ds;
if (sourceAnchorSites==null) {
if (movedBendpoint.getX() < sPos.getX()) {
// bendpoint is left of shape
if (movedBendpoint.getY() < sPos.getY()) {
// bendpoint is above shape
sourceAnchorSites = new AnchorSite[2];
sourceAnchorSites[0] = AnchorSite.LEFT;
sourceAnchorSites[1] = AnchorSite.TOP;
}
else if (sPos.getY()+sSize.getHeight() < movedBendpoint.getY()) {
// bendpoint is below shape
sourceAnchorSites = new AnchorSite[2];
sourceAnchorSites[0] = AnchorSite.LEFT;
sourceAnchorSites[1] = AnchorSite.BOTTOM;
}
else {
// bendpoint is directly left of shape
if (expandSourceSites) {
sourceAnchorSites = new AnchorSite[3];
sourceAnchorSites[0] = AnchorSite.LEFT;
sourceAnchorSites[1] = AnchorSite.TOP;
sourceAnchorSites[2] = AnchorSite.BOTTOM;
}
else {
sourceAnchorSites = new AnchorSite[1];
sourceAnchorSites[0] = AnchorSite.LEFT;
}
}
}
else if (sPos.getX()+sSize.getWidth() < movedBendpoint.getX()) {
// bendpoint is right of shape
if (movedBendpoint.getY() < sPos.getY()) {
// bendpoint is above shape
sourceAnchorSites = new AnchorSite[2];
sourceAnchorSites[0] = AnchorSite.RIGHT;
sourceAnchorSites[1] = AnchorSite.TOP;
}
else if (sPos.getY()+sSize.getHeight() < movedBendpoint.getY()) {
// bendpoint is below shape
sourceAnchorSites = new AnchorSite[2];
sourceAnchorSites[0] = AnchorSite.RIGHT;
sourceAnchorSites[1] = AnchorSite.BOTTOM;
}
else {
// bendpoint is directly right of shape
if (expandSourceSites) {
sourceAnchorSites = new AnchorSite[3];
sourceAnchorSites[0] = AnchorSite.RIGHT;
sourceAnchorSites[1] = AnchorSite.TOP;
sourceAnchorSites[2] = AnchorSite.BOTTOM;
}
else {
sourceAnchorSites = new AnchorSite[1];
sourceAnchorSites[0] = AnchorSite.RIGHT;
}
}
}
else {
// bendpoint is directly above or below shape
if (movedBendpoint.getY() < sPos.getY()) {
// bendpoint is above shape
if (expandSourceSites) {
sourceAnchorSites = new AnchorSite[3];
sourceAnchorSites[0] = AnchorSite.TOP;
sourceAnchorSites[1] = AnchorSite.LEFT;
sourceAnchorSites[2] = AnchorSite.RIGHT;
}
else {
sourceAnchorSites = new AnchorSite[1];
sourceAnchorSites[0] = AnchorSite.TOP;
}
}
else if (sPos.getY()+sSize.getHeight() < movedBendpoint.getY()) {
// bendpoint is below shape
if (expandSourceSites) {
sourceAnchorSites = new AnchorSite[3];
sourceAnchorSites[0] = AnchorSite.BOTTOM;
sourceAnchorSites[1] = AnchorSite.LEFT;
sourceAnchorSites[2] = AnchorSite.RIGHT;
}
else {
sourceAnchorSites = new AnchorSite[1];
sourceAnchorSites[0] = AnchorSite.BOTTOM;
}
}
else {
// bendpoint is inside shape
sourceAnchorSites = new AnchorSite[0];
}
}
}
if (targetAnchorSites==null) {
if (movedBendpoint.getX() < tPos.getX()) {
// bendpoint is left of shape
if (movedBendpoint.getY() < tPos.getY()) {
// bendpoint is above shape
targetAnchorSites = new AnchorSite[2];
targetAnchorSites[0] = AnchorSite.LEFT;
targetAnchorSites[1] = AnchorSite.TOP;
}
else if (tPos.getY()+tSize.getHeight() < movedBendpoint.getY()) {
// bendpoint is below shape
targetAnchorSites = new AnchorSite[2];
targetAnchorSites[0] = AnchorSite.LEFT;
targetAnchorSites[1] = AnchorSite.BOTTOM;
}
else {
// bendpoint is directly left of shape
if (expandTargetSites) {
targetAnchorSites = new AnchorSite[3];
targetAnchorSites[0] = AnchorSite.LEFT;
targetAnchorSites[1] = AnchorSite.TOP;
targetAnchorSites[2] = AnchorSite.BOTTOM;
}
else {
targetAnchorSites = new AnchorSite[1];
targetAnchorSites[0] = AnchorSite.LEFT;
}
}
}
else if (tPos.getX()+tSize.getWidth() < movedBendpoint.getX()) {
// bendpoint is right of shape
if (movedBendpoint.getY() < tPos.getY()) {
// bendpoint is above shape
targetAnchorSites = new AnchorSite[2];
targetAnchorSites[0] = AnchorSite.RIGHT;
targetAnchorSites[1] = AnchorSite.TOP;
}
else if (tPos.getY()+tSize.getHeight() < movedBendpoint.getY()) {
// bendpoint is below shape
targetAnchorSites = new AnchorSite[2];
targetAnchorSites[0] = AnchorSite.RIGHT;
targetAnchorSites[1] = AnchorSite.BOTTOM;
}
else {
// bendpoint is directly right of shape
if (expandTargetSites) {
targetAnchorSites = new AnchorSite[3];
targetAnchorSites[0] = AnchorSite.RIGHT;
targetAnchorSites[1] = AnchorSite.TOP;
targetAnchorSites[2] = AnchorSite.BOTTOM;
}
else {
targetAnchorSites = new AnchorSite[1];
targetAnchorSites[0] = AnchorSite.RIGHT;
}
}
}
else {
// bendpoint is directly above or below shape
if (movedBendpoint.getY() < tPos.getY()) {
// bendpoint is above shape
if (expandTargetSites) {
targetAnchorSites = new AnchorSite[3];
targetAnchorSites[0] = AnchorSite.TOP;
targetAnchorSites[1] = AnchorSite.LEFT;
targetAnchorSites[2] = AnchorSite.RIGHT;
}
else {
targetAnchorSites = new AnchorSite[1];
targetAnchorSites[0] = AnchorSite.TOP;
}
}
else if (tPos.getY()+tSize.getHeight() < movedBendpoint.getY()) {
// bendpoint is below shape
if (expandTargetSites) {
targetAnchorSites = new AnchorSite[3];
targetAnchorSites[0] = AnchorSite.BOTTOM;
targetAnchorSites[1] = AnchorSite.LEFT;
targetAnchorSites[2] = AnchorSite.RIGHT;
}
else {
targetAnchorSites = new AnchorSite[1];
targetAnchorSites[0] = AnchorSite.BOTTOM;
}
}
else {
// bendpoint is inside shape
targetAnchorSites = new AnchorSite[0];
}
}
}
return;
}
// find relative locations
if (sPos.getX()+sSize.getWidth() < tPos.getX()) {
// source shape is to left of target
if (sPos.getY()+sSize.getHeight() < tPos.getY()) {
// source shape is to left and above target:
// omit the two opposite sides of both source and target
if (sourceAnchorSites==null) {
sourceAnchorSites = new AnchorSite[2];
sourceAnchorSites[0] = AnchorSite.RIGHT;
sourceAnchorSites[1] = AnchorSite.BOTTOM;
}
if (targetAnchorSites==null) {
targetAnchorSites = new AnchorSite[2];
targetAnchorSites[0] = AnchorSite.LEFT;
targetAnchorSites[1] = AnchorSite.TOP;
}
}
else if(sPos.getY() > tPos.getY()+tSize.getHeight()) {
// source shape is to left and below target
if (sourceAnchorSites==null) {
sourceAnchorSites = new AnchorSite[2];
sourceAnchorSites[0] = AnchorSite.RIGHT;
sourceAnchorSites[1] = AnchorSite.TOP;
}
if (targetAnchorSites==null) {
targetAnchorSites = new AnchorSite[2];
targetAnchorSites[0] = AnchorSite.LEFT;
targetAnchorSites[1] = AnchorSite.BOTTOM;
}
}
else {
if (sourceAnchorSites==null) {
sourceAnchorSites = new AnchorSite[3];
sourceAnchorSites[0] = AnchorSite.RIGHT;
sourceAnchorSites[1] = AnchorSite.TOP;
sourceAnchorSites[2] = AnchorSite.BOTTOM;
}
if (targetAnchorSites==null) {
targetAnchorSites = new AnchorSite[3];
targetAnchorSites[0] = AnchorSite.LEFT;
targetAnchorSites[1] = AnchorSite.TOP;
targetAnchorSites[2] = AnchorSite.BOTTOM;
}
}
}
else if (sPos.getX() > tPos.getX()+tSize.getWidth()) {
// source shape is to right of target
if (sPos.getY()+sSize.getHeight() < tPos.getY()) {
// source shape is to right and above target
if (sourceAnchorSites==null) {
sourceAnchorSites = new AnchorSite[2];
sourceAnchorSites[0] = AnchorSite.LEFT;
sourceAnchorSites[1] = AnchorSite.BOTTOM;
}
if (targetAnchorSites==null) {
targetAnchorSites = new AnchorSite[2];
targetAnchorSites[0] = AnchorSite.RIGHT;
targetAnchorSites[1] = AnchorSite.TOP;
}
}
else if(sPos.getY() > tPos.getY()+tSize.getHeight()) {
// source shape is to right and below target
if (sourceAnchorSites==null) {
sourceAnchorSites = new AnchorSite[2];
sourceAnchorSites[0] = AnchorSite.LEFT;
sourceAnchorSites[1] = AnchorSite.TOP;
}
if (targetAnchorSites==null) {
targetAnchorSites = new AnchorSite[2];
targetAnchorSites[0] = AnchorSite.RIGHT;
targetAnchorSites[1] = AnchorSite.BOTTOM;
}
}
else {
if (sourceAnchorSites==null) {
sourceAnchorSites = new AnchorSite[3];
sourceAnchorSites[0] = AnchorSite.LEFT;
sourceAnchorSites[1] = AnchorSite.TOP;
sourceAnchorSites[2] = AnchorSite.BOTTOM;
}
if (targetAnchorSites==null) {
targetAnchorSites = new AnchorSite[3];
targetAnchorSites[0] = AnchorSite.RIGHT;
targetAnchorSites[1] = AnchorSite.TOP;
targetAnchorSites[2] = AnchorSite.BOTTOM;
}
}
}
else if (sPos.getY()+sSize.getHeight() < tPos.getY()) {
// source shape is above target
if (sourceAnchorSites==null) {
sourceAnchorSites = new AnchorSite[3];
sourceAnchorSites[0] = AnchorSite.LEFT;
sourceAnchorSites[1] = AnchorSite.RIGHT;
sourceAnchorSites[2] = AnchorSite.BOTTOM;
}
if (targetAnchorSites==null) {
targetAnchorSites = new AnchorSite[3];
targetAnchorSites[0] = AnchorSite.LEFT;
targetAnchorSites[1] = AnchorSite.RIGHT;
targetAnchorSites[2] = AnchorSite.TOP;
}
}
else if(sPos.getY() > tPos.getY()+tSize.getHeight()) {
// source shape is below target
if (sourceAnchorSites==null) {
sourceAnchorSites = new AnchorSite[3];
sourceAnchorSites[0] = AnchorSite.LEFT;
sourceAnchorSites[1] = AnchorSite.RIGHT;
sourceAnchorSites[2] = AnchorSite.TOP;
}
if (targetAnchorSites==null) {
targetAnchorSites = new AnchorSite[3];
targetAnchorSites[0] = AnchorSite.LEFT;
targetAnchorSites[1] = AnchorSite.RIGHT;
targetAnchorSites[2] = AnchorSite.BOTTOM;
}
}
else {
// source and target overlap
if (sourceAnchorSites==null) {
sourceAnchorSites = new AnchorSite[4];
sourceAnchorSites[0] = AnchorSite.LEFT;
sourceAnchorSites[1] = AnchorSite.RIGHT;
sourceAnchorSites[2] = AnchorSite.TOP;
sourceAnchorSites[3] = AnchorSite.BOTTOM;
}
if (targetAnchorSites==null) {
targetAnchorSites = new AnchorSite[4];
targetAnchorSites[0] = AnchorSite.LEFT;
targetAnchorSites[1] = AnchorSite.RIGHT;
targetAnchorSites[2] = AnchorSite.TOP;
targetAnchorSites[3] = AnchorSite.BOTTOM;
}
}
}
protected AnchorSite[] calculateBoundaryEventAnchorSites(Shape shape) {
AnchorSite sites[];
PositionOnLine pol = BoundaryEventPositionHelper.getPositionOnLineProperty(shape);
switch (pol.getLocationType()) {
case BOTTOM:
sites = new AnchorSite[1];
sites[0] = AnchorSite.BOTTOM;
break;
case BOTTOM_LEFT:
sites = new AnchorSite[2];
sites[0] = AnchorSite.BOTTOM;
sites[1] = AnchorSite.LEFT;
break;
case BOTTOM_RIGHT:
sites = new AnchorSite[2];
sites[0] = AnchorSite.BOTTOM;
sites[1] = AnchorSite.RIGHT;
break;
case LEFT:
sites = new AnchorSite[1];
sites[0] = AnchorSite.LEFT;
break;
case RIGHT:
sites = new AnchorSite[1];
sites[0] = AnchorSite.RIGHT;
break;
case TOP:
sites = new AnchorSite[1];
sites[0] = AnchorSite.TOP;
break;
case TOP_LEFT:
sites = new AnchorSite[2];
sites[0] = AnchorSite.TOP;
sites[1] = AnchorSite.LEFT;
break;
case TOP_RIGHT:
sites = new AnchorSite[2];
sites[0] = AnchorSite.TOP;
sites[1] = AnchorSite.RIGHT;
break;
default:
sites = new AnchorSite[4];
sites[0] = AnchorSite.TOP;
sites[1] = AnchorSite.LEFT;
sites[2] = AnchorSite.BOTTOM;
sites[3] = AnchorSite.RIGHT;
break;
}
return sites;
}
protected boolean shouldCalculate(AnchorSite sourceSite, AnchorSite targetSite) {
for (int i=0; i<sourceAnchorSites.length; ++i) {
if (sourceSite == sourceAnchorSites[i]) {
for (int j=0; j<targetAnchorSites.length; ++j) {
if (targetSite == targetAnchorSites[j]) {
return true;
}
}
}
}
return false;
}
/**
* Calculate route.
*
* @return the connection route
*/
protected ConnectionRoute calculateRoute() {
if (isSelfConnection()) {
return calculateSelfConnectionRoute();
}
ConnectionRoute route = new ConnectionRoute(this, 1, source, target);
// relocate the source and target anchors for closest proximity to their
// opposite shapes' centers
AnchorUtil.moveAnchor(sourceAnchor, GraphicsUtil.getShapeCenter(target));
AnchorUtil.moveAnchor(targetAnchor, GraphicsUtil.getShapeCenter(source));
Point start = GraphicsUtil.createPoint(sourceAnchor);
Point end = GraphicsUtil.createPoint(targetAnchor);
route.add(start);
for (int i=1; i<oldPoints.length -1; ++i) {
route.add(oldPoints[i]);
}
route.add(end);
oldPoints = null;
return route;
}
/**
* Route connections whose source and target are the same. This only
* reroutes the connection if there are currently no bendpoints in the
* connection - we don't want to reroute a connection that may have already
* been manually rerouted.
*
* @return true if the router has done any work
*/
protected ConnectionRoute calculateSelfConnectionRoute() {
if (!isSelfConnection())
return null;
if (movedBendpoint==null) {
if (ffc.getStart() != ffc.getEnd() && ffc.getBendpoints().size()>0) {
// this connection starts and ends at the same node but it has different
// anchor cuts and at least one bendpoint, which makes it likely that
// this connection was already routed previously and the self-connection
// is how the user wants it. But, check if the user wants to force routing.
if (!forceRouting(ffc))
return null;
}
}
ILocation loc = peService.getLocationRelativeToDiagram(target);
IDimension size = GraphicsUtil.calculateSize(target);
Point p;
p = Graphiti.getCreateService().createPoint(loc.getX()+size.getWidth()/2, loc.getY());
FixPointAnchor topAnchor = (FixPointAnchor) ffc.getEnd();
AnchorUtil.moveAnchor(topAnchor, p);
p = Graphiti.getCreateService().createPoint(loc.getX()+size.getWidth(), loc.getY()+size.getHeight()/2);
FixPointAnchor rightAnchor = (FixPointAnchor) ffc.getStart();
AnchorUtil.moveAnchor(rightAnchor, p);
// create the bendpoints that loop the connection around the top-right corner of the figure
Point right = GraphicsUtil.createPoint(rightAnchor); // the point to the right of the node
right.setX(right.getX() + 20);
Point top = GraphicsUtil.createPoint(topAnchor); // point above the node
top.setY(top.getY() - 20);
Point corner = Graphiti.getCreateService().createPoint(right.getX(), top.getY()); // point above the top-right corner
// adjust these cuts to the moved or added bendpoint if possible
p = movedBendpoint;
if (p!=null) {
int x = p.getX();
int y = p.getY();
if (x > loc.getX() + size.getWidth() + 2) {
right.setX(x);
corner.setX(x);
}
if (y < loc.getY() - 2) {
top.setY(y);
corner.setY(y);
}
}
// and add them to the new Route
ConnectionRoute route = new ConnectionRoute(this,1,source,target);
route.add(GraphicsUtil.createPoint(rightAnchor));
route.add(right);
route.add(corner);
route.add(top);
route.add(GraphicsUtil.createPoint(topAnchor));
return route;
}
/**
* Compare the connection's original start/end locations and all of its
* bendpoints with the newly calculated route.
*
* @param route the route
* @return true if the connection is different from the newly calculated
* route
*/
protected boolean isRouteChanged(ConnectionRoute route) {
if (route==null || route.size()==0)
return false;
if (oldPoints.length!=route.size()) {
return true;
}
for (int i=0; i<oldPoints.length; ++i) {
Point p1 = oldPoints[i];
Point p2 = route.get(i);
if (!GraphicsUtil.pointsEqual(p1, p2)) {
return true;
}
}
return false;
}
/**
* Set the connection's new start/end point anchors and the newly calculated
* bendpoints.
*
* @param route the route
*/
protected void applyRoute(ConnectionRoute route) {
route.apply(ffc, sourceAnchor, targetAnchor);
DIUtils.updateDIEdge(ffc);
}
protected AnchorSite getNextAnchorSite(AnchorSite site) {
switch (site) {
case BOTTOM:
return AnchorSite.LEFT;
case LEFT:
return AnchorSite.RIGHT;
case RIGHT:
return AnchorSite.TOP;
case TOP:
return AnchorSite.BOTTOM;
case CENTER:
return AnchorSite.CENTER;
}
return site;
}
/**
* Set a property in the given FreeFormConnection that represents the index
* of an existing bendpoint that has been moved by the user. This bendpoint
* is taken into consideration in the new routing calculations.
*
* @param connection - FreeFormConnection to check
* @param index - index of a bendpoint. If this value is out of range, the
* property will be remmoved from the connection
*/
public static void setMovedBendpoint(Connection connection, int index) {
setInterestingBendpoint(connection, "moved.", index); //$NON-NLS-1$
}
/**
* Sets the added bendpoint.
*
* @param connection the connection
* @param index the index
*/
public static void setAddedBendpoint(Connection connection, int index) {
setInterestingBendpoint(connection, "added.", index); //$NON-NLS-1$
}
/**
* Sets the removed bendpoint.
*
* @param connection the connection
* @param index the index
*/
public static void setRemovedBendpoint(Connection connection, Point p) {
AbstractConnectionRouter.setRoutingInfo(connection, "removed."+ROUTING_INFO_BENDPOINT, p.getX() + "." + p.getY());
}
/**
* Sets the fixed bendpoint.
*
* @param connection the connection
* @param index the index
*/
public static void setFixedBendpoint(Connection connection, int index) {
setInterestingBendpoint(connection, "fixed."+index+".", index); //$NON-NLS-1$ //$NON-NLS-2$
}
public static void setOldBendpointLocation(Connection connection, Point p) {
AbstractConnectionRouter.setRoutingInfo(connection, "oldloc."+ROUTING_INFO_BENDPOINT, p.getX() + "." + p.getY());
}
/**
* Sets the interesting bendpoint.
*
* @param connection the connection
* @param type the type
* @param index the index
*/
protected static void setInterestingBendpoint(Connection connection, String type, int index) {
if (connection instanceof FreeFormConnection) {
int size = ((FreeFormConnection)connection).getBendpoints().size();
if (index>=0 && size>0) {
if (index>=size)
index = size-1;
AbstractConnectionRouter.setRoutingInfoInt(connection, type+ROUTING_INFO_BENDPOINT, index);
}
else
AbstractConnectionRouter.removeRoutingInfo(connection, type+ROUTING_INFO_BENDPOINT);
}
}
/**
* Return the "moved bendpoint" property that was previously set in the
* FreeFormConnection by setMovedBendpoint()
*
* @param connection - FreeFormConnection to check
* @return a Graphiti Point in Diagram-relative coordinates, or null if the
* property is not set
*/
public static Point getMovedBendpoint(Connection connection) {
return getInterestingBendpoint(connection, "moved."); //$NON-NLS-1$
}
/**
* Gets the added bendpoint.
*
* @param connection the connection
* @return the added bendpoint
*/
public static Point getAddedBendpoint(Connection connection) {
return getInterestingBendpoint(connection, "added."); //$NON-NLS-1$
}
/**
* Gets the removed bendpoint.
*
* @param connection the connection
* @return the removed bendpoint
*/
public static Point getRemovedBendpoint(Connection connection) {
String value = AbstractConnectionRouter.getRoutingInfo(connection, "removed."+ROUTING_INFO_BENDPOINT);
if (value!=null && !value.isEmpty()) {
String b[] = value.split("\\.");
int x = Integer.parseInt(b[0]);
int y = Integer.parseInt(b[1]);
return GraphicsUtil.createPoint(x, y);
}
return null;
}
/**
* Gets the fixed bendpoint.
*
* @param connection the connection
* @param index the index
* @return the fixed bendpoint
*/
public static Point getFixedBendpoint(Connection connection, int index) {
return getInterestingBendpoint(connection, "fixed."+index+"."); //$NON-NLS-1$ //$NON-NLS-2$
}
public static Point getOldBendpointLocation(Connection connection) {
String value = AbstractConnectionRouter.getRoutingInfo(connection, "oldloc."+ROUTING_INFO_BENDPOINT);
if (value!=null && !value.isEmpty()) {
String b[] = value.split("\\.");
int x = Integer.parseInt(b[0]);
int y = Integer.parseInt(b[1]);
return GraphicsUtil.createPoint(x, y);
}
return null;
}
/**
* Gets the interesting bendpoint.
*
* @param connection the connection
* @param type the type
* @return the interesting bendpoint
*/
protected static Point getInterestingBendpoint(Connection connection, String type) {
try {
int index = AbstractConnectionRouter.getRoutingInfoInt(connection, type+ROUTING_INFO_BENDPOINT);
return ((FreeFormConnection)connection).getBendpoints().get(index);
}
catch (Exception e) {
}
return null;
}
}