]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/EdgeNode.java
Merge commit 'd186091'
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / g2d / nodes / EdgeNode.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in 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.scenegraph.g2d.nodes;\r
13 \r
14 import java.awt.BasicStroke;\r
15 import java.awt.Color;\r
16 import java.awt.Composite;\r
17 import java.awt.Graphics2D;\r
18 import java.awt.Shape;\r
19 import java.awt.Stroke;\r
20 import java.awt.geom.AffineTransform;\r
21 import java.awt.geom.GeneralPath;\r
22 import java.awt.geom.Point2D;\r
23 import java.awt.geom.Rectangle2D;\r
24 \r
25 import org.simantics.scenegraph.g2d.G2DNode;\r
26 import org.simantics.scenegraph.utils.InitValueSupport;\r
27 \r
28 public class EdgeNode extends G2DNode implements InitValueSupport {\r
29 \r
30     private static final long serialVersionUID = 1294351381209071074L;\r
31 \r
32     public static enum ArrowType { None, Stroke, Fill, Both }\r
33 \r
34     protected Color color = null;\r
35     protected Stroke stroke = null;\r
36     protected Shape shape = null;\r
37     protected Point2D firstdir = null;\r
38     protected Point2D lastdir = null;\r
39     protected Point2D first = null;\r
40     protected Point2D last = null;\r
41     protected double firstsize = 0;\r
42     protected double lastsize = 0;\r
43     protected ArrowType first_at = null;\r
44     protected ArrowType last_at = null;\r
45     protected Shape firstShape = null;\r
46     protected Shape lastShape = null;\r
47 \r
48     private transient Rectangle2D bounds;\r
49 \r
50     @SyncField({"color", "stroke", "shape", "firstdir", "lastdir", "first", "last", "firstsize", "lastsize", "first_at", "last_at"})\r
51     public void init(Shape shape, Stroke stroke, Color color, Point2D firstdir, Point2D lastdir, Point2D first, Point2D last, double firstsize, double lastsize, ArrowType first_at, ArrowType last_at, Shape firstShape, Shape lastShape) {\r
52         this.color = color;\r
53         this.stroke = stroke;\r
54         this.shape = shape;\r
55         this.firstdir = firstdir;\r
56         this.lastdir = lastdir;\r
57         this.first = first;\r
58         this.last = last;\r
59         this.firstsize = firstsize;\r
60         this.lastsize = lastsize;\r
61         this.first_at = first_at;\r
62         this.last_at = last_at;\r
63         this.firstShape = firstShape;\r
64         this.lastShape = lastShape;\r
65 \r
66         if (shape != null) {\r
67             this.bounds = shape.getBounds2D();\r
68         }\r
69     }\r
70 \r
71     @Override\r
72     public void render(Graphics2D g) {\r
73         if(color != null) g.setColor(color);\r
74         if(stroke == null || shape == null)  return;\r
75 \r
76         if(alphaComposite != null) {\r
77             g.setComposite(alphaComposite);\r
78         }\r
79 \r
80         Stroke effectiveStroke = stroke;\r
81         if(dynamicStroke != null) {\r
82             effectiveStroke = dynamicStroke;\r
83         }\r
84 \r
85         Color effectiveColor = color;\r
86         if(dynamicColor != null) {\r
87             effectiveColor = dynamicColor;\r
88         }\r
89 \r
90         g.setStroke(effectiveStroke);\r
91 \r
92         // NICENESS\r
93         //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);\r
94 \r
95         //g.draw(shape);\r
96 \r
97         // Draw line "halo"\r
98 //        float f = ((BasicStroke)effectiveStroke).getLineWidth() * 3f;\r
99 //        Color background = Color.WHITE; // FIXME\r
100 //        g.setColor(background);\r
101 //        g.setStroke(new BasicStroke(f));\r
102 //        g.draw(shape);\r
103 \r
104         // Draw line\r
105         g.setColor(effectiveColor);\r
106         g.setStroke(effectiveStroke);\r
107         g.draw(shape);\r
108 \r
109         // Draw line ends if necessary.\r
110         boolean drawArrows = first_at != ArrowType.None || last_at != ArrowType.None;\r
111         if (!drawArrows)\r
112             return;\r
113 \r
114         AffineTransform at = g.getTransform();\r
115 \r
116         g.setStroke(ARROW_STROKE);\r
117 \r
118         if (first_at != ArrowType.None) {\r
119             double theta = Math.atan2(firstdir.getY(), firstdir.getX()) - Math.PI/2;\r
120             g.translate(first.getX(), first.getY());\r
121             g.rotate(theta);\r
122             g.scale(firstsize, firstsize);\r
123 \r
124             if (first_at == ArrowType.Fill)\r
125                 g.fill(FILLED_ARROW);\r
126             else if (first_at == ArrowType.Stroke)\r
127                 g.draw(NORMAL_ARROW);\r
128 \r
129             g.setTransform(at);\r
130         }\r
131 \r
132         if (last_at != ArrowType.None) {\r
133             double theta = Math.atan2(lastdir.getY(), lastdir.getX()) - Math.PI/2;\r
134             g.translate(last.getX(), last.getY());\r
135             g.rotate(theta);\r
136             g.scale(lastsize, lastsize);\r
137 \r
138             if (last_at == ArrowType.Fill)\r
139                 g.fill(FILLED_ARROW);\r
140             else if (last_at == ArrowType.Stroke)\r
141                 g.draw(NORMAL_ARROW);\r
142 \r
143             g.setTransform(at);\r
144         }\r
145     }\r
146 \r
147 \r
148     public transient final static GeneralPath NORMAL_ARROW;\r
149     public transient final static GeneralPath FILLED_ARROW;\r
150     public transient static final Stroke ARROW_STROKE = new BasicStroke(1.0f);\r
151 \r
152     static {\r
153         FILLED_ARROW = new GeneralPath();\r
154         FILLED_ARROW.moveTo(-0.5f, 1f);\r
155         FILLED_ARROW.lineTo(   0f, 0f);\r
156         FILLED_ARROW.lineTo( 0.5f, 1f);\r
157         FILLED_ARROW.closePath();\r
158 \r
159         NORMAL_ARROW = new GeneralPath();\r
160         NORMAL_ARROW.moveTo(-0.5f, 1f);\r
161         NORMAL_ARROW.lineTo(   0f, 0f);\r
162         NORMAL_ARROW.lineTo( 0.5f, 1f);\r
163     }\r
164 \r
165     @Override\r
166     public Rectangle2D getBoundsInLocal() {\r
167         return bounds;\r
168     }\r
169 \r
170     protected Composite alphaComposite = null;\r
171     protected Stroke dynamicStroke = null;\r
172     protected Color dynamicColor = null;\r
173 \r
174     @PropertySetter("alpha")\r
175     @SyncField("alphaComposite")\r
176     public void setAlphaComposite(Composite alphaComposite) {\r
177         this.alphaComposite = alphaComposite;\r
178     }\r
179 \r
180     @PropertySetter("width")\r
181     @SyncField("dynamicStroke")\r
182     public void setDynamicStroke(Stroke stroke) {\r
183         this.dynamicStroke = stroke;\r
184     }\r
185 \r
186     @PropertySetter("color")\r
187     @SyncField("dynamicColor")\r
188     public void setDynamicColor(Color color) {\r
189         this.dynamicColor = color;\r
190     }\r
191 \r
192 //    public void setValue(String key, Object value) {\r
193 //\r
194 //        if ("alpha".equals(key)) {\r
195 //              Float val = Float.parseFloat((String)value);\r
196 //              alphaComposite = AlphaComposite.getInstance(AlphaComposite. SRC_OVER, val);\r
197 //        } else if ("width".equals(key)) {\r
198 //            dynamicStroke = new BasicStroke(Float.parseFloat((String)value));\r
199 //        } else if ("color".equals(key)) {\r
200 //            try {\r
201 //              dynamicColor = new Color(Integer.parseInt(value.toString(), 16));\r
202 //            } catch (Throwable t) {\r
203 //                t.printStackTrace();\r
204 //            }\r
205 //        }\r
206 //    }\r
207 \r
208     @Override\r
209     public void initValues() {\r
210         dynamicStroke = null;\r
211         dynamicColor = null;\r
212         alphaComposite = null;\r
213     }\r
214 \r
215 }\r