From: jkauttio Date: Fri, 22 Nov 2013 16:04:04 +0000 (+0000) Subject: Fixes several inconsistencies with creating flows in different input modes. The Sysdy... X-Git-Tag: 1.8.1~184 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=e054ec2a4f87fa841998809e46091cd26cf8457c;p=simantics%2Fsysdyn.git Fixes several inconsistencies with creating flows in different input modes. The SysdynConnectTool class could still use some cleanup. fixes #4511 git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@28363 ac1ea38d-2e2b-0410-8846-a27921b304fc --- diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynConnectTool.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynConnectTool.java index 8c2f8190..284f09fe 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynConnectTool.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynConnectTool.java @@ -42,6 +42,9 @@ import org.simantics.g2d.routing.IConnection; import org.simantics.g2d.routing.IRouter2; import org.simantics.g2d.routing.TrivialRouter2; import org.simantics.scenegraph.g2d.G2DParentNode; +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.MouseMovedEvent; import org.simantics.scenegraph.g2d.nodes.ShapeNode; import org.simantics.scenegraph.g2d.snap.ISnapAdvisor; @@ -49,198 +52,187 @@ import org.simantics.structural2.modelingRules.ConnectionJudgement; import org.simantics.sysdyn.SysdynResource; import org.simantics.sysdyn.ui.editor.routing.FlowRouter; import org.simantics.sysdyn.ui.elements.CloudFactory; +import org.simantics.sysdyn.ui.elements.SysdynElementHints; import org.simantics.sysdyn.ui.elements.ValveFactory.ValveSceneGraph; import org.simantics.sysdyn.ui.elements.connections.ConnectionClasses; import org.simantics.ui.SimanticsUI; import org.simantics.utils.datastructures.Callback; import org.simantics.utils.datastructures.Pair; +import org.simantics.utils.ui.ErrorLogger; import org.simantics.utils.ui.ExceptionUtils; public class SysdynConnectTool extends ConnectTool2 { - - public SysdynConnectTool(TerminalInfo startTerminal, int mouseId, + + public SysdynConnectTool(TerminalInfo startTerminal, int mouseId, Point2D startCanvasPos) { super(startTerminal, mouseId, startCanvasPos); } - + @Override @SGInit - public void initSG(G2DParentNode parent) { - ghostNode = parent.addNode(G2DParentNode.class); - ghostNode.setZIndex(PAINT_PRIORITY); - - ShapeNode pathNode = ghostNode.getOrCreateNode("path", ShapeNode.class); - pathNode.setColor(Color.BLACK); - pathNode.setStroke(new BasicStroke(1f)); - pathNode.setScaleStroke(true); - pathNode.setZIndex(0); - - G2DParentNode points = ghostNode.getOrCreateNode("points", G2DParentNode.class); - points.setZIndex(1); - - updateSG(); - } - - - protected TerminalInfo createFlag(EdgeEnd connectionEnd) { - ElementClass flagClass = elementClassProvider.get(ElementClasses.FLAG); - IElement e = Element.spawnNew(flagClass); - - e.setHint(FlagClass.KEY_FLAG_TYPE, endToFlagType(connectionEnd)); - e.setHint(FlagClass.KEY_FLAG_MODE, FlagClass.Mode.Internal); - - TerminalInfo ti = new TerminalInfo(); - ti.e = e; - - // start: this part changed to support overlapping terminals + public void initSG(G2DParentNode parent) { + ghostNode = parent.addNode(G2DParentNode.class); + ghostNode.setZIndex(PAINT_PRIORITY); + + ShapeNode pathNode = ghostNode.getOrCreateNode("path", ShapeNode.class); + pathNode.setColor(Color.BLACK); + pathNode.setStroke(new BasicStroke(1f)); + pathNode.setScaleStroke(true); + pathNode.setZIndex(0); + + G2DParentNode points = ghostNode.getOrCreateNode("points", G2DParentNode.class); + points.setZIndex(1); + + updateSG(); + } + + @Override + protected TerminalInfo createFlag(EdgeEnd connectionEnd) { + ElementClass flagClass = elementClassProvider.get(ElementClasses.FLAG); + IElement e = Element.spawnNew(flagClass); + + e.setHint(FlagClass.KEY_FLAG_TYPE, endToFlagType(connectionEnd)); + e.setHint(FlagClass.KEY_FLAG_MODE, FlagClass.Mode.Internal); + + TerminalInfo ti = new TerminalInfo(); + ti.e = e; + + // start: this part changed to support overlapping terminals ArrayList terminals = new ArrayList(); ElementUtils.getTerminals(e, terminals, false); ti.t = terminals.get(0); // end - - ti.posElem = TerminalUtil.getTerminalPosOnElement(e, ti.t); - ti.posDia = TerminalUtil.getTerminalPosOnDiagram(e, ti.t); - - return ti; - } - - 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 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; - } - - public interface SysdynConnection extends IConnection { } - - protected void updateSG() { - if (controlPoints.isEmpty()) - return; - - // Route connection segments separately - IRouter2 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 SysdynConnection() { - @Override - public Collection 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(); - + + ti.posElem = TerminalUtil.getTerminalPosOnElement(e, ti.t); + ti.posDia = TerminalUtil.getTerminalPosOnDiagram(e, ti.t); + + return ti; + } + + 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 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; + } + + public interface SysdynConnection extends IConnection { } + + @Override + protected void updateSG() { + if (controlPoints.isEmpty()) + return; + + // Route connection segments separately + IRouter2 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 SysdynConnection() { + @Override + public Collection 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(); + c.allowedDirections = Constants.EAST_FLAG | Constants.WEST_FLAG - | Constants.NORTH_FLAG | Constants.SOUTH_FLAG; - - TerminalInfo ti = cp.getAttachedTerminal(); - if (ti != null && (ti != startFlag && ti != endFlag)) { - if(ti.e.getElementClass().containsClass(ValveSceneGraph.class)) { - Rectangle2D bounds = ElementUtils.getElementBoundsOnDiagram(ti.e).getBounds2D(); - c.parentObstacle = new Rectangle2D.Double( - bounds.getCenterX() - FlowRouter.OFFSET, - bounds.getCenterY() - FlowRouter.OFFSET, - FlowRouter.OFFSET * 2, - FlowRouter.OFFSET * 2); - } else { - c.parentObstacle = ElementUtils.getElementBoundsOnDiagram(ti.e).getBounds2D(); - } - } else if (ti != null && ti == startFlag) { - c.parentObstacle = org.simantics.scenegraph.utils.GeometryUtils.transformRectangle(AffineTransform.getTranslateInstance(c.x, c.y), - ElementUtils.getElementBoundsOnDiagram(ti.e).getBounds2D()); - } else if (isEndingInFlag() && ti.e != null) { - c.parentObstacle = org.simantics.scenegraph.utils.GeometryUtils.transformRectangle(AffineTransform.getTranslateInstance(c.x, c.y), - CloudFactory.CLOUD_IMAGE.getBounds()); - } else { - c.parentObstacle = org.simantics.scenegraph.utils.GeometryUtils.transformRectangle(AffineTransform.getTranslateInstance(c.x, c.y), - BranchPointClass.DEFAULT_IMAGE2.getBounds()); - } - - 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); - } - - // Create scene graph to visualize the connection. - ShapeNode pathNode = ghostNode.getOrCreateNode("path", ShapeNode.class); - pathNode.setShape(path); - - /* - * Removed Points - */ - - setDirty(); - } - - - @Override + | Constants.NORTH_FLAG | Constants.SOUTH_FLAG; + + TerminalInfo ti = cp.getAttachedTerminal(); + if (ti != null && (ti != startFlag && ti != endFlag)) { + if(ti.e.getElementClass().containsClass(ValveSceneGraph.class)) { + Rectangle2D bounds = ElementUtils.getElementBoundsOnDiagram(ti.e).getBounds2D(); + c.parentObstacle = new Rectangle2D.Double( + bounds.getCenterX() - FlowRouter.OFFSET, + bounds.getCenterY() - FlowRouter.OFFSET, + FlowRouter.OFFSET * 2, + FlowRouter.OFFSET * 2); + } else { + c.parentObstacle = ElementUtils.getElementBoundsOnDiagram(ti.e).getBounds2D(); + } + } else if (ti != null && ti == startFlag) { + c.parentObstacle = org.simantics.scenegraph.utils.GeometryUtils.transformRectangle(AffineTransform.getTranslateInstance(c.x, c.y), + ElementUtils.getElementBoundsOnDiagram(ti.e).getBounds2D()); + } else if (isEndingInFlag() && ti.e != null) { + c.parentObstacle = org.simantics.scenegraph.utils.GeometryUtils.transformRectangle(AffineTransform.getTranslateInstance(c.x, c.y), + CloudFactory.CLOUD_IMAGE.getBounds()); + } else { + c.parentObstacle = org.simantics.scenegraph.utils.GeometryUtils.transformRectangle(AffineTransform.getTranslateInstance(c.x, c.y), + BranchPointClass.DEFAULT_IMAGE2.getBounds()); + } + + return c; + } + + @Override + public void setPath(Object seg, Path2D path) { + ((Segment) seg).path = (Path2D) path.clone(); + } + }); + + // 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); + } + + // Create scene graph to visualize the connection. + ShapeNode pathNode = ghostNode.getOrCreateNode("path", ShapeNode.class); + pathNode.setShape(path); + + /* + * Removed Points + */ + + setDirty(); + } + + @Override protected Object canConnect(final IConnectionAdvisor advisor, final IElement endElement, final Terminal endTerminal) { - final IElement se = startTerminal != null ? startTerminal.e : startFlag.e; - final Terminal st = startTerminal != null ? startTerminal.t : null; + final IElement se = startTerminal != null ? startTerminal.e : startFlag.e; + final Terminal st = startTerminal != null ? startTerminal.t : null; if(se.equals(endElement)) return null; if(Boolean.FALSE.equals(diagram.getHint(DiagramHints.KEY_USE_CONNECTION_FLAGS)) && endElement == null) { @@ -269,7 +261,7 @@ public class SysdynConnectTool extends ConnectTool2 { Resource start = soa.adapt(Resource.class); if(g.isInheritedFrom(start, sr.ModuleSymbol) && !end.equals(sr.InputSymbol)) return null; if(end.equals(sr.StockSymbol)) return null; - if(end.equals(sr.ShadowSymbol)) return null; + if(end.equals(sr.ShadowSymbol)) return null; } else if (currentConnection.equals(flow)) { if(!(end.equals(sr.StockSymbol) || end.equals(sr.ValveSymbol) || end.equals(sr.CloudSymbol))) return null; } else { @@ -289,25 +281,26 @@ public class SysdynConnectTool extends ConnectTool2 { } } - - protected boolean processMouseMove(MouseMovedEvent me) { - mouseHasMoved = true; - Point2D mouseControlPos = me.controlPosition; - Point2D mouseCanvasPos = util.controlToCanvas(mouseControlPos, new Point2D.Double()); + @Override + protected boolean processMouseMove(MouseMovedEvent me) { + mouseHasMoved = true; - ISnapAdvisor snapAdvisor = getHint(DiagramHints.SNAP_ADVISOR); - if (snapAdvisor != null) - snapAdvisor.snap(mouseCanvasPos); + Point2D mouseControlPos = me.controlPosition; + Point2D mouseCanvasPos = util.controlToCanvas(mouseControlPos, new Point2D.Double()); - // Record last snapped canvas position of mouse. - this.lastMouseCanvasPos.setLocation(mouseCanvasPos); + ISnapAdvisor snapAdvisor = getHint(DiagramHints.SNAP_ADVISOR); + if (snapAdvisor != null) + snapAdvisor.snap(mouseCanvasPos); - if (isEndingInFlag()) { - endFlagNode.setTransform(AffineTransform.getTranslateInstance(mouseCanvasPos.getX(), mouseCanvasPos.getY())); - } + // Record last snapped canvas position of mouse. + this.lastMouseCanvasPos.setLocation(mouseCanvasPos); - List tiList = ((org.simantics.sysdyn.ui.editor.participant.SysdynPointerInteractor)pi).pickTerminals(me.controlPosition); + if (isEndingInFlag()) { + endFlagNode.setTransform(AffineTransform.getTranslateInstance(mouseCanvasPos.getX(), mouseCanvasPos.getY())); + } + + List tiList = ((SysdynPointerInteractor)pi).pickTerminals(me.controlPosition); TerminalInfo ti = null; IConnectionAdvisor advisor = diagram.getHint(DiagramHints.CONNECTION_ADVISOR); @@ -320,88 +313,161 @@ public class SysdynConnectTool extends ConnectTool2 { break; } } - - if (ti != null && !isStartTerminal(ti.e, ti.t)) { - Pair canConnect = canConnect(ti.e, ti.t); - if (canConnect != null) { - connectionJudgment = canConnect.first; - - if (!isEndingInFlag() || !TerminalUtil.isSameTerminal(ti, endTerminal)) { - controlPoints.getLast() - .setPosition(ti.posDia) - .setAttachedToTerminal(ti); - - endTerminal = 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(); - return false; - } - } - - connectionJudgment = 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 - // no longer a terminal to connect to. - // - // => Disconnect the last edge segment from the previous - // terminal, mark endElement/endTerminal non-existent - // and connect the disconnected edge to a new branch point. - - controlPoints.getLast() - .setPosition(mouseCanvasPos) - .setDirection(calculateCurrentBranchPointDirection()) - .setAttachedToTerminal(null); - - endTerminal = null; - } else { - // CASE: Mouse was not previously on top of a valid ending - // element terminal. - // - // => Move and re-orient last branch point. - - controlPoints.getLast() - .setPosition(mouseCanvasPos) - .setDirection(calculateCurrentBranchPointDirection()); - } - - // Make sure that we are ending with a flag if ALT is pressed and no end - // terminal is defined. - endWithoutTerminal(lastMouseCanvasPos, shouldEndWithFlag(me)); - - updateSG(); - - return false; - } - - @Override + + if (ti != null && !isStartTerminal(ti.e, ti.t)) { + Pair canConnect = canConnect(ti.e, ti.t); + if (canConnect != null) { + connectionJudgment = canConnect.first; + + if (!isEndingInFlag() || !TerminalUtil.isSameTerminal(ti, endTerminal)) { + controlPoints.getLast() + .setPosition(ti.posDia) + .setAttachedToTerminal(ti); + + endTerminal = ti; + } + + // Make sure that we are ending with a flag if ALT is pressed + // and no end terminal is defined. If we are in flow creation + // mode, we want to show the terminal cloud (or flag) even when + // alt is not pressed. + if (inFlowMode() && flowInProgress() && !startTerminals.isEmpty()) + endWithoutTerminal(lastMouseCanvasPos, true); + else + endWithoutTerminal(lastMouseCanvasPos, shouldEndWithFlag(me)); + updateSG(); + return false; + } + } + + connectionJudgment = 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 + // no longer a terminal to connect to. + // + // => Disconnect the last edge segment from the previous + // terminal, mark endElement/endTerminal non-existent + // and connect the disconnected edge to a new branch point. + + controlPoints.getLast() + .setPosition(mouseCanvasPos) + .setDirection(calculateCurrentBranchPointDirection()) + .setAttachedToTerminal(null); + + endTerminal = null; + } else { + // CASE: Mouse was not previously on top of a valid ending + // element terminal. + // + // => Move and re-orient last branch point. + + controlPoints.getLast() + .setPosition(mouseCanvasPos) + .setDirection(calculateCurrentBranchPointDirection()); + } + + // Make sure that we are ending with a flag if ALT is pressed and no end + // terminal is defined. If we are in flow creation mode, we want to show + // the terminal cloud (or flag) even when alt is not pressed. + if (inFlowMode() && flowInProgress() && !startTerminals.isEmpty()) + endWithoutTerminal(lastMouseCanvasPos, true); + else + endWithoutTerminal(lastMouseCanvasPos, shouldEndWithFlag(me)); + updateSG(); + return false; + } + + @Override + protected boolean processMouseButtonPress(MouseButtonPressedEvent e) { + MouseButtonEvent me = e; + + // Do nothing before the mouse has moved at least a little. + // This prevents the user from ending the connection right where + // it started. + if (!mouseHasMoved) + return true; + + if (me.button == MouseEvent.LEFT_BUTTON || + (me.button == MouseEvent.RIGHT_BUTTON && flowInProgress() && !inFlowMode())) { + Point2D mouseControlPos = me.controlPosition; + Point2D mouseCanvasPos = util.getInverseTransform().transform(mouseControlPos, new Point2D.Double()); + + ISnapAdvisor snapAdvisor = getHint(DiagramHints.SNAP_ADVISOR); + if (snapAdvisor != null) + snapAdvisor.snap(mouseCanvasPos); + + // Clicked on an allowed end terminal. End connection & end mode. + if (isEndTerminalDefined()) { + createConnection(); + remove(); + return true; + } else { + // Finish connection in thin air only if the + // connection was started from a valid terminal. + + // If we are in flow creation mode, we want to be able to + // create the terminal cloud (or flag) without having to + // press alt. + + if (!startTerminals.isEmpty() && ((me.stateMask & MouseEvent.ALT_MASK) != 0 || + (inFlowMode() && flowInProgress()))) { + Pair pair = canConnect(null, null); + if (pair != null) { + connectionJudgment = (ConnectionJudgement) pair.first; + selectedStartTerminal = pair.second; + createConnection(); + setDirty(); + remove(); + } else { + // Inform the user why connection couldn't be created. + ErrorLogger.defaultLogWarning("Can't resolve connection type for new connection.", null); + } + return true; + } else if (routePointsAllowed() + && (me.stateMask & (MouseEvent.ALT_MASK | MouseEvent.SHIFT_MASK | MouseEvent.CTRL_MASK)) == 0) { + // Add new connection control point. + controlPoints.add(newControlPointWithCalculatedDirection(mouseCanvasPos)); + resetForcedBranchPointDirection(); + updateSG(); + } + } + } + + return true; + } + + private boolean inFlowMode() { + return SysdynElementHints.FLOW_TOOL.equals(getHint(SysdynElementHints.SYSDYN_KEY_TOOL)); + } + + private boolean flowInProgress() { + return elementClassProvider.get(ElementClasses.CONNECTION).equals(elementClassProvider.get(ConnectionClasses.FLOW)); + } + + @Override protected void createConnection() { - - if(this.connectionJudgment == null) return; - - final ConnectionJudgement judgment = this.connectionJudgment; - // ConnectionBuilder changed to SysdynconnectionBuilder to support overlapping terminals and valve creation - final ConnectionBuilder builder = new SysdynConnectionBuilder(this.diagram); - final Deque controlPoints = this.controlPoints; - final TerminalInfo startTerminal = this.startTerminal; - final TerminalInfo endTerminal = this.endTerminal; - - SimanticsUI.getSession().asyncRequest(new WriteRequest() { - @Override - public void perform(WriteGraph graph) throws DatabaseException { - builder.create(graph, judgment, controlPoints, startTerminal, endTerminal); - } - }, new Callback() { - @Override - public void run(DatabaseException parameter) { - if (parameter != null) - ExceptionUtils.logAndShowError(parameter); - } - }); - } + + if(this.connectionJudgment == null) return; + + final ConnectionJudgement judgment = this.connectionJudgment; + // ConnectionBuilder changed to SysdynconnectionBuilder to support overlapping terminals and valve creation + final ConnectionBuilder builder = new SysdynConnectionBuilder(this.diagram); + final Deque controlPoints = this.controlPoints; + final TerminalInfo startTerminal = this.startTerminal; + final TerminalInfo endTerminal = this.endTerminal; + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + builder.create(graph, judgment, controlPoints, startTerminal, endTerminal); + } + }, new Callback() { + @Override + public void run(DatabaseException parameter) { + if (parameter != null) + ExceptionUtils.logAndShowError(parameter); + } + }); + } } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynPointerInteractor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynPointerInteractor.java index f5ba77d8..7b348707 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynPointerInteractor.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynPointerInteractor.java @@ -156,7 +156,7 @@ public class SysdynPointerInteractor extends PointerInteractor { } private ICanvasParticipant getFlowConnectTool(TerminalInfo ti, int mouseId, Point2D curCanvasPos) { - // flows must start from thin air or clouds + // flows must not start from auxiliaries, inputs or modules if (ti != null && (ti.e.getElementClass().getId().equals(AuxiliaryFactory.class.getSimpleName()) || ti.e.getElementClass().getId().equals(InputFactory.class.getSimpleName()) || ti.e.getElementClass().getId().equals(ModuleFactory.class.getSimpleName()))) @@ -176,6 +176,7 @@ public class SysdynPointerInteractor extends PointerInteractor { return null; } + @Override public List pickTerminals(Point2D controlPos) { Rectangle2D controlPickRect = new Rectangle2D.Double(controlPos.getX()-SysdynPointerInteractor.PICK_DIST, controlPos.getY()-SysdynPointerInteractor.PICK_DIST, SysdynPointerInteractor.PICK_DIST*2+1, SysdynPointerInteractor.PICK_DIST*2+1); Shape canvasPickRect = GeometryUtils.transformShape(controlPickRect, util.getInverseTransform());