]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
First take on new route graph for flows
authorlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Tue, 1 Nov 2011 09:56:43 +0000 (09:56 +0000)
committerlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Tue, 1 Nov 2011 09:56:43 +0000 (09:56 +0000)
git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@23141 ac1ea38d-2e2b-0410-8846-a27921b304fc

24 files changed:
org.simantics.sysdyn.ontology/graph.tg
org.simantics.sysdyn.ontology/graph/Sysdyn.pgraph
org.simantics.sysdyn.ontology/src/org/simantics/sysdyn/SysdynResource.java
org.simantics.sysdyn.ui/adapters.xml
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramViewer.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/PointerInteractor.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/FlowRouter.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/Orientation.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/SysdynElementHints.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/SysdynElementUtils.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ValveFactory.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowArrowLineStyle.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowConnectionFactoryOld.java [moved from org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowConnectionFactory.java with 95% similarity]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowConnectionStyle.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowEdgeClassOld.java [moved from org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowEdgeClass.java with 95% similarity]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowEdgeFactoryOld.java [moved from org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowEdgeFactory.java with 89% similarity]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowEdgeNodeOld.java [moved from org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowEdgeNode.java with 92% similarity]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowNodeOld.java [moved from org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowNode.java with 94% similarity]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/RouteFlowConnectionFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/RouteFlowEdgeClass.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/RouteFlowEdgeFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/VariableInformationTab.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ValveOrientationGroup.java [new file with mode: 0644]
org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/SheetFormatUtils.java

index 358bb901b8f779559413619d2561ef0ebbdb95ef..1d3d856bc069ef1d6a7a6853e5e7435103a9011e 100644 (file)
Binary files a/org.simantics.sysdyn.ontology/graph.tg and b/org.simantics.sysdyn.ontology/graph.tg differ
index 475e3a606e4381958c273c160292506922ca310f..e35c30e6acaef898e4c9d216ceb278db41bfd4c5 100644 (file)
@@ -392,14 +392,23 @@ SYSDYN.IsTailOfTerminal
     @MOD.terminalRelation SYSDYN.IsTailOf
 
 SYSDYN.SysdynTerminal <T DIA.Terminal
+    @L0.assert DIA.Terminal.AllowedDirections 0
 
 //#####################################################################
 SYSDYN.Valve <T STR.Component
     @MOD.connection SYSDYN.IsTailOf
     @MOD.connection SYSDYN.IsHeadOf
+    
+SYSDYN.HasValveOrientation <R L0.HasProperty : L0.FunctionalRelation
+    L0.HasRange L0.Boolean    
+    
+SYSDYN.Orientation <T L0.Entity    
+SYSDYN.Horizontal <T SYSDYN.Orientation
+SYSDYN.Vertical <T SYSDYN.Orientation   
 
 SYSDYN.ValveSymbol <T DIA.FontProvider <T DIA.ColorProvider
     @MOD.defSymbol "Valve" SYSDYN.Valve
+    @L0.assert SYSDYN.Orientation SYSDYN.Horizontal
     L0.IsDependencyOf BasicSymbols
     STR.IsDefinedBy _ : DIA.Composite <R L0.HasNext 
         @L0.orderedSet 
@@ -481,7 +490,7 @@ SYSDYN.Polarity <R L0.HasProperty : L0.FunctionalRelation
 SYSDYN.PolarityLocation <R L0.HasProperty : L0.FunctionalRelation
     L0.HasRange L0.String
 
-SYSDYN.FlowConnection <T DIA.Connection
+SYSDYN.FlowConnection <T DIA.RouteGraphConnection
     MOD.DiagramConnectionTypeToConnectionType
         SYSDYN.Flow  
 
