]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/rendering/arrows/ArrowLineEndStyle.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.diagram.connection / src / org / simantics / diagram / connection / rendering / arrows / ArrowLineEndStyle.java
diff --git a/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/rendering/arrows/ArrowLineEndStyle.java b/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/rendering/arrows/ArrowLineEndStyle.java
new file mode 100644 (file)
index 0000000..5a046b1
--- /dev/null
@@ -0,0 +1,199 @@
+/*******************************************************************************\r
+ * Copyright (c) 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.diagram.connection.rendering.arrows;\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.io.Serializable;\r
+import java.util.StringTokenizer;\r
+\r
+\r
+/**\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class ArrowLineEndStyle implements ILineEndStyle, Serializable {\r
+\r
+    private static final long serialVersionUID = -346653685430483245L;\r
+\r
+    public static enum ArrowType { None, Stroke, Fill }\r
+\r
+    public static final double DEFAULT_LENGTH = 8.0;\r
+    public static final double DEFAULT_WIDTH = 4.0;\r
+    public static final double DEFAULT_SPACE = 0.0;\r
+\r
+    protected ArrowType        type;\r
+    protected double           lineEndLength;\r
+    protected double           length;\r
+    protected double           width;\r
+    protected double           space;\r
+    protected Color            color;\r
+\r
+    protected transient Path2D path;\r
+\r
+    public ArrowLineEndStyle() {\r
+        this(DEFAULT_LENGTH, DEFAULT_WIDTH, DEFAULT_SPACE, null);\r
+    }\r
+\r
+    public ArrowLineEndStyle(double length, double width, double space) {\r
+       this(length, width, space, null);\r
+    }\r
+\r
+    public ArrowLineEndStyle(double length, double width, double space, Color color) {\r
+        this.type = ArrowType.Fill;\r
+        this.length = length;\r
+        this.width = width;\r
+        this.space = space;\r
+        this.color = color;\r
+        this.path = arrow(length, width, space);\r
+    }\r
+\r
+    public ArrowLineEndStyle(String desc) {\r
+        this.type = ArrowType.None;\r
+        this.lineEndLength = 0.0;\r
+\r
+        double l = DEFAULT_LENGTH;\r
+        double w = DEFAULT_WIDTH;\r
+        double s = DEFAULT_SPACE;\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
+        this.width = w;\r
+        this.length = l;\r
+        this.space = s;\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
+\r
+        AffineTransform old = g.getTransform();\r
+        g.translate(x, y);\r
+        g.rotate(dir*Math.PI*0.5);\r
+        if(color != null)\r
+               g.setColor(color);\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
+        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 static 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 static 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() + "@" + System.identityHashCode(this) + "[" + type + ", w=" + width + ", l=" + length + ", s=" + space + ", lel=" + lineEndLength + "]";\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = 1;\r
+        long temp;\r
+        temp = Double.doubleToLongBits(length);\r
+        result = prime * result + (int) (temp ^ (temp >>> 32));\r
+        temp = Double.doubleToLongBits(lineEndLength);\r
+        result = prime * result + (int) (temp ^ (temp >>> 32));\r
+        temp = Double.doubleToLongBits(space);\r
+        result = prime * result + (int) (temp ^ (temp >>> 32));\r
+        result = prime * result + ((type == null) ? 0 : type.hashCode());\r
+        temp = Double.doubleToLongBits(width);\r
+        result = prime * result + (int) (temp ^ (temp >>> 32));\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj)\r
+            return true;\r
+        if (obj == null)\r
+            return false;\r
+        if (getClass() != obj.getClass())\r
+            return false;\r
+        ArrowLineEndStyle other = (ArrowLineEndStyle) obj;\r
+        if (Double.doubleToLongBits(length) != Double.doubleToLongBits(other.length))\r
+            return false;\r
+        if (Double.doubleToLongBits(lineEndLength) != Double.doubleToLongBits(other.lineEndLength))\r
+            return false;\r
+        if (Double.doubleToLongBits(space) != Double.doubleToLongBits(other.space))\r
+            return false;\r
+        if (type != other.type)\r
+            return false;\r
+        if (Double.doubleToLongBits(width) != Double.doubleToLongBits(other.width))\r
+            return false;\r
+        return true;\r
+    }\r
+\r
+}\r