]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
When selecting a Sysdyn loop, color the elements which belong to that loop (refs...
authormiettinen <miettinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Thu, 23 Jan 2014 12:14:13 +0000 (12:14 +0000)
committermiettinen <miettinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Thu, 23 Jan 2014 12:14:13 +0000 (12:14 +0000)
git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@28688 ac1ea38d-2e2b-0410-8846-a27921b304fc

org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/LoopFactory.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/LoopNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextNode.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyNode.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/FlowConnectionStyle.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/RouteFlowEdgeClass.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/RouteFlowNode.java
org.simantics.sysdyn/src/org/simantics/sysdyn/utils/LoopUtils.java

index c5c8727ae005501b6463adacb75f7946434a9ced..0b83ef3fbf910721c7f42e09dd739aa0195d7882 100644 (file)
@@ -183,7 +183,7 @@ public class LoopFactory extends SysdynElementFactory {
                \r
                private IHintListener hoverHintListener;\r
                \r
-               private static final Key            NODE             = new SceneGraphNodeKey(HoverShapeNode.class, "LOOP_NODE");\r
+               private static final Key            NODE             = new SceneGraphNodeKey(LoopNode.class, "LOOP_NODE");\r
 \r
                public LoopImageSceneGraph(Image i) {\r
                        super(i);\r
@@ -194,7 +194,7 @@ public class LoopFactory extends SysdynElementFactory {
                        super.init(e, parent);\r
 \r
                        // Create new hover shape node for the loop image\r
-                       final HoverShapeNode node = ElementUtils.getOrCreateNode(e, parent, NODE, "loopHover", HoverShapeNode.class);\r
+                       final LoopNode node = ElementUtils.getOrCreateNode(e, parent, NODE, "loopHover", LoopNode.class);\r
                        \r
                        // Mirror the image if clockwise is selected.\r
                        Boolean clockwise = e.getHint(SysdynElementHints.KEY_LOOP_CLOCKWISE);\r
@@ -225,7 +225,7 @@ public class LoopFactory extends SysdynElementFactory {
                                @Override\r
                                public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {\r
                                        IElement e = (IElement)sender;\r
-                                       HoverShapeNode shape = (HoverShapeNode) e.getHint(NODE);\r
+                                       LoopNode shape = (LoopNode) e.getHint(NODE);\r
                                        if(shape == null) {\r
                                                return;\r
                                        }\r
@@ -266,7 +266,7 @@ public class LoopFactory extends SysdynElementFactory {
                        \r
                        // Move the text box into (around) the middle of the loop image\r
                        AffineTransform at = ElementUtils.getTransform(e);\r
-                       final HoverShapeNode node = ElementUtils.getOrCreateNode(e, parent, NODE, "loopComment", HoverShapeNode.class);\r
+                       final LoopNode node = ElementUtils.getOrCreateNode(e, parent, NODE, "loopComment", LoopNode.class);\r
 \r
                        // Unflip the text and image\r
                        unflipText(e);\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/LoopNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/LoopNode.java
new file mode 100644 (file)
index 0000000..11c9c71
--- /dev/null
@@ -0,0 +1,232 @@
+/*******************************************************************************\r
+ * Copyright (c) 2014 Association for Decentralized Information Management\r
+ * in 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.elements;\r
+\r
+import java.awt.Color;\r
+import java.awt.Graphics2D;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.diagram.elements.DiagramNodeUtil;\r
+import org.simantics.g2d.element.ElementHints;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.scenegraph.INode;\r
+import org.simantics.scenegraph.ParentNode;\r
+import org.simantics.scenegraph.g2d.IG2DNode;\r
+import org.simantics.scenegraph.g2d.nodes.ConnectionNode;\r
+import org.simantics.scenegraph.g2d.nodes.spatial.RTreeNode;\r
+import org.simantics.scenegraph.utils.NodeUtil;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Node for Sysdyn loop elements.\r
+ * \r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class LoopNode extends HoverShapeNode {\r
+\r
+       /**\r
+        * Interface for nodes that can be part of loops\r
+        * @author Tuomas Miettinen\r
+        *\r
+        */\r
+       public interface ILoopComponentNode {\r
+               \r
+               /**\r
+                * Sets or resets the loop selected status\r
+                * @param loop The loop which has been selected\r
+                * @param selected true iff the loop is selected\r
+                */\r
+               public void setLoopSelected(LoopNode loop, boolean selected);\r
+               \r
+       }\r
+       \r
+       public static Color HIGHLIGHT_COLOR = Color.decode("#ff5fbf");\r
+       \r
+       private boolean selected = false;\r
+       \r
+       private static final long serialVersionUID = 6173159124691715569L;\r
+       \r
+       @Override\r
+    public void render(Graphics2D g2d) {\r
+               super.render(g2d);\r
+               \r
+               // If the loop is selected, highlight also the elements that belong to the loop.\r
+               boolean selected = NodeUtil.isSelected(this, 1);\r
+               // Do nothing if the selection is and was off.\r
+               if (selected || this.selected != selected) {\r
+                       this.selected = selected; \r
+                       // Tell all items belonging to the loop that the loop is selected.\r
+                       setLoopItemsSelected();\r
+               }\r
+       }\r
+       \r
+       private void setLoopItemsSelected() {\r
+               // Get all variables and dependencies in the loop.\r
+               List<Resource> loopItems = getAllLoopItems();\r
+               \r
+               // Get the diagram where this loop is.\r
+               RTreeNode diagramNode = (RTreeNode)NodeUtil.getNearestParentOfType(this, RTreeNode.class);\r
+               if (diagramNode == null)\r
+                       return;\r
+               \r
+               // Go through all elements on the diagram where this loop is.\r
+               Collection<IG2DNode> children = diagramNode.getNodes();\r
+               Iterator<IG2DNode> it = children.iterator();\r
+               while (it.hasNext()) {\r
+                       IG2DNode n = it.next();\r
+                       \r
+                       // Get the respective node \r
+                       INode child = getNodeOfPossibleLoopComponentNode(n);\r
+                       if (child instanceof ILoopComponentNode) {\r
+                               ILoopComponentNode ln = (ILoopComponentNode)child;\r
+                               // Get the respective element \r
+                               IElement e = DiagramNodeUtil.getElement((IG2DNode)child.getParent());\r
+                               // Get the respective resource \r
+                               Resource r = e.getHint(ElementHints.KEY_OBJECT);\r
+                               // If the node belongs to the loop, tell it that whether the loop is selected or not.\r
+                               ln.setLoopSelected(this, NodeUtil.isSelected(this, 1) && loopItems.contains(r));\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Get the ILoopComponentNode under the variable, dependency, or flow. \r
+        * @param n node under which the ILoopComponentNode is sought\r
+        * @return ILoopComponentNode or null, if there is not any.\r
+        */\r
+       private static INode getNodeOfPossibleLoopComponentNode(IG2DNode n) {\r
+               // Get all nodeIds of n's children.\r
+               Collection<String> nodeIds = ((ParentNode<?>)n).getNodeIds();\r
+\r
+               // Flows and SysdynTextNodes\r
+               for (String id : nodeIds) {\r
+                       if ("text".equals(id)\r
+                                       || id.startsWith("flow_")) \r
+                               return ((ParentNode<?>)n).getNode(id);\r
+               }\r
+\r
+               // Dependencies\r
+               if (n instanceof ConnectionNode) {\r
+                       // See the first (and only) child of n has a DependencyNode as a child.\r
+                       n = ((ConnectionNode) n).getNodes().iterator().next();\r
+                       if (n instanceof ParentNode<?>) {\r
+                               nodeIds = ((ParentNode<?>)n).getNodeIds();\r
+                               for (String id : nodeIds) {\r
+                                       if (id.startsWith("edge_"))\r
+                                               return ((ParentNode<?>)n).getNode(id);\r
+                               }\r
+                       }\r
+               }\r
+               \r
+               return null; // n was no variable, dependency, or flow\r
+\r
+       }\r
+\r
+       /**\r
+        * Get all variables and dependencies in the loop.\r
+        * @return A list where the items are, in unspecified order.\r
+        */\r
+       private List<Resource> getAllLoopItems() {\r
+               IElement loopElement = DiagramNodeUtil.getElement(this);\r
+               final Resource loopSymbolResource = loopElement.getHint(ElementHints.KEY_OBJECT);\r
+               List<Resource> loopItems = Collections.emptyList();\r
+               \r
+               try {\r
+                       loopItems = SimanticsUI.getSession().syncRequest(new Read<List<Resource>>(){\r
+\r
+                               @Override\r
+                               public List<Resource> perform(ReadGraph graph) throws DatabaseException {\r
+                                       ModelingResources mod = ModelingResources.getInstance(graph);\r
+                                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                       Resource loopComponentResource = graph.getPossibleObject(loopSymbolResource, mod.ElementToComponent);\r
+                                       if (loopComponentResource == null)\r
+                                               return Collections.emptyList();\r
+                                       \r
+                                       Resource loopResource = graph.getPossibleObject(loopComponentResource, sr.Loop_Items);\r
+                                       if (loopResource == null)\r
+                                               return Collections.emptyList();\r
+                                       \r
+                                       List<Resource> loopItems = ListUtils.toPossibleList(graph, loopResource);\r
+                                       if (loopItems == null)\r
+                                               return Collections.emptyList();\r
+                                       \r
+                                       ArrayList<Resource> dependencyItems = new ArrayList<Resource>();\r
+                                       \r
+                                       // Add dependencies and flows.\r
+                                       for (int i = 0; i < loopItems.size(); ++i) {\r
+                                       boolean skipBackwardFlows = false;\r
+                                       \r
+                                       // Go through forward dependencies and flows\r
+                                       Collection<Resource> forwardDependencies = graph.getObjects(loopItems.get(i), sr.Variable_isTailOf);\r
+                                       for (Resource dependency : forwardDependencies) {\r
+                                               Resource dependingVariable = graph.getSingleObject(dependency, sr.Variable_HasHead);\r
+                                               if (dependingVariable.equals(loopItems.get((i + 1) % loopItems.size()))) {\r
+                                                       if (graph.isInstanceOf(dependency, sr.Flow)\r
+                                                                       && graph.isInstanceOf(loopItems.get(i), sr.Stock)) {\r
+                                                               // Flows from stocks don't count. \r
+                                                               continue;\r
+                                                       }\r
+                                                       skipBackwardFlows = true;\r
+                                                       dependencyItems.add(graph.getSingleObject(dependency, mod.ConnectionToDiagramConnection));\r
+                                                       break;\r
+                                               }\r
+                                       }\r
+                                       \r
+                                       if (skipBackwardFlows)\r
+                                               continue;\r
+                                       \r
+                                       // Backward flows from stocks.\r
+                                       Collection<Resource> backwardFlows = graph.getObjects(loopItems.get(i), sr.Variable_isHeadOf);\r
+                                               for (Resource flow : backwardFlows) {\r
+                                                       if (graph.isInstanceOf(flow, sr.Flow)) {\r
+                                                               Resource dependingVariable = graph.getSingleObject(flow, sr.Variable_HasTail);\r
+                                                               if (dependingVariable.equals(loopItems.get((i + 1) % loopItems.size()))\r
+                                                                               && graph.isInstanceOf(dependingVariable, sr.Stock)) {\r
+                                                                       dependencyItems.add(graph.getSingleObject(flow, mod.ConnectionToDiagramConnection));\r
+                                                                       break;\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                               }\r
+                                       \r
+                                       // Convert variables from component to element.\r
+                                       for (int i = 0; i < loopItems.size(); ++i) {\r
+                                               loopItems.set(i, graph.getPossibleObject(loopItems.get(i), mod.ComponentToElement));\r
+                                       }\r
+                                       // Merge the two lists.\r
+                                       loopItems.addAll(dependencyItems);\r
+                                       \r
+                                       return loopItems;\r
+                               }\r
+                               \r
+                       });\r
+               } catch (DatabaseException e1) {\r
+                       // TODO Auto-generated catch block\r
+                       e1.printStackTrace();\r
+               }\r
+               \r
+               return loopItems;\r
+       }\r
+       \r
+}\r
index 03301917d0606aedf93cf76e6b3780d2b33e1331..1d593a3912ec11193dc16884902eb73416911c16 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************\r
- * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Copyright (c) 2013-2014 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,6 +15,7 @@ package org.simantics.sysdyn.ui.elements;
 import java.awt.BasicStroke;\r
 import java.awt.Color;\r
 import java.awt.Graphics2D;\r
+import java.util.HashMap;\r
 \r
 import org.simantics.diagram.elements.TextEditActivation;\r
 import org.simantics.diagram.elements.TextNode;\r
@@ -22,6 +23,7 @@ import org.simantics.g2d.canvas.ICanvasContext;
 import org.simantics.g2d.element.IElement;\r
 import org.simantics.scenegraph.g2d.events.EventTypes;\r
 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDragBegin;\r
+import org.simantics.sysdyn.ui.elements.LoopNode.ILoopComponentNode;\r
 import org.simantics.sysdyn.ui.utils.SysdynWorkbenchUtils;\r
 \r
 /**\r
@@ -31,13 +33,18 @@ import org.simantics.sysdyn.ui.utils.SysdynWorkbenchUtils;
  *  1. Draw borders when hovering\r
  *  2. Support Sysdyn's diagram locking\r
  * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
  *\r
  */\r
-public class SysdynTextNode extends TextNode {\r
+public class SysdynTextNode extends TextNode implements ILoopComponentNode {\r
 \r
     private static final long serialVersionUID = 5235077104121753251L;\r
+       private HashMap<LoopNode, Boolean> loopSelectionMap = new HashMap<LoopNode, Boolean>();\r
+\r
+       private boolean isLoopSelected() {\r
+               return loopSelectionMap.containsValue(true);\r
+       }\r
 \r
-    \r
     @Override\r
     public int getEventMask(){\r
         return EventTypes.FocusLostMask | super.getEventMask();\r
@@ -66,8 +73,16 @@ public class SysdynTextNode extends TextNode {
             g.setColor(oldColor);\r
             g.setStroke(oldStroke);\r
             \r
+        } else if (isLoopSelected()) {\r
+            BasicStroke oldStroke = (BasicStroke)g.getStroke();\r
+            Color oldColor = g.getColor();\r
+            g.setColor(LoopNode.HIGHLIGHT_COLOR);\r
+            g.setStroke(new BasicStroke((float)(2.0*scale)));\r
+            g.draw(getBoundsInLocal());\r
+            g.setColor(oldColor);\r
+            g.setStroke(oldStroke);\r
+            \r
         }\r
-        \r
     }\r
     \r
     public TextEditActivation activateEdit(int mouseId, IElement e, ICanvasContext ctx, boolean save) {\r
@@ -76,4 +91,12 @@ public class SysdynTextNode extends TextNode {
         return super.activateEdit(mouseId, e, ctx);\r
     }\r
     \r
+       @Override\r
+       public void setLoopSelected(LoopNode loop, boolean selected) {\r
+               Boolean loopSelected = loopSelectionMap.get(loop);\r
+               if (loopSelected == null || loopSelected != selected) {\r
+                       loopSelectionMap.put(loop, selected);\r
+                       repaint();\r
+               }\r
+       }\r
 }\r
index 33522c97ae6c48bfe45ea0f2e77bd60c802f6ec4..96681fcb3219cc29307eb5d4efb0c2d9699559af 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************\r
- * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Copyright (c) 2010, 2012, 2014 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
@@ -24,6 +24,7 @@ import java.awt.geom.Rectangle2D;
 import java.beans.PropertyChangeEvent;\r
 import java.beans.PropertyChangeListener;\r
 import java.util.Collection;\r
+import java.util.HashMap;\r
 \r
 import org.simantics.diagram.elements.TextNode;\r
 import org.simantics.g2d.utils.Alignment;\r
@@ -38,6 +39,8 @@ import org.simantics.scenegraph.g2d.nodes.ConnectionNode;
 import org.simantics.scenegraph.g2d.nodes.SingleElementNode;\r
 import org.simantics.scenegraph.utils.NodeUtil;\r
 import org.simantics.sysdyn.ui.editor.routing.DependencyRouter;\r
+import org.simantics.sysdyn.ui.elements.LoopNode.ILoopComponentNode;\r
+import org.simantics.sysdyn.ui.elements.LoopNode;\r
 import org.simantics.sysdyn.ui.elements.SysdynElementHints;\r
 import org.simantics.sysdyn.ui.utils.SysdynWorkbenchUtils;\r
 import org.simantics.utils.datastructures.Triple;\r
@@ -48,7 +51,7 @@ import org.simantics.utils.datastructures.Triple;
  * @author Tuomas Miettinen\r
  *\r
  */\r
-public class DependencyNode extends TextNode implements ISelectionPainterNode {\r
+public class DependencyNode extends TextNode implements ISelectionPainterNode, ILoopComponentNode {\r
 \r
     public static final String INSIDE = "Inside";\r
     public static final String OUTSIDE = "Outside";\r
@@ -216,6 +219,15 @@ public class DependencyNode extends TextNode implements ISelectionPainterNode {
                 g.fill(shapes.second);\r
             }\r
             if (delayMark) g.draw(shapes.third);\r
+        } else if (isLoopSelected()) {\r
+            g.setColor(LoopNode.HIGHLIGHT_COLOR);\r
+            if(stroke != null) g.setStroke(stroke);\r
+            g.draw(shapes.first);\r
+            if (arrowHead) {\r
+               g.draw(shapes.second);\r
+                g.fill(shapes.second);\r
+            }\r
+            if (delayMark) g.draw(shapes.third);\r
         } else {\r
             if(color != null) g.setColor(color);\r
             if(stroke != null) g.setStroke(stroke);\r
@@ -255,7 +267,12 @@ public class DependencyNode extends TextNode implements ISelectionPainterNode {
     }\r
 \r
     boolean pressHit = false;\r
+       private HashMap<LoopNode, Boolean> loopSelectionMap = new HashMap<LoopNode, Boolean>();\r
 \r
+       private boolean isLoopSelected() {\r
+               return loopSelectionMap.containsValue(true);\r
+       }\r
+       \r
     protected boolean hitTest(org.simantics.scenegraph.g2d.events.MouseEvent event, double tolerance) {\r
         if(beginBounds == null || endBounds == null) return false;\r
         Point2D localPos = NodeUtil.worldToLocal(this, event.controlPosition, new Point2D.Double());\r
@@ -380,4 +397,13 @@ public class DependencyNode extends TextNode implements ISelectionPainterNode {
     protected boolean isDragging() {\r
        return dragging;\r
     }\r
+\r
+       @Override\r
+       public void setLoopSelected(LoopNode loop, boolean selected) {\r
+               Boolean loopSelected = loopSelectionMap.get(loop);\r
+               if (loopSelected == null || loopSelected != selected) {\r
+                       loopSelectionMap.put(loop, selected);\r
+                       repaint();\r
+               }\r
+       }\r
 }\r
index 464344aee81182b977c6c113e1c9aaefb578bccd..a7476de6f285372bb9ba73a84ff29da369e72504 100644 (file)
@@ -12,6 +12,7 @@ import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.request.Read;\r
 import org.simantics.diagram.connection.rendering.BasicConnectionStyle;\r
 import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.elements.LoopNode;\r
 import org.simantics.ui.SimanticsUI;\r
 \r
 public class FlowConnectionStyle  extends BasicConnectionStyle {\r
@@ -22,6 +23,9 @@ public class FlowConnectionStyle  extends BasicConnectionStyle {
     Stroke                    lineStroke;\r
 \r
        private Resource resource;\r
+\r
+       // Is the default color overridden by the loop color\r
+       private boolean loopColorOverride = false;\r
     \r
     public static final float DEFAULT_LINE_WIDTH = 1.0f;\r
 \r
@@ -42,8 +46,8 @@ public class FlowConnectionStyle  extends BasicConnectionStyle {
 \r
     @Override\r
     public void drawPath(Graphics2D g, Path2D path, boolean isTransient) {\r
-        if (lineColor != null)\r
-            g.setColor(lineColor);\r
+        if (lineColor != null) // Highlight the flow if loop where the flow belongs to is selected.\r
+            g.setColor(loopColorOverride ? LoopNode.HIGHLIGHT_COLOR : lineColor);\r
         if (lineStroke != null)\r
             g.setStroke(lineStroke);\r
 \r
@@ -81,5 +85,13 @@ public class FlowConnectionStyle  extends BasicConnectionStyle {
     public double getDegeneratedLineLength() {\r
         return 0;\r
     }\r
+\r
+    /**\r
+     * Set if the flow color should be overwritten with loop color\r
+     * @param loopColorOverride \r
+     */\r
+       public void setLoopColorOverride(boolean loopColorOverride) {\r
+               this.loopColorOverride  = loopColorOverride;\r
+       }\r
     \r
 }\r
index c300b646164a6747e78315e91a85959c48a7e9c5..5061e7382ef950e230945e8cc0acf84b4e6e993f 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************\r
- * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Copyright (c) 2007, 2011, 2014 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
@@ -57,11 +57,7 @@ public class RouteFlowEdgeClass extends RouteGraphConnectionClass {
             if (rg == null || renderer == null) {\r
                 cleanup(connection);\r
             } else {\r
-               RouteFlowNode rgn = connection.getHint(KEY_RG_NODE);\r
-                if (rgn == null) {\r
-                    rgn = parent.addNode(ElementUtils.generateNodeId(connection), RouteFlowNode.class);\r
-                    connection.setHint(KEY_RG_NODE, rgn);\r
-                }\r
+               RouteFlowNode rgn = ElementUtils.getOrCreateNode(connection, parent, KEY_RG_NODE, "flow_" + connection.hashCode(), RouteFlowNode.class);\r
                 rgn.setRouteGraph(rg);\r
                 rgn.setRenderer(renderer);\r
 \r
index 531809698ca80d58e2a1c90e4173fe2075959f84..4a75f08292164e4c205dcf339ced228ca3b0b029 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************\r
- * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Copyright (c) 2013-2014 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
  *******************************************************************************/\r
 package org.simantics.sysdyn.ui.elements.connections;\r
 \r
+import java.util.HashMap;\r
+\r
+import org.simantics.diagram.connection.rendering.ConnectionStyle;\r
+import org.simantics.diagram.connection.rendering.StyledRouteGraphRenderer;\r
 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDragBegin;\r
 import org.simantics.scenegraph.g2d.nodes.connection.RouteGraphNode;\r
+import org.simantics.sysdyn.ui.elements.LoopNode;\r
+import org.simantics.sysdyn.ui.elements.LoopNode.ILoopComponentNode;\r
 import org.simantics.sysdyn.ui.elements.SysdynElementHints;\r
 import org.simantics.sysdyn.ui.utils.SysdynWorkbenchUtils;\r
 \r
@@ -21,11 +27,16 @@ import org.simantics.sysdyn.ui.utils.SysdynWorkbenchUtils;
  * @author Tuomas Miettinen\r
  *\r
  */\r
-public class RouteFlowNode extends RouteGraphNode {\r
+public class RouteFlowNode extends RouteGraphNode implements ILoopComponentNode {\r
 \r
        private static final long serialVersionUID = 2576929364910319487L;\r
        boolean isLock = false;\r
+       private HashMap<LoopNode, Boolean> loopSelectionMap = new HashMap<LoopNode, Boolean>();\r
 \r
+       private boolean isLoopSelected() {\r
+               return loopSelectionMap.containsValue(true);\r
+       }\r
+       \r
        @Override\r
     protected boolean mouseDragged(MouseDragBegin e) {\r
                // Disable dragging if LockSketch is ON\r
@@ -34,4 +45,28 @@ public class RouteFlowNode extends RouteGraphNode {
                else\r
                        return super.mouseDragged(e);\r
        }\r
+\r
+       @Override\r
+       public void setLoopSelected(LoopNode loop, boolean selected) {\r
+               Boolean loopSelected = loopSelectionMap.get(loop);\r
+               if (loopSelected == null || loopSelected != selected) {\r
+                       loopSelectionMap.put(loop, selected);\r
+                       \r
+                       // Here the FlowConnectionStyle takes care of drawing the flow, so\r
+                       // find it and tell it to change the color accordingly\r
+                       if (!(renderer instanceof StyledRouteGraphRenderer))\r
+                               return;\r
+               \r
+                       StyledRouteGraphRenderer renderer = (StyledRouteGraphRenderer)this.renderer;\r
+                       ConnectionStyle style = renderer.getStyle();\r
+                       if (!(style instanceof FlowConnectionStyle))\r
+                               return;\r
+                       \r
+                       FlowConnectionStyle fcs = (FlowConnectionStyle)style;\r
+                       \r
+                       fcs.setLoopColorOverride(isLoopSelected());\r
+                       repaint();\r
+               }\r
+       }\r
+       \r
 }\r
index 130ebb0874cc14044149ff329faab2fbacf31864..cfb10396359da444f686df4fd2f01eb1f4a4880f 100644 (file)
@@ -32,7 +32,7 @@ import org.simantics.sysdyn.elementaryCycles.ElementaryCyclesSearch;
 import org.simantics.ui.SimanticsUI;\r
 \r
 /**\r
- * Utils for configurations\r
+ * Utils for loops\r
  * @author Tuomas Miettinen\r
  *\r
  */\r
@@ -313,7 +313,6 @@ public class LoopUtils {
                                                        oddNumberOfNegativeCausalities = !oddNumberOfNegativeCausalities;\r
                                                        break;\r
                                                }\r
-                                               continue;\r
                                        }\r
                                }\r
                        }\r