Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/linklf/AbsoluteBendpointsConvention.java')
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/linklf/AbsoluteBendpointsConvention.java233
1 files changed, 203 insertions, 30 deletions
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/linklf/AbsoluteBendpointsConvention.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/linklf/AbsoluteBendpointsConvention.java
index 8298f78f3a6..b0ac64428a7 100644
--- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/linklf/AbsoluteBendpointsConvention.java
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/linklf/AbsoluteBendpointsConvention.java
@@ -1,10 +1,12 @@
package org.eclipse.papyrus.infra.gmfdiag.common.linklf;
+import java.util.Collections;
import java.util.List;
import org.eclipse.draw2d.AbsoluteBendpoint;
import org.eclipse.draw2d.Bendpoint;
import org.eclipse.draw2d.Connection;
+import org.eclipse.draw2d.ConnectionAnchor;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PointList;
@@ -12,49 +14,220 @@ import org.eclipse.gmf.runtime.notation.Edge;
import org.eclipse.gmf.runtime.notation.RelativeBendpoints;
import org.eclipse.gmf.runtime.notation.datatype.RelativeBendpoint;
-public class AbsoluteBendpointsConvention {
+/**
+ * This class defines when to enable the enhanced link anchors and bendpoints behavior,
+ * which implementation is based on storing the fixed bendpoints coordinates instead of their relative locations to
+ * anchors.
+ */
+public abstract class AbsoluteBendpointsConvention {
- private static final int MAGIC = -643984;
+ private static AbsoluteBendpointsConvention ourInstance;
- public static RelativeBendpoint createAbsoluteBendpointStoredAsRelative(Point point) {
- return new RelativeBendpoint(point.x, point.y, MAGIC, MAGIC);
+ public static AbsoluteBendpointsConvention getInstance() {
+ if(ourInstance == null) {
+ //ourInstance = new OnlyForNewLinks();
+ ourInstance = new ForAllLinks();
+ }
+ return ourInstance;
}
- public static boolean isAbsoluteStoredAsRelative(RelativeBendpoint modelBP) {
- return modelBP.getTargetX() == MAGIC && modelBP.getTargetY() == MAGIC;
- }
+ public abstract RelativeBendpoint createAbsoluteBendpointStoredAsRelative(Point point);
+
+ public abstract boolean isAbsoluteStoredAsRelative(RelativeBendpoint modelBP);
+
+ public abstract Bendpoint d2dBendpoint(RelativeBendpoint modelBP, Connection connection, float weight);
+
+ public abstract boolean hasAbsoluteStoredAsRelativeBendpoints(Edge edge);
+
+ public abstract PointList getPointList(Edge edge, Object linkConstraint);
+
+ private abstract static class ConventionBase extends AbsoluteBendpointsConvention {
- public static Bendpoint d2dBendpoint(RelativeBendpoint modelBP, Connection connection, float weight) {
- if(isAbsoluteStoredAsRelative(modelBP)) {
- return new AbsoluteBendpoint(modelBP.getSourceX(), modelBP.getSourceY());
+ private static final int MAGIC = -643984;
+
+ @Override
+ public RelativeBendpoint createAbsoluteBendpointStoredAsRelative(Point point) {
+ return new RelativeBendpoint(point.x, point.y, MAGIC, MAGIC);
+ }
+
+ @Override
+ public boolean isAbsoluteStoredAsRelative(RelativeBendpoint modelBP) {
+ return modelBP.getTargetX() == MAGIC && modelBP.getTargetY() == MAGIC;
}
- org.eclipse.draw2d.RelativeBendpoint rbp = new org.eclipse.draw2d.RelativeBendpoint(connection);
- rbp.setRelativeDimensions(new Dimension(modelBP.getSourceX(), modelBP.getSourceY()), //
- new Dimension(modelBP.getTargetX(), modelBP.getTargetY()));
- rbp.setWeight(weight);
- return rbp;
+
+ @Override
+ public Bendpoint d2dBendpoint(RelativeBendpoint modelBP, Connection connection, float weight) {
+ if(isAbsoluteStoredAsRelative(modelBP)) {
+ return new AbsoluteBendpoint(modelBP.getSourceX(), modelBP.getSourceY());
+ }
+ return null;
+ }
+
+ @Override
+ public PointList getPointList(Edge edge, Object linkConstraint) {
+ PointList result = new PointList();
+ List<?> d2dBendpoints = linkConstraint instanceof List<?> ? (List<?>)linkConstraint : Collections.emptyList();
+ RelativeBendpoints allModelBendpoints = (RelativeBendpoints)edge.getBendpoints();
+ @SuppressWarnings("unchecked")
+ List<RelativeBendpoint> modelBendpoints = allModelBendpoints.getPoints();
+ for(int i = 0; i < modelBendpoints.size(); i++) {
+ RelativeBendpoint nextModel = modelBendpoints.get(i);
+ Object nextD2d = d2dBendpoints.size() > i ? d2dBendpoints.get(i) : null;
+
+ Point nextPoint = getLocation(nextModel, nextD2d);
+ if(nextPoint == null) {
+ throw new IllegalStateException("Can't extract location: modelBP: " + nextModel + ", d2dBP: " + nextD2d);
+ }
+ result.addPoint(nextPoint);
+ }
+ return result;
+ }
+
+ protected static org.eclipse.draw2d.RelativeBendpoint newRelativeBendpointD2d(RelativeBendpoint modelBP, Connection connection, float weight) {
+ org.eclipse.draw2d.RelativeBendpoint rbp = new org.eclipse.draw2d.RelativeBendpoint(connection);
+ rbp.setRelativeDimensions(new Dimension(modelBP.getSourceX(), modelBP.getSourceY()), //
+ new Dimension(modelBP.getTargetX(), modelBP.getTargetY()));
+ rbp.setWeight(weight);
+ return rbp;
+ }
+
+ protected abstract Point getLocation(RelativeBendpoint modelBendpoint, Object d2dbendpoint);
+
}
- public static boolean hasAbsoluteStoredAsRelativeBendpoints(Edge edge) {
- List<?> bendpoints = ((RelativeBendpoints)edge.getBendpoints()).getPoints();
- for(Object o : bendpoints) {
- if(o instanceof RelativeBendpoint && isAbsoluteStoredAsRelative((RelativeBendpoint)o)) {
- return true;
+ protected static class OnlyForNewLinks extends ConventionBase {
+
+ @Override
+ public Bendpoint d2dBendpoint(RelativeBendpoint modelBP, Connection connection, float weight) {
+ Bendpoint result = super.d2dBendpoint(modelBP, connection, weight);
+ if(result == null) {
+ result = newRelativeBendpointD2d(modelBP, connection, weight);
+ }
+ return result;
+ }
+
+ @Override
+ public boolean hasAbsoluteStoredAsRelativeBendpoints(Edge edge) {
+ List<?> bendpoints = ((RelativeBendpoints)edge.getBendpoints()).getPoints();
+ for(Object o : bendpoints) {
+ if(o instanceof RelativeBendpoint && isAbsoluteStoredAsRelative((RelativeBendpoint)o)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ protected Point getLocation(RelativeBendpoint modelBendpoint, Object d2dbendpoint) {
+ if(isAbsoluteStoredAsRelative(modelBendpoint)) {
+ return new Point(modelBendpoint.getSourceX(), modelBendpoint.getSourceY());
+ }
+ if(d2dbendpoint instanceof Bendpoint) {
+ return ((Bendpoint)d2dbendpoint).getLocation();
}
+ return null;
}
- return false;
+
}
- public static PointList getAbsoluteRelativeBendpointsList(Edge edge) {
- PointList result = new PointList();
- for(Object o : ((RelativeBendpoints)edge.getBendpoints()).getPoints()) {
- if(o instanceof RelativeBendpoint && isAbsoluteStoredAsRelative((RelativeBendpoint)o)) {
- RelativeBendpoint relativeBendpoint = (RelativeBendpoint)o;
- result.addPoint(new Point(relativeBendpoint.getSourceX(), relativeBendpoint.getSourceY()));
- } else {
- throw new IllegalArgumentException("Expecting absolute bendpoints stored as relative, found: " + o);
+ protected static class ForAllLinks extends ConventionBase {
+
+ @Override
+ public Bendpoint d2dBendpoint(RelativeBendpoint modelBP, Connection connection, float weight) {
+ Bendpoint result = super.d2dBendpoint(modelBP, connection, weight);
+ if(result == null) {
+ org.eclipse.draw2d.RelativeBendpoint rbp = newRelativeBendpointD2d(modelBP, connection, weight);
+ //if(connection.getSourceAnchor() != null && connection.getTargetAnchor() != null) {
+ result = new RelativeBendpointWrapper(rbp, connection);
+ //}
+ }
+ return result;
+ }
+
+ @Override
+ public boolean hasAbsoluteStoredAsRelativeBendpoints(Edge edge) {
+ List<?> bendpoints = ((RelativeBendpoints)edge.getBendpoints()).getPoints();
+ return !bendpoints.isEmpty();
+ }
+
+ @Override
+ protected Point getLocation(RelativeBendpoint modelBendpoint, Object d2dBendpoint) {
+ if(isAbsoluteStoredAsRelative(modelBendpoint)) {
+ return new Point(modelBendpoint.getSourceX(), modelBendpoint.getSourceY());
+ }
+ if(d2dBendpoint instanceof AbsoluteBendpoint) {
+ AbsoluteBendpoint wrapper = (AbsoluteBendpoint)d2dBendpoint;
+ return wrapper.getLocation();
+ }
+ throw new IllegalStateException("I had to create AbsoluteBendpointWrapper for this: " + modelBendpoint + ", " + d2dBendpoint);
+ }
+
+ /**
+ * Provides implicit migration of the diagrams created before the LinksLF.
+ * <p/>
+ * Idea is to create the same "absolute" bendpoints for the old relative bendpoints created with previous version, and only update the
+ * persistence on the first modification of the link.
+ * <p/>
+ * However, positions of the {@link RelativeBendpoint} depends on the anchors and, more generally on the bounds of link ends, so they can't be
+ * computed immediately at the time of creation. This class introduced the deferred replacement, that is, once the {@link RelativeBendpoint}
+ * can compute its positions, their coordinates are saved and don't depend on the source or target anchors anymore.
+ */
+ @SuppressWarnings("serial")
+ private static class RelativeBendpointWrapper extends AbsoluteBendpoint {
+
+ private Point myLocation = null;
+
+ private org.eclipse.draw2d.RelativeBendpoint myRelativeBendpoint;
+
+ private Connection myConnection;
+
+ /**
+ * Wraps the {@link RelativeBendpoint} and defers computation of its positions until it is ready.
+ *
+ * @param relativeBendpoint
+ * @param conn
+ */
+ public RelativeBendpointWrapper(org.eclipse.draw2d.RelativeBendpoint relativeBendpoint, Connection conn) {
+ super(new Point());
+ myRelativeBendpoint = relativeBendpoint;
+ myConnection = conn;
+ }
+
+ @Override
+ public Point getLocation() {
+ if(myLocation == null && isReadyToComputeLocation()) {
+ myLocation = new Point(myRelativeBendpoint.getLocation());
+ myRelativeBendpoint = null;
+ myConnection = null;
+ }
+ return myLocation != null ? myLocation : myRelativeBendpoint.getLocation();
+ }
+
+ private boolean isReadyToComputeLocation() {
+ if(myConnection == null) {
+ return false;
+ }
+ ConnectionAnchor source = myConnection.getSourceAnchor();
+ ConnectionAnchor target = myConnection.getTargetAnchor();
+ if(source == null || target == null) {
+ return false;
+ }
+ return hasLocation(source.getReferencePoint()) && hasLocation(target.getReferencePoint());
+ }
+
+ private boolean hasLocation(Point point) {
+ return point != null && (point.x() != 0 || point.y() != 0);
+ }
+
+ @Override
+ public int x() {
+ return getLocation().x();
+ }
+
+ @Override
+ public int y() {
+ return getLocation().y();
}
}
- return result;
}
}

Back to the top