]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
Arrowheads
authorlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Tue, 1 Dec 2009 15:50:56 +0000 (15:50 +0000)
committerlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Tue, 1 Dec 2009 15:50:56 +0000 (15:50 +0000)
git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@13205 ac1ea38d-2e2b-0410-8846-a27921b304fc

org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/FlowElement.java

index 2642aa5281e1a75e0304e4838f300418f2164be9..2675900cb6a332e641f5633fe24efd7b9ccf0368 100644 (file)
@@ -1,6 +1,5 @@
 package org.simantics.sysdyn.ui.elements;\r
 \r
-import java.awt.Shape;\r
 import java.awt.geom.Path2D;\r
 import java.awt.geom.Rectangle2D;\r
 \r
@@ -17,167 +16,214 @@ import org.simantics.scenegraph.g2d.G2DParentNode;
 @GraphType("http://www.simantics.org/Sysdyn#Flow")\r
 public class FlowElement extends Element implements IElementListener {\r
 \r
-       public static double ARROW_LENGTH1 = 0.2;\r
-    public static double ARROW_LENGTH2 = 3.0;\r
-    public static double ARROW_WIDTH = 1.8;\r
-    \r
+    public static double ARROW_LENGTH = 3.2;\r
+    public static double ARROW_WIDTH = 3;\r
+\r
     static final double OFFSET = 1.5;\r
-    \r
-       /*\r
-        * Total length of the arrow is ARROW_LENGTH1 + ARROW_LENGTH2\r
-        */    \r
+    static final double ARROW_OFFSET = 3.2;\r
+\r
+    /*\r
+     * Total length of the arrow is ARROW_LENGTH1 + ARROW_LENGTH2\r
+     */    \r
     @RelatedElement("http://www.simantics.org/Sysdyn#HasTail")\r
-       Connectable tail;\r
+    Connectable tail;\r
     @RelatedElement("http://www.simantics.org/Sysdyn#HasHead")\r
-       Connectable head;\r
-       double angle = 0.1;\r
-\r
-       // Auxiliary    \r
-       double angle0;\r
-       double angle1;\r
-       double cx;\r
-       double cy;\r
-       double r;\r
-       \r
-       // Scene graph\r
-       ShapeNode lineNode1;\r
-       ShapeNode lineNode2;\r
-       FilledShapeNode arrowNode;\r
-       \r
-       public FlowElement() {      \r
-       }\r
-       \r
-       public FlowElement(Connectable tail, Connectable head) {\r
-               super();\r
-               this.tail = tail;\r
-               this.head = head;\r
-       }\r
-       \r
-       @Override\r
-       public void elementUpdated(IElement element) {\r
-               update();               \r
-       }       \r
-\r
-       @Override\r
-       public void remove() {\r
-               lineNode1.remove();\r
-               lineNode2.remove();\r
-               tail.removeListener(this);\r
-               head.removeListener(this);\r
-       }\r
-\r
-       @Override\r
-       public void init(G2DParentNode parent) {\r
-               tail.addListener(this);\r
-               head.addListener(this);\r
-               \r
-               lineNode1 = parent.addNode(ShapeNode.class);\r
-               lineNode1.setScaleStroke(true);\r
-               lineNode2 = parent.addNode(ShapeNode.class);\r
-               lineNode2.setScaleStroke(true);\r
-               \r
-               //arrowNode = parent.addNode(FilledShapeNode.class);\r
-               update();\r
-       }\r
-       \r
-       protected Shape createArrow(double x, double y, double dx, double dy) {\r
+    Connectable head;\r
+    double angle = 0.1;\r
+\r
+    // Auxiliary       \r
+    double angle0;\r
+    double angle1;\r
+    double cx;\r
+    double cy;\r
+    double r;\r
+\r
+    // Scene graph\r
+    ShapeNode lineNode1;\r
+    ShapeNode lineNode2;\r
+    FilledShapeNode arrowNode;\r
+\r
+    public FlowElement() {         \r
+    }\r
+\r
+    public FlowElement(Connectable tail, Connectable head) {\r
+        super();\r
+        this.tail = tail;\r
+        this.head = head;\r
+    }\r
+\r
+    @Override\r
+    public void elementUpdated(IElement element) {\r
+        update();              \r
+    }  \r
+\r
+    @Override\r
+    public void remove() {\r
+        lineNode1.remove();\r
+        lineNode2.remove();\r
+        tail.removeListener(this);\r
+        head.removeListener(this);\r
+    }\r
+\r
+    @Override\r
+    public void init(G2DParentNode parent) {\r
+        tail.addListener(this);\r
+        head.addListener(this);\r
+\r
+        lineNode1 = parent.addNode(ShapeNode.class);\r
+        lineNode1.setScaleStroke(true);\r
+        lineNode2 = parent.addNode(ShapeNode.class);\r
+        lineNode2.setScaleStroke(true);\r
+\r
+        arrowNode = parent.addNode(FilledShapeNode.class);\r
+        update();\r
+    }\r
+\r
+    protected void createArrow(Connectable head, Connectable tail) {   \r
+        double x = tail.getOrigo().getX();\r
+        double y = tail.getOrigo().getY();\r
+\r
+        Rectangle2D rect = new Rectangle2D.Double();\r
+        head.getBounds(rect);\r
+        double cx = rect.getCenterX();\r
+        double minx = rect.getMinX();\r
+        double maxx = rect.getMaxX();\r
+        double miny = rect.getMinY();\r
+        double maxy = rect.getMaxY();\r
+\r
         Path2D path = new Path2D.Double();\r
-        path.moveTo(x+ARROW_LENGTH1*dx, y+ARROW_LENGTH1*dy);\r
-        x -= ARROW_LENGTH2*dx;\r
-        y -= ARROW_LENGTH2*dy;\r
-        path.lineTo(x-ARROW_WIDTH*dy, y+ARROW_WIDTH*dx);\r
-        path.lineTo(x+ARROW_WIDTH*dy, y-ARROW_WIDTH*dx);\r
+\r
+        // approach from top\r
+        if (y < miny) {\r
+            path.moveTo(cx, miny);\r
+            path.lineTo(cx + ARROW_WIDTH, miny - ARROW_LENGTH);\r
+            path.lineTo(cx - ARROW_WIDTH, miny - ARROW_LENGTH);\r
+        } \r
+\r
+        // approach from beneath\r
+        else if (y > maxy) {\r
+            path.moveTo(cx, maxy);\r
+            path.lineTo(cx + ARROW_WIDTH, maxy + ARROW_LENGTH);\r
+            path.lineTo(cx - ARROW_WIDTH, maxy + ARROW_LENGTH);\r
+        }\r
+\r
+        // approach from left\r
+        else if (x < minx) {\r
+            path.moveTo(minx, y);\r
+            path.lineTo(minx - ARROW_LENGTH, y - ARROW_WIDTH);\r
+            path.lineTo(minx - ARROW_LENGTH, y + ARROW_WIDTH);\r
+        }\r
+\r
+        // approach from right\r
+        else if (x > maxx) {\r
+            path.moveTo(maxx, y);\r
+            path.lineTo(maxx + ARROW_LENGTH, y - ARROW_WIDTH);\r
+            path.lineTo(maxx + ARROW_LENGTH, y + ARROW_WIDTH);\r
+        }\r
+\r
         path.closePath();\r
-        return path;\r
+        arrowNode.setShape(path);\r
     }\r
-       \r
-       // TODO\r
-       \r
-       private void draw(boolean vertical, double ... coordinates) {\r
-               lineNode1.setShape(Flows.createOffsetLine(vertical, OFFSET, coordinates));\r
-               lineNode2.setShape(Flows.createOffsetLine(vertical, -OFFSET, coordinates));\r
-       }\r
-\r
-       private void draw(Connectable valve, Connectable node) {\r
-               double x0 = valve.getOrigo().getX();\r
-               double y0 = valve.getOrigo().getY();        \r
-               double x1 = node.getOrigo().getX();\r
-               double y1 = node.getOrigo().getY();\r
-\r
-               Rectangle2D rect = new Rectangle2D.Double();\r
-               node.getBounds(rect);\r
-               if( ((ValveElement)valve).rotated ) {\r
-                       if(y1 > y0)\r
-                               y0 += OFFSET;\r
-                       else\r
-                               y0 -= OFFSET;\r
-                       if(rect.getMinX() <= x0 && rect.getMaxX() >= x0) {\r
-                               if(y1 > y0)\r
-                                       draw(true, y0, x0, rect.getMinY());\r
-                               else\r
-                                       draw(true, y0, x0, rect.getMaxY());\r
-                       }\r
-                       else {\r
-                               if(x1 > x0)\r
-                                       draw(true, y0, x0, y1, rect.getMinX());\r
-                               else\r
-                                       draw(true, y0, x0, y1, rect.getMaxX());\r
-                       }\r
-               }\r
-               else {\r
-                       if(x1 > x0)\r
-                               x0 += OFFSET;\r
-                       else\r
-                               x0 -= OFFSET;\r
-                       if(rect.getMinY() <= y0 && rect.getMaxY() >= y0) {\r
-                               if(x1 > x0)\r
-                                       draw(false, x0, y0, rect.getMinX());\r
-                               else\r
-                                       draw(false, x0, y0, rect.getMaxX());\r
-                       }\r
-                       else {\r
-                               if(y1 > y0)\r
-                                       draw(false, x0, y0, x1, rect.getMinY());\r
-                               else\r
-                                       draw(false, x0, y0, x1, rect.getMaxY());\r
-                       }\r
-               }\r
-       }\r
-\r
-       protected void updateSceneGraph() {\r
-               if(tail instanceof ValveElement)\r
-                       draw(tail, head);\r
-               else if(head instanceof ValveElement)\r
-                       draw(head, tail);\r
-       }\r
-       \r
-       // TODO\r
-       \r
-       public void update() {\r
-               if(lineNode1 != null)\r
-                       updateSceneGraph();\r
-               super.update();\r
-       }\r
-               \r
-       @Override\r
-       public void getBounds(Rectangle2D bounds) {\r
-               bounds.setFrame(lineNode1.getBounds());\r
-       }\r
-\r
-       @Override\r
-       public boolean hitTest(double x, double y, double tolerance) {\r
+\r
+    // TODO\r
+\r
+    private void draw(boolean vertical, double ... coordinates) {\r
+        lineNode1.setShape(Flows.createOffsetLine(vertical, OFFSET, coordinates));\r
+        lineNode2.setShape(Flows.createOffsetLine(vertical, -OFFSET, coordinates));\r
+    }\r
+\r
+    private void draw(boolean hasArrow, Connectable valve, Connectable node) {\r
+        double x0 = valve.getOrigo().getX();\r
+        double y0 = valve.getOrigo().getY();        \r
+        double x1 = node.getOrigo().getX();\r
+        double y1 = node.getOrigo().getY();\r
+\r
+        Rectangle2D rect = new Rectangle2D.Double();\r
+        node.getBounds(rect);\r
+        \r
+        double minY = hasArrow ? rect.getMinY() - ARROW_OFFSET : rect.getMinY();\r
+        double maxY = hasArrow ? rect.getMaxY() + ARROW_OFFSET : rect.getMaxY();\r
+        double minX = hasArrow ? rect.getMinX() - ARROW_OFFSET : rect.getMinX();\r
+        double maxX = hasArrow ? rect.getMaxX() + ARROW_OFFSET : rect.getMaxX();\r
+        \r
+        \r
+        if( ((ValveElement)valve).rotated ) {\r
+            if(y1 > y0)\r
+                y0 += OFFSET;\r
+            else\r
+                y0 -= OFFSET;\r
+            if(rect.getMinX() <= x0 && rect.getMaxX() >= x0) {\r
+                if(y1 > y0)\r
+                    draw(true, y0, x0, minY);\r
+                else\r
+                    draw(true, y0, x0, maxY);\r
+            }\r
+            else {\r
+                if(x1 > x0)\r
+                    draw(true, y0, x0, y1, minX);\r
+                else\r
+                    draw(true, y0, x0, y1, maxX);\r
+            }\r
+        }\r
+        else {\r
+            if(x1 > x0)\r
+                x0 += OFFSET;\r
+            else\r
+                x0 -= OFFSET;\r
+            if(rect.getMinY() <= y0 && rect.getMaxY() >= y0) {\r
+                if(x1 > x0)\r
+                    draw(false, x0, y0, minX);\r
+                else\r
+                    draw(false, x0, y0, maxX);\r
+            }\r
+            else {\r
+                if(y1 > y0)\r
+                    draw(false, x0, y0, x1, minY);\r
+                else\r
+                    draw(false, x0, y0, x1, maxY);\r
+            }\r
+        }\r
+\r
+\r
+    }\r
+\r
+    protected void updateSceneGraph() {\r
+        boolean hasArrow = tail instanceof ValveElement && !(head instanceof ValveElement);\r
+        if(tail instanceof ValveElement)\r
+            draw(hasArrow, tail, head);\r
+        else if(head instanceof ValveElement)\r
+            draw(hasArrow, head, tail);\r
+        if(hasArrow)\r
+            createArrow(head, tail);\r
+    }\r
+\r
+    // TODO\r
+\r
+    public void update() {\r
+        if(lineNode1 != null)\r
+            updateSceneGraph();\r
+        super.update();\r
+    }\r
+\r
+    @Override\r
+    public void getBounds(Rectangle2D bounds) {\r
+        bounds.setFrame(lineNode1.getBounds());\r
+    }\r
+\r
+    @Override\r
+    public boolean hitTest(double x, double y, double tolerance) {\r
         // TODO\r
         return false;\r
-       }\r
-\r
-       @Override\r
-       public <T> T getInterface(Class<T> clazz) {             \r
-               return super.getInterface(clazz);\r
-       }\r
-\r
-       @Override\r
-       public void elementRemoved(IElement element) {\r
-               remove();               \r
-       }\r
-       \r
+    }\r
+\r
+    @Override\r
+    public <T> T getInterface(Class<T> clazz) {                \r
+        return super.getInterface(clazz);\r
+    }\r
+\r
+    @Override\r
+    public void elementRemoved(IElement element) {\r
+        remove();              \r
+    }\r
+\r
 }\r