From d7dab6bbd23c7406cf67ca70b4e077dc8d15d36e Mon Sep 17 00:00:00 2001 From: lempinen Date: Thu, 24 Jun 2010 09:08:35 +0000 Subject: [PATCH] All this stuff to make sysdyn connections partially working git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@16326 ac1ea38d-2e2b-0410-8846-a27921b304fc --- org.simantics.sysdyn.ui/adapters.xml | 2 +- .../LibraryViewpointContributor.java | 2 + .../ui/editor/DiagramToCompositeMapping3.java | 142 +++-- .../sysdyn/ui/editor/DiagramViewer.java | 21 +- .../ui/editor/participant/ConnectTool.java | 502 ++++++++++++++++++ .../editor/participant/PointerInteractor.java | 185 +++++++ .../ui/elements2/ConnectionClasses.java | 20 + .../DependencyConnectionFactory.java | 60 +++ ...dgeClass.java => DependencyEdgeClass.java} | 23 +- .../ui/elements2/DependencyEdgeFactory.java | 43 ++ .../sysdyn/ui/elements2/DependencyNode.java | 182 +++++++ ...actory.java => FlowConnectionFactory.java} | 5 +- .../sysdyn/ui/elements2/FlowEdgeClass.java | 198 +++++++ ...nEdgeFactory.java => FlowEdgeFactory.java} | 6 +- .../sysdyn/ui/elements2/FlowNode.java | 182 +++++++ .../sysdyn/ui/elements2/FlowStroke.java | 18 + .../org/simantics/sysdyn/SysdynResource.java | 9 +- sysdyn_ontologies/sysdyn.graph | 15 +- 18 files changed, 1538 insertions(+), 77 deletions(-) create mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/ConnectTool.java create mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/PointerInteractor.java create mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ConnectionClasses.java create mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyConnectionFactory.java rename org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/{SysdynEdgeClass.java => DependencyEdgeClass.java} (91%) create mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyEdgeFactory.java create mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyNode.java rename org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/{SysdynConnectionFactory.java => FlowConnectionFactory.java} (88%) create mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowEdgeClass.java rename org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/{SysdynConnectionEdgeFactory.java => FlowEdgeFactory.java} (85%) create mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowNode.java create mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowStroke.java diff --git a/org.simantics.sysdyn.ui/adapters.xml b/org.simantics.sysdyn.ui/adapters.xml index 8fb25f46..dce8a8e7 100644 --- a/org.simantics.sysdyn.ui/adapters.xml +++ b/org.simantics.sysdyn.ui/adapters.xml @@ -25,5 +25,5 @@ - + \ No newline at end of file diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/LibraryViewpointContributor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/LibraryViewpointContributor.java index 50ab222a..fd43e11f 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/LibraryViewpointContributor.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/LibraryViewpointContributor.java @@ -19,6 +19,7 @@ import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.exception.DatabaseException; import org.simantics.db.request.Read; +import org.simantics.sysdyn.SysdynResource; import org.simantics.sysdyn.ui.browser.nodes.AbstractNode; /** @@ -35,6 +36,7 @@ public abstract class LibraryViewpointContributor extend ArrayList result = new ArrayList(); for (Resource r : graph.syncRequest(getChildRequest(graph, lib))) { try { + System.out.println("Is Flow? " + graph.isInstanceOf(r, SysdynResource.getInstance(graph).Flow)); AbstractNode n = graph.adapt(r, AbstractNode.class); result.add(n); } catch (DatabaseException e) { diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramToCompositeMapping3.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramToCompositeMapping3.java index 2eed79ee..27bfbfab 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramToCompositeMapping3.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramToCompositeMapping3.java @@ -17,75 +17,113 @@ import org.simantics.db.exception.DatabaseException; import org.simantics.layer0.utils.binaryPredicates.InversePredicate; import org.simantics.layer0.utils.binaryPredicates.OrderedSetElementsPredicate; import org.simantics.mapping.constraint.instructions.IInstruction; +import org.simantics.mapping.constraint.instructions.PrintStateInstruction; import org.simantics.mapping.constraint.instructions.TypedBracketInstruction.CreationInstruction; import org.simantics.mapping.rule.instructions.IRuleInstruction; -import org.simantics.modeling.mapping.NamingCreationInstruction; import org.simantics.sysdyn.SysdynResource; public class DiagramToCompositeMapping3 extends org.simantics.modeling.mapping.DiagramToCompositeMapping3 { - private SysdynResource sdr; + private SysdynResource sdr; - public DiagramToCompositeMapping3(ReadGraph g, Resource mapping) - throws DatabaseException { - super(g, mapping); - } + public DiagramToCompositeMapping3(ReadGraph g, Resource mapping) + throws DatabaseException { + super(g, mapping); + } - @Override - protected void setup(ReadGraph graph) { - sdr = SysdynResource.getInstance(graph); - } + @Override + protected void setup(ReadGraph graph) { + sdr = SysdynResource.getInstance(graph); + } - @Override - protected Resource getConfigurationConnectionType() { - return sdr.Flow; - } + @Override + protected Resource getConfigurationConnectionType() { + return sdr.DependencyConnection; + } - public CreationInstruction componentCreationInstruction(int component, int componentType, int configuration) { - return new SysdynCreationInstruction(project, configurationRoot, component, componentType, configuration); - } - - @Override - protected IRuleInstruction destructiveRule() { - return - if_(and(bf(b.ConsistsOf, Configuration, Component), + @Override + public CreationInstruction componentCreationInstruction(int component, int componentType, int configuration) { + return new SysdynCreationInstruction(project, configurationRoot, component, componentType, configuration); + } + + @Override + protected IRuleInstruction additiveRule() { + return + + if_(bf(OrderedSetElementsPredicate.INSTANCE, Diagram, Element), + query( + if_(and(bf(b.InstanceOf, Element, ElementType), + bf(mr.SymbolToComponentType, ElementType, ComponentType) + ), + // If element type of the element has a corresponding component type + createComponentRule(), + + if_(and(b(dr.Connection, Element), bf(b.InstanceOf, Element, ElementType), bf(mr.DiagramConnectionTypeToConnectionType, ElementType, ComponentType)), + createNormalConnectionRule(), + + if_(b(dr.Flag, Element), + createFlagRule() + ) + ) + ) + ) + ); + } + + @Override + protected IRuleInstruction destructiveRule() { + return + if_(and(bf(b.ConsistsOf, Configuration, Component), b(mapped, Component) // handle only mapped components - ), - query( + ), + query( if_(and(bf(mr.ComponentToElement, Component, Element), bf(new InversePredicate(OrderedSetElementsPredicate.INSTANCE), Element, Diagram) - ), - // If component has a corresponding element in the diagram - if_(and(statement_bff(Component, ConnectionRelation, Connection, sr.IsConnectedTo), - b(mapped, Connection) - ), - // If component has a mapped connection - unless( - bf(mr.ConnectionToDiagramConnection, Connection, DiagramConnectionRelation), - // If the configuration connection does not have a correspondence in the diagram remove it - and(deny(exists(Connection))) - ) - ), + ), + // If component has a corresponding element in the diagram + if_(and(statement_bff(Component, ConnectionRelation, Connection, sr.IsConnectedTo), + b(mapped, Connection) + ), + // If component has a mapped connection + unless( + bf(mr.ConnectionToDiagramConnection, Connection, DiagramConnectionRelation), + // If the configuration connection does not have a correspondence in the diagram remove it + and(deny(exists(Connection))) + ) + ), + + unless( + bf(mr.ConnectionToDiagramConnection, Component, Element), + // If the configuration connection does not have a correspondence in the diagram remove it + and(deny(exists(Component))) + ) - unless( - bf(mr.ConnectionToDiagramConnection, Component, Element), - // If the configuration connection does not have a correspondence in the diagram remove it - and(deny(exists(Component))) - ) - ) - ) + ) ); - } - - protected IInstruction claimBasicConnection() { - return and(exists( + } + + @Override + protected IInstruction claimBasicConnection() { + return and(exists( bf(mr.DiagramConnectionToConnection, Element, Connection), Connection - ), - bb(b.InstanceOf, Connection, ConnectionType), - bb(b.PartOf, Connection, Configuration) - ); - } + ), + bb(b.InstanceOf, Connection, ComponentType), + b(mapped, Connection) + ); + } + +// @Override +// protected IInstruction claimBasicConnection() { +// return and(exists( +// bf(mr.DiagramConnectionToConnection, Element, Connection), +// Connection +// ), +// bb(b.InstanceOf, Connection, ComponentType), +// b(mapped, Connection), +// bb(b.PartOf, Connection, Configuration) +// ); +// } } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramViewer.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramViewer.java index e223b193..a130c3a8 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramViewer.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramViewer.java @@ -14,6 +14,7 @@ import org.simantics.g2d.canvas.ICanvasContext; import org.simantics.g2d.canvas.impl.CanvasContext; import org.simantics.g2d.diagram.DiagramHints; import org.simantics.g2d.diagram.participant.DeleteHandler; +import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor; import org.simantics.g2d.element.ElementClassProviders; import org.simantics.g2d.element.ElementClasses; import org.simantics.g2d.element.IElementClassProvider; @@ -21,6 +22,8 @@ import org.simantics.g2d.element.handler.impl.StaticObjectAdapter; import org.simantics.g2d.elementclass.connection.ConnectionClass; import org.simantics.modeling.ui.diagramEditor.handlers.WorkbenchStructuralSelectionProvider2; import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.elements2.ConnectionClasses; +import org.simantics.sysdyn.ui.elements2.SysdynConnectionClass; import org.simantics.sysdyn.ui.properties.SysdynPropertyPage; /** @@ -42,10 +45,15 @@ public class DiagramViewer extends org.simantics.modeling.ui.diagramEditor.Diagr protected IElementClassProvider createElementClassProvider(ReadGraph graph) { DiagramResource dr = DiagramResource.getInstance(graph); SysdynResource sr = SysdynResource.getInstance(graph); + return ElementClassProviders.mappedProvider( - ElementClasses.CONNECTION, ConnectionClass.CLASS.newClassWith(new StaticObjectAdapter(sr.Connection)), - ElementClasses.FLAG, FlagClassFactory.createFlagClass(dr.Flag) + ElementClasses.CONNECTION, SysdynConnectionClass.CLASS.newClassWith(new StaticObjectAdapter(sr.FlowConnection)), + ElementClasses.FLAG, FlagClassFactory.createFlagClass(dr.Flag), + ConnectionClasses.FLOW, SysdynConnectionClass.CLASS.newClassWith(new StaticObjectAdapter(sr.FlowConnection)), + ConnectionClasses.DEPENDENCY, SysdynConnectionClass.CLASS.newClassWith(new StaticObjectAdapter(sr.DependencyConnection)) ); + + } @Override @@ -73,4 +81,13 @@ public class DiagramViewer extends org.simantics.modeling.ui.diagramEditor.Diagr ctx.add(new WorkbenchStructuralSelectionProvider2(swt, getSite(), structuralPath)); } + @Override + protected void addOtherParticipants(CanvasContext ctx) { + } + + @Override + protected PointerInteractor getPointerInteractor() { + return new org.simantics.sysdyn.ui.editor.participant.PointerInteractor(true, true, true, false, true, false, synchronizer.getElementClassProvider()); + } + } 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 new file mode 100644 index 00000000..6bb112b6 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/ConnectTool.java @@ -0,0 +1,502 @@ +package org.simantics.sysdyn.ui.editor.participant; + +import java.awt.AlphaComposite; +import java.awt.Composite; +import java.awt.geom.Point2D; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Deque; +import java.util.HashMap; +import java.util.List; + +import org.simantics.db.Resource; +import org.simantics.diagram.content.ResourceTerminal; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency; +import org.simantics.g2d.canvas.impl.SGNodeReflection.SGCleanup; +import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit; +import org.simantics.g2d.command.CommandEvent; +import org.simantics.g2d.command.Commands; +import org.simantics.g2d.connection.IConnectionAdvisor; +import org.simantics.g2d.connection.handler.ConnectionHandler; +import org.simantics.g2d.diagram.DiagramHints; +import org.simantics.g2d.diagram.DiagramMutator; +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; +import org.simantics.g2d.diagram.handler.Topology.Connection; +import org.simantics.g2d.diagram.handler.Topology.Terminal; +import org.simantics.g2d.diagram.handler.TransactionContext.TransactionType; +import org.simantics.g2d.diagram.impl.Diagram; +import org.simantics.g2d.diagram.impl.MutatedDiagram; +import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant; +import org.simantics.g2d.diagram.participant.ElementPainter; +import org.simantics.g2d.diagram.participant.TerminalPainter; +import org.simantics.g2d.diagram.participant.TerminalPainter.TerminalHoverStrategy; +import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor; +import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil.TerminalInfo; +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.IElementClassProvider; +import org.simantics.g2d.element.SceneGraphNodeKey; +import org.simantics.g2d.element.handler.Parent; +import org.simantics.g2d.element.handler.EdgeVisuals.EdgeEnd; +import org.simantics.g2d.elementclass.BranchPoint; +import org.simantics.g2d.elementclass.FlagClass; +import org.simantics.g2d.elementclass.FlagHandler; +import org.simantics.g2d.event.Event; +import org.simantics.g2d.event.KeyEvent; +import org.simantics.g2d.event.MouseEvent; +import org.simantics.g2d.event.EventHandlerReflection.EventHandler; +import org.simantics.g2d.event.KeyEvent.KeyPressedEvent; +import org.simantics.g2d.event.MouseEvent.MouseButtonEvent; +import org.simantics.g2d.event.MouseEvent.MouseButtonPressedEvent; +import org.simantics.g2d.event.MouseEvent.MouseMovedEvent; +import org.simantics.g2d.participant.KeyUtil; +import org.simantics.g2d.participant.MouseUtil; +import org.simantics.g2d.participant.TransformUtil; +import org.simantics.g2d.snap.ISnapAdvisor; +import org.simantics.scenegraph.Node; +import org.simantics.scenegraph.g2d.G2DParentNode; +import org.simantics.sysdyn.ui.elements2.ConnectionClasses; +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); + firstTerminal = ElementUtils.getSingleTerminal(firstElement); + 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; + 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(); + 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 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(IConnectionAdvisor advisor, IElement endElement, Terminal endTerminal) { + // Making sure that tail (head) terminal doesn't connect to another tail (head) terminal + Resource t1 = ((ResourceTerminal) startTerminal).getResource(); + Resource t2 = ((ResourceTerminal) endTerminal).getResource(); + if (startElement.equals(endElement) || t1.equals(t2)) + return null; + + if (advisor == null) + return Boolean.TRUE; + return advisor.canBeConnected(null, startElement, startTerminal, endElement, endTerminal); + } + + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/PointerInteractor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/PointerInteractor.java new file mode 100644 index 00000000..17f78792 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/PointerInteractor.java @@ -0,0 +1,185 @@ +package org.simantics.sysdyn.ui.editor.participant; +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ + +import java.awt.Shape; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.util.List; + +import org.simantics.g2d.canvas.Hints; +import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency; +import org.simantics.g2d.canvas.impl.DependencyReflection.Reference; +import org.simantics.g2d.connection.IConnectionAdvisor; +import org.simantics.g2d.diagram.DiagramHints; +import org.simantics.g2d.diagram.handler.PickContext; +import org.simantics.g2d.diagram.participant.Selection; +import org.simantics.g2d.diagram.participant.TerminalPainter; +import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil; +import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil.TerminalInfo; +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.IElementClassProvider; +import org.simantics.g2d.event.MouseEvent; +import org.simantics.g2d.event.EventHandlerReflection.EventHandler; +import org.simantics.g2d.event.MouseEvent.MouseButtonPressedEvent; +import org.simantics.g2d.participant.KeyUtil; +import org.simantics.g2d.participant.MouseUtil; +import org.simantics.g2d.participant.TransformUtil; +import org.simantics.g2d.routing.RouterFactory; +import org.simantics.g2d.snap.ISnapAdvisor; +import org.simantics.g2d.utils.GeometryUtils; +import org.simantics.sysdyn.ui.elements2.ConnectionClasses; + +/** + * Pointer tool does the following operations with mouse: + * - Selections + * - Scale + * - Rotate + * - Translate + * - Draws connections + * + * + * Pointer tool is active only when KEY_TOOLMODE is PointerToolMode + * + * TODO Pick rectangle not a point + * + * @author Toni Kalajainen + */ +public class PointerInteractor extends org.simantics.g2d.diagram.participant.pointertool.PointerInteractor { + + @Dependency Selection selection; + @Dependency KeyUtil keys; + @Dependency TransformUtil util; + @Dependency PickContext pickContext; + @Dependency MouseUtil mice; + @Reference TerminalPainter terminalPainter; + + public PointerInteractor(boolean clickSelect, boolean boxSelect, boolean dragElement, boolean dndDragElement, boolean connect, boolean doubleClickEdit, IElementClassProvider newConnectionClassProvider) { + super(clickSelect, boxSelect, dragElement, dndDragElement, connect, doubleClickEdit, newConnectionClassProvider); + } + + @EventHandler(priority = TOOL_PRIORITY) + public boolean handlePress(MouseButtonPressedEvent me) { + if (!connects()) return false; +// if (me.button != MouseEvent.LEFT_BUTTON) return false; + if (getHint(Hints.KEY_TOOL) != Hints.POINTERTOOL) return false; + assertDependencies(); + Point2D curCanvasPos = util.controlToCanvas(me.controlPosition, null); + + // Pick Terminal + TerminalInfo ti = pickTerminal(me.controlPosition); + + if(elementClassProvider != null) { + + ElementClass connectionClass = null; + + if( me.button == MouseEvent.LEFT_BUTTON && (me.stateMask & MouseEvent.ALT_MASK) != 0) { + diagram.setHint(DiagramHints.ROUTE_ALGORITHM, RouterFactory.create(false, false)); + connectionClass = elementClassProvider.get(ConnectionClasses.DEPENDENCY); + + } else if (me.button == MouseEvent.RIGHT_BUTTON && (me.stateMask & MouseEvent.ALT_MASK) != 0) { + diagram.setHint(DiagramHints.ROUTE_ALGORITHM, RouterFactory.create(true, true)); + connectionClass = elementClassProvider.get(ConnectionClasses.FLOW); + } else { + return false; + } + + ConnectTool bsi = null; + if (ti != null) { + IConnectionAdvisor advisor = diagram.getHint(DiagramHints.CONNECTION_ADVISOR); + if (advisor == null || (advisor != null && advisor.canBeginConnection(null, ti.e, ti.t))) { + bsi = new ConnectTool(diagram, connectionClass, ti.e, ti.t, me.mouseId, curCanvasPos); + } + } else { + ISnapAdvisor snapAdvisor = getHint(DiagramHints.SNAP_ADVISOR); + if(snapAdvisor != null) + snapAdvisor.snap(curCanvasPos); + + // Start connection out of thin air, without a terminal. + bsi = new ConnectTool(diagram, elementClassProvider.get(ConnectionClasses.DEPENDENCY), null, null, me.mouseId, curCanvasPos); + } + if (bsi != null) { + getContext().add(bsi); + return true; + } + + } + return false; + } + + public List pickTerminals(Point2D controlPos) + { + Rectangle2D controlPickRect = new Rectangle2D.Double(controlPos.getX()-PointerInteractor.PICK_DIST, controlPos.getY()-PointerInteractor.PICK_DIST, PointerInteractor.PICK_DIST*2+1, PointerInteractor.PICK_DIST*2+1); + Shape canvasPickRect = GeometryUtils.transformShape(controlPickRect, util.getInverseTransform()); + List ti = TerminalUtil.pickTerminals(diagram, canvasPickRect, false, true); + return ti; + } + + /** + * Paint bend handles. Handle is a selectable and draggable object. + * + * @param gc + */ +// @Painter(priority = TerminalPainter.PAINT_PRIORITY + 10) +// public void paintBendHandles(GraphicsContext gc) { +// if (!connects()) return; +// double controlScale = GeometryUtils.getScale(gc.getGraphics2D().getTransform()); +// // TODO: use another key for setting the bend point stroke color +// //Color bgColor = getHint(Hints.KEY_BACKGROUND_COLOR); +// Color bgColor = null; +// if (bgColor==null) bgColor = Color.GRAY; +// Graphics2D g = gc.createClone(); +// util.controlToCanvas(g); +// if (!connects()) return; +// ArrayList bends = new ArrayList(); +// AffineTransform _at = g.getTransform(); +// Point2D bendPos = new Point2D.Double(); +// for (IElement e : selection.getAllSelections()) +// { +// BendsHandler bh = e.getElementClass().getAtMostOneItemOfClass(BendsHandler.class); +// if (bh==null) continue; +// bends.clear(); bh.getBends(e, bends); +// if (bends.isEmpty()) continue; +// g.setTransform(_at); +// g.transform( ElementUtils.getTransform(e) ); +// double scale = GeometryUtils.getScale( g.getTransform() ); +// for (Bend b : bends) { +// bh.getBendPosition(e, b, bendPos); +// g.translate(bendPos.getX(), bendPos.getY()); +// g.setColor(Color.WHITE); +// g.scale(controlScale / scale, controlScale / scale); +// g.fill(BENDS); +// g.setColor(bgColor); +// g.draw(BENDS); +// g.scale(scale / controlScale, scale / controlScale); +// g.translate(-bendPos.getX(), -bendPos.getY()); +// } +// } +// } +// static final Shape BENDS = new Rectangle2D.Double(-5, -5, 11, 11); + + + + // + /* + @EventHandler(priority = -1) + public boolean scaleKey(KeyEvent ke) { + boolean alt = (ke.stateMask & java.awt.event.MouseEvent.ALT_DOWN_MASK) != 0; + if (alt && ke.keyCode == java.awt.event.KeyEvent.VK_S) { + //ScaleMode sm = new ScaleMode(me.startCanvasPos, curCanvasPos, me.mouseId, elementsToScale); + //getContext().add(sm); + } + return false; + } + // + */ +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ConnectionClasses.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ConnectionClasses.java new file mode 100644 index 00000000..7d102882 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ConnectionClasses.java @@ -0,0 +1,20 @@ +package org.simantics.sysdyn.ui.elements2; + +public class ConnectionClasses { + + public static final Object CONNECTION = new Object() { + public String toString() { return "CONNECTION"; } + }; + + public static final Object FLAG = new Object() { + public String toString() { return "FLAG"; } + }; + + public static final Object FLOW = new Object() { + public String toString() { return "CONNECTION"; } + }; + + public static final Object DEPENDENCY = new Object() { + public String toString() { return "DEPENDENCY"; } + }; +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyConnectionFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyConnectionFactory.java new file mode 100644 index 00000000..8f699654 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyConnectionFactory.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements2; + +import org.simantics.db.AsyncReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.procedure.AsyncProcedure; +import org.simantics.diagram.adapter.ElementFactoryAdapter; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.diagram.DiagramHints; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.impl.StaticObjectAdapter; +import org.simantics.g2d.elementclass.connection.ConnectionClass; +import org.simantics.g2d.routing.RouterFactory; + +/** + * An element class for single connection entity elements. A connection entity + * consists of connection edge segments and branch points as its children. + * + * @author Tuukka Lehtonen + */ +public class DependencyConnectionFactory extends ElementFactoryAdapter { + + public static final ElementClass CLASS = SysdynConnectionClass.CLASS; + + @Override + public void create(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType, final AsyncProcedure procedure) { + DiagramResource dr = graph.getService(DiagramResource.class); + graph.forSingleType(elementType, dr.Connection, new AsyncProcedure() { + @Override + public void exception(AsyncReadGraph graph, Throwable throwable) { + procedure.exception(graph, throwable); + } + @Override + public void execute(AsyncReadGraph graph, Resource connectionType) { + procedure.execute(graph, ConnectionClass.CLASS.newClassWith(false, new StaticObjectAdapter(connectionType))); + } + }); + } + + @Override + public void load(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementResource, + final IElement element, final AsyncProcedure procedure) { + element.setHint(DiagramHints.ROUTE_ALGORITHM, RouterFactory.create(false, false)); + procedure.execute(graph, element); + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/SysdynEdgeClass.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyEdgeClass.java similarity index 91% rename from org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/SysdynEdgeClass.java rename to org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyEdgeClass.java index 95ace230..5a2d9a41 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/SysdynEdgeClass.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyEdgeClass.java @@ -49,13 +49,12 @@ import org.simantics.g2d.elementclass.connection.EdgeClass.EdgeHandler; import org.simantics.g2d.elementclass.connection.EdgeClass.FixedTransform; import org.simantics.g2d.utils.PathUtils; import org.simantics.scenegraph.g2d.G2DParentNode; -import org.simantics.scenegraph.g2d.nodes.EdgeNode; import org.simantics.utils.datastructures.hints.IHintContext.Key; /** * @author Toni Kalajainen */ -public class SysdynEdgeClass { +public class DependencyEdgeClass { // TODO scale, rotate, move, transform public static final ElementClass CLASS = @@ -79,11 +78,11 @@ public class SysdynEdgeClass { public static final Stroke ARROW_STROKE = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER); - public static final Key KEY_SG_NODE = new SceneGraphNodeKey(EdgeNode.class, "EDGE_NODE"); + public static final Key KEY_SG_NODE = new SceneGraphNodeKey(DependencyNode.class, "EDGE_NODE"); @Override public void init(IElement e, G2DParentNode parent) { - ElementUtils.getOrCreateNode(e, parent, KEY_SG_NODE, "edge_" + e.hashCode(), EdgeNode.class); + ElementUtils.getOrCreateNode(e, parent, KEY_SG_NODE, "edge_" + e.hashCode(), DependencyNode.class); update(e); } @@ -93,7 +92,7 @@ public class SysdynEdgeClass { } public void update(final IElement e) { - EdgeNode node = e.getHint(KEY_SG_NODE); + DependencyNode node = e.getHint(KEY_SG_NODE); if(node == null) return; EdgeVisuals vh = e.getElementClass().getSingleItem(EdgeVisuals.class); @@ -131,7 +130,7 @@ public class SysdynEdgeClass { // Read bends BendsHandler bh = e.getElementClass().getSingleItem(BendsHandler.class); Path2D line = bh.getPath(e); - + boolean drawArrows = at1 != ArrowType.None || at2 != ArrowType.None; //line = clipLineEnds(line, beginTerminalShape, endTerminalShape); @@ -142,17 +141,17 @@ public class SysdynEdgeClass { PathIterator pi = line.getPathIterator(null); drawArrows &= PathUtils.getPathArrows(pi, first, dir1, last, dir2); - EdgeNode.ArrowType pat1 = convert(at1); - EdgeNode.ArrowType pat2 = convert(at2); + DependencyNode.ArrowType pat1 = convert(at1); + DependencyNode.ArrowType pat2 = convert(at2); node.init(new GeneralPath(line), stroke, c, dir1, dir2, first, last, as1, as2, pat1, pat2, null, null); } - private static EdgeNode.ArrowType convert(ArrowType at) { + private static DependencyNode.ArrowType convert(ArrowType at) { switch (at) { - case None: return EdgeNode.ArrowType.None; - case Stroke: return EdgeNode.ArrowType.Stroke; - case Fill: return EdgeNode.ArrowType.Fill; + case None: return DependencyNode.ArrowType.None; + case Stroke: return DependencyNode.ArrowType.Stroke; + case Fill: return DependencyNode.ArrowType.Fill; default: throw new IllegalArgumentException("unsupported arrow type: " + at); } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyEdgeFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyEdgeFactory.java new file mode 100644 index 00000000..7443d020 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyEdgeFactory.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements2; + +import org.simantics.db.AsyncReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.procedure.AsyncProcedure; +import org.simantics.diagram.adapter.ElementFactoryAdapter; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.element.ElementClass; + +/** + * An element class factory for sysdyn dependency connection edge segments. + * + * @author Tuukka Lehtonen + */ +public class DependencyEdgeFactory extends ElementFactoryAdapter { + + private static final ElementClass CLASS = DependencyEdgeClass.CLASS; + + @Override + public void create(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType, + AsyncProcedure procedure) { + procedure.execute(graph, CLASS); + } + + @Override + public void getClass(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementResource, + AsyncProcedure procedure) { + throw new UnsupportedOperationException(); + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyNode.java new file mode 100644 index 00000000..3584f169 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyNode.java @@ -0,0 +1,182 @@ +package org.simantics.sysdyn.ui.elements2; + +import java.awt.AlphaComposite; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.geom.AffineTransform; +import java.awt.geom.GeneralPath; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import org.simantics.scenegraph.g2d.G2DNode; + +public class DependencyNode extends G2DNode { + + private static final long serialVersionUID = 1294351381209071074L; + + public static enum ArrowType { None, Stroke, Fill, Both } + + protected Color color = null; + protected Stroke stroke = null; + protected Shape shape = null; + protected Point2D firstdir = null; + protected Point2D lastdir = null; + protected Point2D first = null; + protected Point2D last = null; + protected double firstsize = 0; + protected double lastsize = 0; + protected ArrowType first_at = null; + protected ArrowType last_at = null; + protected Shape firstShape = null; + protected Shape lastShape = null; + + private transient Rectangle2D bounds; + + @SyncField({"color", "stroke", "shape", "firstdir", "lastdir", "first", "last", "firstsize", "lastsize", "first_at", "last_at"}) + public void init(Shape shape, Stroke stroke, Color color, Point2D firstdir, Point2D lastdir, Point2D first, Point2D last, double firstsize, double lastsize, ArrowType first_at, ArrowType last_at, Shape firstShape, Shape lastShape) { + this.color = color; + this.stroke = stroke; + this.shape = shape; + this.firstdir = firstdir; + this.lastdir = lastdir; + this.first = first; + this.last = last; + this.firstsize = firstsize; + this.lastsize = lastsize; + this.first_at = first_at; + this.last_at = last_at; + this.firstShape = firstShape; + this.lastShape = lastShape; + + if (shape != null) { + this.bounds = shape.getBounds2D(); + } + } + + @Override + public void render(Graphics2D g) { + if(color != null) g.setColor(color); + if(stroke == null || shape == null) return; + + if(alphaComposite != null) { + g.setComposite(alphaComposite); + } + + Stroke effectiveStroke = stroke; + if(dynamicStroke != null) { + effectiveStroke = dynamicStroke; + } + + Color effectiveColor = color; + if(dynamicColor != null) { + effectiveColor = dynamicColor; + } + + g.setStroke(effectiveStroke); + + // NICENESS + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + //g.draw(shape); + + // Draw line "halo" + float f = 0.1f * 3f; + Color background = Color.WHITE; // FIXME + g.setColor(background); + g.setStroke(new BasicStroke(f)); + g.draw(shape); + + // Draw line + g.setColor(effectiveColor); + g.setStroke(effectiveStroke); + g.draw(shape); + + // Draw line ends if necessary. + boolean drawArrows = first_at != ArrowType.None || last_at != ArrowType.None; + if (!drawArrows) + return; + + g.setStroke(ARROW_STROKE); + AffineTransform at = g.getTransform(); + + double theta = Math.atan2(firstdir.getY(), firstdir.getX()) - Math.PI/2; + g.translate(first.getX(), first.getY()); + g.rotate(theta); + g.scale(firstsize, firstsize); + + if (first_at == ArrowType.Fill) + g.fill(FILLED_ARROW); + else if (first_at == ArrowType.Stroke) + g.draw(NORMAL_ARROW); + + g.setTransform(at); + + theta = Math.atan2(lastdir.getY(), lastdir.getX()) - Math.PI/2; + + g.translate(last.getX(), last.getY()); + g.rotate(theta); + g.scale(lastsize, lastsize); + + if (last_at == ArrowType.Fill) + g.fill(FILLED_ARROW); + else if (last_at == ArrowType.Stroke) + g.draw(NORMAL_ARROW); + } + + + public transient final static GeneralPath NORMAL_ARROW; + public transient final static GeneralPath FILLED_ARROW; + public transient static final Stroke ARROW_STROKE = new BasicStroke(1.0f); + + static { + FILLED_ARROW = new GeneralPath(); + FILLED_ARROW.moveTo(-0.5f, 1f); + FILLED_ARROW.lineTo( 0f, 0f); + FILLED_ARROW.lineTo( 0.5f, 1f); + FILLED_ARROW.closePath(); + + NORMAL_ARROW = new GeneralPath(); + NORMAL_ARROW.moveTo(-0.5f, 1f); + NORMAL_ARROW.lineTo( 0f, 0f); + NORMAL_ARROW.lineTo( 0.5f, 1f); + } + + @Override + public Rectangle2D getBoundsInLocal() { + return bounds; + } + + protected Composite alphaComposite = null; + protected Stroke dynamicStroke = null; + protected Color dynamicColor = null; + + @Override + public void setValue(String key, Object value) { + + if ("alpha".equals(key)) { + Float val = Float.parseFloat((String)value); + alphaComposite = AlphaComposite.getInstance(AlphaComposite. SRC_OVER, val); + } else if ("width".equals(key)) { + dynamicStroke = new BasicStroke(((Double)value).floatValue()); + } else if ("color".equals(key)) { + try { + dynamicColor = new Color(Integer.parseInt(value.toString(), 16)); + } catch (Throwable t) { + t.printStackTrace(); + } + } + } + + @Override + public void initValues() { + dynamicStroke = null; + dynamicColor = null; + alphaComposite = null; + } + + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/SysdynConnectionFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowConnectionFactory.java similarity index 88% rename from org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/SysdynConnectionFactory.java rename to org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowConnectionFactory.java index 3023e544..691cf55e 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/SysdynConnectionFactory.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowConnectionFactory.java @@ -17,11 +17,13 @@ import org.simantics.db.procedure.AsyncProcedure; import org.simantics.diagram.adapter.ElementFactoryAdapter; import org.simantics.diagram.stubs.DiagramResource; import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.diagram.DiagramHints; import org.simantics.g2d.diagram.IDiagram; import org.simantics.g2d.element.ElementClass; import org.simantics.g2d.element.IElement; import org.simantics.g2d.element.handler.impl.StaticObjectAdapter; import org.simantics.g2d.elementclass.connection.ConnectionClass; +import org.simantics.g2d.routing.RouterFactory; /** * An element class for single connection entity elements. A connection entity @@ -29,7 +31,7 @@ import org.simantics.g2d.elementclass.connection.ConnectionClass; * * @author Tuukka Lehtonen */ -public class SysdynConnectionFactory extends ElementFactoryAdapter { +public class FlowConnectionFactory extends ElementFactoryAdapter { public static final ElementClass CLASS = SysdynConnectionClass.CLASS; @@ -51,6 +53,7 @@ public class SysdynConnectionFactory extends ElementFactoryAdapter { @Override public void load(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementResource, final IElement element, final AsyncProcedure procedure) { + element.setHint(DiagramHints.ROUTE_ALGORITHM, RouterFactory.create(true, true)); procedure.execute(graph, element); } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowEdgeClass.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowEdgeClass.java new file mode 100644 index 00000000..9e6f4771 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowEdgeClass.java @@ -0,0 +1,198 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements2; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.geom.AffineTransform; +import java.awt.geom.GeneralPath; +import java.awt.geom.Path2D; +import java.awt.geom.PathIterator; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.diagram.handler.Topology; +import org.simantics.g2d.diagram.handler.Topology.Connection; +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.SceneGraphNodeKey; +import org.simantics.g2d.element.handler.BendsHandler; +import org.simantics.g2d.element.handler.EdgeVisuals; +import org.simantics.g2d.element.handler.EdgeVisuals.ArrowType; +import org.simantics.g2d.element.handler.EdgeVisuals.EdgeEnd; +import org.simantics.g2d.element.handler.Rotate; +import org.simantics.g2d.element.handler.SceneGraph; +import org.simantics.g2d.element.handler.TerminalLayout; +import org.simantics.g2d.element.handler.impl.ConfigurableEdgeVisuals; +import org.simantics.g2d.element.handler.impl.ConnectionSelectionOutline; +import org.simantics.g2d.element.handler.impl.FillColorImpl; +import org.simantics.g2d.element.handler.impl.ParentImpl; +import org.simantics.g2d.element.handler.impl.ShapePick; +import org.simantics.g2d.element.handler.impl.SimpleElementLayers; +import org.simantics.g2d.elementclass.BranchPoint; +import org.simantics.g2d.elementclass.connection.EdgeClass.EdgeHandler; +import org.simantics.g2d.elementclass.connection.EdgeClass.FixedTransform; +import org.simantics.g2d.utils.PathUtils; +import org.simantics.scenegraph.g2d.G2DParentNode; +import org.simantics.utils.datastructures.hints.IHintContext.Key; + +/** + * @author Toni Kalajainen + */ +public class FlowEdgeClass { + + // TODO scale, rotate, move, transform + public static final ElementClass CLASS = + ElementClass.compile( + SysdynEdgeSceneGraph.INSTANCE, + EdgeHandler.INSTANCE, + ConfigurableEdgeVisuals.DEFAULT, + FillColorImpl.BLACK, + FixedTransform.INSTANCE, + ShapePick.INSTANCE, + ConnectionSelectionOutline.INSTANCE, + SimpleElementLayers.INSTANCE, + ParentImpl.INSTANCE + ).setId("EdgeClass.STRAIGHT"); + + public static class SysdynEdgeSceneGraph implements SceneGraph { + + private static final long serialVersionUID = 2914383071126238996L; + + public static final SysdynEdgeSceneGraph INSTANCE = new SysdynEdgeSceneGraph(); + + public static final Stroke ARROW_STROKE = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER); + + public static final Key KEY_SG_NODE = new SceneGraphNodeKey(FlowNode.class, "EDGE_NODE"); + + @Override + public void init(IElement e, G2DParentNode parent) { + ElementUtils.getOrCreateNode(e, parent, KEY_SG_NODE, "edge_" + e.hashCode(), FlowNode.class); + update(e); + } + + @Override + public void cleanup(IElement e) { + ElementUtils.removePossibleNode(e, KEY_SG_NODE); + } + + public void update(final IElement e) { + FlowNode node = e.getHint(KEY_SG_NODE); + if(node == null) return; + + EdgeVisuals vh = e.getElementClass().getSingleItem(EdgeVisuals.class); + ArrowType at1 = vh.getArrowType(e, EdgeEnd.Begin); + ArrowType at2 = vh.getArrowType(e, EdgeEnd.End); + Stroke stroke = new FlowStroke( + new BasicStroke(0.4f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER), + new BasicStroke(0.1f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)); +// Stroke stroke = vh.getStroke(e); + //StrokeType strokeType = vh.getStrokeType(e); + double as1 = vh.getArrowSize(e, EdgeEnd.Begin); + double as2 = vh.getArrowSize(e, EdgeEnd.End); + + Color c = ElementUtils.getFillColor(e, Color.BLACK); + + // Get terminal shape for clipping the painted edge to its bounds. + IDiagram diagram = ElementUtils.peekDiagram(e); + Shape beginTerminalShape = null; + Shape endTerminalShape = null; + if (diagram != null) { + Topology topology = diagram.getDiagramClass().getAtMostOneItemOfClass(Topology.class); + if (topology != null) { + Connection beginConnection = topology.getConnection(e, EdgeEnd.Begin); + Connection endConnection = topology.getConnection(e, EdgeEnd.End); + beginTerminalShape = getTerminalShape(beginConnection); + endTerminalShape = getTerminalShape(endConnection); + int beginBranchDegree = getBranchPointDegree(beginConnection, topology); + int endBranchDegree = getBranchPointDegree(endConnection, topology); + if (beginBranchDegree > 0 && beginBranchDegree < 3) { + at1 = ArrowType.None; + } + if (endBranchDegree > 0 && endBranchDegree < 3) { + at2 = ArrowType.None; + } + } + } + + // Read bends + BendsHandler bh = e.getElementClass().getSingleItem(BendsHandler.class); + Path2D line = bh.getPath(e); + + boolean drawArrows = at1 != ArrowType.None || at2 != ArrowType.None; + //line = clipLineEnds(line, beginTerminalShape, endTerminalShape); + + Point2D first = new Point2D.Double(); + Point2D dir1 = new Point2D.Double(); + Point2D last = new Point2D.Double(); + Point2D dir2 = new Point2D.Double(); + PathIterator pi = line.getPathIterator(null); + drawArrows &= PathUtils.getPathArrows(pi, first, dir1, last, dir2); + + FlowNode.ArrowType pat1 = convert(at1); + FlowNode.ArrowType pat2 = convert(at2); + + node.init(new GeneralPath(line), stroke, c, dir1, dir2, first, last, as1, as2, pat1, pat2, null, null); + } + + private static FlowNode.ArrowType convert(ArrowType at) { + switch (at) { + case None: return FlowNode.ArrowType.None; + case Stroke: return FlowNode.ArrowType.Stroke; + case Fill: return FlowNode.ArrowType.Fill; + default: + throw new IllegalArgumentException("unsupported arrow type: " + at); + } + } + + private static final Rectangle2D EMPTY = new Rectangle2D.Double(); + + private static Shape getTerminalShape(Connection connection) { + if (connection != null && connection.node != null && connection.terminal != null) { + TerminalLayout layout = connection.node.getElementClass().getAtMostOneItemOfClass(TerminalLayout.class); + if (layout != null) { + //return layout.getTerminalShape(connection.node, connection.terminal); + Shape shp = layout.getTerminalShape(connection.node, connection.terminal); + Rotate rotate = connection.node.getElementClass().getAtMostOneItemOfClass(Rotate.class); + if (rotate == null) + return shp; + + double theta = rotate.getAngle(connection.node); + return AffineTransform.getRotateInstance(theta).createTransformedShape(shp); + } + } + return null; + } + + private final Collection connectionsTemp = new ArrayList(); + private int getBranchPointDegree(Connection connection, Topology topology) { + if (connection != null && connection.node != null) { + if (connection.node.getElementClass().containsClass(BranchPoint.class)) { + connectionsTemp.clear(); + topology.getConnections(connection.node, connection.terminal, connectionsTemp); + int degree = connectionsTemp.size(); + connectionsTemp.clear(); + return degree; + } + } + return -1; + } + + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/SysdynConnectionEdgeFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowEdgeFactory.java similarity index 85% rename from org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/SysdynConnectionEdgeFactory.java rename to org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowEdgeFactory.java index 180a2349..7d428da9 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/SysdynConnectionEdgeFactory.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowEdgeFactory.java @@ -20,13 +20,13 @@ import org.simantics.g2d.diagram.IDiagram; import org.simantics.g2d.element.ElementClass; /** - * An element class factory for sysdyn connection edge segments. + * An element class factory for sysdyn flow connection edge segments. * * @author Tuukka Lehtonen */ -public class SysdynConnectionEdgeFactory extends ElementFactoryAdapter { +public class FlowEdgeFactory extends ElementFactoryAdapter { - private static final ElementClass CLASS = SysdynEdgeClass.CLASS; + private static final ElementClass CLASS = FlowEdgeClass.CLASS; @Override public void create(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType, diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowNode.java new file mode 100644 index 00000000..5bfb68d6 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowNode.java @@ -0,0 +1,182 @@ +package org.simantics.sysdyn.ui.elements2; + +import java.awt.AlphaComposite; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.geom.AffineTransform; +import java.awt.geom.GeneralPath; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import org.simantics.scenegraph.g2d.G2DNode; + +public class FlowNode extends G2DNode { + + private static final long serialVersionUID = 1294351381209071074L; + + public static enum ArrowType { None, Stroke, Fill, Both } + + protected Color color = null; + protected Stroke stroke = null; + protected Shape shape = null; + protected Point2D firstdir = null; + protected Point2D lastdir = null; + protected Point2D first = null; + protected Point2D last = null; + protected double firstsize = 0; + protected double lastsize = 0; + protected ArrowType first_at = null; + protected ArrowType last_at = null; + protected Shape firstShape = null; + protected Shape lastShape = null; + + private transient Rectangle2D bounds; + + @SyncField({"color", "stroke", "shape", "firstdir", "lastdir", "first", "last", "firstsize", "lastsize", "first_at", "last_at"}) + public void init(Shape shape, Stroke stroke, Color color, Point2D firstdir, Point2D lastdir, Point2D first, Point2D last, double firstsize, double lastsize, ArrowType first_at, ArrowType last_at, Shape firstShape, Shape lastShape) { + this.color = color; + this.stroke = stroke; + this.shape = shape; + this.firstdir = firstdir; + this.lastdir = lastdir; + this.first = first; + this.last = last; + this.firstsize = firstsize; + this.lastsize = lastsize; + this.first_at = first_at; + this.last_at = last_at; + this.firstShape = firstShape; + this.lastShape = lastShape; + + if (shape != null) { + this.bounds = shape.getBounds2D(); + } + } + + @Override + public void render(Graphics2D g) { + if(color != null) g.setColor(color); + if(stroke == null || shape == null) return; + + if(alphaComposite != null) { + g.setComposite(alphaComposite); + } + + Stroke effectiveStroke = stroke; + if(dynamicStroke != null) { + effectiveStroke = dynamicStroke; + } + + Color effectiveColor = color; + if(dynamicColor != null) { + effectiveColor = dynamicColor; + } + + g.setStroke(effectiveStroke); + + // NICENESS + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + //g.draw(shape); + + // Draw line "halo" + float f = 0.1f * 3f; + Color background = Color.WHITE; // FIXME + g.setColor(background); + g.setStroke(new BasicStroke(f)); + g.draw(shape); + + // Draw line + g.setColor(effectiveColor); + g.setStroke(effectiveStroke); + g.draw(shape); + + // Draw line ends if necessary. + boolean drawArrows = first_at != ArrowType.None || last_at != ArrowType.None; + if (!drawArrows) + return; + + g.setStroke(ARROW_STROKE); + AffineTransform at = g.getTransform(); + + double theta = Math.atan2(firstdir.getY(), firstdir.getX()) - Math.PI/2; + g.translate(first.getX(), first.getY()); + g.rotate(theta); + g.scale(firstsize, firstsize); + + if (first_at == ArrowType.Fill) + g.fill(FILLED_ARROW); + else if (first_at == ArrowType.Stroke) + g.draw(NORMAL_ARROW); + + g.setTransform(at); + + theta = Math.atan2(lastdir.getY(), lastdir.getX()) - Math.PI/2; + + g.translate(last.getX(), last.getY()); + g.rotate(theta); + g.scale(lastsize, lastsize); + + if (last_at == ArrowType.Fill) + g.fill(FILLED_ARROW); + else if (last_at == ArrowType.Stroke) + g.draw(NORMAL_ARROW); + } + + + public transient final static GeneralPath NORMAL_ARROW; + public transient final static GeneralPath FILLED_ARROW; + public transient static final Stroke ARROW_STROKE = new BasicStroke(1.0f); + + static { + FILLED_ARROW = new GeneralPath(); + FILLED_ARROW.moveTo(-0.5f, 1f); + FILLED_ARROW.lineTo( 0f, 0f); + FILLED_ARROW.lineTo( 0.5f, 1f); + FILLED_ARROW.closePath(); + + NORMAL_ARROW = new GeneralPath(); + NORMAL_ARROW.moveTo(-0.5f, 1f); + NORMAL_ARROW.lineTo( 0f, 0f); + NORMAL_ARROW.lineTo( 0.5f, 1f); + } + + @Override + public Rectangle2D getBoundsInLocal() { + return bounds; + } + + protected Composite alphaComposite = null; + protected Stroke dynamicStroke = null; + protected Color dynamicColor = null; + + @Override + public void setValue(String key, Object value) { + + if ("alpha".equals(key)) { + Float val = Float.parseFloat((String)value); + alphaComposite = AlphaComposite.getInstance(AlphaComposite. SRC_OVER, val); + } else if ("width".equals(key)) { + dynamicStroke = new BasicStroke(((Double)value).floatValue()); + } else if ("color".equals(key)) { + try { + dynamicColor = new Color(Integer.parseInt(value.toString(), 16)); + } catch (Throwable t) { + t.printStackTrace(); + } + } + } + + @Override + public void initValues() { + dynamicStroke = null; + dynamicColor = null; + alphaComposite = null; + } + + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowStroke.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowStroke.java new file mode 100644 index 00000000..76e7d4de --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowStroke.java @@ -0,0 +1,18 @@ +package org.simantics.sysdyn.ui.elements2; + +import java.awt.Shape; +import java.awt.Stroke; + +public class FlowStroke implements Stroke { + private Stroke stroke1, stroke2; + + public FlowStroke( Stroke stroke1, Stroke stroke2 ) { + this.stroke1 = stroke1; + this.stroke2 = stroke2; + } + + public Shape createStrokedShape( Shape shape ) { + return stroke2.createStrokedShape( stroke1.createStrokedShape( shape ) ); + } + +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/SysdynResource.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/SysdynResource.java index c58bc230..723dc234 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/SysdynResource.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/SysdynResource.java @@ -27,14 +27,15 @@ public class SysdynResource { public final Resource CloudSymbol; public final Resource Configuration; public final Resource ConfigurationDiagram; - public final Resource Connection; public final Resource ConstantExpression; public final Resource DelayExpression; public final Resource Dependency; + public final Resource DependencyConnection; public final Resource DiagramToCompositeMapping; public final Resource Experiment; public final Resource Expression; public final Resource Flow; + public final Resource FlowConnection; public final Resource GameExperiment; public final Resource HasAngle; public final Resource HasEquation; @@ -94,14 +95,15 @@ public class SysdynResource { public static final String CloudSymbol = "http://www.simantics.org/Sysdyn-1.0/CloudSymbol"; public static final String Configuration = "http://www.simantics.org/Sysdyn-1.0/Configuration"; public static final String ConfigurationDiagram = "http://www.simantics.org/Sysdyn-1.0/ConfigurationDiagram"; - public static final String Connection = "http://www.simantics.org/Sysdyn-1.0/Connection"; public static final String ConstantExpression = "http://www.simantics.org/Sysdyn-1.0/ConstantExpression"; public static final String DelayExpression = "http://www.simantics.org/Sysdyn-1.0/DelayExpression"; public static final String Dependency = "http://www.simantics.org/Sysdyn-1.0/Dependency"; + public static final String DependencyConnection = "http://www.simantics.org/Sysdyn-1.0/DependencyConnection"; public static final String DiagramToCompositeMapping = "http://www.simantics.org/Sysdyn-1.0/DiagramToCompositeMapping"; public static final String Experiment = "http://www.simantics.org/Sysdyn-1.0/Experiment"; public static final String Expression = "http://www.simantics.org/Sysdyn-1.0/Expression"; public static final String Flow = "http://www.simantics.org/Sysdyn-1.0/Flow"; + public static final String FlowConnection = "http://www.simantics.org/Sysdyn-1.0/FlowConnection"; public static final String GameExperiment = "http://www.simantics.org/Sysdyn-1.0/GameExperiment"; public static final String HasAngle = "http://www.simantics.org/Sysdyn-1.0/HasAngle"; public static final String HasEquation = "http://www.simantics.org/Sysdyn-1.0/HasEquation"; @@ -171,14 +173,15 @@ public class SysdynResource { CloudSymbol = getResourceOrNull(graph, URIs.CloudSymbol); Configuration = getResourceOrNull(graph, URIs.Configuration); ConfigurationDiagram = getResourceOrNull(graph, URIs.ConfigurationDiagram); - Connection = getResourceOrNull(graph, URIs.Connection); ConstantExpression = getResourceOrNull(graph, URIs.ConstantExpression); DelayExpression = getResourceOrNull(graph, URIs.DelayExpression); Dependency = getResourceOrNull(graph, URIs.Dependency); + DependencyConnection = getResourceOrNull(graph, URIs.DependencyConnection); DiagramToCompositeMapping = getResourceOrNull(graph, URIs.DiagramToCompositeMapping); Experiment = getResourceOrNull(graph, URIs.Experiment); Expression = getResourceOrNull(graph, URIs.Expression); Flow = getResourceOrNull(graph, URIs.Flow); + FlowConnection = getResourceOrNull(graph, URIs.FlowConnection); GameExperiment = getResourceOrNull(graph, URIs.GameExperiment); HasAngle = getResourceOrNull(graph, URIs.HasAngle); HasEquation = getResourceOrNull(graph, URIs.HasEquation); diff --git a/sysdyn_ontologies/sysdyn.graph b/sysdyn_ontologies/sysdyn.graph index afbd29a8..d2a16833 100644 --- a/sysdyn_ontologies/sysdyn.graph +++ b/sysdyn_ontologies/sysdyn.graph @@ -164,8 +164,6 @@ Terminal