From 9d0f11024381459a552b0a0022f81a15f02324f3 Mon Sep 17 00:00:00 2001 From: lempinen Date: Thu, 9 Sep 2010 12:54:23 +0000 Subject: [PATCH] Valves are created automatically if a new flow is not connected to valve on either end git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@17861 ac1ea38d-2e2b-0410-8846-a27921b304fc --- .../ui/editor/participant/ConnectTool.java | 1120 +++++++++-------- .../sysdyn/ui/elements2/ValveFactory.java | 4 +- 2 files changed, 615 insertions(+), 509 deletions(-) diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/ConnectTool.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/ConnectTool.java index 922bdf90..10fc52a3 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/ConnectTool.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/ConnectTool.java @@ -12,8 +12,10 @@ import java.util.List; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; +import org.simantics.db.common.request.Queries; import org.simantics.db.exception.DatabaseException; import org.simantics.db.request.Read; +import org.simantics.diagram.query.DiagramRequests; import org.simantics.g2d.canvas.ICanvasContext; import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency; import org.simantics.g2d.canvas.impl.SGNodeReflection.SGCleanup; @@ -64,533 +66,635 @@ import org.simantics.g2d.snap.ISnapAdvisor; import org.simantics.scenegraph.Node; import org.simantics.scenegraph.g2d.G2DParentNode; import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.elements2.ValveFactory; import org.simantics.ui.SimanticsUI; import org.simantics.utils.datastructures.hints.IHintContext.Key; public class ConnectTool extends AbstractDiagramParticipant { - public static final Key KEY_SG_NODE = new SceneGraphNodeKey(Node.class, "CONNECT_SG_NODE"); - - @Dependency TransformUtil util; - @Dependency ElementPainter diagramPainter; - @Dependency PickContext pickContext; - @Dependency PointerInteractor pi; - @Dependency MouseUtil mouseUtil; - @Dependency KeyUtil keys; - - boolean createFlags; - Point2D startPos; - - IElement startElement; - Terminal startTerminal; - - IElement endElement; - Terminal endTerminal; - - IDiagram inputDiagram; - MutatedDiagram ghostDiagram; - Topology topology; - - ElementClass connectionClass; - - ConnectionHandler connectionHandler; - IElement connection; - Deque edges = new ArrayDeque(); - Deque controlPoints = new ArrayDeque(); - int mouseId; - - Collection terminals = new ArrayList(); - - TerminalHoverStrategy originalStrategy = null; - TerminalHoverStrategy terminalHoverStrategy = new TerminalHoverStrategy() { - @Override - public boolean highlightEnabled() { - return true; - } - - @Override - public boolean highlight(TerminalInfo ti) { - IConnectionAdvisor advisor = diagram.getHint(DiagramHints.CONNECTION_ADVISOR); - return canConnect(advisor, ti.e, ti.t) != null; - } - }; - - public ConnectTool(IDiagram diagram, ElementClass connectionClass, IElement startElement, Terminal startTerminal, int mouseId, Point2D mouseDiagramPos) - { - this.inputDiagram = diagram; - this.connectionClass = connectionClass; - this.mouseId = mouseId; - this.startPos = mouseDiagramPos; - this.startElement = startElement; - this.startTerminal = startTerminal; - } - - @Override - public void addedToContext(ICanvasContext ctx) { - - super.addedToContext(ctx); - - // Force terminals to always be highlighted. - originalStrategy = getHint(TerminalPainter.TERMINAL_HOVER_STRATEGY); - setHint(TerminalPainter.TERMINAL_HOVER_STRATEGY, terminalHoverStrategy); - - // See if flags should be created or not - this.createFlags = Boolean.TRUE.equals(inputDiagram.getHint(DiagramHints.KEY_USE_CONNECTION_FLAGS)); - - // Mutate current diagram and add the connection to the mutated copy. - ghostDiagram = Diagram.mutate(inputDiagram); - topology = ghostDiagram.getDiagramClass().getSingleItem(Topology.class); - - IElement firstElement = null; - Terminal firstTerminal = null; - - // Where is start terminal? - if (startElement != null && startTerminal != null) { - // Whoomp, there it is. Is it already a part of an existing connection? - assert ElementUtils.peekDiagram(startElement) == inputDiagram; - IElement possibleConnection = getConnectionFromPart(startElement); - if (possibleConnection != null) { - // TODO: broken. - connection = ghostDiagram.getMutatedCorrespondence(possibleConnection); - } else { - connection = createConnection(connectionClass); - ghostDiagram.addElement(connection); - } - - connectionHandler = connection.getElementClass().getSingleItem(ConnectionHandler.class); - assert connectionHandler != null; - - firstElement = ghostDiagram.getMutatedCorrespondence(startElement); - firstTerminal = startTerminal; - } else { - connection = createConnection(connectionClass); - connectionHandler = connection.getElementClass().getSingleItem(ConnectionHandler.class); - assert connectionHandler != null; - ghostDiagram.addElement(connection); - - firstElement = createBranchPointOrFlag(startPos, EdgeEnd.Begin); - ArrayList terminals = new ArrayList(); - ElementUtils.getTerminals(firstElement, terminals, false); - firstTerminal = terminals.get(0); - startElement = firstElement; - startTerminal = firstTerminal; - } - - IElement secondElement = connectionHandler.newBranchPoint(connection); - controlPoints.add(secondElement); -// ghostDiagram.addElement(secondElement); - ElementUtils.setPos(secondElement, startPos); - Terminal secondTerminal = ElementUtils.getSingleTerminal(secondElement); - - IElement edge = connectionHandler.newEdge(connection); - edges.add(edge); -// ghostDiagram.addElement(edge); - - topology.connect(edge, EdgeEnd.Begin, firstElement, firstTerminal); - topology.connect(edge, EdgeEnd.End, secondElement, secondTerminal); - - } - - @Override - public void removedFromContext(ICanvasContext ctx) { - - if (getHint(TerminalPainter.TERMINAL_HOVER_STRATEGY) == terminalHoverStrategy) { - if (originalStrategy != null) - setHint(TerminalPainter.TERMINAL_HOVER_STRATEGY, originalStrategy); - else - removeHint(TerminalPainter.TERMINAL_HOVER_STRATEGY); - } - - ghostDiagram.destroy(); - - super.removedFromContext(ctx); - } - - final static Composite ALPHA_COMPOSITE = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.75f); - public static final int PAINT_PRIORITY = ElementPainter.ELEMENT_PAINT_PRIORITY + 5; - - protected G2DParentNode node = null; - - @SGInit - public void initSG(G2DParentNode parent) { - node = parent.addNode(G2DParentNode.class); - node.setZIndex(PAINT_PRIORITY); - update(); - } - - public void update() { - if (ghostDiagram != null) { - diagramPainter.paintDiagram(node, ghostDiagram, ghostDiagram.getDifferences(), KEY_SG_NODE); - } - } - - @SGCleanup - public void cleanupSG() { - node.remove(); - node = null; - } - - boolean cancelPreviousBend() { - if (!routePointsAllowed()) - return false; - - // If not at the first branch point, remove the last branch - // point and edge. Otherwise, cancel action - if (controlPoints.size() < 2) { - DiagramMutator mutator = diagram.getHint(DiagramHints.KEY_MUTATOR); - mutator.clear(); - update(); - remove(); - return true; - } - // Cancel prev bend - IElement lastControlPoint = controlPoints.removeLast(); - IElement prevControlPoint = controlPoints.peekLast(); - IElement lastEdge = edges.removeLast(); - for (Terminal t : ElementUtils.getTerminals(lastControlPoint, terminals, true)) - topology.disconnect(lastEdge, EdgeEnd.End, lastControlPoint, t); - for (Terminal t : ElementUtils.getTerminals(prevControlPoint, terminals, true)) - topology.disconnect(lastEdge, EdgeEnd.Begin, prevControlPoint, t); - connectionHandler.removeBranchPoint(connection, lastControlPoint); - connectionHandler.removeEdge(connection, lastEdge); - Point2D mousePos = mouseUtil.getMouseInfo(mouseId).canvasPosition; - ElementUtils.setPos(controlPoints.peekLast(), mousePos); - DiagramUtils.validateAndFix(ghostDiagram, getContext()); - update(); - setDirty(); - return true; - } - - @EventHandler(priority = 20) - public boolean handleEvent(Event e) { - // Back-space, cancel prev bend - if (e instanceof KeyPressedEvent) { - KeyEvent ke = (KeyEvent) e; - if (ke.keyCode == java.awt.event.KeyEvent.VK_BACK_SPACE) { - return cancelPreviousBend(); - } - } - if (e instanceof CommandEvent) { - CommandEvent ce = (CommandEvent) e; - if (ce.command.equals(Commands.CANCEL)) - { - DiagramMutator mutator = diagram.getHint(DiagramHints.KEY_MUTATOR); - mutator.clear(); - update(); - remove(); - return true; - } - } - if (e instanceof MouseMovedEvent) { - MouseMovedEvent me = (MouseMovedEvent) e; - Point2D mouseControlPos = me.controlPosition; - Point2D mouseCanvasPos = util.controlToCanvas(mouseControlPos, new Point2D.Double()); - - ISnapAdvisor snapAdvisor = getHint(DiagramHints.SNAP_ADVISOR); - if (snapAdvisor != null) - snapAdvisor.snap(mouseCanvasPos); - - List tiList = ((org.simantics.sysdyn.ui.editor.participant.PointerInteractor)pi).pickTerminals(me.controlPosition); - TerminalInfo ti = null; - - IConnectionAdvisor advisor = diagram.getHint(DiagramHints.CONNECTION_ADVISOR); - for(TerminalInfo info : tiList) { - if(advisor == null || info.e == null || info.t == null) - continue; - Object canConnect = canConnect(advisor, info.e, info.t); - if (canConnect != null) { - connection.setHint(ElementHints.KEY_CONNECTION_TYPE, canConnect); - ti = info; - } - } - - if (ti != null && !(ti.e == startElement && ti.t == startTerminal)) { - if (endElement == null) { - endElement = ti.e; - endTerminal = ti.t; - - IElement lastControlPoint = controlPoints.pollLast(); - topology.disconnect(edges.peekLast(), EdgeEnd.End, lastControlPoint, ElementUtils.getSingleTerminal(lastControlPoint)); - connectionHandler.removeBranchPoint(connection, lastControlPoint); - - topology.connect(edges.peekLast(), EdgeEnd.End, ghostDiagram.getMutatedCorrespondence(endElement), endTerminal); - DiagramUtils.validateAndFix(ghostDiagram, getContext()); - } else if (!ti.e.equals(endElement) || !ti.t.equals(endTerminal)) { - topology.disconnect(edges.peekLast(), EdgeEnd.End, ghostDiagram.getMutatedCorrespondence(endElement), endTerminal); - - endElement = ti.e; - endTerminal = ti.t; - - topology.connect(edges.peekLast(), EdgeEnd.End, ghostDiagram.getMutatedCorrespondence(endElement), endTerminal); - DiagramUtils.validateAndFix(ghostDiagram, getContext()); - } - - update(); - setDirty(); - return false; - } - - { - connection.removeHint(ElementHints.KEY_CONNECTION_TYPE); - if (endElement != null) { - topology.disconnect(edges.peekLast(), EdgeEnd.End, ghostDiagram.getMutatedCorrespondence(endElement), endTerminal); - - endElement = null; - endTerminal = null; - - IElement bp = connectionHandler.newBranchPoint(connection); - controlPoints.add(bp); -// ghostDiagram.addElement(bp); - ElementUtils.setPos(controlPoints.peekLast(), mouseCanvasPos); - - topology.connect(edges.peekLast(), EdgeEnd.End, bp, ElementUtils.getSingleTerminal(bp)); - } else { - ElementUtils.setPos(controlPoints.peekLast(), mouseCanvasPos); - } - DiagramUtils.validateAndFix(ghostDiagram, getContext()); - - update(); - setDirty(); - } - - } - - if (e instanceof MouseButtonPressedEvent) { - MouseButtonEvent me = (MouseButtonEvent) e; - if (me.button==MouseEvent.LEFT_BUTTON && me.mouseId==mouseId) { - Point2D mouseControlPos = me.controlPosition; - final Point2D mouseCanvasPos = util.getInverseTransform().transform(mouseControlPos, new Point2D.Double()); - - ISnapAdvisor snapAdvisor = getHint(DiagramHints.SNAP_ADVISOR); - if (snapAdvisor != null) - snapAdvisor.snap(mouseCanvasPos); - - // Clicked on a terminal .. End connection, End mode - if (endElement != null) { - attachToBranchPoint(); - createValveIfNecessary(); - commitDiagram(); - update(); - remove(); // Remove ConnectTool participant - return true; - } else { - if (isCurrentConnectionFlow() && startElement != null && startTerminal != null) { - - createValveIfNecessary(); - - IConnectionAdvisor advisor = diagram.getHint(DiagramHints.CONNECTION_ADVISOR); - Object canConnect = canConnect(advisor, null, null); - if (canConnect != null) - connection.setHint(ElementHints.KEY_CONNECTION_TYPE, canConnect); - - // Finish connection in thin air only if the - // connection was started from a valid terminal. - if (createFlags) { - // Replace the last branch point with a flag. - IElement lastBp = controlPoints.pollLast(); - topology.disconnect(edges.peekLast(), EdgeEnd.End, lastBp, ElementUtils.getSingleTerminal(lastBp)); - connectionHandler.removeBranchPoint(connection, lastBp); - - IElement end = createFlag(mouseCanvasPos, EdgeEnd.End); - ArrayList terminals = new ArrayList(); - ElementUtils.getTerminals(end, terminals, false); - Terminal endTerminal = terminals.get(1); - topology.connect(edges.peekLast(), EdgeEnd.End, end, endTerminal); - } - - DiagramUtils.validateAndFix(ghostDiagram, getContext()); - commitDiagram(); - update(); - remove(); // Remove ConnectTool participant - return true; - } - } - - } - } - - // Don't let any events slip to creator participant - if (e instanceof MouseEvent) { - MouseEvent me = (MouseEvent) e; - return me.mouseId == mouseId; - } - - return false; - } - - - private boolean isCurrentConnectionFlow() { - // Could this check be done better? - Boolean isFlow = false; + public static final Key KEY_SG_NODE = new SceneGraphNodeKey(Node.class, "CONNECT_SG_NODE"); + + @Dependency TransformUtil util; + @Dependency ElementPainter diagramPainter; + @Dependency PickContext pickContext; + @Dependency PointerInteractor pi; + @Dependency MouseUtil mouseUtil; + @Dependency KeyUtil keys; + + boolean createFlags; + Point2D startPos; + + IElement startElement; + Terminal startTerminal; + + IElement endElement; + Terminal endTerminal; + + IDiagram inputDiagram; + MutatedDiagram ghostDiagram; + Topology topology; + + ElementClass connectionClass; + + ConnectionHandler connectionHandler; + IElement connection; + Deque edges = new ArrayDeque(); + Deque controlPoints = new ArrayDeque(); + int mouseId; + + Collection terminals = new ArrayList(); + + TerminalHoverStrategy originalStrategy = null; + TerminalHoverStrategy terminalHoverStrategy = new TerminalHoverStrategy() { + @Override + public boolean highlightEnabled() { + return true; + } + + @Override + public boolean highlight(TerminalInfo ti) { + IConnectionAdvisor advisor = diagram.getHint(DiagramHints.CONNECTION_ADVISOR); + return canConnect(advisor, ti.e, ti.t) != null; + } + }; + + public ConnectTool(IDiagram diagram, ElementClass connectionClass, IElement startElement, Terminal startTerminal, int mouseId, Point2D mouseDiagramPos) + { + this.inputDiagram = diagram; + this.connectionClass = connectionClass; + this.mouseId = mouseId; + this.startPos = mouseDiagramPos; + this.startElement = startElement; + this.startTerminal = startTerminal; + } + + @Override + public void addedToContext(ICanvasContext ctx) { + + super.addedToContext(ctx); + + // Force terminals to always be highlighted. + originalStrategy = getHint(TerminalPainter.TERMINAL_HOVER_STRATEGY); + setHint(TerminalPainter.TERMINAL_HOVER_STRATEGY, terminalHoverStrategy); + + // See if flags should be created or not + this.createFlags = Boolean.TRUE.equals(inputDiagram.getHint(DiagramHints.KEY_USE_CONNECTION_FLAGS)); + + // Mutate current diagram and add the connection to the mutated copy. + ghostDiagram = Diagram.mutate(inputDiagram); + topology = ghostDiagram.getDiagramClass().getSingleItem(Topology.class); + + IElement firstElement = null; + Terminal firstTerminal = null; + + // Where is start terminal? + if (startElement != null && startTerminal != null) { + // Whoomp, there it is. Is it already a part of an existing connection? + assert ElementUtils.peekDiagram(startElement) == inputDiagram; + IElement possibleConnection = getConnectionFromPart(startElement); + if (possibleConnection != null) { + // TODO: broken. + connection = ghostDiagram.getMutatedCorrespondence(possibleConnection); + } else { + connection = createConnection(connectionClass); + ghostDiagram.addElement(connection); + } + + connectionHandler = connection.getElementClass().getSingleItem(ConnectionHandler.class); + assert connectionHandler != null; + + firstElement = ghostDiagram.getMutatedCorrespondence(startElement); + firstTerminal = startTerminal; + } else { + connection = createConnection(connectionClass); + connectionHandler = connection.getElementClass().getSingleItem(ConnectionHandler.class); + assert connectionHandler != null; + ghostDiagram.addElement(connection); + + firstElement = createBranchPointOrFlag(startPos, EdgeEnd.Begin); + ArrayList terminals = new ArrayList(); + ElementUtils.getTerminals(firstElement, terminals, false); + firstTerminal = terminals.get(1); + startElement = firstElement; + startTerminal = firstTerminal; + } + + IElement secondElement = connectionHandler.newBranchPoint(connection); + controlPoints.add(secondElement); + // ghostDiagram.addElement(secondElement); + ElementUtils.setPos(secondElement, startPos); + Terminal secondTerminal = ElementUtils.getSingleTerminal(secondElement); + + IElement edge = connectionHandler.newEdge(connection); + edges.add(edge); + // ghostDiagram.addElement(edge); + + topology.connect(edge, EdgeEnd.Begin, firstElement, firstTerminal); + topology.connect(edge, EdgeEnd.End, secondElement, secondTerminal); + + } + + + + private void createValveIfNecessary(Point2D point) { + if(startElement != null && startElement.getElementClass().getId().equals(ValveFactory.class.getSimpleName())) { + return; + } else if(endElement != null && endElement.getElementClass().getId().equals(ValveFactory.class.getSimpleName())) { + return; + } + + ArrayList terminals = new ArrayList(); + + if(endElement != null) { + // Disconnect from end element + topology.disconnect(edges.peekLast(), EdgeEnd.End, ghostDiagram.getMutatedCorrespondence(endElement), endTerminal); + } else { + IElement lastBp = controlPoints.pollLast(); + ElementUtils.getTerminals(lastBp, terminals, true); + topology.disconnect(edges.peekLast(), EdgeEnd.End, lastBp, terminals.get(0)); + connectionHandler.removeBranchPoint(connection, lastBp); + } + + + // Set the position in the middle of the route + double startX = startPos.getX(); + double startY = startPos.getY(); + double x = point.getX(); + double y = point.getY(); + Point2D pos = new Point2D.Double((startX + x) / 2, (startY + y) / 2); + + // Create the valve + IElement end = createValve(pos); + + ElementUtils.getTerminals(end, terminals, true); + topology.connect(edges.peekLast(), EdgeEnd.End, end, terminals.get(0)); + DiagramUtils.validateAndFix(ghostDiagram, getContext()); + + + IElement firstElement = end; + Terminal firstTerminal = terminals.get(1); + + + IElement possibleConnection = getConnectionFromPart(firstElement); + if (possibleConnection != null) { + // TODO: broken. + connection = ghostDiagram.getMutatedCorrespondence(possibleConnection); + } else { + connection = createConnection(connectionClass); + ghostDiagram.addElement(connection); + } + + connectionHandler = connection.getElementClass().getSingleItem(ConnectionHandler.class); + + + + + IElement edge = connectionHandler.newEdge(connection); + edges.add(edge); + + topology.connect(edge, EdgeEnd.Begin, firstElement, firstTerminal); + + if (endElement != null) { + topology.connect(edge, EdgeEnd.End, ghostDiagram.getMutatedCorrespondence(endElement), endTerminal); + } else { + IElement secondElement = connectionHandler.newBranchPoint(connection); + controlPoints.add(secondElement); + ElementUtils.setPos(secondElement, pos); + Terminal secondTerminal = ElementUtils.getSingleTerminal(secondElement); + topology.connect(edge, EdgeEnd.End, secondElement, secondTerminal); + } + DiagramUtils.validateAndFix(ghostDiagram, getContext()); + + } + + @Override + public void removedFromContext(ICanvasContext ctx) { + + if (getHint(TerminalPainter.TERMINAL_HOVER_STRATEGY) == terminalHoverStrategy) { + if (originalStrategy != null) + setHint(TerminalPainter.TERMINAL_HOVER_STRATEGY, originalStrategy); + else + removeHint(TerminalPainter.TERMINAL_HOVER_STRATEGY); + } + + ghostDiagram.destroy(); + + super.removedFromContext(ctx); + } + + final static Composite ALPHA_COMPOSITE = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.75f); + public static final int PAINT_PRIORITY = ElementPainter.ELEMENT_PAINT_PRIORITY + 5; + + protected G2DParentNode node = null; + + @SGInit + public void initSG(G2DParentNode parent) { + node = parent.addNode(G2DParentNode.class); + node.setZIndex(PAINT_PRIORITY); + update(); + } + + public void update() { + if (ghostDiagram != null) { + diagramPainter.paintDiagram(node, ghostDiagram, ghostDiagram.getDifferences(), KEY_SG_NODE); + } + } + + @SGCleanup + public void cleanupSG() { + node.remove(); + node = null; + } + + boolean cancelPreviousBend() { + if (!routePointsAllowed()) + return false; + + // If not at the first branch point, remove the last branch + // point and edge. Otherwise, cancel action + if (controlPoints.size() < 2) { + DiagramMutator mutator = diagram.getHint(DiagramHints.KEY_MUTATOR); + mutator.clear(); + update(); + remove(); + return true; + } + // Cancel prev bend + IElement lastControlPoint = controlPoints.removeLast(); + IElement prevControlPoint = controlPoints.peekLast(); + IElement lastEdge = edges.removeLast(); + for (Terminal t : ElementUtils.getTerminals(lastControlPoint, terminals, true)) + topology.disconnect(lastEdge, EdgeEnd.End, lastControlPoint, t); + for (Terminal t : ElementUtils.getTerminals(prevControlPoint, terminals, true)) + topology.disconnect(lastEdge, EdgeEnd.Begin, prevControlPoint, t); + connectionHandler.removeBranchPoint(connection, lastControlPoint); + connectionHandler.removeEdge(connection, lastEdge); + Point2D mousePos = mouseUtil.getMouseInfo(mouseId).canvasPosition; + ElementUtils.setPos(controlPoints.peekLast(), mousePos); + DiagramUtils.validateAndFix(ghostDiagram, getContext()); + update(); + setDirty(); + return true; + } + + @EventHandler(priority = 20) + public boolean handleEvent(Event e) { + // Back-space, cancel prev bend + if (e instanceof KeyPressedEvent) { + KeyEvent ke = (KeyEvent) e; + if (ke.keyCode == java.awt.event.KeyEvent.VK_BACK_SPACE) { + return cancelPreviousBend(); + } + } + if (e instanceof CommandEvent) { + CommandEvent ce = (CommandEvent) e; + if (ce.command.equals(Commands.CANCEL)) + { + DiagramMutator mutator = diagram.getHint(DiagramHints.KEY_MUTATOR); + mutator.clear(); + update(); + remove(); + return true; + } + } + if (e instanceof MouseMovedEvent) { + MouseMovedEvent me = (MouseMovedEvent) e; + Point2D mouseControlPos = me.controlPosition; + Point2D mouseCanvasPos = util.controlToCanvas(mouseControlPos, new Point2D.Double()); + + ISnapAdvisor snapAdvisor = getHint(DiagramHints.SNAP_ADVISOR); + if (snapAdvisor != null) + snapAdvisor.snap(mouseCanvasPos); + + List tiList = ((org.simantics.sysdyn.ui.editor.participant.PointerInteractor)pi).pickTerminals(me.controlPosition); + TerminalInfo ti = null; + + IConnectionAdvisor advisor = diagram.getHint(DiagramHints.CONNECTION_ADVISOR); + for(TerminalInfo info : tiList) { + if(advisor == null || info.e == null || info.t == null) + continue; + Object canConnect = canConnect(advisor, info.e, info.t); + if (canConnect != null) { + connection.setHint(ElementHints.KEY_CONNECTION_TYPE, canConnect); + ti = info; + } + } + + if (ti != null && !(ti.e == startElement && ti.t == startTerminal)) { + if (endElement == null) { + endElement = ti.e; + endTerminal = ti.t; + + IElement lastControlPoint = controlPoints.pollLast(); + topology.disconnect(edges.peekLast(), EdgeEnd.End, lastControlPoint, ElementUtils.getSingleTerminal(lastControlPoint)); + connectionHandler.removeBranchPoint(connection, lastControlPoint); + + topology.connect(edges.peekLast(), EdgeEnd.End, ghostDiagram.getMutatedCorrespondence(endElement), endTerminal); + DiagramUtils.validateAndFix(ghostDiagram, getContext()); + } else if (!ti.e.equals(endElement) || !ti.t.equals(endTerminal)) { + topology.disconnect(edges.peekLast(), EdgeEnd.End, ghostDiagram.getMutatedCorrespondence(endElement), endTerminal); + + endElement = ti.e; + endTerminal = ti.t; + + topology.connect(edges.peekLast(), EdgeEnd.End, ghostDiagram.getMutatedCorrespondence(endElement), endTerminal); + DiagramUtils.validateAndFix(ghostDiagram, getContext()); + } + + update(); + setDirty(); + return false; + } + + { + connection.removeHint(ElementHints.KEY_CONNECTION_TYPE); + if (endElement != null) { + topology.disconnect(edges.peekLast(), EdgeEnd.End, ghostDiagram.getMutatedCorrespondence(endElement), endTerminal); + + endElement = null; + endTerminal = null; + + IElement bp = connectionHandler.newBranchPoint(connection); + controlPoints.add(bp); + // ghostDiagram.addElement(bp); + ElementUtils.setPos(controlPoints.peekLast(), mouseCanvasPos); + + topology.connect(edges.peekLast(), EdgeEnd.End, bp, ElementUtils.getSingleTerminal(bp)); + } else { + ElementUtils.setPos(controlPoints.peekLast(), mouseCanvasPos); + } + DiagramUtils.validateAndFix(ghostDiagram, getContext()); + + update(); + setDirty(); + } + + } + + if (e instanceof MouseButtonPressedEvent) { + MouseButtonEvent me = (MouseButtonEvent) e; + if (me.button==MouseEvent.LEFT_BUTTON && me.mouseId==mouseId) { + Point2D mouseControlPos = me.controlPosition; + final Point2D mouseCanvasPos = util.getInverseTransform().transform(mouseControlPos, new Point2D.Double()); + + ISnapAdvisor snapAdvisor = getHint(DiagramHints.SNAP_ADVISOR); + if (snapAdvisor != null) + snapAdvisor.snap(mouseCanvasPos); + + // Clicked on a terminal .. End connection, End mode + if (endElement != null) { + attachToBranchPoint(); + createValveIfNecessary(mouseCanvasPos); + commitDiagram(); + update(); + remove(); // Remove ConnectTool participant + return true; + } else { + if (isCurrentConnectionFlow() && startElement != null && startTerminal != null) { + + createValveIfNecessary(mouseCanvasPos); + + IConnectionAdvisor advisor = diagram.getHint(DiagramHints.CONNECTION_ADVISOR); + Object canConnect = canConnect(advisor, null, null); + if (canConnect != null) + connection.setHint(ElementHints.KEY_CONNECTION_TYPE, canConnect); + + // Finish connection in thin air only if the + // connection was started from a valid terminal. + if (createFlags) { + // Replace the last branch point with a flag. + IElement lastBp = controlPoints.pollLast(); + topology.disconnect(edges.peekLast(), EdgeEnd.End, lastBp, ElementUtils.getSingleTerminal(lastBp)); + connectionHandler.removeBranchPoint(connection, lastBp); + + IElement end = createFlag(mouseCanvasPos, EdgeEnd.End); + ArrayList terminals = new ArrayList(); + ElementUtils.getTerminals(end, terminals, false); + Terminal endTerminal = terminals.get(0); + topology.connect(edges.peekLast(), EdgeEnd.End, end, endTerminal); + } + + DiagramUtils.validateAndFix(ghostDiagram, getContext()); + commitDiagram(); + update(); + remove(); // Remove ConnectTool participant + return true; + } + } + + } + } + + // Don't let any events slip to creator participant + if (e instanceof MouseEvent) { + MouseEvent me = (MouseEvent) e; + return me.mouseId == mouseId; + } + + return false; + } + + + + + private boolean isCurrentConnectionFlow() { + // Could this check be done better? + Boolean isFlow = false; try { isFlow = SimanticsUI.getSession().syncRequest(new Read() { @Override public Boolean perform(ReadGraph graph) - throws DatabaseException { + throws DatabaseException { SysdynResource sr = SysdynResource.getInstance(graph); - StaticObjectAdapter soa = connectionClass.getSingleItem(StaticObjectAdapter.class); - Resource conntype = soa.adapt(Resource.class); + StaticObjectAdapter soa = connectionClass.getSingleItem(StaticObjectAdapter.class); + Resource conntype = soa.adapt(Resource.class); return conntype.equals(sr.FlowConnection); } - + }); } catch (DatabaseException e1) { e1.printStackTrace(); } return isFlow; - } - private void createValveIfNecessary() { - System.out.println("CREATE VALVE IF NECESSARY"); - } - - private void attachToBranchPoint() { - DiagramUtils.inDiagramTransaction(diagram, TransactionType.WRITE, new Runnable() { - - @Override - public void run() { - - // We are attaching to a branch point - some reordering is needed! - if (endElement.getElementClass().containsClass(BranchPoint.class)) { - - // Scrap everything we have and reconstruct - DiagramMutator mutator = diagram.getHint(DiagramHints.KEY_MUTATOR); - mutator.clear(); - - HashMap bps = new HashMap(); - for(IElement bp : controlPoints) { - IElement nbp = mutator.newBranchPoint(endElement); - Point2D pos = ElementUtils.getPos(bp); - ElementUtils.setPos(nbp, pos); - bps.put(bp, nbp); - } - - for(IElement edge : edges) { - IElement newEdge = mutator.newEdge(endElement); - - // Disconnect and remove old edge - Connection b = mutator.getConnection(edge, EdgeEnd.Begin); - Connection e = mutator.getConnection(edge, EdgeEnd.End); - - IElement mappedB = bps.get(b.node) != null ? bps.get(b.node) : b.node; - IElement mappedE = bps.get(e.node) != null ? bps.get(e.node) : e.node; - - mutator.connect(newEdge, b.end, mappedB, b.terminal); - mutator.connect(newEdge, e.end, mappedE, e.terminal); - } - } - } - }); - } - - private void commitDiagram() { - DiagramMutator mutator = diagram.getHint(DiagramHints.KEY_MUTATOR); - mutator.commit(); - } - - FlagClass.Type endToFlagType(EdgeEnd end) { - switch (end) { - case Begin: return FlagClass.Type.In; - case End: return FlagClass.Type.Out; - default: throw new IllegalArgumentException("unrecognized edge end: " + end); - } - } - - IElement createConnection(ElementClass element) { - DiagramMutator mutator = diagram.getHint(DiagramHints.KEY_MUTATOR); - return mutator.newConnection(element); - } - - IElement createFlag(Point2D pos, EdgeEnd connectionEnd) { - - DiagramMutator mutator = diagram.getHint(DiagramHints.KEY_MUTATOR); - IElement e = mutator.newFlag(); - -// FlagHandler fh = e.getElementClass().getSingleItem(FlagHandler.class); -// fh.setType(e, endToFlagType(connectionEnd)); - //fh.setMode(e, FlagClass.Mode.Internal); - ElementUtils.setPos(e, pos); - - ghostDiagram.addElement(e); - - return e; - - } - - /** - * Try to get a connection element from a connection part element. - * - * @param e a potential connection part - * @return null if e is not part a part of a connection. - */ - IElement getConnectionFromPart(IElement e) { - Parent parent = e.getElementClass().getAtMostOneItemOfClass(Parent.class); - if (parent == null) - return null; - IElement p = parent.getParent(e); - if (!p.getElementClass().containsClass(ConnectionHandler.class)) - return null; - return p; - } - - IElement createBranchPointOrFlag(Point2D pos, EdgeEnd connectionEnd) { - IElement e = null; - if (createFlags) { - e = createFlag(pos, connectionEnd); - } else { - e = connectionHandler.newBranchPoint(connection); - ElementUtils.setPos(e, pos); - } - return e; - } - - boolean routePointsAllowed() { - return Boolean.TRUE.equals(diagram.getHint(DiagramHints.KEY_ALLOW_ROUTE_POINTS)); - } - - Object canConnect(final IConnectionAdvisor advisor, final IElement endElement, final Terminal endTerminal) { - if(startElement.equals(endElement)) return null; - - if(endElement == null && endTerminal == null) - return advisor.canBeConnected(null, startElement, startTerminal, endElement, endTerminal); - - try { - return SimanticsUI.getSession().syncRequest(new Read() { - - @Override - public Object perform(ReadGraph g) throws DatabaseException { - - // Checking if connection type can be connected to the intended endElement - SysdynResource sr = SysdynResource.getInstance(g); - if(connection != null) { - StaticObjectAdapter soa = connectionClass.getSingleItem(StaticObjectAdapter.class); - Resource conntype = soa.adapt(Resource.class); - soa = endElement.getElementClass().getSingleItem(StaticObjectAdapter.class); - Resource end = soa.adapt(Resource.class); - if(conntype.equals(sr.DependencyConnection)) { - if(end.equals(sr.CloudSymbol)) return null; - //if(!(end.equals(sr.AuxiliarySymbol) || end.equals(sr.ValveSymbol))) return null; - } else if (conntype.equals(sr.FlowConnection)) { - if(!(end.equals(sr.StockSymbol) || end.equals(sr.ValveSymbol) || end.equals(sr.CloudSymbol))) return null; - } else { - return null; - } - } - - - if (advisor == null) - return Boolean.TRUE; - return advisor.canBeConnected(g, startElement, startTerminal, endElement, endTerminal); - } - - }); - } catch(DatabaseException e) { - e.printStackTrace(); - return null; - } - - } + } + + + private void attachToBranchPoint() { + DiagramUtils.inDiagramTransaction(diagram, TransactionType.WRITE, new Runnable() { + + @Override + public void run() { + + // We are attaching to a branch point - some reordering is needed! + if (endElement.getElementClass().containsClass(BranchPoint.class)) { + + // Scrap everything we have and reconstruct + DiagramMutator mutator = diagram.getHint(DiagramHints.KEY_MUTATOR); + mutator.clear(); + + HashMap bps = new HashMap(); + for(IElement bp : controlPoints) { + IElement nbp = mutator.newBranchPoint(endElement); + Point2D pos = ElementUtils.getPos(bp); + ElementUtils.setPos(nbp, pos); + bps.put(bp, nbp); + } + + for(IElement edge : edges) { + IElement newEdge = mutator.newEdge(endElement); + + // Disconnect and remove old edge + Connection b = mutator.getConnection(edge, EdgeEnd.Begin); + Connection e = mutator.getConnection(edge, EdgeEnd.End); + + IElement mappedB = bps.get(b.node) != null ? bps.get(b.node) : b.node; + IElement mappedE = bps.get(e.node) != null ? bps.get(e.node) : e.node; + + mutator.connect(newEdge, b.end, mappedB, b.terminal); + mutator.connect(newEdge, e.end, mappedE, e.terminal); + } + } + } + }); + } + + private void commitDiagram() { + DiagramMutator mutator = diagram.getHint(DiagramHints.KEY_MUTATOR); + mutator.commit(); + } + + FlagClass.Type endToFlagType(EdgeEnd end) { + switch (end) { + case Begin: return FlagClass.Type.In; + case End: return FlagClass.Type.Out; + default: throw new IllegalArgumentException("unrecognized edge end: " + end); + } + } + + IElement createConnection(ElementClass element) { + DiagramMutator mutator = diagram.getHint(DiagramHints.KEY_MUTATOR); + return mutator.newConnection(element); + } + + IElement createFlag(Point2D pos, EdgeEnd connectionEnd) { + + DiagramMutator mutator = diagram.getHint(DiagramHints.KEY_MUTATOR); + IElement e = mutator.newFlag(); + + // FlagHandler fh = e.getElementClass().getSingleItem(FlagHandler.class); + // fh.setType(e, endToFlagType(connectionEnd)); + //fh.setMode(e, FlagClass.Mode.Internal); + ElementUtils.setPos(e, pos); + + ghostDiagram.addElement(e); + + return e; + + } + + IElement createValve(Point2D pos) { + DiagramMutator mutator = diagram.getHint(DiagramHints.KEY_MUTATOR); + + ElementClass ec = null; + try { + Resource r = SimanticsUI + .getSession() + .syncRequest( + Queries + .resource(SysdynResource.URIs.ValveSymbol)); + ec = SimanticsUI.getSession().syncRequest( + DiagramRequests.getElementClass(r, diagram)); + + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + + if(ec == null) return null; + + IElement e = mutator.newElement(ec); + + ElementUtils.setPos(e, pos); + + ghostDiagram.addElement(e); + + return e; + } + + /** + * Try to get a connection element from a connection part element. + * + * @param e a potential connection part + * @return null if e is not part a part of a connection. + */ + IElement getConnectionFromPart(IElement e) { + Parent parent = e.getElementClass().getAtMostOneItemOfClass(Parent.class); + if (parent == null) + return null; + IElement p = parent.getParent(e); + if (!p.getElementClass().containsClass(ConnectionHandler.class)) + return null; + return p; + } + + IElement createBranchPointOrFlag(Point2D pos, EdgeEnd connectionEnd) { + IElement e = null; + if (createFlags) { + e = createFlag(pos, connectionEnd); + } else { + e = connectionHandler.newBranchPoint(connection); + ElementUtils.setPos(e, pos); + } + return e; + } + + boolean routePointsAllowed() { + return Boolean.TRUE.equals(diagram.getHint(DiagramHints.KEY_ALLOW_ROUTE_POINTS)); + } + + Object canConnect(final IConnectionAdvisor advisor, final IElement endElement, final Terminal endTerminal) { + if(startElement.equals(endElement)) return null; + + if(endElement == null && endTerminal == null) + return advisor.canBeConnected(null, startElement, startTerminal, endElement, endTerminal); + + try { + return SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Object perform(ReadGraph g) throws DatabaseException { + + // Checking if connection type can be connected to the intended endElement + SysdynResource sr = SysdynResource.getInstance(g); + if(connection != null) { + StaticObjectAdapter soa = connectionClass.getSingleItem(StaticObjectAdapter.class); + Resource conntype = soa.adapt(Resource.class); + soa = endElement.getElementClass().getSingleItem(StaticObjectAdapter.class); + Resource end = soa.adapt(Resource.class); + if(conntype.equals(sr.DependencyConnection)) { + if(end.equals(sr.CloudSymbol)) return null; + //if(!(end.equals(sr.AuxiliarySymbol) || end.equals(sr.ValveSymbol))) return null; + } else if (conntype.equals(sr.FlowConnection)) { + if(!(end.equals(sr.StockSymbol) || end.equals(sr.ValveSymbol) || end.equals(sr.CloudSymbol))) return null; + } else { + return null; + } + } + + + if (advisor == null) + return Boolean.TRUE; + return advisor.canBeConnected(g, startElement, startTerminal, endElement, endTerminal); + } + + }); + } catch(DatabaseException e) { + e.printStackTrace(); + return null; + } + + } } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ValveFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ValveFactory.java index ffcadcdb..b37a7a7e 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ValveFactory.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ValveFactory.java @@ -20,6 +20,7 @@ import java.util.Collection; import org.simantics.db.Resource; import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.ElementHints; import org.simantics.g2d.element.ElementUtils; import org.simantics.g2d.element.IElement; import org.simantics.g2d.element.SceneGraphNodeKey; @@ -124,7 +125,8 @@ public class ValveFactory extends SysdynElementFactory { node.setScaleStroke(true); node.setColor(Color.BLACK); node.setShape(createShape(VALVE_SIZE, Boolean.TRUE.equals(e.getHint(KEY_ROTATED)))); - node.setHover(ElementUtils.isHovering(e)); + Boolean hover = e.getHint(ElementHints.KEY_HOVER); + node.setHover(hover != null ? hover : false); if(at != null) node.setTransform(at); -- 2.47.1