X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=bundles%2Forg.simantics.diagram%2Fsrc%2Forg%2Fsimantics%2Fdiagram%2Fparticipant%2FConnectTool2.java;h=2165794e89c489c34e34daddf5613fa22d13e9ae;hb=ab50d6f63e29f31dc6912b53b1aec3868d14d5aa;hp=4aaa717d843109cb5d92e97e925fc3dd6dfab020;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git
diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/participant/ConnectTool2.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/participant/ConnectTool2.java
index 4aaa717d8..2165794e8 100644
--- a/bundles/org.simantics.diagram/src/org/simantics/diagram/participant/ConnectTool2.java
+++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/participant/ConnectTool2.java
@@ -25,7 +25,6 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -39,12 +38,15 @@ import org.simantics.db.common.utils.NameUtils;
import org.simantics.db.exception.DatabaseException;
import org.simantics.diagram.connection.RouteGraph;
import org.simantics.diagram.connection.RouteGraphConnectionClass;
+import org.simantics.diagram.connection.RouteLine;
import org.simantics.diagram.connection.RouteTerminal;
+import org.simantics.diagram.connection.delta.RouteGraphDelta;
import org.simantics.diagram.connection.rendering.arrows.PlainLineEndStyle;
import org.simantics.diagram.content.ResourceTerminal;
import org.simantics.diagram.stubs.DiagramResource;
import org.simantics.diagram.synchronization.ISynchronizationContext;
import org.simantics.diagram.synchronization.SynchronizationHints;
+import org.simantics.diagram.synchronization.graph.RouteGraphConnection;
import org.simantics.g2d.canvas.ICanvasContext;
import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;
import org.simantics.g2d.canvas.impl.DependencyReflection.Reference;
@@ -54,6 +56,7 @@ import org.simantics.g2d.connection.IConnectionAdvisor;
import org.simantics.g2d.diagram.DiagramHints;
import org.simantics.g2d.diagram.DiagramUtils;
import org.simantics.g2d.diagram.IDiagram;
+import org.simantics.g2d.diagram.handler.PickContext;
import org.simantics.g2d.diagram.handler.Topology.Terminal;
import org.simantics.g2d.diagram.participant.ElementPainter;
import org.simantics.g2d.diagram.participant.TerminalPainter;
@@ -70,6 +73,7 @@ import org.simantics.g2d.element.IElementClassProvider;
import org.simantics.g2d.element.handler.EdgeVisuals.EdgeEnd;
import org.simantics.g2d.element.handler.SceneGraph;
import org.simantics.g2d.element.handler.TerminalTopology;
+import org.simantics.g2d.element.handler.impl.BranchPointTerminal;
import org.simantics.g2d.element.impl.Element;
import org.simantics.g2d.elementclass.BranchPoint;
import org.simantics.g2d.elementclass.BranchPoint.Direction;
@@ -77,8 +81,8 @@ import org.simantics.g2d.elementclass.FlagClass;
import org.simantics.g2d.elementclass.FlagHandler;
import org.simantics.g2d.participant.RenderingQualityInteractor;
import org.simantics.g2d.participant.TransformUtil;
+import org.simantics.g2d.utils.geom.DirectionSet;
import org.simantics.modeling.ModelingResources;
-import org.simantics.scenegraph.INode;
import org.simantics.scenegraph.g2d.G2DParentNode;
import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;
import org.simantics.scenegraph.g2d.events.KeyEvent;
@@ -95,12 +99,13 @@ import org.simantics.scenegraph.g2d.snap.ISnapAdvisor;
import org.simantics.scenegraph.utils.GeometryUtils;
import org.simantics.scenegraph.utils.Quality;
import org.simantics.structural2.modelingRules.ConnectionJudgement;
-import org.simantics.utils.datastructures.Callback;
import org.simantics.utils.datastructures.Pair;
import org.simantics.utils.logging.TimeLogger;
import org.simantics.utils.ui.ErrorLogger;
import org.simantics.utils.ui.ExceptionUtils;
+import gnu.trove.map.hash.THashMap;
+
/**
* A basic tool for making connection on diagrams.
*
@@ -141,6 +146,9 @@ public class ConnectTool2 extends AbstractMode {
@Dependency
protected PointerInteractor pi;
+ @Dependency
+ protected PickContext pickContext;
+
/**
* Start element terminal of the connection. null
if connection
* was started from a flag or a branch point.
@@ -208,6 +216,13 @@ public class ConnectTool2 extends AbstractMode {
*/
protected ConnectionJudgement connectionJudgment;
+ /**
+ * The latest connectability judgment from the active
+ * {@link IConnectionAdvisor} should the connection happen between
+ * {@link #selectedStartTerminal} and {@link #lastRouteGraphTarget}.
+ */
+ protected ConnectionJudgement attachToConnectionJudgement;
+
/**
* If non-null during connection drawing this field tells the direction
* forced for the current branch point by the user through the UI commands
@@ -269,6 +284,8 @@ public class ConnectTool2 extends AbstractMode {
protected G2DParentNode endFlagNode;
+ private RouteGraphTarget lastRouteGraphTarget;
+
/**
* @param startTerminal
* @param mouseId
@@ -387,9 +404,9 @@ public class ConnectTool2 extends AbstractMode {
ShapeNode pathNode = ghostNode.getOrCreateNode("path", ShapeNode.class);
pathNode.setColor(new Color(160, 0, 0));
- pathNode.setStroke(new BasicStroke(2f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10,
- new float[] { 5f, 2f }, 0));
- pathNode.setScaleStroke(true);
+ pathNode.setStroke(new BasicStroke(0.1f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10,
+ new float[] { 0.5f, 0.2f }, 0));
+ pathNode.setScaleStroke(false);
pathNode.setZIndex(0);
G2DParentNode points = ghostNode.getOrCreateNode("points", G2DParentNode.class);
@@ -398,22 +415,6 @@ public class ConnectTool2 extends AbstractMode {
updateSG();
}
- static class Segment {
- public final ControlPoint begin;
- public final ControlPoint end;
- public Path2D path;
-
- public Segment(ControlPoint begin, ControlPoint end) {
- this.begin = begin;
- this.end = end;
- }
-
- @Override
- public String toString() {
- return "Segment[begin=" + begin + ", end=" + end + ", path=" + path + "]";
- }
- }
-
private RouteTerminal addControlPoint(RouteGraph routeGraph, ControlPoint cp) {
TerminalInfo ti = cp.getAttachedTerminal();
if(ti != null && ti != startFlag && ti != endFlag) {
@@ -443,105 +444,18 @@ public class ConnectTool2 extends AbstractMode {
ControlPoint begin = controlPoints.getFirst();
ControlPoint end = controlPoints.getLast();
-
+
RouteGraph routeGraph = new RouteGraph();
RouteTerminal a = addControlPoint(routeGraph, begin);
RouteTerminal b = addControlPoint(routeGraph, end);
routeGraph.link(a, b);
-
- // Route connection segments separately
- /*Router2 router = ElementUtils.getHintOrDefault(diagram, DiagramHints.ROUTE_ALGORITHM, TrivialRouter2.INSTANCE);
- final List segments = toSegments(controlPoints);
- //System.out.println("controlpoints: " + controlPoints);
- //System.out.println("segments: " + segments);
- router.route(new IConnection() {
- @Override
- public Collection extends Object> getSegments() {
- return segments;
- }
-
- @Override
- public Connector getBegin(Object seg) {
- return getConnector(((Segment) seg).begin);
- }
-
- @Override
- public Connector getEnd(Object seg) {
- return getConnector(((Segment) seg).end);
- }
-
- private Connector getConnector(ControlPoint cp) {
- Connector c = new Connector();
- c.x = cp.getPosition().getX();
- c.y = cp.getPosition().getY();
- TerminalInfo ti = cp.getAttachedTerminal();
- if (ti != null && (ti == startFlag || ti != endFlag)) {
- //System.out.println("CP1: " + cp);
- c.parentObstacle = DiagramUtils.getObstacleShape(ti.e);
- ConnectionDirectionUtil.determineAllowedDirections(c);
- } else {
- //System.out.println("CP2: " + cp);
- c.parentObstacle = GeometryUtils.transformRectangle(AffineTransform.getTranslateInstance(c.x, c.y),
- BranchPointClass.DEFAULT_IMAGE2.getBounds());
- c.allowedDirections = toAllowedDirections(cp.getDirection());
- }
-
- return c;
- }
-
- @Override
- public void setPath(Object seg, Path2D path) {
- ((Segment) seg).path = (Path2D) path.clone();
- }
-
- private int toAllowedDirections(BranchPoint.Direction direction) {
- switch (direction) {
- case Any:
- return 0xf;
- case Horizontal:
- return Constants.EAST_FLAG | Constants.WEST_FLAG;
- case Vertical:
- return Constants.NORTH_FLAG | Constants.SOUTH_FLAG;
- default:
- throw new IllegalArgumentException("unrecognized direction: " + direction);
- }
- }
- });
-
- // Combine the routed paths
- Path2D path = new Path2D.Double();
- for (Segment seg : segments) {
- //System.out.println("SEG: " + seg);
- if (seg.path != null)
- path.append(seg.path.getPathIterator(null), true);
- }*/
-
Path2D path = routeGraph.getPath2D();
// Create scene graph to visualize the connection.
ShapeNode pathNode = ghostNode.getOrCreateNode("path", ShapeNode.class);
pathNode.setShape(path);
- G2DParentNode points = ghostNode.getOrCreateNode("points", G2DParentNode.class);
- HashSet unusedChildren = new HashSet(points.getNodes());
- int i = 0;
- for (ControlPoint cp : controlPoints) {
- if (cp.isAttachedToTerminal())
- continue;
-
- String id = String.valueOf(i);
- BranchPointNode bpn = points.getOrCreateNode(id, BranchPointNode.class);
- bpn.setDegree(2);
- bpn.setDirection((byte) cp.getDirection().ordinal());
- bpn.setTransform(AffineTransform.getTranslateInstance(cp.getPosition().getX(), cp.getPosition().getY()));
-
- ++i;
- unusedChildren.remove(bpn);
- }
- for (INode unusedChild : unusedChildren)
- points.removeNode(unusedChild);
-
setDirty();
}
@@ -558,23 +472,6 @@ public class ConnectTool2 extends AbstractMode {
return elementParent;
}
- private List toSegments(Deque points) {
- if (points.isEmpty())
- return Collections.emptyList();
-
- List segments = new ArrayList();
-
- Iterator it = points.iterator();
- ControlPoint prev = it.next();
- while (it.hasNext()) {
- ControlPoint next = it.next();
- segments.add(new Segment(prev, next));
- prev = next;
- }
-
- return segments;
- }
-
@SGCleanup
public void cleanupSG() {
ghostNode.remove();
@@ -668,15 +565,52 @@ public class ConnectTool2 extends AbstractMode {
// Make sure that we are ending with a flag if ALT is pressed
// and no end terminal is defined.
- endWithoutTerminal(lastMouseCanvasPos, shouldEndWithFlag(me));
-
- updateSG();
+ if (!endWithoutTerminal(lastMouseCanvasPos, shouldEndWithFlag(me)))
+ updateSG();
return false;
}
}
+ } else {
+ RouteGraphTarget cp = RouteGraphConnectTool.pickRouteGraphConnection(
+ diagram,
+ pi.getCanvasPickShape(me.controlPosition),
+ pi.getPickDistance());
+ if (cp != null) {
+ // Remove branch point highlight from previously picked route graph.
+ if (lastRouteGraphTarget != null && cp.getNode() != lastRouteGraphTarget.getNode())
+ cp.getNode().showBranchPoint(null);
+ lastRouteGraphTarget = cp;
+
+ // Validate connection before visualizing connectability
+ Point2D isectPos = cp.getIntersectionPosition();
+ TerminalInfo ti = TerminalInfo.create(
+ isectPos,
+ cp.getElement(),
+ BranchPointTerminal.existingTerminal(
+ isectPos,
+ DirectionSet.ANY,
+ BranchPointNode.SHAPE),
+ BranchPointNode.SHAPE);
+ Pair canConnect = canConnect(ti.e, ti.t);
+ if (canConnect != null) {
+ attachToConnectionJudgement = canConnect.first;
+ controlPoints.getLast().setPosition(ti.posDia).setAttachedToTerminal(ti);
+ endTerminal = ti;
+ cp.getNode().showBranchPoint(isectPos);
+ if (!endWithoutTerminal(lastMouseCanvasPos, shouldEndWithFlag(me)))
+ updateSG();
+ return false;
+ }
+ } else {
+ if (lastRouteGraphTarget != null) {
+ lastRouteGraphTarget.getNode().showBranchPoint(null);
+ lastRouteGraphTarget = null;
+ }
+ }
}
connectionJudgment = null;
+ attachToConnectionJudgement = null;
if (isEndTerminalDefined()) {
// CASE: Mouse was previously on top of a valid terminal to end
// the connection. Now the mouse has been moved where there is
@@ -705,9 +639,8 @@ public class ConnectTool2 extends AbstractMode {
// Make sure that we are ending with a flag if ALT is pressed and no end
// terminal is defined.
- endWithoutTerminal(lastMouseCanvasPos, shouldEndWithFlag(me));
-
- updateSG();
+ if (!endWithoutTerminal(lastMouseCanvasPos, shouldEndWithFlag(me)))
+ updateSG();
return false;
}
@@ -729,11 +662,16 @@ public class ConnectTool2 extends AbstractMode {
if (snapAdvisor != null)
snapAdvisor.snap(mouseCanvasPos);
- // Clicked on an allowed end terminal. End connection & end mode.
- if (isEndTerminalDefined()) {
+ if (isEndTerminalDefined() && connectionJudgment != null) {
+ // Clicked on an allowed end terminal. End connection & end mode.
createConnection();
remove();
return true;
+ } else if (lastRouteGraphTarget != null && attachToConnectionJudgement != null) {
+ lastRouteGraphTarget.getNode().showBranchPoint(null);
+ attachToConnection();
+ remove();
+ return true;
} else {
// Finish connection in thin air only if the
// connection was started from a valid terminal.
@@ -772,6 +710,50 @@ public class ConnectTool2 extends AbstractMode {
return false;
}
+ private void attachToConnection() {
+ ConnectionJudgement judgment = this.attachToConnectionJudgement;
+ if (judgment == null) {
+ ErrorLogger.defaultLogError("Cannot attach to connection, no judgment available on connection validity", null);
+ return;
+ }
+
+ ConnectionBuilder builder = new ConnectionBuilder(this.diagram);
+ RouteGraph before = lastRouteGraphTarget.getNode().getRouteGraph();
+ THashMap