index 5e1f85b6a319c436c3ff4cb73e54558024c8853f..674f69a0b4bf3e6510e6b0b4b73850ce9a4b1a81 100644 (file)
@@ -134,7 +134,10 @@ public class SysdynResource {
     public final Resource HasTolerance_Inverse;\r
     public final Resource HasUnit;\r
     public final Resource HasUnit_Inverse;\r
+    public final Resource HasValveOrientation;\r
+    public final Resource HasValveOrientation_Inverse;\r
     public final Resource HistoryRealization;\r
+    public final Resource Horizontal;\r
     public final Resource ImportModuleTree;\r
     public final Resource ImportedOntologies;\r
     public final Resource IndependentVariable;\r
@@ -153,6 +156,7 @@ public class SysdynResource {
     public final Resource Module;\r
     public final Resource ModuleSymbol;\r
     public final Resource NormalExpression;\r
+    public final Resource Orientation;\r
     public final Resource ParameterExpression;\r
     public final Resource PlaybackExperiment;\r
     public final Resource Polarity;\r
@@ -228,6 +232,7 @@ public class SysdynResource {
     public final Resource Variable;\r
     public final Resource Variable_Type;\r
     public final Resource Variable_Type_Inverse;\r
+    public final Resource Vertical;\r
     public final Resource WithLookupExpression;\r
     public final Resource angle;\r
     public final Resource angle_Inverse;\r
@@ -360,7 +365,10 @@ public class SysdynResource {
         public static final String HasTolerance_Inverse = "http://www.simantics.org/Sysdyn-1.1/HasTolerance/Inverse";\r
         public static final String HasUnit = "http://www.simantics.org/Sysdyn-1.1/HasUnit";\r
         public static final String HasUnit_Inverse = "http://www.simantics.org/Sysdyn-1.1/HasUnit/Inverse";\r
+        public static final String HasValveOrientation = "http://www.simantics.org/Sysdyn-1.1/HasValveOrientation";\r
+        public static final String HasValveOrientation_Inverse = "http://www.simantics.org/Sysdyn-1.1/HasValveOrientation/Inverse";\r
         public static final String HistoryRealization = "http://www.simantics.org/Sysdyn-1.1/HistoryRealization";\r
+        public static final String Horizontal = "http://www.simantics.org/Sysdyn-1.1/Horizontal";\r
         public static final String ImportModuleTree = "http://www.simantics.org/Sysdyn-1.1/ImportModuleTree";\r
         public static final String ImportedOntologies = "http://www.simantics.org/Sysdyn-1.1/ImportedOntologies";\r
         public static final String IndependentVariable = "http://www.simantics.org/Sysdyn-1.1/IndependentVariable";\r
@@ -379,6 +387,7 @@ public class SysdynResource {
         public static final String Module = "http://www.simantics.org/Sysdyn-1.1/Module";\r
         public static final String ModuleSymbol = "http://www.simantics.org/Sysdyn-1.1/ModuleSymbol";\r
         public static final String NormalExpression = "http://www.simantics.org/Sysdyn-1.1/NormalExpression";\r
+        public static final String Orientation = "http://www.simantics.org/Sysdyn-1.1/Orientation";\r
         public static final String ParameterExpression = "http://www.simantics.org/Sysdyn-1.1/ParameterExpression";\r
         public static final String PlaybackExperiment = "http://www.simantics.org/Sysdyn-1.1/PlaybackExperiment";\r
         public static final String Polarity = "http://www.simantics.org/Sysdyn-1.1/Polarity";\r
@@ -454,6 +463,7 @@ public class SysdynResource {
         public static final String Variable = "http://www.simantics.org/Sysdyn-1.1/Variable";\r
         public static final String Variable_Type = "http://www.simantics.org/Sysdyn-1.1/Variable/Type";\r
         public static final String Variable_Type_Inverse = "http://www.simantics.org/Sysdyn-1.1/Variable/Type/Inverse";\r
+        public static final String Vertical = "http://www.simantics.org/Sysdyn-1.1/Vertical";\r
         public static final String WithLookupExpression = "http://www.simantics.org/Sysdyn-1.1/WithLookupExpression";\r
         public static final String angle = "http://www.simantics.org/Sysdyn-1.1/angle";\r
         public static final String angle_Inverse = "http://www.simantics.org/Sysdyn-1.1/angle/Inverse";\r
@@ -596,7 +606,10 @@ public class SysdynResource {
         HasTolerance_Inverse = getResourceOrNull(graph, URIs.HasTolerance_Inverse);\r
         HasUnit = getResourceOrNull(graph, URIs.HasUnit);\r
         HasUnit_Inverse = getResourceOrNull(graph, URIs.HasUnit_Inverse);\r
+        HasValveOrientation = getResourceOrNull(graph, URIs.HasValveOrientation);\r
+        HasValveOrientation_Inverse = getResourceOrNull(graph, URIs.HasValveOrientation_Inverse);\r
         HistoryRealization = getResourceOrNull(graph, URIs.HistoryRealization);\r
+        Horizontal = getResourceOrNull(graph, URIs.Horizontal);\r
         ImportModuleTree = getResourceOrNull(graph, URIs.ImportModuleTree);\r
         ImportedOntologies = getResourceOrNull(graph, URIs.ImportedOntologies);\r
         IndependentVariable = getResourceOrNull(graph, URIs.IndependentVariable);\r
@@ -615,6 +628,7 @@ public class SysdynResource {
         Module = getResourceOrNull(graph, URIs.Module);\r
         ModuleSymbol = getResourceOrNull(graph, URIs.ModuleSymbol);\r
         NormalExpression = getResourceOrNull(graph, URIs.NormalExpression);\r
+        Orientation = getResourceOrNull(graph, URIs.Orientation);\r
         ParameterExpression = getResourceOrNull(graph, URIs.ParameterExpression);\r
         PlaybackExperiment = getResourceOrNull(graph, URIs.PlaybackExperiment);\r
         Polarity = getResourceOrNull(graph, URIs.Polarity);\r
@@ -690,6 +704,7 @@ public class SysdynResource {
         Variable = getResourceOrNull(graph, URIs.Variable);\r
         Variable_Type = getResourceOrNull(graph, URIs.Variable_Type);\r
         Variable_Type_Inverse = getResourceOrNull(graph, URIs.Variable_Type_Inverse);\r
+        Vertical = getResourceOrNull(graph, URIs.Vertical);\r
         WithLookupExpression = getResourceOrNull(graph, URIs.WithLookupExpression);\r
         angle = getResourceOrNull(graph, URIs.angle);\r
         angle_Inverse = getResourceOrNull(graph, URIs.angle_Inverse);\r
index 282a08e5d18d3bee195b18637e12350cca633077..b1be736a7087a95ad896b9fbd8b91cf78921d33b 100644 (file)
@@ -10,5 +10,5 @@
         VTT Technical Research Centre of Finland - initial API and implementation\r
  -->\r
 
-<adapters>\r\r   <target interface="org.simantics.db.layer0.adapter.Realization">\r               <type uri="http://www.simantics.org/Sysdyn-0.0/Module"\r                 class="org.simantics.structural2.realization.StructuralRealization">\r                   <this />\r               </type>\r        </target>\r\r<!-- \r       <target interface="org.simantics.db.layer0.variable.Variable">\r         <type uri="http://www.simantics.org/Sysdyn-0.0/HistoryRealization"\r                     class="org.simantics.sysdyn.ui.project.HistoryVariable" >\r                      <this />\r               </type>\r                <type uri="http://www.simantics.org/Sysdyn-0.0/DefaultRealization"\r                     class="org.simantics.sysdyn.ui.project.DefaultVariable" >\r                      <this />\r               </type>\r        </target>\r -->\r\r        <target interface="org.simantics.layer0.utils.triggers.ITrigger">\r      <type uri = "http://www.simantics.org/Sysdyn-0.0/DiagramToCompositeMapping"\r          class = "org.simantics.sysdyn.ui.editor.DiagramToCompositeMapping3">\r         <graph/>\r           <this />\r       </type>\r        </target>\r      \r       <target interface="org.simantics.structural.ui.modelBrowser.nodes.AbstractNode">\r               <type uri="http://www.simantics.org/Sysdyn-0.0/SysdynModel"\r                    class="org.simantics.structural.ui.modelBrowser.nodes.ModelNode">\r                      <this />\r               </type>\r        </target>               \r               \r\r      <target\r                interface="org.simantics.browsing.ui.common.node.AbstractNode">\r                <type\r                  uri="http://www.simantics.org/Sysdyn-0.0/SysdynModel"\r                  class="org.simantics.sysdyn.ui.browser.nodes.ModelNode">\r                       <this />\r               </type>\r\r               <resource\r                      uri="http://www.simantics.org/Sysdyn-0.0/ModuleSymbol"\r                 class="org.simantics.sysdyn.ui.browser.nodes.SymbolNode">\r                      <this />\r               </resource>\r\r           <type\r                  uri="http://www.simantics.org/Simulation-1.0/Experiment"\r                       class="org.simantics.sysdyn.ui.browser.nodes.ExperimentNode">\r                  <this />\r               </type>\r                \r               <type\r                  uri="http://www.simantics.org/Sysdyn-0.0/Result"\r                       class="org.simantics.sysdyn.ui.browser.nodes.SimulationResultNode">\r                    <this />\r               </type>\r                \r       </target>\r\r     <!-- Inject default connection routing algorithm for sysdyn diagrams -->\r       <target interface="org.simantics.g2d.diagram.DiagramClass">\r            <adapter uri="http://www.simantics.org/Sysdyn-0.0/ConfigurationDiagram"\r                        adapterClass="org.simantics.sysdyn.ui.elements2.ConfigurationDiagramClassAdapter" />\r   </target>\r\r     <!-- Sysdyn symbols -->\r        <target interface="org.simantics.diagram.adapter.ElementFactory">\r              <resource uri="http://www.simantics.org/Sysdyn-0.0/StockSymbol"\r                        class="org.simantics.sysdyn.ui.elements2.StockFactory" />\r              <resource uri="http://www.simantics.org/Sysdyn-0.0/ModuleSymbol"\r                       class="org.simantics.sysdyn.ui.elements2.ModuleFactory" />\r             <resource uri="http://www.simantics.org/Sysdyn-0.0/ValveSymbol"\r                        class="org.simantics.sysdyn.ui.elements2.ValveFactory" />\r              <resource uri="http://www.simantics.org/Sysdyn-0.0/AuxiliarySymbol"\r                    class="org.simantics.sysdyn.ui.elements2.AuxiliaryFactory" />\r          <resource uri="http://www.simantics.org/Sysdyn-0.0/CloudSymbol"\r                        class="org.simantics.sysdyn.ui.elements2.CloudFactory" />\r              <resource uri="http://www.simantics.org/Sysdyn-0.0/InputSymbol"\r                        class="org.simantics.sysdyn.ui.elements2.InputFactory" />\r\r             <type uri="http://www.simantics.org/Sysdyn-0.0/StockSymbol"\r                    class="org.simantics.sysdyn.ui.elements2.StockFactory" />\r              <type uri="http://www.simantics.org/Sysdyn-0.0/ModuleSymbol"\r                   class="org.simantics.sysdyn.ui.elements2.ModuleFactory" />\r             <type uri="http://www.simantics.org/Sysdyn-0.0/ValveSymbol"\r                    class="org.simantics.sysdyn.ui.elements2.ValveFactory" />\r              <type uri="http://www.simantics.org/Sysdyn-0.0/AuxiliarySymbol"\r                        class="org.simantics.sysdyn.ui.elements2.AuxiliaryFactory" />\r          <type uri="http://www.simantics.org/Sysdyn-0.0/CloudSymbol"\r                    class="org.simantics.sysdyn.ui.elements2.CloudFactory" />\r              <type uri="http://www.simantics.org/Sysdyn-0.0/InputSymbol"\r                    class="org.simantics.sysdyn.ui.elements2.InputFactory" />                       \r       </target>\r      \r       <!-- Sysdyn connections -->\r    <target interface="org.simantics.diagram.adapter.ElementFactory">\r              <!-- Edges -->\r         <resource uri="http://www.simantics.org/Sysdyn-0.0/FlowConnection"\r                     class="org.simantics.sysdyn.ui.elements2.connections.FlowEdgeFactory" />\r               <resource uri="http://www.simantics.org/Sysdyn-0.0/DependencyConnection"\r                       class="org.simantics.sysdyn.ui.elements2.connections.DependencyEdgeFactory" />\r         <type uri="http://www.simantics.org/Sysdyn-0.0/FlowConnection"\r                 class="org.simantics.sysdyn.ui.elements2.connections.FlowEdgeFactory" />\r               <type uri="http://www.simantics.org/Sysdyn-0.0/DependencyConnection"\r                   class="org.simantics.sysdyn.ui.elements2.connections.DependencyEdgeFactory" />\r         <!-- : SYSDYN.Connection-->\r            <type uri="http://www.simantics.org/Sysdyn-0.0/FlowConnection"\r                 class="org.simantics.sysdyn.ui.elements2.connections.FlowConnectionFactory" />\r         <type uri="http://www.simantics.org/Sysdyn-0.0/DependencyConnection"\r                   class="org.simantics.sysdyn.ui.elements2.connections.DependencyConnectionFactory" />\r   </target>\r      \r       <target interface="org.simantics.g2d.connection.EdgeVisualsConfigurer">\r          <baseType uri="http://www.simantics.org/Diagram-0.0/HasConnector" />\r   <resource uri="http://www.simantics.org/Diagram-0.0/HasPlainConnector"\r          class="org.simantics.diagram.content.ArrowConfigurer">\r         <string>none 0</string>\r       </resource>\r    <resource uri="http://www.simantics.org/Diagram-0.0/HasArrowConnector"\r          class="org.simantics.diagram.content.ArrowConfigurer">\r         <string>fill 1</string>\r       </resource>\r  </target>\r      \r       <!-- ModelBrowser2 -->\r \r       <target interface="org.simantics.browsing.ui.model.children.ChildRule">\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectBrowseContext/ModuleTypeChildRule"\r            class="org.simantics.sysdyn.ui.browser.childrules.ModuleTypeChildRule"/>\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectBrowseContext/ModuleContentChildRule"\r            class="org.simantics.sysdyn.ui.browser.childrules.ModuleContentChildRule"/>            \r    </target>\r    \r    <target interface="org.simantics.browsing.ui.model.visuals.VisualsRule">\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectBrowseContext/ModuleTypeLabelRule"\r            class="org.simantics.sysdyn.ui.browser.labelrules.ModuleTypeLabelRule"/>\r    </target>    \r    \r    <target interface="org.simantics.db.layer0.adapter.ActionFactory">\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectActionContext/Actions/NewModuleType"\r            class="org.simantics.sysdyn.ui.browser.actions.NewModuleTypeAction" />\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectActionContext/Actions/NewEnumeration"\r            class="org.simantics.sysdyn.ui.browser.actions.NewEnumerationAction" />\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectActionContext/Actions/OpenWorkbook"\r            class="org.simantics.sysdyn.ui.browser.actions.OpenWorkbookAction" />\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectActionContext/Actions/NewFunction"\r            class="org.simantics.sysdyn.ui.browser.actions.NewFunctionAction" />\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectActionContext/Actions/NewFunctionLibrary"\r            class="org.simantics.sysdyn.ui.browser.actions.NewFunctionLibraryAction" />\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectActionContext/Actions/NewSharedFunctionLibrary"\r            class="org.simantics.sysdyn.ui.browser.actions.NewSharedFunctionLibraryAction" />            \r    </target>              \r  \r  <!-- PROFILES -->\r    <target interface="org.simantics.scenegraph.profile.Style">\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/SimulationPlaybackStyle"\r            class="org.simantics.sysdyn.ui.elements2.profiles.SimulationPlaybackStyle">\r        </resource>\r                <resource uri="http://www.simantics.org/Sysdyn-0.0/IssueStyle"\r            class="org.simantics.sysdyn.ui.elements2.profiles.IssueDecorationStyle">\r        </resource>\r    </target>\r
+<adapters>\r\r   <target interface="org.simantics.db.layer0.adapter.Realization">\r               <type uri="http://www.simantics.org/Sysdyn-0.0/Module"\r                 class="org.simantics.structural2.realization.StructuralRealization">\r                   <this />\r               </type>\r        </target>\r\r<!-- \r       <target interface="org.simantics.db.layer0.variable.Variable">\r         <type uri="http://www.simantics.org/Sysdyn-0.0/HistoryRealization"\r                     class="org.simantics.sysdyn.ui.project.HistoryVariable" >\r                      <this />\r               </type>\r                <type uri="http://www.simantics.org/Sysdyn-0.0/DefaultRealization"\r                     class="org.simantics.sysdyn.ui.project.DefaultVariable" >\r                      <this />\r               </type>\r        </target>\r -->\r\r        <target interface="org.simantics.layer0.utils.triggers.ITrigger">\r      <type uri = "http://www.simantics.org/Sysdyn-0.0/DiagramToCompositeMapping"\r          class = "org.simantics.sysdyn.ui.editor.DiagramToCompositeMapping3">\r         <graph/>\r           <this />\r       </type>\r        </target>\r      \r       <target interface="org.simantics.structural.ui.modelBrowser.nodes.AbstractNode">\r               <type uri="http://www.simantics.org/Sysdyn-0.0/SysdynModel"\r                    class="org.simantics.structural.ui.modelBrowser.nodes.ModelNode">\r                      <this />\r               </type>\r        </target>               \r               \r\r      <target\r                interface="org.simantics.browsing.ui.common.node.AbstractNode">\r                <type\r                  uri="http://www.simantics.org/Sysdyn-0.0/SysdynModel"\r                  class="org.simantics.sysdyn.ui.browser.nodes.ModelNode">\r                       <this />\r               </type>\r\r               <resource\r                      uri="http://www.simantics.org/Sysdyn-0.0/ModuleSymbol"\r                 class="org.simantics.sysdyn.ui.browser.nodes.SymbolNode">\r                      <this />\r               </resource>\r\r           <type\r                  uri="http://www.simantics.org/Simulation-1.0/Experiment"\r                       class="org.simantics.sysdyn.ui.browser.nodes.ExperimentNode">\r                  <this />\r               </type>\r                \r               <type\r                  uri="http://www.simantics.org/Sysdyn-0.0/Result"\r                       class="org.simantics.sysdyn.ui.browser.nodes.SimulationResultNode">\r                    <this />\r               </type>\r                \r       </target>\r\r     <!-- Inject default connection routing algorithm for sysdyn diagrams -->\r       <target interface="org.simantics.g2d.diagram.DiagramClass">\r            <adapter uri="http://www.simantics.org/Sysdyn-0.0/ConfigurationDiagram"\r                        adapterClass="org.simantics.sysdyn.ui.elements2.ConfigurationDiagramClassAdapter" />\r   </target>\r\r     <!-- Sysdyn symbols -->\r        <target interface="org.simantics.diagram.adapter.ElementFactory">\r              <resource uri="http://www.simantics.org/Sysdyn-0.0/StockSymbol"\r                        class="org.simantics.sysdyn.ui.elements2.StockFactory" />\r              <resource uri="http://www.simantics.org/Sysdyn-0.0/ModuleSymbol"\r                       class="org.simantics.sysdyn.ui.elements2.ModuleFactory" />\r             <resource uri="http://www.simantics.org/Sysdyn-0.0/ValveSymbol"\r                        class="org.simantics.sysdyn.ui.elements2.ValveFactory" />\r              <resource uri="http://www.simantics.org/Sysdyn-0.0/AuxiliarySymbol"\r                    class="org.simantics.sysdyn.ui.elements2.AuxiliaryFactory" />\r          <resource uri="http://www.simantics.org/Sysdyn-0.0/CloudSymbol"\r                        class="org.simantics.sysdyn.ui.elements2.CloudFactory" />\r              <resource uri="http://www.simantics.org/Sysdyn-0.0/InputSymbol"\r                        class="org.simantics.sysdyn.ui.elements2.InputFactory" />\r\r             <type uri="http://www.simantics.org/Sysdyn-0.0/StockSymbol"\r                    class="org.simantics.sysdyn.ui.elements2.StockFactory" />\r              <type uri="http://www.simantics.org/Sysdyn-0.0/ModuleSymbol"\r                   class="org.simantics.sysdyn.ui.elements2.ModuleFactory" />\r             <type uri="http://www.simantics.org/Sysdyn-0.0/ValveSymbol"\r                    class="org.simantics.sysdyn.ui.elements2.ValveFactory" />\r              <type uri="http://www.simantics.org/Sysdyn-0.0/AuxiliarySymbol"\r                        class="org.simantics.sysdyn.ui.elements2.AuxiliaryFactory" />\r          <type uri="http://www.simantics.org/Sysdyn-0.0/CloudSymbol"\r                    class="org.simantics.sysdyn.ui.elements2.CloudFactory" />\r              <type uri="http://www.simantics.org/Sysdyn-0.0/InputSymbol"\r                    class="org.simantics.sysdyn.ui.elements2.InputFactory" />                       \r       </target>\r      \r       <!-- Sysdyn connections -->\r    <target interface="org.simantics.diagram.adapter.ElementFactory">\r              <!-- Edges -->       \r        <resource uri="http://www.simantics.org/Sysdyn-0.0/FlowConnection"\r            class="org.simantics.sysdyn.ui.elements2.connections.RouteFlowEdgeFactory" />\r        <type uri="http://www.simantics.org/Sysdyn-0.0/FlowConnection"\r            class="org.simantics.sysdyn.ui.elements2.connections.RouteFlowEdgeFactory" />            \r        <type uri="http://www.simantics.org/Sysdyn-0.0/FlowConnection"\r            class="org.simantics.sysdyn.ui.elements2.connections.RouteFlowConnectionFactory">\r            <graph/>\r        </type>                       \r                       \r               <resource uri="http://www.simantics.org/Sysdyn-0.0/DependencyConnection"\r                       class="org.simantics.sysdyn.ui.elements2.connections.DependencyEdgeFactory" />\r         <type uri="http://www.simantics.org/Sysdyn-0.0/DependencyConnection"\r                   class="org.simantics.sysdyn.ui.elements2.connections.DependencyEdgeFactory" />\r         <type uri="http://www.simantics.org/Sysdyn-0.0/DependencyConnection"\r                   class="org.simantics.sysdyn.ui.elements2.connections.DependencyConnectionFactory" />\r   </target>\r      \r       <target interface="org.simantics.g2d.connection.EdgeVisualsConfigurer">\r          <baseType uri="http://www.simantics.org/Diagram-0.0/HasConnector" />\r   <resource uri="http://www.simantics.org/Diagram-0.0/HasPlainConnector"\r          class="org.simantics.diagram.content.ArrowConfigurer">\r         <string>none 0</string>\r       </resource>\r    <resource uri="http://www.simantics.org/Diagram-0.0/HasArrowConnector"\r          class="org.simantics.diagram.content.ArrowConfigurer">\r         <string>fill 1</string>\r       </resource>\r  </target>\r      \r       <!-- ModelBrowser2 -->\r \r       <target interface="org.simantics.browsing.ui.model.children.ChildRule">\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectBrowseContext/ModuleTypeChildRule"\r            class="org.simantics.sysdyn.ui.browser.childrules.ModuleTypeChildRule"/>\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectBrowseContext/ModuleContentChildRule"\r            class="org.simantics.sysdyn.ui.browser.childrules.ModuleContentChildRule"/>            \r    </target>\r    \r    <target interface="org.simantics.browsing.ui.model.visuals.VisualsRule">\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectBrowseContext/ModuleTypeLabelRule"\r            class="org.simantics.sysdyn.ui.browser.labelrules.ModuleTypeLabelRule"/>\r    </target>    \r    \r    <target interface="org.simantics.db.layer0.adapter.ActionFactory">\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectActionContext/Actions/NewModuleType"\r            class="org.simantics.sysdyn.ui.browser.actions.NewModuleTypeAction" />\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectActionContext/Actions/NewEnumeration"\r            class="org.simantics.sysdyn.ui.browser.actions.NewEnumerationAction" />\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectActionContext/Actions/OpenWorkbook"\r            class="org.simantics.sysdyn.ui.browser.actions.OpenWorkbookAction" />\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectActionContext/Actions/NewFunction"\r            class="org.simantics.sysdyn.ui.browser.actions.NewFunctionAction" />\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectActionContext/Actions/NewFunctionLibrary"\r            class="org.simantics.sysdyn.ui.browser.actions.NewFunctionLibraryAction" />\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ProjectActionContext/Actions/NewSharedFunctionLibrary"\r            class="org.simantics.sysdyn.ui.browser.actions.NewSharedFunctionLibraryAction" />            \r    </target>              \r  \r  <!-- PROFILES -->\r    <target interface="org.simantics.scenegraph.profile.Style">\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/SimulationPlaybackStyle"\r            class="org.simantics.sysdyn.ui.elements2.profiles.SimulationPlaybackStyle">\r        </resource>\r                <resource uri="http://www.simantics.org/Sysdyn-0.0/IssueStyle"\r            class="org.simantics.sysdyn.ui.elements2.profiles.IssueDecorationStyle">\r        </resource>\r    </target>\r
 </adapters>
\ No newline at end of file
index 8e697c51e5e6cb99dc37aa3c1faca67cdd41135b..e6c5107af9116b0ffe91d4f1f77611dbebc9d2fc 100644 (file)
@@ -60,6 +60,7 @@ import org.simantics.sysdyn.ui.elements2.CloudFactory;
 import org.simantics.sysdyn.ui.elements2.SysdynElementClasses;\r
 import org.simantics.sysdyn.ui.elements2.SysdynElementFactory;\r
 import org.simantics.sysdyn.ui.elements2.connections.ConnectionClasses;\r
+import org.simantics.sysdyn.ui.elements2.connections.RouteFlowEdgeClass;\r
 import org.simantics.sysdyn.ui.elements2.connections.SysdynConnectionClass;\r
 import org.simantics.sysdyn.ui.properties.SysdynPropertyPage;\r
 import org.simantics.ui.workbench.IPropertyPage;\r
@@ -115,10 +116,11 @@ public class DiagramViewer extends org.simantics.modeling.ui.diagramEditor.Diagr
        protected IElementClassProvider createElementClassProvider(ReadGraph graph) {\r
                SysdynResource sr = SysdynResource.getInstance(graph);\r
                ElementClass dependencyClass = SysdynConnectionClass.CLASS.newClassWith(new StaticObjectAdapter(sr.DependencyConnection));\r
+               ElementClass flowClass = RouteFlowEdgeClass.FLOW_CLASS.newClassWith(new StaticObjectAdapter(sr.FlowConnection));\r
                return SysdynElementClassProviders.mappedProvider(\r
                                ElementClasses.CONNECTION, dependencyClass,\r
                                ElementClasses.FLAG, CloudFactory.createElementClass(sr.CloudSymbol, SysdynElementFactory.createTerminals(graph, sr.CloudSymbol)),\r
-                               ConnectionClasses.FLOW, SysdynConnectionClass.CLASS.newClassWith(new StaticObjectAdapter(sr.FlowConnection)),\r
+                               ConnectionClasses.FLOW, flowClass,\r
                                ConnectionClasses.DEPENDENCY, dependencyClass,\r
                                SysdynElementClasses.VALVE,  CloudFactory.createElementClass(sr.ValveSymbol, SysdynElementFactory.createTerminals(graph, sr.ValveSymbol))\r
                );\r
index 8af06aac942623bd25a902d3340af4daa5ec769d..9f0b53dbe3c963d64dab8ab295f313fe81c7f183 100644 (file)
@@ -34,13 +34,13 @@ import org.simantics.g2d.element.IElementClassProvider;
 import org.simantics.g2d.participant.KeyUtil;\r
 import org.simantics.g2d.participant.MouseUtil;\r
 import org.simantics.g2d.participant.TransformUtil;\r
+import org.simantics.g2d.routing.algorithm2.Router4;\r
 import org.simantics.g2d.utils.GeometryUtils;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent;\r
 import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent;\r
 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent;\r
 import org.simantics.sysdyn.ui.editor.participant.SysdynElementClassProviders.ISysdynElementClassProvider;\r
 import org.simantics.sysdyn.ui.editor.routing.DependencyRouter;\r
-import org.simantics.sysdyn.ui.editor.routing.FlowRouter;\r
 import org.simantics.sysdyn.ui.elements2.AuxiliaryFactory;\r
 import org.simantics.sysdyn.ui.elements2.CloudFactory;\r
 import org.simantics.sysdyn.ui.elements2.InputFactory;\r
@@ -62,7 +62,7 @@ import org.simantics.sysdyn.ui.elements2.connections.ConnectionClasses;
  *\r
  * @author Toni Kalajainen\r
  */\r
-public class PointerInteractor extends org.simantics.g2d.diagram.participant.pointertool.PointerInteractor {\r
+public class PointerInteractor extends org.simantics.diagram.participant.PointerInteractor2 {\r
 \r
        @Dependency Selection selection;\r
        @Dependency KeyUtil keys;\r
@@ -108,7 +108,8 @@ public class PointerInteractor extends org.simantics.g2d.diagram.participant.poi
                                        if(id.equals(AuxiliaryFactory.class.getSimpleName())\r
                                                        || id.equals(InputFactory.class.getSimpleName())\r
                                                        || id.equals(ModuleFactory.class.getSimpleName())) return false;\r
-                                       diagram.setHint(DiagramHints.ROUTE_ALGORITHM, new FlowRouter(false));\r
+//                                     diagram.setHint(DiagramHints.ROUTE_ALGORITHM, new FlowRouter(false));\r
+                                       diagram.setHint(DiagramHints.ROUTE_ALGORITHM, new Router4(false));\r
                                        diagram.setHint(DiagramHints.KEY_USE_CONNECTION_FLAGS, true);\r
                                        ISysdynElementClassProvider secp = (ISysdynElementClassProvider)elementClassProvider;\r
                                        secp.put(ElementClasses.CONNECTION, elementClassProvider.get(ConnectionClasses.FLOW));\r
@@ -122,7 +123,8 @@ public class PointerInteractor extends org.simantics.g2d.diagram.participant.poi
                        }  \r
                        else if (me.button == MouseEvent.RIGHT_BUTTON) {\r
                                 // Start connection out of thin air, without a terminal.\r
-                                diagram.setHint(DiagramHints.ROUTE_ALGORITHM, new FlowRouter(false));\r
+//                              diagram.setHint(DiagramHints.ROUTE_ALGORITHM, new FlowRouter(false));\r
+                                diagram.setHint(DiagramHints.ROUTE_ALGORITHM, new Router4(false));\r
                                 diagram.setHint(DiagramHints.KEY_USE_CONNECTION_FLAGS, true);\r
                                 ISysdynElementClassProvider secp = (ISysdynElementClassProvider)elementClassProvider;\r
                                 secp.put(ElementClasses.CONNECTION, elementClassProvider.get(ConnectionClasses.FLOW));\r
index 2e67cedc402ac63bbd232c499acfd56121ea70c3..f8042337f9398801942379acf13a38e4292f2397 100644 (file)
@@ -1,5 +1,7 @@
 package org.simantics.sysdyn.ui.editor.routing;\r
 \r
+import gnu.trove.TObjectIntHashMap;\r
+\r
 import java.awt.geom.AffineTransform;\r
 import java.awt.geom.Path2D;\r
 import java.awt.geom.PathIterator;\r
@@ -10,8 +12,6 @@ import org.simantics.g2d.routing.Constants;
 import org.simantics.g2d.routing.IConnection;\r
 import org.simantics.g2d.routing.IConnection.Connector;\r
 import org.simantics.g2d.routing.IRouter2;\r
-import org.simantics.sysdyn.ui.editor.participant.SysdynConnectTool.SysdynConnection;\r
-import org.simantics.sysdyn.ui.elements2.connections.Flows;\r
 \r
 public class FlowRouter implements IRouter2{\r
 \r
@@ -80,7 +80,8 @@ public class FlowRouter implements IRouter2{
         }\r
 \r
         localRouter.route();\r
-\r
+        return localRouter.path;\r
+        /*\r
         Path2D completePath = new Path2D.Double();\r
         \r
         double[] coordinates = new double[localRouter.points.size()];\r
@@ -109,8 +110,162 @@ public class FlowRouter implements IRouter2{
        \r
 //     Flows.createLines(completePath, false, beginObstacle, endObstacle);\r
         return completePath;\r
+        */\r
+    }\r
+    \r
+    @Override\r
+    public void route(IConnection connection) {\r
+        Collection<?> segments = connection.getSegments();\r
+        if(segments.size() == 1)\r
+            for(Object seg : segments) {\r
+                Connector begin = connection.getBegin(seg);\r
+                Connector end = connection.getEnd(seg);\r
+\r
+                double bestLength = Double.POSITIVE_INFINITY;\r
+                Path2D bestPath = null;\r
+\r
+                for(int sDir : Constants.POSSIBLE_DIRECTIONS[begin.allowedDirections])\r
+                    for(int tDir : Constants.POSSIBLE_DIRECTIONS[end.allowedDirections]) {\r
+                        Path2D path = route(begin.x, begin.y, sDir, begin.parentObstacle,\r
+                                end.x, end.y, tDir, end.parentObstacle);\r
+\r
+                        double length = pathCost(path);\r
+                        if(length < bestLength) {\r
+                            bestLength = length;\r
+                            bestPath = localRouter.path;\r
+                        }\r
+                    }\r
+\r
+                if(bestPath != null)\r
+                    connection.setPath(seg, bestPath);\r
+            }\r
+        else {\r
+            TObjectIntHashMap<Connector> leftSegments = new TObjectIntHashMap<Connector>();\r
+            TObjectIntHashMap<Connector> rightSegments = new TObjectIntHashMap<Connector>();\r
+            TObjectIntHashMap<Connector> upSegments = new TObjectIntHashMap<Connector>();\r
+            TObjectIntHashMap<Connector> downSegments = new TObjectIntHashMap<Connector>();\r
+            TObjectIntHashMap<Connector> horizontalCount = new TObjectIntHashMap<Connector>();\r
+            for(Object seg : segments) {\r
+                Connector begin = connection.getBegin(seg);\r
+                Connector end = connection.getEnd(seg);\r
+                if(begin.x < end.x) {\r
+                    leftSegments.adjustOrPutValue(end, 1, 1);\r
+                    rightSegments.adjustOrPutValue(begin, 1, 1);\r
+                }\r
+                else {\r
+                    leftSegments.adjustOrPutValue(begin, 1, 1);\r
+                    rightSegments.adjustOrPutValue(end, 1, 1);\r
+                }\r
+                if(begin.y < end.y) {\r
+                    upSegments.adjustOrPutValue(end, 1, 1);\r
+                    downSegments.adjustOrPutValue(begin, 1, 1);\r
+                }\r
+                else {\r
+                    upSegments.adjustOrPutValue(begin, 1, 1);\r
+                    downSegments.adjustOrPutValue(end, 1, 1);\r
+                }\r
+                if((begin.allowedDirections & 5) != 0)\r
+                    horizontalCount.adjustOrPutValue(end, 1, 1);\r
+                if((begin.allowedDirections & 10) != 0)\r
+                    horizontalCount.adjustOrPutValue(end, -1, -1);\r
+                if((end.allowedDirections & 5) != 0)\r
+                    horizontalCount.adjustOrPutValue(begin, 1, 1);\r
+                if((end.allowedDirections & 10) != 0)\r
+                    horizontalCount.adjustOrPutValue(begin, -1, -1);\r
+            }\r
+            for(Object seg : segments) {\r
+                Connector begin = connection.getBegin(seg);\r
+                Connector end = connection.getEnd(seg);\r
+                int allowedBegin = begin.allowedDirections;\r
+                int allowedEnd = end.allowedDirections;\r
+\r
+                if(horizontalCount.get(begin) + horizontalCount.get(end) >= 0) {\r
+                    //System.out.println("horizontal");\r
+                    if(begin.x < end.x) {\r
+                        if(allowedBegin == 0xf) {\r
+                            if(rightSegments.get(begin) <= 1)\r
+                                allowedBegin = 1;\r
+                            else\r
+                                allowedBegin = 11;\r
+                        }\r
+                        if(allowedEnd == 0xf) {\r
+                            if(leftSegments.get(end) <= 1)\r
+                                allowedEnd = 4;\r
+                            else\r
+                                allowedEnd = 14;\r
+                        }\r
+                    }\r
+                    else {\r
+                        if(allowedBegin == 0xf) {\r
+                            if(leftSegments.get(begin) <= 1)\r
+                                allowedBegin = 4;\r
+                            else\r
+                                allowedBegin = 14;\r
+                        }\r
+                        if(allowedEnd == 0xf) {\r
+                            if(rightSegments.get(end) <= 1)\r
+                                allowedEnd = 1;\r
+                            else\r
+                                allowedEnd = 11;\r
+                        }\r
+                    }\r
+                }\r
+                else {\r
+                    //System.out.println("vertical");\r
+                    if(begin.y < end.y) {\r
+                        if(allowedBegin == 0xf) {\r
+                            if(downSegments.get(begin) <= 1)\r
+                                allowedBegin = 2;\r
+                            else\r
+                                allowedBegin = 7;\r
+                        }\r
+                        if(allowedEnd == 0xf) {\r
+                            if(upSegments.get(end) <= 1)\r
+                                allowedEnd = 8;\r
+                            else\r
+                                allowedEnd = 13;\r
+                        }\r
+                    }\r
+                    else {\r
+                        if(allowedBegin == 0xf) {\r
+                            if(upSegments.get(begin) <= 1)\r
+                                allowedBegin = 8;\r
+                            else\r
+                                allowedBegin = 13;\r
+                        }\r
+                        if(allowedEnd == 0xf) {\r
+                            if(downSegments.get(end) <= 1)\r
+                                allowedEnd = 2;\r
+                            else\r
+                                allowedEnd = 7;\r
+                        }\r
+                    }\r
+                }\r
+\r
+                //System.out.println(allowedBegin + " " + allowedEnd);\r
+\r
+                double bestLength = Double.POSITIVE_INFINITY;\r
+                Path2D bestPath = null;\r
+\r
+                for(int sDir : Constants.POSSIBLE_DIRECTIONS[allowedBegin])\r
+                    for(int tDir : Constants.POSSIBLE_DIRECTIONS[allowedEnd]) {\r
+                        Path2D path = route(begin.x, begin.y, sDir, begin.parentObstacle,\r
+                                end.x, end.y, tDir, end.parentObstacle);\r
+\r
+                        double length = pathCost(path);\r
+                        if(length < bestLength) {\r
+                            bestLength = length;\r
+                            bestPath = localRouter.path;\r
+                        }\r
+                    }\r
+\r
+                if(bestPath != null)\r
+                    connection.setPath(seg, bestPath);\r
+            }\r
+        }\r
     }\r
 \r
+    /*\r
     @Override\r
     public void route(IConnection connection) {\r
        \r
@@ -142,6 +297,7 @@ public class FlowRouter implements IRouter2{
                     connection.setPath(seg, bestPath);\r
             }\r
     }\r
+    */\r
 \r
     final static AffineTransform IDENTITY = new AffineTransform();\r
 \r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/Orientation.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/Orientation.java
new file mode 100644 (file)
index 0000000..7773307
--- /dev/null
@@ -0,0 +1,35 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements2;\r
+\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.handler.ElementHandler;\r
+\r
+public class Orientation implements ElementHandler {\r
+\r
+    private static final long serialVersionUID = 958120463924210936L;\r
+    \r
+    public static final Orientation INSTANCE = new Orientation();\r
+    \r
+    public String getOrientation(IElement e) {\r
+        return e.getHint(SysdynElementHints.KEY_ORIENTATION);\r
+    }\r
+\r
+    \r
+    public void setOrientation(IElement e, String orientation) {\r
+        if (orientation != null)\r
+            e.setHint(SysdynElementHints.KEY_ORIENTATION, orientation);\r
+        else\r
+            e.removeHint(SysdynElementHints.KEY_ORIENTATION);\r
+    }\r
+}\r
+    \r
index c7f47e7e6d07ef9cb50b3ab1b8eed25072a7ee68..bbe07794619504bf43ebca9f4e979657ee053c53 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************\r
- * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Copyright (c) 2010, 2011 Association for Decentralized Information Management in\r
  * Industry THTH ry.\r
  * All rights reserved. This program and the accompanying materials\r
  * are made available under the terms of the Eclipse Public License v1.0\r
@@ -17,5 +17,6 @@ import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;
 public class SysdynElementHints {\r
 \r
     public static final Key KEY_INPUT_REFERENCE = new KeyOf(String.class, "INPUT_REFERENCE");\r
+    public static final Key KEY_ORIENTATION = new KeyOf(String.class, "ORIENTATION");    \r
     \r
 }\r
index ec8a5721ebe343bc5c6b6d7bca754c70bfce656e..1837728caaee7002a05089c7944f4b50c3dceebc 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************\r
- * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Copyright (c) 2010, 2011 Association for Decentralized Information Management in\r
  * Industry THTH ry.\r
  * All rights reserved. This program and the accompanying materials\r
  * are made available under the terms of the Eclipse Public License v1.0\r
@@ -15,17 +15,37 @@ import org.simantics.g2d.element.IElement;
 \r
 public class SysdynElementUtils {\r
 \r
-    \r
+\r
     public static void setInputReference(IElement e, String inputReference)\r
     {\r
         Input i = e.getElementClass().getSingleItem(Input.class);\r
-        i.setInputReference(e, inputReference);\r
+        if(i != null)\r
+            i.setInputReference(e, inputReference);\r
     }\r
 \r
     public static String getInputReference(IElement e)\r
     {\r
         Input i = e.getElementClass().getSingleItem(Input.class);\r
-        return i.getInputReference(e);\r
+        if(i != null)\r
+            return i.getInputReference(e);\r
+        else\r
+            return null;\r
+    }\r
+\r
+    public static void setOrientation(IElement e, String orientation)\r
+    {\r
+        Orientation o = e.getElementClass().getSingleItem(Orientation.class);\r
+        if(o != null)\r
+            o.setOrientation(e, orientation);\r
     }\r
-    \r
+\r
+    public static String getOrientation(IElement e)\r
+    {\r
+        Orientation o = e.getElementClass().getSingleItem(Orientation.class);\r
+        if(o != null)\r
+            return o.getOrientation(e);\r
+        else\r
+            return null;\r
+    }\r
+\r
 }\r
index 4824b40ee47ff6efd3ece959cbbb166a1b447ef4..c154c1dc8ed393ad4ed72e6cb570181561355f7c 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************\r
- * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Copyright (c) 2010, 2011 Association for Decentralized Information Management in\r
  * Industry THTH ry.\r
  * All rights reserved. This program and the accompanying materials\r
  * are made available under the terms of the Eclipse Public License v1.0\r
@@ -18,8 +18,12 @@ import java.awt.geom.Path2D;
 import java.awt.geom.Rectangle2D;\r
 import java.util.Collection;\r
 \r
+import org.simantics.db.ReadGraph;\r
 import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
 import org.simantics.diagram.elements.TextNode;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.diagram.IDiagram;\r
 import org.simantics.g2d.element.ElementClass;\r
 import org.simantics.g2d.element.ElementHints;\r
 import org.simantics.g2d.element.ElementUtils;\r
@@ -44,10 +48,11 @@ import org.simantics.g2d.image.impl.ShapeImage;
 import org.simantics.g2d.utils.Alignment;\r
 import org.simantics.scenegraph.g2d.G2DParentNode;\r
 import org.simantics.scenegraph.g2d.nodes.ShapeNode;\r
-import org.simantics.utils.datastructures.hints.IHintListener;\r
-import org.simantics.utils.datastructures.hints.IHintObservable;\r
+import org.simantics.sysdyn.SysdynResource;\r
 import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
 import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;\r
+import org.simantics.utils.datastructures.hints.IHintListener;\r
+import org.simantics.utils.datastructures.hints.IHintObservable;\r
 \r
 \r
 public class ValveFactory extends SysdynElementFactory {\r
@@ -77,10 +82,29 @@ public class ValveFactory extends SysdynElementFactory {
                 HoverImpl.INSTANCE,\r
                 ValveSceneGraph.INSTANCE,\r
                 BoundsOutline.INSTANCE,\r
+                Orientation.INSTANCE,\r
                 new WholeElementTerminals(terminals)\r
         ).setId(ValveFactory.class.getSimpleName());\r
     }\r
     \r
+    @Override\r
+    public void load(ReadGraph graph, final ICanvasContext canvas, final IDiagram diagram, final Resource element, final IElement e) throws DatabaseException {\r
+        super.load(graph, canvas, diagram, element, e);\r
+        \r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        \r
+        Resource orientation = graph.getPossibleObject(element, sr.HasValveOrientation);\r
+        \r
+        String orientationText;\r
+        if(orientation != null && sr.Vertical.equals(orientation)) {\r
+            orientationText = "Vertical";\r
+        } else {\r
+            orientationText = "Horizontal";\r
+        } \r
+        SysdynElementUtils.setOrientation(e, orientationText);\r
+            \r
+    }\r
+    \r
     /**\r
      * @param valveSize\r
      * @param rotated <code>true</code> for vertical valve, <code>false</code>\r
@@ -126,7 +150,11 @@ public class ValveFactory extends SysdynElementFactory {
             node.setStroke(STROKE);\r
             node.setScaleStroke(true);\r
             node.setColor(Color.BLACK);\r
-            node.setShape(createShape(VALVE_SIZE, Boolean.TRUE.equals(e.getHint(KEY_ROTATED))));\r
+            boolean rotated = false;\r
+            String orientation = SysdynElementUtils.getOrientation(e);\r
+            if(orientation != null && orientation.equals("Vertical"))\r
+                rotated = true;\r
+            node.setShape(createShape(VALVE_SIZE, Boolean.TRUE.equals(rotated)));\r
             Boolean hover = e.getHint(ElementHints.KEY_HOVER); \r
             node.setHover(hover != null ? hover : false);\r
 \r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowArrowLineStyle.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowArrowLineStyle.java
new file mode 100644 (file)
index 0000000..ca2f092
--- /dev/null
@@ -0,0 +1,169 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements2.connections;\r
+\r
+import java.awt.Color;\r
+import java.awt.Graphics2D;\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Path2D;\r
+import java.awt.geom.Rectangle2D;\r
+import java.io.Serializable;\r
+import java.util.StringTokenizer;\r
+\r
+import org.simantics.diagram.connection.rendering.arrows.ILineEndStyle;\r
+\r
+\r
+/**\r
+ * Copied from ArrowLLineEndStyle\r
+ */\r
+public class FlowArrowLineStyle implements ILineEndStyle, Serializable {\r
+\r
+    private static final long serialVersionUID = 5348566089660986479L;\r
+\r
+    public static enum ArrowType { None, Stroke, Fill }\r
+\r
+    public static final double length = 8.0;\r
+    public static final double width = 4.0;\r
+    public static final double space = 0.0;\r
+\r
+    protected ArrowType type;\r
+    protected Path2D path;\r
+    protected double lineEndLength;\r
+    \r
+    protected Rectangle2D bounds = new Rectangle2D.Double();\r
+    \r
+    public FlowArrowLineStyle(String desc, Rectangle2D bounds) {\r
+        this.type = ArrowType.None;\r
+        this.lineEndLength = 0.0;\r
+\r
+        double l = length;\r
+        double w = width;\r
+        double s = space;\r
+        this.bounds = bounds;\r
+\r
+        StringTokenizer tokenizer = new StringTokenizer(desc);\r
+        if (tokenizer.hasMoreTokens()) {\r
+            String type = tokenizer.nextToken();\r
+            this.type = parseType(type);\r
+\r
+            if (tokenizer.hasMoreTokens()) {\r
+                String ls = tokenizer.nextToken();\r
+                l = parseSize(ls, length);\r
+\r
+                if (tokenizer.hasMoreTokens()) {\r
+                    String ws = tokenizer.nextToken();\r
+                    w = parseSize(ws, width);\r
+\r
+                    if (tokenizer.hasMoreTokens()) {\r
+                        String ss = tokenizer.nextToken();\r
+                        s = parseSize(ss, space);\r
+                    }\r
+                }\r
+            }\r
+            if (this.type != ArrowType.None) {\r
+                this.path = arrow(l, w, s);\r
+                lineEndLength = l+s;\r
+            }\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void render(Graphics2D g, double x, double y, int dir) {\r
+        if (type == ArrowType.None || path == null)\r
+            return;\r
+        // Calculate coordinates to the border of the terminal\r
+        switch(dir) {\r
+            case 0:\r
+                x = bounds.getMinX();\r
+                break;\r
+            case 1:\r
+                y = bounds.getMinY();\r
+                break;\r
+            case 2:\r
+                x = bounds.getMaxX();\r
+                break;\r
+            case 3:\r
+                y = bounds.getMaxY();\r
+                break;\r
+            default:\r
+                return;\r
+        }\r
+        AffineTransform old = g.getTransform();\r
+        g.translate(x, y);\r
+        g.rotate(dir*Math.PI*0.5);\r
+        g.setColor(Color.BLACK);\r
+\r
+        switch (type) {\r
+            case Fill:\r
+                g.fill(path);\r
+                break;\r
+            case Stroke:\r
+                g.draw(path);\r
+                break;\r
+        }\r
+\r
+        g.setTransform(old);\r
+    }\r
+\r
+    @Override\r
+    public double getLineEndLength(int direction) {\r
+        switch(direction) {\r
+            case 0:\r
+                lineEndLength = bounds.getWidth() / 2.0;\r
+                break;\r
+            case 1:\r
+                lineEndLength = bounds.getHeight() / 2.0;\r
+                break;\r
+            case 2:\r
+                lineEndLength =  bounds.getWidth() / 2.0;\r
+                break;\r
+            case 3:\r
+                lineEndLength = bounds.getHeight() / 2.0;\r
+                break;\r
+        }\r
+        return lineEndLength;\r
+    }\r
+\r
+    private static Path2D arrow(double length, double width, double space) {\r
+        Path2D.Double path = new Path2D.Double();\r
+        path.moveTo(-space, 0);\r
+        path.lineTo(-length-space, -width);\r
+        path.lineTo(-length-space, +width);\r
+        path.closePath();\r
+        return path;\r
+    }\r
+\r
+    private double parseSize(String size, double defaultValue) {\r
+        try {\r
+            return Double.parseDouble(size);\r
+        } catch (NumberFormatException e) {\r
+            return defaultValue;\r
+        }\r
+    }\r
+\r
+    private ArrowType parseType(String type) {\r
+        String lower = type.toLowerCase();\r
+        if ("none".equals(lower))\r
+            return ArrowType.None;\r
+        if ("stroke".equals(lower))\r
+            return ArrowType.Stroke;\r
+        if ("fill".equals(lower))\r
+            return ArrowType.Fill;\r
+        throw new IllegalArgumentException("unrecognized arrow type: " + type);\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        return getClass().getSimpleName() + "[" + type + ", " + path + "]";\r
+    }\r
+\r
+}\r
similarity index 95%
rename from org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowConnectionFactory.java
rename to org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowConnectionFactoryOld.java
index c770d6028fb3fd411af507cc64947051dfdb09fe..40d3e080c10d7b0fb4fba2e1c030d7c7115ee7c7 100644 (file)
@@ -31,7 +31,7 @@ import org.simantics.sysdyn.ui.editor.routing.FlowRouter;
  * \r
  * @author Tuukka Lehtonen\r
  */\r
-public class FlowConnectionFactory extends ElementFactoryAdapter {\r
+public class FlowConnectionFactoryOld extends ElementFactoryAdapter {\r
 \r
     public static final ElementClass CLASS = SysdynConnectionClass.CLASS;\r
 \r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowConnectionStyle.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowConnectionStyle.java
new file mode 100644 (file)
index 0000000..b975e17
--- /dev/null
@@ -0,0 +1,143 @@
+package org.simantics.sysdyn.ui.elements2.connections;\r
+\r
+import java.awt.Color;\r
+import java.awt.Graphics2D;\r
+import java.awt.Stroke;\r
+import java.awt.geom.Path2D;\r
+import java.awt.geom.PathIterator;\r
+import java.io.Serializable;\r
+\r
+import org.simantics.diagram.connection.rendering.ConnectionStyle;\r
+\r
+public class FlowConnectionStyle  implements ConnectionStyle, Serializable {\r
+\r
+    private static final long serialVersionUID = 2777194644079591357L;\r
+\r
+    Color                     lineColor;\r
+    Stroke                    lineStroke;\r
+\r
+    public FlowConnectionStyle(Color lineColor, Stroke lineStroke) {\r
+        this.lineColor = lineColor;\r
+        this.lineStroke = lineStroke;\r
+    }\r
+    \r
+    @Override\r
+    public void drawBranchPoint(Graphics2D g, double x, double y) {\r
+    }\r
+\r
+    @Override\r
+    public void drawLine(Graphics2D g, double x1, double y1, double x2, double y2, boolean isTransient) {\r
+        System.out.println("DrawLine");\r
+    }\r
+\r
+    @Override\r
+    public void drawPath(Graphics2D g, Path2D path, boolean isTransient) {\r
+        if (lineColor != null)\r
+            g.setColor(lineColor);\r
+        if (lineStroke != null)\r
+            g.setStroke(lineStroke);\r
+\r
+        Path2D p1 = createOffsetPath(g, path, 1);\r
+        Path2D p2 = createOffsetPath(g, path, -1);\r
+        p1.append(p2, false);\r
+        g.draw(p1);\r
+    }\r
+\r
+    @Override\r
+    public void drawDegeneratedLine(Graphics2D g, double x, double y, boolean isHorizontal, boolean isTransient) {\r
+    }\r
+\r
+    @Override\r
+    public double getDegeneratedLineLength() {\r
+        return 0;\r
+    }\r
+    \r
+    private static int x = 0;\r
+    private static int y = 1;\r
+    private Path2D createOffsetPath(Graphics2D g, Path2D originalPath, float offset) {\r
+        PathIterator pi = originalPath.getPathIterator(null);\r
+        Path2D newPath = new Path2D.Double();\r
+        double[] previous = new double[6];\r
+        double[] current = new double[6];\r
+        double[] next = new double[6];\r
+        boolean vertical = false;\r
+        pi.currentSegment(current);\r
+        pi.next();\r
+        pi.currentSegment(next);\r
+        \r
+        Direction direction = getDirection(current, next);\r
+\r
+        int i = 0;\r
+        if(direction == Direction.SOUTH || direction == Direction.NORTH) {\r
+            // First line vertical\r
+            vertical = true;\r
+            current[x] += offset;\r
+            newPath.moveTo(current[x], current[y]);\r
+            \r
+            if(direction == Direction.SOUTH)\r
+                offset = -offset;\r
+        } else {\r
+            // First line horizontal\r
+            current[y] += offset;\r
+            i = 1;\r
+            newPath.moveTo(current[x], current[y]);\r
+            if(direction == Direction.WEST)\r
+                offset = -offset;\r
+        }\r
+        \r
+\r
+        previous[x] = current[x];\r
+        previous[y] = current[y];\r
+        current[x] = next[x];\r
+        current[y] = next[y];\r
+\r
+        while(!pi.isDone()) {\r
+            pi.next();\r
+            pi.currentSegment(next);\r
+            if(previous[i] < next[i] ^ (i&1)==1) {\r
+                if(vertical) {\r
+                    if(!pi.isDone()) current[y] += offset;\r
+                    newPath.lineTo(previous[x], current[y]);\r
+                } else {\r
+                    if(!pi.isDone()) current[x] += offset;\r
+                    newPath.lineTo(current[x], previous[y]);\r
+                }\r
+            } else {\r
+                if(vertical) {\r
+                    if(!pi.isDone()) current[y] -= offset;\r
+                    newPath.lineTo(previous[x], current[y]);\r
+                } else {\r
+                    if(!pi.isDone()) current[x] -= offset;\r
+                    newPath.lineTo(current[x], previous[y]);\r
+                }\r
+            }\r
+            \r
+            previous[x] = current[x];\r
+            previous[y] = current[y];\r
+            current[x] = next[x];\r
+            current[y] = next[y];\r
+            vertical = !vertical;\r
+            i = (i + 1) % 2;\r
+        }\r
+        return newPath;\r
+    }\r
+    \r
+    private enum Direction {NORTH, SOUTH, EAST, WEST};\r
+\r
+    private Direction getDirection(double[] current, double[] next) {\r
+        if(current[x] == next[x]) {\r
+            // move vertically\r
+            if(current[y] < next[y])\r
+                return Direction.SOUTH;\r
+            else\r
+                return Direction.NORTH;\r
+        } else {\r
+            //move horizontally\r
+            if(current[x] < next[x])\r
+                return Direction.EAST;\r
+            else\r
+                return Direction.WEST;\r
+        }\r
+    }\r
+\r
+}\r
similarity index 95%
rename from org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowEdgeClass.java
rename to org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowEdgeClassOld.java
index e002cb23fd4e4791f9b4a8bef5bbeb26e921b73f..c04f747aeab1dcdc697d057c58e7124befb94e4d 100644 (file)
@@ -46,7 +46,6 @@ import org.simantics.g2d.elementclass.BranchPoint;
 import org.simantics.g2d.elementclass.connection.EdgeClass.EdgeHandler;\r
 import org.simantics.g2d.elementclass.connection.EdgeClass.FixedTransform;\r
 import org.simantics.g2d.elementclass.connection.EdgeSceneGraph;\r
-import org.simantics.g2d.routing.ConnectionDirectionUtil;\r
 import org.simantics.g2d.routing.Constants;\r
 import org.simantics.g2d.routing.IRouter2;\r
 import org.simantics.g2d.utils.PathUtils;\r
@@ -56,7 +55,7 @@ import org.simantics.sysdyn.ui.editor.participant.SysdynConnectTool.SysdynConnec
 import org.simantics.sysdyn.ui.editor.routing.FlowRouter;\r
 import org.simantics.sysdyn.ui.elements2.ValveFactory.ValveSceneGraph;\r
 \r
-public class FlowEdgeClass {\r
+public class FlowEdgeClassOld {\r
 \r
        // TODO scale, rotate, move, transform\r
        public static final ElementClass CLASS = ElementClass.compile(\r
@@ -75,7 +74,7 @@ public class FlowEdgeClass {
                @Override\r
                public void init(IElement e, G2DParentNode parent) {\r
                        ElementUtils.getOrCreateNode(e, parent, KEY_SG_NODE,\r
-                                       "edge_" + e.hashCode(), FlowEdgeNode.class);\r
+                                       "edge_" + e.hashCode(), FlowEdgeNodeOld.class);\r
                        final IDiagram diagram = ElementUtils.peekDiagram(e);\r
 \r
                        boolean toValve = false;\r
similarity index 89%
rename from org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowEdgeFactory.java
rename to org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowEdgeFactoryOld.java
index 6acef9fc34d86d6643dbf271dcc0e84614db6687..ae6eee9827293c165f930fc5d7a2d600cd029bf5 100644 (file)
@@ -24,9 +24,9 @@ import org.simantics.g2d.element.ElementClass;
  * \r
  * @author Tuukka Lehtonen\r
  */\r
-public class FlowEdgeFactory extends ElementFactoryAdapter {\r
+public class FlowEdgeFactoryOld extends ElementFactoryAdapter {\r
 \r
-    private static final ElementClass CLASS = FlowEdgeClass.CLASS;\r
+    private static final ElementClass CLASS = FlowEdgeClassOld.CLASS;\r
 \r
     @Override\r
     public void create(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType,\r
similarity index 92%
rename from org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowEdgeNode.java
rename to org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowEdgeNodeOld.java
index e6640f179eb985a9769d81b4b81b058ec9773a58..81143035ee3a3b68ef8e02a5015a8aec082da36b 100644 (file)
@@ -11,7 +11,7 @@ import org.simantics.scenegraph.ISelectionPainterNode;
 import org.simantics.scenegraph.g2d.nodes.EdgeNode;\r
 import org.simantics.scenegraph.utils.NodeUtil;\r
 \r
-public class FlowEdgeNode extends EdgeNode implements ISelectionPainterNode {\r
+public class FlowEdgeNodeOld extends EdgeNode implements ISelectionPainterNode {\r
        \r
        private static final long serialVersionUID = -6774653631527343539L;\r
 \r
similarity index 94%
rename from org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowNode.java
rename to org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowNodeOld.java
index 25cec6400cf13f65eb011247db9be45c4ee4faaf..4f69a76515969f90783b424e10c7604b69e7f4a2 100644 (file)
@@ -22,7 +22,7 @@ import org.simantics.scenegraph.ISelectionPainterNode;
 import org.simantics.scenegraph.g2d.G2DNode;\r
 import org.simantics.scenegraph.utils.NodeUtil;\r
 \r
-public class FlowNode extends G2DNode implements ISelectionPainterNode {\r
+public class FlowNodeOld extends G2DNode implements ISelectionPainterNode {\r
 \r
     private static final long serialVersionUID = 328942356917631237L;\r
 \r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/RouteFlowConnectionFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/RouteFlowConnectionFactory.java
new file mode 100644 (file)
index 0000000..f909749
--- /dev/null
@@ -0,0 +1,606 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements2.connections;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.awt.Shape;\r
+import java.awt.Stroke;\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Rectangle2D;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.AsyncReadGraph;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.Statement;\r
+import org.simantics.db.common.procedure.adapter.TransientCacheListener;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.procedure.AsyncProcedure;\r
+import org.simantics.diagram.adapter.SyncElementFactory;\r
+import org.simantics.diagram.connection.ConnectionVisuals;\r
+import org.simantics.diagram.connection.RouteGraph;\r
+import org.simantics.diagram.connection.RouteGraphConnectionClass;\r
+import org.simantics.diagram.connection.RouteLine;\r
+import org.simantics.diagram.connection.RouteNode;\r
+import org.simantics.diagram.connection.RouteTerminal;\r
+import org.simantics.diagram.connection.rendering.ConnectionStyle;\r
+import org.simantics.diagram.connection.rendering.StyledRouteGraphRenderer;\r
+import org.simantics.diagram.connection.rendering.arrows.ILineEndStyle;\r
+import org.simantics.diagram.content.EdgeResource;\r
+import org.simantics.diagram.content.ResourceTerminal;\r
+import org.simantics.diagram.content.TerminalMap;\r
+import org.simantics.diagram.query.DiagramRequests;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;\r
+import org.simantics.diagram.synchronization.graph.RouteGraphConnection;\r
+import org.simantics.diagram.ui.DiagramModelHints;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.connection.ConnectionEntity;\r
+import org.simantics.g2d.diagram.DiagramHints;\r
+import org.simantics.g2d.diagram.IDiagram;\r
+import org.simantics.g2d.diagram.handler.DataElementMap;\r
+import org.simantics.g2d.diagram.handler.Topology.Connection;\r
+import org.simantics.g2d.diagram.handler.Topology.Terminal;\r
+import org.simantics.g2d.element.ElementClass;\r
+import org.simantics.g2d.element.ElementHints;\r
+import org.simantics.g2d.element.ElementUtils;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.handler.EdgeVisuals.EdgeEnd;\r
+import org.simantics.g2d.element.handler.TerminalTopology;\r
+import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;\r
+import org.simantics.g2d.routing.algorithm2.Router4;\r
+import org.simantics.g2d.utils.TopologicalSelectionExpander;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.scenegraph.g2d.nodes.connection.IRouteGraphListener;\r
+import org.simantics.scenegraph.g2d.nodes.connection.RouteGraphChangeEvent;\r
+import org.simantics.scenegraph.utils.GeometryUtils;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.structural2.modelingRules.CPTerminal;\r
+import org.simantics.structural2.modelingRules.IAttachmentRelationMap;\r
+import org.simantics.structural2.modelingRules.IModelingRules;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.elements2.ValveFactory.ValveSceneGraph;\r
+/**\r
+ * An element class for Sysdyn Flow elements.\r
+ * Copied from RouteGraphConnectionClassFactory and adapted to Flow needs\r
+ * \r
+ * @author Tuukka Lehtonen\r
+ * \r
+ * \r
+ * \r
+ts. oma ehdotukseni on tämä:\r
+- etsi miten pystyt syöttämään jokaiselle sysdynin "terminaalille" oman ILineEndStyle:n joka sisältää viitteen mokkulan mittoihin\r
+- lisää direction-parametri getLineEndLength:iin niin että voit palauttaa siellä mokkulan mittojen mukaisen etäisyyden\r
+ */\r
+public class RouteFlowConnectionFactory extends SyncElementFactory {\r
+\r
+    public static final ElementClass CLASS = RouteFlowEdgeClass.FLOW_CLASS;\r
+\r
+    Layer0                             L0;\r
+    DiagramResource                    DIA;\r
+    StructuralResource2                STR;\r
+    ModelingResources                  MOD;\r
+\r
+    public RouteFlowConnectionFactory(ReadGraph graph) {\r
+        this.L0 = Layer0.getInstance(graph);\r
+        this.DIA = DiagramResource.getInstance(graph);\r
+        this.STR = StructuralResource2.getInstance(graph);\r
+        this.MOD = ModelingResources.getInstance(graph);\r
+    }\r
+\r
+    @Override\r
+    public void create(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType, final AsyncProcedure<ElementClass> procedure) {\r
+        SysdynResource sr = graph.getService(SysdynResource.class);\r
+        graph.forSingleType(elementType, sr.FlowConnection, new AsyncProcedure<Resource>() {\r
+            @Override\r
+            public void exception(AsyncReadGraph graph, Throwable throwable) {\r
+                procedure.exception(graph, throwable);\r
+            }\r
+            @Override\r
+            public void execute(AsyncReadGraph graph, Resource connectionType) {\r
+                procedure.execute(graph, CLASS.newClassWith(false, new StaticObjectAdapter(connectionType)));\r
+            }\r
+        });\r
+    }\r
+    \r
+    @Override\r
+    public void load(ReadGraph graph, final ICanvasContext canvas, final IDiagram diagram, final Resource connection,\r
+            IElement element) throws DatabaseException {\r
+        \r
+        // Do we need this?\r
+        element.setHint(DiagramHints.ROUTE_ALGORITHM, new Router4(false));\r
+        \r
+        IModelingRules modelingRules = diagram.getHint(DiagramModelHints.KEY_MODELING_RULES);\r
+\r
+        IElement mappedElement = ElementUtils.getByData(diagram, connection);\r
+        if (mappedElement == null)\r
+            // FIXME: With undo this seems to happen, don't know why yet!\r
+            return;\r
+\r
+        RouteGraph rg = new RouteGraph();\r
+\r
+        Set<Resource> nodes = new HashSet<Resource>();\r
+        Set<EdgeResource> links = new HashSet<EdgeResource>();\r
+        Map<Object, RouteNode> nodeByData = new HashMap<Object, RouteNode>();\r
+\r
+        // Needed to support ConnectionEntity#getTerminalConnections\r
+        Set<BackendConnection> backendonnections = new HashSet<BackendConnection>();\r
+\r
+        // Load all route graph interior RouteNodes: route lines and points\r
+        for (Resource interiorNode : graph.getObjects(connection, DIA.HasInteriorRouteNode)) {\r
+            if (graph.isInstanceOf(interiorNode, DIA.RouteLine)) {\r
+                Boolean isHorizontal = graph.getRelatedValue(interiorNode, DIA.IsHorizontal, Bindings.BOOLEAN);\r
+                Double position = graph.getRelatedValue(interiorNode, DIA.HasPosition, Bindings.DOUBLE);\r
+                RouteLine line = rg.addLine(isHorizontal, position);\r
+                line.setData( RouteGraphConnection.serialize(graph, interiorNode) );\r
+\r
+                nodes.add( interiorNode );\r
+                nodeByData.put( interiorNode, line );\r
+\r
+                for (Resource connectedTo : graph.getObjects(interiorNode, DIA.AreConnected)) {\r
+                    links.add( new EdgeResource(interiorNode, connectedTo) );\r
+                }\r
+            } else if (graph.isInstanceOf(interiorNode, DIA.RoutePoint)) {\r
+                // Not supported yet. Ignore.\r
+            }\r
+        }\r
+\r
+        Rectangle2D bounds = new Rectangle2D.Double();\r
+\r
+        // Load all node terminal connections as RouteTerminals\r
+        for (Statement toConnector : graph.getStatements(connection, DIA.HasConnector)) {\r
+            Resource connector = toConnector.getObject();\r
+            Resource attachmentRelation = toConnector.getPredicate();\r
+\r
+            Statement terminalStm = findTerminalStatement(graph, STR, connection, connector);\r
+            if (terminalStm == null)\r
+                // Ignore broken connector: attached to the connection but not to any terminal.\r
+                continue;\r
+\r
+            Resource terminalElement = terminalStm.getObject();\r
+            Resource terminalElementType = graph.getPossibleType(terminalElement, DIA.Element);\r
+            if (terminalElementType == null)\r
+                // Ignore non-element terminal elements\r
+                continue;\r
+\r
+            Resource connectionRelation = graph.getInverse(terminalStm.getPredicate());\r
+\r
+            // Discover node and terminal this connector is connected to.\r
+            TerminalMap terminals = graph.syncRequest(DiagramRequests.elementTypeTerminals(terminalElementType),\r
+                    TransientCacheListener.<TerminalMap> instance());\r
+            Resource terminal = terminals.getTerminal(connectionRelation);\r
+            if (terminal == null) {\r
+                System.err.println(getClass().getSimpleName()\r
+                        + ": Could not find terminal for connection point "\r
+                        + NameUtils.getSafeName(graph, connectionRelation, true)\r
+                        + " in element "\r
+                        + NameUtils.getSafeName(graph, terminalElement, true)); \r
+                continue;\r
+            }\r
+\r
+            double[] position = graph.getRelatedValue(connector, DIA.HasRelativeLocation, Bindings.DOUBLE_ARRAY);\r
+            if (position.length != 2)\r
+                position = new double[] { 0, 0 };\r
+\r
+            //System.out.println("terminalStm: " + NameUtils.toString(graph, terminalStm));\r
+            AffineTransform terminalElementTr = getWorldTransform(graph, terminalElement);\r
+\r
+            double x = terminalElementTr.getTranslateX();\r
+            double y = terminalElementTr.getTranslateY();\r
+            double minx = x-1, miny = y-1, maxx = x+1, maxy = y+1;\r
+            int direction = 0x0;\r
+\r
+            // Use modelingRules to ascertain the proper attachmentRelation\r
+            // for this terminal connection, if available.\r
+            if (modelingRules != null) {\r
+                // Get attachmentRelation from modelingRules if possible.\r
+                IAttachmentRelationMap map = modelingRules.getAttachmentRelations(graph, connection);\r
+                Resource att = map.get(graph, new CPTerminal(terminalElement, terminal));\r
+                if (att != null) {\r
+                    //System.out.println("modeling rules attachment: " + NameUtils.getSafeLabel(graph, att));\r
+                    attachmentRelation = att;\r
+                }\r
+            }\r
+            //System.out.println("attachment: " + NameUtils.getSafeLabel(graph, attachmentRelation));\r
+\r
+            // Get element bounds to decide allowed terminal direction(s)\r
+            IElement te = graph.syncRequest(DiagramRequests.getElement(canvas, diagram, terminalElement, null));\r
+            \r
+            \r
+            ElementUtils.getElementBounds(te, bounds);\r
+            {\r
+                Shape shp = org.simantics.g2d.utils.GeometryUtils.transformShape(bounds, terminalElementTr);\r
+                bounds.setFrame(shp.getBounds2D());\r
+            }\r
+            \r
+            // Valve behaves differently. The flow must start inside the valve bounds\r
+            if(te.getElementClass().containsClass(ValveSceneGraph.class)) {\r
+                bounds.setFrame(new Rectangle2D.Double(bounds.getCenterX() - 1, bounds.getCenterY() - 1, 2, 2));\r
+            }\r
+\r
+            x = bounds.getCenterX();\r
+            y = bounds.getCenterY();\r
+            \r
+            // Expand bounds by 4mm to make the connections enter the terminals\r
+            // at a straight angle and from a distance instead of coming in\r
+            // "horizontally".\r
+            GeometryUtils.expandRectangle(bounds, 4);\r
+\r
+            minx = bounds.getMinX();\r
+            miny = bounds.getMinY();\r
+            maxx = bounds.getMaxX();\r
+            maxy = bounds.getMaxY();\r
+            \r
+\r
+            Integer allowedDirections = graph.getPossibleRelatedValue(terminal, DIA.Terminal_AllowedDirections, Bindings.INTEGER);\r
+            \r
+            // Valve behaves differently. Allowed directions depend on the orientation of the valve\r
+            if(te.getElementClass().containsClass(ValveSceneGraph.class)) {\r
+                SysdynResource sr = SysdynResource.getInstance(graph);\r
+                if(graph.hasStatement(terminalElement, sr.HasValveOrientation, sr.Vertical)) {\r
+                    allowedDirections = 10; // Directions up and down (1010)\r
+                } else {\r
+                    allowedDirections = 5; // Directions left and right (0101)\r
+                }\r
+            }\r
+            if (allowedDirections != null) {\r
+                direction |= allowedDirections;\r
+            } else {\r
+                direction |= RouteGraphConnectionClass.shortestDirectionOutOfBounds(x, y, bounds);\r
+            }\r
+\r
+            backendonnections.add(\r
+                    new BackendConnection(\r
+                            toEdgeEnd(graph, attachmentRelation, EdgeEnd.Begin),\r
+                            terminalElement,\r
+                            terminal)\r
+                    );\r
+\r
+            if (direction == 0)\r
+                // Accept any horizontal/vertical direction if nothing is defined\r
+                direction = 0xf;\r
+\r
+            //System.out.println("load line style: " + NameUtils.getSafeLabel(graph, attachmentRelation));\r
+            ILineEndStyle endStyle = loadLineEndStyle(graph, te, attachmentRelation, new Rectangle2D.Double(\r
+                    bounds.getX(), \r
+                    bounds.getY(), \r
+                    bounds.getWidth(), \r
+                    bounds.getHeight())\r
+            );\r
+\r
+            RouteTerminal routeTerminal = rg.addTerminal(x, y, minx, miny, maxx, maxy, direction, endStyle);\r
+            routeTerminal.setData( RouteGraphConnection.serialize(graph, connector) );\r
+\r
+            nodes.add( connector );\r
+            nodeByData.put( connector, routeTerminal );\r
+\r
+            for (Resource connectedTo : graph.getObjects(connector, DIA.AreConnected)) {\r
+                links.add( new EdgeResource(connectedTo, connector) );\r
+            }\r
+        }\r
+\r
+        // Finish route graph loading by Linking route nodes together\r
+        for (EdgeResource link : links) {\r
+            RouteNode n1 = nodeByData.get(link.first());\r
+            RouteNode n2 = nodeByData.get(link.second());\r
+            if (n1 == null || n2 == null) {\r
+                System.err.println("Stray connection link found: " + link.toString(graph));\r
+                continue;\r
+            }\r
+            rg.link(n1, n2);\r
+        }\r
+\r
+        // Load connection line style\r
+        ConnectionStyle style = readConnectionStyle(graph, modelingRules, connection, element);\r
+        StyledRouteGraphRenderer renderer = new StyledRouteGraphRenderer(style);\r
+\r
+        // Finish element load\r
+        element.setHint(RouteGraphConnectionClass.KEY_ROUTEGRAPH, rg);\r
+        element.setHint(RouteGraphConnectionClass.KEY_RENDERER, renderer);\r
+        element.setHint(RouteGraphConnectionClass.KEY_PICK_TOLERANCE, 0.5);\r
+\r
+        // Initialize ConnectionEntity in element\r
+        // NOTE: MUST use the mapped element with class CE, not the connection (element) were loading into.\r
+        // GDS will synchronize element into mappedElement in a controlled manner.\r
+        element.setHint(ElementHints.KEY_CONNECTION_ENTITY, new CE(connection, mappedElement, backendonnections));\r
+\r
+        // Setup graph writeback support for route graph modifications\r
+        final Session session = graph.getSession();\r
+        element.setHint(RouteGraphConnectionClass.KEY_RG_LISTENER, new IRouteGraphListener() {\r
+            @Override\r
+            public void routeGraphChanged(RouteGraphChangeEvent event) {\r
+                scheduleSynchronize(session, connection, event);\r
+            }\r
+        });\r
+    }\r
+\r
+    private EdgeEnd toEdgeEnd(ReadGraph graph, Resource attachmentRelation, EdgeEnd defaultValue)\r
+            throws DatabaseException {\r
+        if (graph.isSubrelationOf(attachmentRelation, DIA.IsTailConnectorOf))\r
+            return EdgeEnd.Begin;\r
+        if (graph.isSubrelationOf(attachmentRelation, DIA.IsHeadConnectorOf))\r
+            return EdgeEnd.End;\r
+        return defaultValue;\r
+    }\r
+\r
+    private ConnectionStyle readConnectionStyle(ReadGraph graph, IModelingRules modelingRules, Resource connection,\r
+            IElement element) throws DatabaseException {\r
+        Resource connectionType = null;\r
+        if (modelingRules != null)\r
+            connectionType = modelingRules.getConnectionType(graph, connection);\r
+        if (connectionType == null)\r
+            connectionType = graph.getPossibleObject(connection, STR.HasConnectionType);\r
+\r
+        ConnectionVisuals cv = null;\r
+        if (connectionType != null)\r
+            cv = graph.syncRequest(DiagramRequests.getConnectionVisuals(connectionType),\r
+                    TransientCacheListener.<ConnectionVisuals> instance());\r
+\r
+        Color lineColor = cv != null ? cv.toColor() : null;\r
+        if (lineColor == null)\r
+            lineColor = Color.DARK_GRAY;\r
+        Stroke lineStroke = cv != null ? cv.stroke : null;\r
+        if (lineStroke == null)\r
+            lineStroke = new BasicStroke(0.1f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 10, null, 0);\r
+\r
+        return new FlowConnectionStyle(\r
+                lineColor,\r
+                lineStroke);\r
+    }\r
+\r
+    /**\r
+     * @param graph\r
+     * @param STR\r
+     * @param connection\r
+     * @param connector\r
+     * @return connection relation statement from diagram connection connector\r
+     *         to a node\r
+     * @throws DatabaseException\r
+     */\r
+    private static Statement findTerminalStatement(ReadGraph graph, StructuralResource2 STR, Resource connection,\r
+            Resource connector) throws DatabaseException {\r
+        for (Statement stm : graph.getStatements(connector, STR.Connects)) {\r
+            if (connection.equals(stm.getObject()))\r
+                continue;\r
+            return stm;\r
+        }\r
+        return null;\r
+    }\r
+\r
+    public ILineEndStyle loadLineEndStyle(ReadGraph graph, IElement te, Resource attachmentRelation, Rectangle2D bounds)\r
+            throws DatabaseException {\r
+        ILineEndStyle style;\r
+        // TODO: change bounds according to terminal type: Very small rectangle for Valves, Text box size for Stocks and Clouds\r
+        if(te.getElementClass().containsClass(ValveSceneGraph.class)) {\r
+            GeometryUtils.expandRectangle(bounds, -4);\r
+            style =  new FlowArrowLineStyle("none 0 0 0", bounds);\r
+        } else {\r
+            if (graph.isSubrelationOf(attachmentRelation, DIA.HasHeadConnector)) {\r
+                GeometryUtils.expandRectangle(bounds, -2.5);\r
+                style = new FlowArrowLineStyle("fill 2 2 -1.5", bounds);\r
+            } else {\r
+                GeometryUtils.expandRectangle(bounds, -4);\r
+                style =  new FlowArrowLineStyle("none 0 0 0", bounds);\r
+            }\r
+        }\r
+        return style;\r
+    }\r
+\r
+    /**\r
+     * @param graph\r
+     * @param element\r
+     * @return\r
+     * @throws DatabaseException\r
+     */\r
+    private static AffineTransform getWorldTransform(ReadGraph graph, Resource element) throws DatabaseException {\r
+        ModelingResources MOD = ModelingResources.getInstance(graph);\r
+        AffineTransform result = DiagramGraphUtil.getAffineTransform(graph, element);\r
+        while (true) {\r
+            Resource parentComponent = graph.getPossibleObject(element, MOD.HasParentComponent);\r
+            if (parentComponent == null)\r
+                return result;\r
+            element = graph.getPossibleObject(parentComponent, MOD.ComponentToElement);\r
+            if (element == null)\r
+                return result;\r
+            AffineTransform tr = DiagramGraphUtil.getAffineTransform(graph, element);\r
+            tr.setToTranslation(tr.getTranslateX(), tr.getTranslateY());\r
+            result.preConcatenate(tr);\r
+        }\r
+    }\r
+\r
+//    private int directionSetToToDirectionMask(DirectionSet directions) {\r
+//        if (directions == DirectionSet.ANY)\r
+//            return 0xf;\r
+//        int mask = 0;\r
+//        for (Double d : directions) {\r
+//            mask |= compassAngleToToDirectionMask(d);\r
+//        }\r
+//        return mask;\r
+//    }\r
+//\r
+//    private int compassAngleToToDirectionMask(double compassAngle) {\r
+//        Double d = DirectionSet.NESW.getClosestDirection(compassAngle);\r
+//        int id = (int) Math.round(d);\r
+//        // bits:\r
+//        // 0 right (1,0)\r
+//        // 1 down  (0,1)\r
+//        // 2 left  (-1,0)\r
+//        // 3 up    (0,-1)\r
+//        switch (id) {\r
+//            case 0: return (1 << 3);\r
+//            case 90: return (1 << 2);\r
+//            case 180: return (1 << 1);\r
+//            case 270: return (1 << 0);\r
+//        }\r
+//        return 0xf;\r
+//    }\r
+\r
+    protected void scheduleSynchronize(Session session, Resource connection, RouteGraphChangeEvent event) {\r
+        session.asyncRequest(RouteGraphConnection.synchronizer(connection, event));\r
+    }\r
+\r
+    /**\r
+     * Must have this in order for {@link TopologicalSelectionExpander} to work.\r
+     * Otherwise this is pretty useless and should be deprecated altogether.\r
+     * \r
+     * @see ElementHints#KEY_CONNECTION_ENTITY\r
+     */\r
+    static class CE implements ConnectionEntity {\r
+\r
+        /**\r
+         * The connection instance resource in the graph backend.\r
+         */\r
+        final Resource               connection;\r
+\r
+        /**\r
+         * The connection entity element which is a part of the diagram.\r
+         */\r
+        final IElement               connectionElement;\r
+\r
+        /**\r
+         * @see #getTerminalConnections(Collection)\r
+         */\r
+        final Set<BackendConnection> backendConnections;\r
+\r
+        /**\r
+         * Cache.\r
+         */\r
+        Set<Connection>              terminalConnections;\r
+\r
+        CE(Resource connection, IElement connectionElement, Set<BackendConnection> backendConnections) {\r
+            this.connection = connection;\r
+            this.connectionElement = connectionElement;\r
+            this.backendConnections = backendConnections;\r
+        }\r
+\r
+        @Override\r
+        public IElement getConnection() {\r
+            return connectionElement;\r
+        }\r
+\r
+        public Object getConnectionObject() {\r
+            return connection;\r
+        }\r
+\r
+        public IElement getConnectionElement() {\r
+            return connectionElement;\r
+        }\r
+\r
+        @Override\r
+        public Collection<IElement> getBranchPoints(Collection<IElement> result) {\r
+            return result != null ? result : Collections.<IElement> emptyList();\r
+        }\r
+\r
+        @Override\r
+        public Collection<IElement> getSegments(Collection<IElement> result) {\r
+            return result != null ? result : Collections.<IElement> emptyList();\r
+        }\r
+\r
+        @Override\r
+        public Collection<Connection> getTerminalConnections(Collection<Connection> result) {\r
+            if (terminalConnections == null)\r
+                terminalConnections = calculateTerminalConnections();\r
+            if (result == null)\r
+                result = new ArrayList<Connection>(terminalConnections);\r
+            else\r
+                result.addAll(terminalConnections);\r
+            return terminalConnections;\r
+        }\r
+\r
+        private Set<Connection> calculateTerminalConnections() {\r
+            IDiagram diagram = connectionElement.getDiagram();\r
+            DataElementMap dem = diagram.getDiagramClass().getSingleItem(DataElementMap.class);\r
+            Set<Connection> result = new HashSet<Connection>();\r
+            ArrayList<Terminal> ts = new ArrayList<Terminal>();\r
+            for (BackendConnection bc : backendConnections) {\r
+                IElement e = dem.getElement(diagram, bc.node);\r
+                if (e == null)\r
+                    continue;\r
+                TerminalTopology tt = e.getElementClass().getSingleItem(TerminalTopology.class);\r
+                tt.getTerminals(e, ts);\r
+                for (Terminal t : ts) {\r
+                    if (t instanceof ResourceTerminal) {\r
+                        ResourceTerminal rt = (ResourceTerminal) t;\r
+                        if (bc.terminal.equals(rt.getResource())) {\r
+                            result.add(new Connection(connectionElement, bc.end, e, t));\r
+                            break;\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            return result;\r
+        }\r
+\r
+        @Override\r
+        public void setListener(ConnectionListener listener) {\r
+            throw new UnsupportedOperationException();\r
+        }\r
+\r
+        @Override\r
+        public String toString() {\r
+            return getClass().getSimpleName() + "[resource=" + connection + ", connectionElement=" + connectionElement\r
+                    + "]";\r
+        }\r
+\r
+    }\r
+\r
+    public static class BackendConnection {\r
+        public final Resource node;\r
+        public final Resource terminal;\r
+        public final EdgeEnd  end;\r
+        public BackendConnection(EdgeEnd end, Resource node, Resource terminal) {\r
+            assert end != null;\r
+            assert node != null;\r
+            assert terminal != null;\r
+            this.end = end;\r
+            this.node = node;\r
+            this.terminal = terminal;\r
+        }\r
+        @Override\r
+        public boolean equals(Object obj) {\r
+            if (this == obj)\r
+                return true;\r
+            if (!(obj instanceof Connection))\r
+                return false;\r
+            Connection other = (Connection) obj;\r
+            return other.terminal == terminal\r
+                    && other.node == node\r
+                    && other.end == end;\r
+        }\r
+        @Override\r
+        public int hashCode() {\r
+            final int prime = 31;\r
+            int result = 1;\r
+            result = prime * result + end.hashCode();\r
+            result = prime * result + ((node == null) ? 0 : node.hashCode());\r
+            result = prime * result + ((terminal == null) ? 0 : terminal.hashCode());\r
+            return result;\r
+        }\r
+        @Override\r
+        public String toString() {\r
+            return "BackendConnection[node=" + node + ", terminal=" + terminal + ", end=" + end + "]";\r
+        }\r
+    }\r
+\r
+}\r
+\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/RouteFlowEdgeClass.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/RouteFlowEdgeClass.java
new file mode 100644 (file)
index 0000000..638e317
--- /dev/null
@@ -0,0 +1,88 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements2.connections;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.simantics.diagram.connection.RouteGraph;\r
+import org.simantics.diagram.connection.RouteGraphConnectionClass;\r
+import org.simantics.diagram.connection.rendering.IRouteGraphRenderer;\r
+import org.simantics.g2d.element.ElementClass;\r
+import org.simantics.g2d.element.ElementUtils;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.handler.ElementHandler;\r
+import org.simantics.g2d.element.handler.SceneGraph;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+import org.simantics.scenegraph.g2d.nodes.connection.IRouteGraphListener;\r
+import org.simantics.scenegraph.g2d.nodes.connection.RouteGraphNode;\r
+\r
+\r
+\r
+public class RouteFlowEdgeClass extends RouteGraphConnectionClass {\r
+    \r
+    public static final ElementClass FLOW_CLASS = getElementClass();\r
+\r
+            \r
+    public static final ElementClass getElementClass() {\r
+        List<ElementHandler> oldList = CLASS.getAll();\r
+        ArrayList<ElementHandler> list = new ArrayList<ElementHandler>();\r
+        list.add(FlowConnectionSceneGraph.INSTANCE);\r
+        for(ElementHandler eh : oldList) {\r
+            if(!(eh instanceof SceneGraph)) {\r
+                list.add(eh);\r
+            }\r
+        }\r
+        return  ElementClass.compile(list);\r
+    }\r
+    \r
+    \r
+    static final class FlowConnectionSceneGraph implements SceneGraph {\r
+\r
+        public static final FlowConnectionSceneGraph INSTANCE = new FlowConnectionSceneGraph();\r
+\r
+        private static final long serialVersionUID = 1865920472882420644L;\r
+\r
+        @Override\r
+        public void init(IElement connection, G2DParentNode parent) {\r
+            RouteGraph rg = connection.getHint(KEY_ROUTEGRAPH);\r
+            IRouteGraphRenderer renderer = connection.getHint(KEY_RENDERER);\r
+            if (rg == null || renderer == null) {\r
+                cleanup(connection);\r
+            } else {\r
+                RouteGraphNode rgn = connection.getHint(KEY_RG_NODE);\r
+                if (rgn == null) {\r
+                    rgn = parent.addNode(ElementUtils.generateNodeId(connection), RouteGraphNode.class);\r
+                    connection.setHint(KEY_RG_NODE, rgn);\r
+                }\r
+                rgn.setRouteGraph(rg);\r
+                rgn.setRenderer(renderer);\r
+\r
+                IRouteGraphListener listener = connection.getHint(KEY_RG_LISTENER);\r
+                rgn.setRouteGraphListener(listener);\r
+\r
+                Double tolerance = connection.getHint(KEY_PICK_TOLERANCE);\r
+                if (tolerance != null)\r
+                    rgn.setPickTolerance(tolerance);\r
+            }\r
+        }\r
+\r
+        @Override\r
+        public void cleanup(IElement connection) {\r
+            ElementUtils.removePossibleNode(connection, KEY_RG_NODE);\r
+            connection.removeHint(KEY_RG_NODE);\r
+        }\r
+    }\r
+\r
+}\r
+\r
+\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/RouteFlowEdgeFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/RouteFlowEdgeFactory.java
new file mode 100644 (file)
index 0000000..8ee7934
--- /dev/null
@@ -0,0 +1,38 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements2.connections;\r
+\r
+import org.simantics.db.AsyncReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.procedure.AsyncProcedure;\r
+import org.simantics.diagram.adapter.ElementFactoryAdapter;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.diagram.IDiagram;\r
+import org.simantics.g2d.element.ElementClass;\r
+\r
+public class RouteFlowEdgeFactory extends ElementFactoryAdapter {\r
+\r
+    private static final ElementClass CLASS = RouteFlowEdgeClass.FLOW_CLASS;\r
+\r
+    @Override\r
+    public void create(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType,\r
+            AsyncProcedure<ElementClass> procedure) {\r
+        procedure.execute(graph, CLASS);\r
+    }\r
+\r
+    @Override\r
+    public void getClass(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementResource,\r
+            AsyncProcedure<ElementClass> procedure) {\r
+        throw new UnsupportedOperationException();\r
+    }\r
+\r
+}\r
index 9a3b21e8d015c746030ce7b810221c9d05bc8770..17bcb250998dd656e98c1228777dc5b8137ae4f4 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************\r
- * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Copyright (c) 2010, 2011 Association for Decentralized Information Management in\r
  * Industry THTH ry.\r
  * All rights reserved. This program and the accompanying materials\r
  * are made available under the terms of the Eclipse Public License v1.0\r
@@ -26,6 +26,7 @@ import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;
 import org.simantics.db.management.ISessionContext;\r
 import org.simantics.layer0.Layer0;\r
 import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.widgets.ValveOrientationGroup;\r
 import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory;\r
 import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier;\r
 \r
@@ -80,6 +81,9 @@ public class VariableInformationTab extends LabelPropertyTabContributor {
         rangeStep.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.HasRangeStep));\r
         rangeStep.setInputValidator(new DoubleValidator());\r
         GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeStep.getWidget());\r
+        \r
+        \r
+        new ValveOrientationGroup(composite, context, support, SWT.NONE);\r
 \r
     }\r
 \r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ValveOrientationGroup.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ValveOrientationGroup.java
new file mode 100644 (file)
index 0000000..436e8ba
--- /dev/null
@@ -0,0 +1,136 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Group;\r
+import org.simantics.browsing.ui.swt.widgets.Button;\r
+import org.simantics.browsing.ui.swt.widgets.WidgetImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.utils.datastructures.Triple;\r
+\r
+public class ValveOrientationGroup extends WidgetImpl {\r
+\r
+    Group group;\r
+    Button vertical, horizontal;\r
+    \r
+    public ValveOrientationGroup(Composite parent, ISessionContext context, WidgetSupport support, int style) {\r
+        super(support);\r
+        support.register(this);\r
+        group = new Group(parent, SWT.NONE);\r
+        group.setText("Valve orientation");\r
+        GridDataFactory.fillDefaults().applyTo(group);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(group);\r
+        \r
+        horizontal = new Button(group, support, SWT.RADIO);\r
+        horizontal.setText("Horizontal");\r
+        horizontal.setSelectionFactory(new OrientationSelectionFactory(SysdynResource.URIs.Horizontal, true));\r
+        horizontal.addSelectionListener(new OrientationSelectionListener(context, SysdynResource.URIs.Horizontal));\r
+        \r
+        vertical = new Button(group, support, SWT.RADIO);\r
+        vertical.setText("Vertical");\r
+        vertical.setSelectionFactory(new OrientationSelectionFactory(SysdynResource.URIs.Vertical));\r
+        vertical.addSelectionListener(new OrientationSelectionListener(context, SysdynResource.URIs.Vertical));\r
+    }\r
+\r
+    @Override\r
+    public void setInput(ISessionContext context, Object input) {\r
+        \r
+        \r
+    }\r
+\r
+    @Override\r
+    public Control getControl() {\r
+        return this.group;\r
+    }\r
+    \r
+    private class OrientationSelectionFactory extends ReadFactoryImpl<Resource, Boolean> {\r
+        \r
+        boolean defaultSelected;\r
+        String uri;\r
+        \r
+        public OrientationSelectionFactory(String uri) {\r
+            this(uri, false);\r
+        }\r
+\r
+        public OrientationSelectionFactory(String uri, boolean defaultSelected) {\r
+            this.uri = uri;\r
+            this.defaultSelected = defaultSelected;\r
+        }\r
+        \r
+        public Object getIdentity(Object inputContents) {\r
+            return new Triple<Object, Object, Class<?>>(uri, defaultSelected, getClass());\r
+        }\r
+\r
+        @Override\r
+        public Boolean perform(ReadGraph graph, Resource valve) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            ModelingResources mr = ModelingResources.getInstance(graph);\r
+            if(!graph.isInstanceOf(valve, sr.Valve))\r
+                return Boolean.FALSE;\r
+            \r
+            Resource symbol = graph.getPossibleObject(valve, mr.ComponentToElement);\r
+            if(symbol == null)\r
+                return Boolean.FALSE;\r
+            \r
+            Resource orientation = graph.getPossibleObject(symbol, sr.HasValveOrientation);\r
+            \r
+            if(orientation == null)\r
+                return defaultSelected;\r
+            \r
+            return orientation.equals(graph.getResource(uri));\r
+        }\r
+        \r
+    }\r
+    \r
+    \r
+    private class OrientationSelectionListener extends SelectionListenerImpl<Resource> {\r
+        \r
+        String uri;\r
+        \r
+        public OrientationSelectionListener(ISessionContext context, String uri) {\r
+            super(context);\r
+            this.uri = uri;\r
+        }\r
+\r
+        @Override\r
+        public void apply(WriteGraph graph, Resource valve) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            ModelingResources mr = ModelingResources.getInstance(graph);\r
+            if(!graph.isInstanceOf(valve, sr.Valve))\r
+                return;\r
+            \r
+            Resource symbol = graph.getPossibleObject(valve, mr.ComponentToElement);\r
+            if(symbol == null)\r
+                return;\r
+            \r
+            if(graph.hasStatement(symbol, sr.HasValveOrientation))\r
+                graph.deny(symbol, sr.HasValveOrientation);\r
+            graph.claim(symbol, sr.HasValveOrientation, graph.getResource(uri));\r
+        }\r
+        \r
+    }\r
+\r
+}\r
index fd04c6c071365dbf2423ffa417f9cf7ad3b1e81b..5923c1946bf43916c2a0659d3d486a9bf3764c65 100644 (file)
@@ -17,7 +17,7 @@ import org.simantics.sysdyn.representation.Variable;
 public class SheetFormatUtils {\r
     \r
     public static String reformatSheetReferences(Variable v, String expression) {\r
-        if(!expression.contains("("))\r
+        if(expression == null || !expression.contains("("))\r
             return expression;\r
         ExpressionParser parser = new ExpressionParser(new StringReader(expression));\r
         try {\r