]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/ShapeNode.java
Merge commit 'd186091'
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / g2d / nodes / ShapeNode.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;
13
14 import java.awt.BasicStroke;\r
15 import java.awt.Color;\r
16 import java.awt.Graphics2D;\r
17 import java.awt.Paint;\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.Rectangle2D;\r
22 \r
23 import org.simantics.scenegraph.g2d.G2DNode;\r
24 import org.simantics.scenegraph.utils.GeometryUtils;\r
25 import org.simantics.scenegraph.utils.InitValueSupport;\r
26
27 /**
28  * A scene graph node that renders a specified AWT {@link Shape} by optionally
29  * filling or drawing it.
30  * 
31  * If filling is enabled, it will be performed before stroking the shape.
32  * 
33  * @author J-P Laine\r
34  * @author Tuukka Lehtonen
35  * 
36  * TODO: separate paint for stroke and fill
37  */
38 public class ShapeNode extends G2DNode implements InitValueSupport {
39
40     private static final long serialVersionUID = 8508750881358776559L;
41 \r
42     protected static final Stroke DEFAULT_STROKE = new BasicStroke(2);\r
43
44     protected Shape shape = null;\r
45     protected Stroke stroke = DEFAULT_STROKE;
46     protected Paint color = Color.BLACK;
47     protected boolean fill = false;
48     protected boolean scaleStroke = false;
49     protected boolean scaleShape = false;
50 \r
51     protected transient Shape dynamicShape = null;\r
52     protected transient Stroke dynamicStroke = null;\r
53     protected transient Paint dynamicColor = null;\r
54     protected transient Boolean dynamicFill = null;\r
55     protected transient Boolean dynamicScaleStroke = null;\r
56     protected transient Boolean dynamicScaleShape = null;\r
57 \r
58     @PropertySetter("shape")
59     @SyncField("shape")
60     public void setShape(Shape shape) {
61         this.shape = shape;
62         repaint();
63     }
64 \r
65     @PropertySetter("stroke")
66     @SyncField("stroke")
67     public void setStroke(Stroke stroke) {
68         this.stroke = stroke;
69     }
70 \r
71     @PropertySetter("color")
72     @SyncField("color")
73     public void setColor(Paint color) {
74         this.color = color;
75     }
76
77     @SyncField("fill")
78     public void setFill(boolean fill) {
79         this.fill = fill;
80     }
81
82     @SyncField("scaleStroke")
83     public void setScaleStroke(boolean scaleStroke) {
84         this.scaleStroke = scaleStroke;
85     }
86
87     @SyncField("scaleShape")
88     public void setScaleShape(boolean scaleShape) {
89         this.scaleShape = scaleShape;
90     }
91
92     @Override
93     public void render(Graphics2D g2d) {
94         Shape shape = dynamicShape != null ? dynamicShape : this.shape;\r
95         if (shape == null)
96             return;
97 \r
98         AffineTransform ot = setupRender(g2d);\r
99         renderShape(g2d, shape);\r
100         if (ot != null)\r
101             g2d.setTransform(ot);
102     }
103
104     /**\r
105      * @param g2d\r
106      * @return current transform\r
107      */\r
108     protected AffineTransform setupRender(Graphics2D g2d) {\r
109         AffineTransform old = null;
110         if (!transform.isIdentity()) {\r
111             old = g2d.getTransform();\r
112             g2d.transform(transform);\r
113         }\r
114 \r
115         Paint color = dynamicColor != null ? dynamicColor : this.color;
116         if (color != null) g2d.setPaint(color);\r
117 \r
118         Stroke stroke = dynamicStroke != null ? dynamicStroke : this.stroke;
119         if (stroke != null) {\r
120             boolean scaleStroke = Boolean.TRUE.equals(dynamicScaleStroke) ? true : this.scaleStroke;
121             if (scaleStroke && stroke instanceof BasicStroke) {
122                 BasicStroke bs = GeometryUtils.scaleStroke(stroke, (float) (1.0 / GeometryUtils.getScale(g2d.getTransform())));
123                 g2d.setStroke(bs);
124             } else {
125                 g2d.setStroke(stroke);
126             }
127         }\r
128
129         boolean scaleShape = Boolean.TRUE.equals(dynamicScaleShape) ? true : this.scaleShape;\r
130         if (scaleShape) {
131             double xs = g2d.getTransform().getScaleX();
132             double ys = g2d.getTransform().getScaleY();
133             g2d.scale(1/xs, 1/ys);
134         }\r
135 \r
136         return old;\r
137     }
138
139     protected void renderShape(Graphics2D g2d, Shape s) {\r
140         boolean fill = Boolean.TRUE.equals(dynamicFill) ? true : this.fill;\r
141         if (fill)
142             g2d.fill(s);\r
143
144         Stroke stroke = dynamicStroke != null ? dynamicStroke : this.stroke;\r
145         if (stroke != null)
146             g2d.draw(s);
147     }
148
149     @Override
150     public Rectangle2D getBoundsInLocal() {
151         if(shape == null) return null;
152         return shape.getBounds2D();
153     }\r
154 \r
155     public void setValue(String key, Object value) {\r
156         if ("shape".equals(key))\r
157             dynamicShape = (Shape) value;\r
158         else if ("stroke".equals(key))\r
159             dynamicStroke = (Stroke) value;\r
160         else if ("color".equals(key))\r
161             dynamicColor = (Paint) value;\r
162         else if ("fill".equals(key))\r
163             dynamicFill = (Boolean) value;\r
164         else if ("scaleStroke".equals(key))\r
165             dynamicScaleStroke = (Boolean) value;\r
166         else if ("scaleShape".equals(key))\r
167             dynamicScaleShape = (Boolean) value;\r
168 //        else super.setValue(key, value);\r
169     }\r
170 \r
171     @Override\r
172     public void initValues() {\r
173         dynamicShape = null;\r
174         dynamicStroke = null;\r
175         dynamicColor = null;\r
176         dynamicFill = null;\r
177         dynamicScaleStroke = null;\r
178         dynamicScaleShape = null;\r
179     }\r
180 \r
181     @Override\r
182     public String toString() {\r
183         return super.toString() + " [shape=" + shape + ",color=" + color + "]";\r
184     }\r
185
186 }