import java.util.Deque;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.List;
import java.util.Set;
import org.simantics.Simantics;
import org.simantics.scenegraph.g2d.events.MouseEvent;
import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonEvent;
import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonReleasedEvent;
import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;
import org.simantics.scenegraph.g2d.events.command.CommandEvent;
import org.simantics.scenegraph.g2d.events.command.Commands;
import org.simantics.scenegraph.g2d.snap.ISnapAdvisor;
import org.simantics.scenegraph.utils.GeometryUtils;
import org.simantics.structural2.modelingRules.ConnectionJudgement;
-import org.simantics.utils.datastructures.Callback;
import org.simantics.utils.datastructures.Pair;
import org.simantics.utils.datastructures.Triple;
import org.simantics.utils.logging.TimeLogger;
if (me instanceof MouseButtonPressedEvent)
return processMouseButtonPress((MouseButtonPressedEvent) me);
+ // #7653: Support creating connections between terminals without lifting mouse button in between.
+ if (me instanceof MouseButtonReleasedEvent)
+ return processMouseButtonRelease((MouseButtonReleasedEvent) me);
+
return false;
}
endFlagNode.setTransform(AffineTransform.getTranslateInstance(mouseCanvasPos.getX(), mouseCanvasPos.getY()));
}
- TerminalInfo ti = pi.pickTerminal(me.controlPosition);
- if (ti != null) {
- Object canConnect = canConnect(ti.e, ti.t);
- if (canConnect != null) {
- connectionJudgment = (ConnectionJudgement) canConnect;
+ List<TerminalInfo> tis = pi.pickTerminals(me.controlPosition);
+ tis = TerminalUtil.findNearestOverlappingTerminals(tis);
+ if (!tis.isEmpty()) {
+ for (TerminalInfo ti : tis) {
+ Object canConnect = canConnect(ti.e, ti.t);
- if (!isEndingInFlag() || !TerminalUtil.isSameTerminal(ti, endTerminal)) {
- controlPoints.getLast()
- .setPosition(ti.posDia)
- .setAttachedToTerminal(ti);
+ if (canConnect != null) {
+ connectionJudgment = (ConnectionJudgement) canConnect;
- endTerminal = ti;
+ if (!isEndingInFlag() || !TerminalUtil.isSameTerminal(ti, endTerminal)) {
+ controlPoints.getLast().setPosition(ti.posDia).setAttachedToTerminal(ti);
- connect(ti);
-
- }
+ endTerminal = ti;
+
+ connect(ti);
- // Make sure that we are ending with a flag if ALT is pressed
- // and no end terminal is defined.
- endWithoutTerminal(lastMouseCanvasPos, shouldEndWithFlag(me));
+ }
- updateSG(new Point2D.Double(ti.posDia.getTranslateX(), ti.posDia.getTranslateY()));
- return false;
+ // Make sure that we are ending with a flag if ALT is pressed
+ // and no end terminal is defined.
+ endWithoutTerminal(lastMouseCanvasPos, shouldEndWithFlag(me));
+
+ updateSG(new Point2D.Double(ti.posDia.getTranslateX(), ti.posDia.getTranslateY()));
+ return false;
+ }
}
}
protected void disconnect(Point2D mouseCanvasPos) {
setEndTerminal(mouseCanvasPos.getX(), mouseCanvasPos.getY(), null, 0xf);
}
-
- protected boolean processMouseButtonPress(MouseButtonPressedEvent e) {
- MouseButtonEvent me = e;
+ protected boolean processMouseButtonPress(MouseButtonEvent me) {
// Do nothing before the mouse has moved at least a little.
// This prevents the user from ending the connection right where
// it started.
snapAdvisor.snap(mouseCanvasPos);
// Clicked on an allowed end terminal. End connection & end mode.
- if (isEndTerminalDefined()) {
- createConnection();
- remove();
+ if (tryEndConnection()) {
return true;
} else {
// Finish connection in thin air only if the
return false;
}
+ private int mouseLeftReleaseCount = 0;
+
+ protected boolean processMouseButtonRelease(MouseButtonReleasedEvent me) {
+ if (me.button == MouseEvent.LEFT_BUTTON
+ && ++mouseLeftReleaseCount == 1) {
+ return tryEndConnection();
+ }
+ return false;
+ }
+
+ /**
+ * @return <code>true</code> if connection was successfully ended
+ */
+ private boolean tryEndConnection() {
+ if (isEndTerminalDefined()) {
+ createConnection();
+ remove();
+ return true;
+ }
+ return false;
+ }
+
protected boolean cancelPreviousBend() {
if (!routePointsAllowed())
return false;
Resource attachToLine = RouteGraphConnection.deserialize(graph, attachedToRouteLine.getData());
builder.attachToRouteGraph(graph, judgment, connection, attachToLine, controlPoints, endTerminal, FlagClass.Type.Out);
}
- }, new Callback<DatabaseException>() {
- @Override
- public void run(DatabaseException parameter) {
- if (parameter != null)
- ExceptionUtils.logAndShowError(parameter);
- }
+ }, e -> {
+ if (e != null)
+ ExceptionUtils.logAndShowError(e);
});
}
// ------------------------------------------------------------------------
- static RouteGraphTarget pickRouteGraphConnection(IDiagram diagram, Shape pickShape, double pickDistance) {
+ static RouteGraphTarget pickRouteGraphConnection(ICanvasContext ctx, IDiagram diagram, Shape pickShape, double pickDistance) {
ArrayList<IElement> elements = new ArrayList<IElement>();
- PickRequest req = new PickRequest(pickShape);
+ PickRequest req = new PickRequest(pickShape).context(ctx);
DiagramUtils.pick(diagram, req, elements);
for (Iterator<IElement> it = elements.iterator(); it.hasNext();) {
IElement e = it.next();