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
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.scenegraph.g2d.nodes;
\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
25 import org.simantics.scenegraph.g2d.G2DNode;
\r
26 import org.simantics.scenegraph.utils.InitValueSupport;
\r
28 public class EdgeNode extends G2DNode implements InitValueSupport {
\r
30 private static final long serialVersionUID = 1294351381209071074L;
\r
32 public static enum ArrowType { None, Stroke, Fill, Both }
\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
48 private transient Rectangle2D bounds;
\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
53 this.stroke = stroke;
\r
55 this.firstdir = firstdir;
\r
56 this.lastdir = lastdir;
\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
66 if (shape != null) {
\r
67 this.bounds = shape.getBounds2D();
\r
72 public void render(Graphics2D g) {
\r
73 if(color != null) g.setColor(color);
\r
74 if(stroke == null || shape == null) return;
\r
76 if(alphaComposite != null) {
\r
77 g.setComposite(alphaComposite);
\r
80 Stroke effectiveStroke = stroke;
\r
81 if(dynamicStroke != null) {
\r
82 effectiveStroke = dynamicStroke;
\r
85 Color effectiveColor = color;
\r
86 if(dynamicColor != null) {
\r
87 effectiveColor = dynamicColor;
\r
90 g.setStroke(effectiveStroke);
\r
93 //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
\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
105 g.setColor(effectiveColor);
\r
106 g.setStroke(effectiveStroke);
\r
109 // Draw line ends if necessary.
\r
110 boolean drawArrows = first_at != ArrowType.None || last_at != ArrowType.None;
\r
114 AffineTransform at = g.getTransform();
\r
116 g.setStroke(ARROW_STROKE);
\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
122 g.scale(firstsize, firstsize);
\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
129 g.setTransform(at);
\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
136 g.scale(lastsize, lastsize);
\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
143 g.setTransform(at);
\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
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
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
166 public Rectangle2D getBoundsInLocal() {
\r
170 protected Composite alphaComposite = null;
\r
171 protected Stroke dynamicStroke = null;
\r
172 protected Color dynamicColor = null;
\r
174 @PropertySetter("alpha")
\r
175 @SyncField("alphaComposite")
\r
176 public void setAlphaComposite(Composite alphaComposite) {
\r
177 this.alphaComposite = alphaComposite;
\r
180 @PropertySetter("width")
\r
181 @SyncField("dynamicStroke")
\r
182 public void setDynamicStroke(Stroke stroke) {
\r
183 this.dynamicStroke = stroke;
\r
186 @PropertySetter("color")
\r
187 @SyncField("dynamicColor")
\r
188 public void setDynamicColor(Color color) {
\r
189 this.dynamicColor = color;
\r
192 // public void setValue(String key, Object value) {
\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
201 // dynamicColor = new Color(Integer.parseInt(value.toString(), 16));
\r
202 // } catch (Throwable t) {
\r
203 // t.printStackTrace();
\r
209 public void initValues() {
\r
210 dynamicStroke = null;
\r
211 dynamicColor = null;
\r
212 alphaComposite = null;
\r