]> gerrit.simantics Code Review - simantics/platform.git/blob - 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
1 /*******************************************************************************\r
2  * Copyright (c) 2011 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.diagram.connection.rendering.arrows;\r
13 \r
14 import java.awt.Color;\r
15 import java.awt.Graphics2D;\r
16 import java.awt.geom.AffineTransform;\r
17 import java.awt.geom.Path2D;\r
18 import java.io.Serializable;\r
19 import java.util.StringTokenizer;\r
20 \r
21 \r
22 /**\r
23  * @author Tuukka Lehtonen\r
24  */\r
25 public class ArrowLineEndStyle implements ILineEndStyle, Serializable {\r
26 \r
27     private static final long serialVersionUID = -346653685430483245L;\r
28 \r
29     public static enum ArrowType { None, Stroke, Fill }\r
30 \r
31     public static final double DEFAULT_LENGTH = 8.0;\r
32     public static final double DEFAULT_WIDTH = 4.0;\r
33     public static final double DEFAULT_SPACE = 0.0;\r
34 \r
35     protected ArrowType        type;\r
36     protected double           lineEndLength;\r
37     protected double           length;\r
38     protected double           width;\r
39     protected double           space;\r
40     protected Color            color;\r
41 \r
42     protected transient Path2D path;\r
43 \r
44     public ArrowLineEndStyle() {\r
45         this(DEFAULT_LENGTH, DEFAULT_WIDTH, DEFAULT_SPACE, null);\r
46     }\r
47 \r
48     public ArrowLineEndStyle(double length, double width, double space) {\r
49         this(length, width, space, null);\r
50     }\r
51 \r
52     public ArrowLineEndStyle(double length, double width, double space, Color color) {\r
53         this.type = ArrowType.Fill;\r
54         this.length = length;\r
55         this.width = width;\r
56         this.space = space;\r
57         this.color = color;\r
58         this.path = arrow(length, width, space);\r
59     }\r
60 \r
61     public ArrowLineEndStyle(String desc) {\r
62         this.type = ArrowType.None;\r
63         this.lineEndLength = 0.0;\r
64 \r
65         double l = DEFAULT_LENGTH;\r
66         double w = DEFAULT_WIDTH;\r
67         double s = DEFAULT_SPACE;\r
68 \r
69         StringTokenizer tokenizer = new StringTokenizer(desc);\r
70         if (tokenizer.hasMoreTokens()) {\r
71             String type = tokenizer.nextToken();\r
72             this.type = parseType(type);\r
73 \r
74             if (tokenizer.hasMoreTokens()) {\r
75                 String ls = tokenizer.nextToken();\r
76                 l = parseSize(ls, length);\r
77 \r
78                 if (tokenizer.hasMoreTokens()) {\r
79                     String ws = tokenizer.nextToken();\r
80                     w = parseSize(ws, width);\r
81 \r
82                     if (tokenizer.hasMoreTokens()) {\r
83                         String ss = tokenizer.nextToken();\r
84                         s = parseSize(ss, space);\r
85                     }\r
86                 }\r
87             }\r
88             if (this.type != ArrowType.None) {\r
89                 this.path = arrow(l, w, s);\r
90                 lineEndLength = l+s;\r
91             }\r
92         }\r
93 \r
94         this.width = w;\r
95         this.length = l;\r
96         this.space = s;\r
97     }\r
98 \r
99     @Override\r
100     public void render(Graphics2D g, double x, double y, int dir) {\r
101         if (type == ArrowType.None || path == null)\r
102             return;\r
103 \r
104         AffineTransform old = g.getTransform();\r
105         g.translate(x, y);\r
106         g.rotate(dir*Math.PI*0.5);\r
107         if(color != null)\r
108                 g.setColor(color);\r
109 \r
110         switch (type) {\r
111             case Fill:\r
112                 g.fill(path);\r
113                 break;\r
114             case Stroke:\r
115                 g.draw(path);\r
116                 break;\r
117         }\r
118 \r
119         g.setTransform(old);\r
120     }\r
121 \r
122     @Override\r
123     public double getLineEndLength(int direction) {\r
124         return lineEndLength;\r
125     }\r
126 \r
127     private static Path2D arrow(double length, double width, double space) {\r
128         Path2D.Double path = new Path2D.Double();\r
129         path.moveTo(-space, 0);\r
130         path.lineTo(-length-space, -width);\r
131         path.lineTo(-length-space, +width);\r
132         path.closePath();\r
133         return path;\r
134     }\r
135 \r
136     private static double parseSize(String size, double defaultValue) {\r
137         try {\r
138             return Double.parseDouble(size);\r
139         } catch (NumberFormatException e) {\r
140             return defaultValue;\r
141         }\r
142     }\r
143 \r
144     private static ArrowType parseType(String type) {\r
145         String lower = type.toLowerCase();\r
146         if ("none".equals(lower))\r
147             return ArrowType.None;\r
148         if ("stroke".equals(lower))\r
149             return ArrowType.Stroke;\r
150         if ("fill".equals(lower))\r
151             return ArrowType.Fill;\r
152         throw new IllegalArgumentException("unrecognized arrow type: " + type);\r
153     }\r
154 \r
155     @Override\r
156     public String toString() {\r
157         return getClass().getSimpleName() + "@" + System.identityHashCode(this) + "[" + type + ", w=" + width + ", l=" + length + ", s=" + space + ", lel=" + lineEndLength + "]";\r
158     }\r
159 \r
160     @Override\r
161     public int hashCode() {\r
162         final int prime = 31;\r
163         int result = 1;\r
164         long temp;\r
165         temp = Double.doubleToLongBits(length);\r
166         result = prime * result + (int) (temp ^ (temp >>> 32));\r
167         temp = Double.doubleToLongBits(lineEndLength);\r
168         result = prime * result + (int) (temp ^ (temp >>> 32));\r
169         temp = Double.doubleToLongBits(space);\r
170         result = prime * result + (int) (temp ^ (temp >>> 32));\r
171         result = prime * result + ((type == null) ? 0 : type.hashCode());\r
172         temp = Double.doubleToLongBits(width);\r
173         result = prime * result + (int) (temp ^ (temp >>> 32));\r
174         return result;\r
175     }\r
176 \r
177     @Override\r
178     public boolean equals(Object obj) {\r
179         if (this == obj)\r
180             return true;\r
181         if (obj == null)\r
182             return false;\r
183         if (getClass() != obj.getClass())\r
184             return false;\r
185         ArrowLineEndStyle other = (ArrowLineEndStyle) obj;\r
186         if (Double.doubleToLongBits(length) != Double.doubleToLongBits(other.length))\r
187             return false;\r
188         if (Double.doubleToLongBits(lineEndLength) != Double.doubleToLongBits(other.lineEndLength))\r
189             return false;\r
190         if (Double.doubleToLongBits(space) != Double.doubleToLongBits(other.space))\r
191             return false;\r
192         if (type != other.type)\r
193             return false;\r
194         if (Double.doubleToLongBits(width) != Double.doubleToLongBits(other.width))\r
195             return false;\r
196         return true;\r
197     }\r
198 \r
199 }\r