]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.diagram/src/org/simantics/diagram/connection/RouteGraphConnectionClass.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / connection / RouteGraphConnectionClass.java
index 0a82dd584c1895f120bcb5ada31681ccce5a2730..72b8232c131040ed9951c7d6159fd09c52d95dc4 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 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.diagram.connection;\r
-\r
-import java.awt.Shape;\r
-import java.awt.geom.Rectangle2D;\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-\r
-import org.simantics.diagram.connection.rendering.IRouteGraphRenderer;\r
-import org.simantics.g2d.connection.ConnectionEntity;\r
-import org.simantics.g2d.connection.handler.ConnectionHandler;\r
-import org.simantics.g2d.diagram.handler.PickRequest.PickPolicy;\r
-import org.simantics.g2d.diagram.handler.Topology.Connection;\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.SceneGraphNodeKey;\r
-import org.simantics.g2d.element.handler.InternalSize;\r
-import org.simantics.g2d.element.handler.Outline;\r
-import org.simantics.g2d.element.handler.Pick;\r
-import org.simantics.g2d.element.handler.SceneGraph;\r
-import org.simantics.g2d.element.handler.SelectionOutline;\r
-import org.simantics.g2d.element.handler.impl.ConfigurableEdgeVisuals;\r
-import org.simantics.g2d.element.handler.impl.ConnectionSelectionOutline;\r
-import org.simantics.g2d.element.handler.impl.FillColorImpl;\r
-import org.simantics.g2d.element.handler.impl.TextImpl;\r
-import org.simantics.g2d.elementclass.connection.EdgeClass.FixedTransform;\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
-import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
-import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;\r
-\r
-/**\r
- * An element class for single connection entity elements. A connection entity\r
- * consists of connection edge segments and branch points as its children.\r
- * \r
- * @author Tuukka Lehtonen\r
- */\r
-public class RouteGraphConnectionClass {\r
-\r
-    public static final Key          KEY_ROUTEGRAPH     = new KeyOf(RouteGraph.class, "ROUTE_GRAPH");\r
-    public static final Key          KEY_RENDERER       = new KeyOf(IRouteGraphRenderer.class, "ROUTE_GRAPH_RENDERER");\r
-    public static final Key          KEY_PICK_TOLERANCE = new KeyOf(Double.class, "PICK_TOLERANCE");\r
-    public static final Key          KEY_USE_TOLERANCE_IN_SELECTION  = new KeyOf(Boolean.class, "PICK_TOLERANCE_SELECTION");\r
-    public static final Key          KEY_RG_LISTENER    = new KeyOf(IRouteGraphListener.class, "ROUTE_GRAPH_LISTENER");\r
-    public static final Key          KEY_RG_NODE        = new SceneGraphNodeKey(RouteGraphNode.class, "ROUTE_GRAPH_NODE");\r
-    \r
-    public static final double       BOUND_TOLERANCE = 0.9;\r
-\r
-    public static final ElementClass CLASS =\r
-        ElementClass.compile(\r
-                TextImpl.INSTANCE,\r
-\r
-                FixedTransform.INSTANCE,\r
-\r
-                ConnectionBoundsAndPick.INSTANCE,\r
-                ConnectionSelectionOutline.INSTANCE,\r
-                ConnectionHandlerImpl.INSTANCE,\r
-                ConnectionSceneGraph.INSTANCE,\r
-                //SimpleElementLayers.INSTANCE,\r
-\r
-                // Exists only loading connection visuals through ConnectionVisualsLoader\r
-                ConfigurableEdgeVisuals.DEFAULT,\r
-                FillColorImpl.BLACK\r
-        ).setId(RouteGraphConnectionClass.class.getSimpleName());\r
-\r
-\r
-    static class ConnectionHandlerImpl implements ConnectionHandler {\r
-\r
-        public static final ConnectionHandlerImpl INSTANCE = new ConnectionHandlerImpl();\r
-\r
-        private static final long serialVersionUID = 3267139233182458330L;\r
-\r
-        @Override\r
-        public Collection<IElement> getBranchPoints(IElement connection, Collection<IElement> result) {\r
-            return Collections.<IElement>emptySet();\r
-        }\r
-\r
-        @Override\r
-        public Collection<IElement> getChildren(IElement connection, Collection<IElement> result) {\r
-            return Collections.emptySet();\r
-        }\r
-\r
-        @Override\r
-        public Collection<IElement> getSegments(IElement connection, Collection<IElement> result) {\r
-            return Collections.<IElement>emptySet();\r
-        }\r
-\r
-        @Override\r
-        public Collection<Connection> getTerminalConnections(IElement connection, Collection<Connection> result) {\r
-            ConnectionEntity ce = connection.getHint(ElementHints.KEY_CONNECTION_ENTITY);\r
-            if (ce == null)\r
-                return Collections.<Connection>emptySet();\r
-            return ce.getTerminalConnections(result);\r
-        }\r
-\r
-    }\r
-\r
-    static final class ConnectionSceneGraph implements SceneGraph {\r
-\r
-        public static final ConnectionSceneGraph INSTANCE = new ConnectionSceneGraph();\r
-\r
-        private static final long serialVersionUID = 4232871859964883266L;\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
-    static final class ConnectionBoundsAndPick implements InternalSize, Outline, Pick {\r
-\r
-        private static final long serialVersionUID = 4232871859964883266L;\r
-\r
-        public static final ConnectionBoundsAndPick INSTANCE = new ConnectionBoundsAndPick();\r
-\r
-        // Single-threaded system, should be fine to use this for everything.\r
-        Rectangle2D temp = new Rectangle2D.Double();\r
-\r
-        private Shape getSelectionShape(IElement e) {\r
-            for (SelectionOutline so : e.getElementClass().getItemsByClass(SelectionOutline.class)) {\r
-                Shape shape = so.getSelectionShape(e);\r
-                if (shape != null)\r
-                    return shape;\r
-            }\r
-            // Using on-diagram coordinates because neither connections nor\r
-            // edges have a non-identity transform which means that\r
-            // coordinates are always absolute. Therefore branch point\r
-            // shape also needs to be calculated in absolute coordinates.\r
-            Shape shape = ElementUtils.getElementShapeOrBoundsOnDiagram(e);\r
-            return shape;\r
-        }\r
-\r
-        @Override\r
-        public boolean pickTest(IElement e, Shape s, PickPolicy policy) {\r
-            RouteGraph rg = getRouteGraph(e);\r
-            if (rg == null)\r
-                return false;\r
-\r
-            Rectangle2D bounds = getBounds(s);\r
-            switch (policy) {\r
-                case PICK_CONTAINED_OBJECTS:\r
-                    Shape selectionShape = getSelectionShape(e);\r
-                    return bounds.contains(selectionShape.getBounds2D());\r
-                case PICK_INTERSECTING_OBJECTS:\r
-                       double tolerance = 0.0;\r
-                       if (e.containsHint(KEY_USE_TOLERANCE_IN_SELECTION))\r
-                               tolerance = getTolerance(e);\r
-                       else\r
-                               tolerance = (bounds.getHeight()+bounds.getHeight()) * 0.25;\r
-                       Object node = rg.pickLine(bounds.getCenterX(), bounds.getCenterY(), tolerance);\r
-                    return node != null;\r
-            }\r
-            return false;\r
-        }\r
-\r
-        @Override\r
-        public Rectangle2D getBounds(IElement e, Rectangle2D size) {\r
-            RouteGraph rg = getRouteGraph(e);\r
-            if (rg != null) {\r
-                if (size == null)\r
-                    size = new Rectangle2D.Double();\r
-                rg.getBounds(size);\r
-            }\r
-            return size;\r
-        }\r
-\r
-        @Override\r
-        public Shape getElementShape(IElement e) {\r
-            RouteGraph rg = getRouteGraph(e);\r
-            return rg == null ? null : rg.getPath2D();\r
-        }\r
-\r
-        private Rectangle2D getBounds(Shape shape) {\r
-            if (shape instanceof Rectangle2D)\r
-                return (Rectangle2D) shape;\r
-            return shape.getBounds2D();\r
-        }\r
-\r
-        private RouteGraph getRouteGraph(IElement e) {\r
-            RouteGraphNode rgn = e.getHint(KEY_RG_NODE);\r
-            return rgn == null ? null : rgn.getRouteGraph();\r
-        }\r
-        \r
-        private double getTolerance(IElement e) {\r
-               RouteGraphNode rgn = e.getHint(KEY_RG_NODE);\r
-               return rgn.getPickTolerance();\r
-        }\r
-\r
-    }\r
-\r
-    public static int shortestDirectionOutOfBounds(double x, double y, Rectangle2D bounds) {\r
-        double mx = bounds.getMinX();\r
-        double Mx = bounds.getMaxX();\r
-        double my = bounds.getMinY();\r
-        double My = bounds.getMaxY();\r
-\r
-        double up = y - my;\r
-        double down = My - y;\r
-        double left = x - mx;\r
-        double right = Mx - x;\r
-\r
-        // Insertion sort\r
-        double[] dists = { right, down, left, up };\r
-        byte[] masks = { 0x1, 0x2, 0x4, 0x8 };\r
-        for (int i = 1; i < 4; ++i) {\r
-            double value = dists[i];\r
-            byte mask = masks[i];\r
-            int j = i - 1;\r
-            while (j >= 0 && dists[j] > value) {\r
-                dists[j + 1] = dists[j];\r
-                masks[j + 1] = masks[j];\r
-                --j;\r
-            }\r
-            dists[j + 1] = value;\r
-            masks[j + 1] = mask;\r
-        }\r
-\r
-        // Construct mask out of the shortest equal directions \r
-        int mask = masks[0];\r
-        double value = dists[0] / BOUND_TOLERANCE;\r
-        for (int i = 1; i < 4; ++i) {\r
-            if (dists[i] > value)\r
-                break;\r
-            mask |= masks[i];\r
-        }\r
-        return mask;\r
-    }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.diagram.connection;
+
+import java.awt.Shape;
+import java.awt.geom.Rectangle2D;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.simantics.diagram.connection.rendering.IRouteGraphRenderer;
+import org.simantics.g2d.connection.ConnectionEntity;
+import org.simantics.g2d.connection.handler.ConnectionHandler;
+import org.simantics.g2d.diagram.handler.PickRequest.PickPolicy;
+import org.simantics.g2d.diagram.handler.Topology.Connection;
+import org.simantics.g2d.element.ElementClass;
+import org.simantics.g2d.element.ElementHints;
+import org.simantics.g2d.element.ElementUtils;
+import org.simantics.g2d.element.IElement;
+import org.simantics.g2d.element.SceneGraphNodeKey;
+import org.simantics.g2d.element.handler.InternalSize;
+import org.simantics.g2d.element.handler.Outline;
+import org.simantics.g2d.element.handler.Pick;
+import org.simantics.g2d.element.handler.SceneGraph;
+import org.simantics.g2d.element.handler.SelectionOutline;
+import org.simantics.g2d.element.handler.impl.ConfigurableEdgeVisuals;
+import org.simantics.g2d.element.handler.impl.ConnectionSelectionOutline;
+import org.simantics.g2d.element.handler.impl.FillColorImpl;
+import org.simantics.g2d.element.handler.impl.TextImpl;
+import org.simantics.g2d.elementclass.connection.EdgeClass.FixedTransform;
+import org.simantics.scenegraph.g2d.G2DParentNode;
+import org.simantics.scenegraph.g2d.nodes.connection.IRouteGraphListener;
+import org.simantics.scenegraph.g2d.nodes.connection.RouteGraphNode;
+import org.simantics.utils.datastructures.hints.IHintContext.Key;
+import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;
+
+/**
+ * An element class for single connection entity elements. A connection entity
+ * consists of connection edge segments and branch points as its children.
+ * 
+ * @author Tuukka Lehtonen
+ */
+public class RouteGraphConnectionClass {
+
+    public static final Key          KEY_ROUTEGRAPH     = new KeyOf(RouteGraph.class, "ROUTE_GRAPH");
+    public static final Key          KEY_RENDERER       = new KeyOf(IRouteGraphRenderer.class, "ROUTE_GRAPH_RENDERER");
+    public static final Key          KEY_PICK_TOLERANCE = new KeyOf(Double.class, "PICK_TOLERANCE");
+    public static final Key          KEY_USE_TOLERANCE_IN_SELECTION  = new KeyOf(Boolean.class, "PICK_TOLERANCE_SELECTION");
+    public static final Key          KEY_RG_LISTENER    = new KeyOf(IRouteGraphListener.class, "ROUTE_GRAPH_LISTENER");
+    public static final Key          KEY_RG_NODE        = new SceneGraphNodeKey(RouteGraphNode.class, "ROUTE_GRAPH_NODE");
+    
+    public static final double       BOUND_TOLERANCE = 0.9;
+
+    public static final ElementClass CLASS =
+        ElementClass.compile(
+                TextImpl.INSTANCE,
+
+                FixedTransform.INSTANCE,
+
+                ConnectionBoundsAndPick.INSTANCE,
+                ConnectionSelectionOutline.INSTANCE,
+                ConnectionHandlerImpl.INSTANCE,
+                ConnectionSceneGraph.INSTANCE,
+                //SimpleElementLayers.INSTANCE,
+
+                // Exists only loading connection visuals through ConnectionVisualsLoader
+                ConfigurableEdgeVisuals.DEFAULT,
+                FillColorImpl.BLACK
+        ).setId(RouteGraphConnectionClass.class.getSimpleName());
+
+
+    static class ConnectionHandlerImpl implements ConnectionHandler {
+
+        public static final ConnectionHandlerImpl INSTANCE = new ConnectionHandlerImpl();
+
+        private static final long serialVersionUID = 3267139233182458330L;
+
+        @Override
+        public Collection<IElement> getBranchPoints(IElement connection, Collection<IElement> result) {
+            return Collections.<IElement>emptySet();
+        }
+
+        @Override
+        public Collection<IElement> getChildren(IElement connection, Collection<IElement> result) {
+            return Collections.emptySet();
+        }
+
+        @Override
+        public Collection<IElement> getSegments(IElement connection, Collection<IElement> result) {
+            return Collections.<IElement>emptySet();
+        }
+
+        @Override
+        public Collection<Connection> getTerminalConnections(IElement connection, Collection<Connection> result) {
+            ConnectionEntity ce = connection.getHint(ElementHints.KEY_CONNECTION_ENTITY);
+            if (ce == null)
+                return Collections.<Connection>emptySet();
+            return ce.getTerminalConnections(result);
+        }
+
+    }
+
+    static final class ConnectionSceneGraph implements SceneGraph {
+
+        public static final ConnectionSceneGraph INSTANCE = new ConnectionSceneGraph();
+
+        private static final long serialVersionUID = 4232871859964883266L;
+
+        @Override
+        public void init(IElement connection, G2DParentNode parent) {
+            RouteGraph rg = connection.getHint(KEY_ROUTEGRAPH);
+            IRouteGraphRenderer renderer = connection.getHint(KEY_RENDERER);
+            if (rg == null || renderer == null) {
+                cleanup(connection);
+            } else {
+                RouteGraphNode rgn = connection.getHint(KEY_RG_NODE);
+                if (rgn == null) {
+                    rgn = parent.addNode(ElementUtils.generateNodeId(connection), RouteGraphNode.class);
+                    connection.setHint(KEY_RG_NODE, rgn);
+                }
+                rgn.setRouteGraph(rg);
+                rgn.setRenderer(renderer);
+
+                IRouteGraphListener listener = connection.getHint(KEY_RG_LISTENER);
+                rgn.setRouteGraphListener(listener);
+
+                Double tolerance = connection.getHint(KEY_PICK_TOLERANCE);
+                if (tolerance != null)
+                    rgn.setPickTolerance(tolerance);
+            }
+        }
+
+        @Override
+        public void cleanup(IElement connection) {
+            ElementUtils.removePossibleNode(connection, KEY_RG_NODE);
+            connection.removeHint(KEY_RG_NODE);
+        }
+    }
+
+    static final class ConnectionBoundsAndPick implements InternalSize, Outline, Pick {
+
+        private static final long serialVersionUID = 4232871859964883266L;
+
+        public static final ConnectionBoundsAndPick INSTANCE = new ConnectionBoundsAndPick();
+
+        // Single-threaded system, should be fine to use this for everything.
+        Rectangle2D temp = new Rectangle2D.Double();
+
+        private Shape getSelectionShape(IElement e) {
+            for (SelectionOutline so : e.getElementClass().getItemsByClass(SelectionOutline.class)) {
+                Shape shape = so.getSelectionShape(e);
+                if (shape != null)
+                    return shape;
+            }
+            // Using on-diagram coordinates because neither connections nor
+            // edges have a non-identity transform which means that
+            // coordinates are always absolute. Therefore branch point
+            // shape also needs to be calculated in absolute coordinates.
+            Shape shape = ElementUtils.getElementShapeOrBoundsOnDiagram(e);
+            return shape;
+        }
+
+        @Override
+        public boolean pickTest(IElement e, Shape s, PickPolicy policy) {
+            RouteGraph rg = getRouteGraph(e);
+            if (rg == null)
+                return false;
+
+            Rectangle2D bounds = getBounds(s);
+            switch (policy) {
+                case PICK_CONTAINED_OBJECTS:
+                    Shape selectionShape = getSelectionShape(e);
+                    return bounds.contains(selectionShape.getBounds2D());
+                case PICK_INTERSECTING_OBJECTS:
+                       double tolerance = 0.0;
+                       if (e.containsHint(KEY_USE_TOLERANCE_IN_SELECTION))
+                               tolerance = getTolerance(e);
+                       else
+                               tolerance = (bounds.getHeight()+bounds.getHeight()) * 0.25;
+                       Object node = rg.pickLine(bounds.getCenterX(), bounds.getCenterY(), tolerance);
+                    return node != null;
+            }
+            return false;
+        }
+
+        @Override
+        public Rectangle2D getBounds(IElement e, Rectangle2D size) {
+            RouteGraph rg = getRouteGraph(e);
+            if (rg != null) {
+                if (size == null)
+                    size = new Rectangle2D.Double();
+                rg.getBounds(size);
+            }
+            return size;
+        }
+
+        @Override
+        public Shape getElementShape(IElement e) {
+            RouteGraph rg = getRouteGraph(e);
+            return rg == null ? null : rg.getPath2D();
+        }
+
+        private Rectangle2D getBounds(Shape shape) {
+            if (shape instanceof Rectangle2D)
+                return (Rectangle2D) shape;
+            return shape.getBounds2D();
+        }
+
+        private RouteGraph getRouteGraph(IElement e) {
+            RouteGraphNode rgn = e.getHint(KEY_RG_NODE);
+            return rgn == null ? null : rgn.getRouteGraph();
+        }
+        
+        private double getTolerance(IElement e) {
+               RouteGraphNode rgn = e.getHint(KEY_RG_NODE);
+               return rgn.getPickTolerance();
+        }
+
+    }
+
+    public static int shortestDirectionOutOfBounds(double x, double y, Rectangle2D bounds) {
+        double mx = bounds.getMinX();
+        double Mx = bounds.getMaxX();
+        double my = bounds.getMinY();
+        double My = bounds.getMaxY();
+
+        double up = y - my;
+        double down = My - y;
+        double left = x - mx;
+        double right = Mx - x;
+
+        // Insertion sort
+        double[] dists = { right, down, left, up };
+        byte[] masks = { 0x1, 0x2, 0x4, 0x8 };
+        for (int i = 1; i < 4; ++i) {
+            double value = dists[i];
+            byte mask = masks[i];
+            int j = i - 1;
+            while (j >= 0 && dists[j] > value) {
+                dists[j + 1] = dists[j];
+                masks[j + 1] = masks[j];
+                --j;
+            }
+            dists[j + 1] = value;
+            masks[j + 1] = mask;
+        }
+
+        // Construct mask out of the shortest equal directions 
+        int mask = masks[0];
+        double value = dists[0] / BOUND_TOLERANCE;
+        for (int i = 1; i < 4; ++i) {
+            if (dists[i] > value)
+                break;
+            mask |= masks[i];
+        }
+        return mask;
+    }
+
+}