]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkVertexNode.java
Fixed regressions in box selection and element color function validation
[simantics/district.git] / org.simantics.district.network.ui / src / org / simantics / district / network / ui / nodes / DistrictNetworkVertexNode.java
1 package org.simantics.district.network.ui.nodes;
2
3 import java.awt.BasicStroke;
4 import java.awt.Color;
5 import java.awt.Graphics2D;
6 import java.awt.RenderingHints;
7 import java.awt.geom.AffineTransform;
8 import java.awt.geom.Point2D;
9 import java.awt.geom.Rectangle2D;
10
11 import org.simantics.district.network.ModelledCRS;
12 import org.simantics.district.network.ui.adapters.DistrictNetworkVertex;
13 import org.simantics.scenegraph.ISelectionPainterNode;
14 import org.simantics.scenegraph.g2d.G2DNode;
15 import org.simantics.scenegraph.utils.GeometryUtils;
16 import org.simantics.scenegraph.utils.NodeUtil;
17
18 public class DistrictNetworkVertexNode extends G2DNode implements ISelectionPainterNode {
19
20     //private static final Logger LOGGER = LoggerFactory.getLogger(DistrictNetworkVertexNode.class);
21
22     private static final long serialVersionUID = -2641639101400236719L;
23
24     private static final BasicStroke STROKE           = new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
25     private static final Color       SELECTION_COLOR  = new Color(255, 0, 255, 96);
26
27     private static final double left = -0.25;
28     private static final double top = -0.25;
29     private static final double width = 0.5;
30     private static final double height = 0.5;
31
32     private static final Rectangle2D NORMAL = new Rectangle2D.Double(left, top, width, height);
33     private static final Rectangle2D HOVERED = new Rectangle2D.Double(left * 3, top * 3, width * 3, height * 3);
34
35     private DistrictNetworkVertex vertex;
36
37     private boolean scaleStroke = true;
38     private boolean hover;
39
40     private Color color;
41     private transient Color dynamicColor;
42
43     private Rectangle2D bounds;
44     private transient Point2D point;
45     private transient Rectangle2D rect;
46
47     private double nodeSize = 1;
48
49     @Override
50     public void init() {
51         setZIndex(2);
52     }
53
54     @Override
55     public void render(Graphics2D g2d) {
56         if (nodeSize <= 0.0)
57             return;
58
59         AffineTransform ot = null;
60         AffineTransform t = getTransform();
61         if (t != null && !t.isIdentity()) {
62             ot = g2d.getTransform();
63             g2d.transform(getTransform());
64         }
65
66         Object oaaHint = null;
67         Object aaHint = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
68         if (aaHint != RenderingHints.VALUE_ANTIALIAS_OFF) {
69             oaaHint = aaHint;
70             g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
71         }
72
73         Color oldColor = g2d.getColor();
74         Color newColor = dynamicColor != null ? dynamicColor : color;
75         boolean changeColor = !oldColor.equals(newColor);
76
77         double viewScaleRecip = 1;
78         if (scaleStroke) {
79             double scale = GeometryUtils.getScale(g2d.getTransform());
80             scale = Math.max(10000, Math.min(scale, 50000));
81             viewScaleRecip = 1.0 / scale;
82         }
83         double scaleRecip = viewScaleRecip * nodeSize;
84
85         // Translate lat and lon to X and Y
86         Point2D p = point = calculatePoint2D(vertex, point);
87         Rectangle2D toDraw = calculateDrawnGeometry(p, hover ? HOVERED : NORMAL, rect, scaleRecip);
88
89         if (NodeUtil.isSelected(this, 1)) {
90             changeColor = true;
91             g2d.setColor(SELECTION_COLOR);
92             BasicStroke ss = GeometryUtils.scaleStroke(STROKE, (float) viewScaleRecip*5);
93             g2d.setStroke(ss);
94             g2d.draw(toDraw);
95         }
96
97         // render
98         if (changeColor)
99             g2d.setColor(newColor);
100         g2d.fill(toDraw);
101
102         // Reset settings
103         if (changeColor)
104             g2d.setColor(oldColor);
105         if (oaaHint != null)
106            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aaHint);
107         if (ot != null)
108             g2d.setTransform(ot);
109     }
110
111     private Rectangle2D calculateDrawnGeometry(Point2D p, Rectangle2D margin, Rectangle2D result, double scaleRecip) {
112         if (result == null)
113             result = new Rectangle2D.Double();
114         double mw = margin.getWidth();
115         double mh = margin.getHeight();
116         result.setFrame(p.getX() - (mw / 2 * scaleRecip), p.getY() - (mh / 2 * scaleRecip), mw * scaleRecip, mh * scaleRecip);
117         return result;
118     }
119
120     @Override
121     public Rectangle2D getBounds() {
122         return super.getBounds();
123     }
124
125     @Override
126     public Rectangle2D getBoundsInLocal() {
127         return bounds;
128     }
129
130     private void updateBounds() {
131         Rectangle2D oldBounds = bounds;
132         if (oldBounds == null)
133             oldBounds = new Rectangle2D.Double();
134         bounds = calculateBounds(oldBounds);
135     }
136
137     @Override
138     public void setTransform(AffineTransform transform) {
139         super.setTransform(transform);
140         // Update bounds
141         updateBounds();
142     }
143
144     @Override
145     public AffineTransform getTransform() {
146         return super.getTransform();
147     }
148
149     private Rectangle2D calculateBounds(Rectangle2D rect) {
150         Point2D calcPoint = calculatePoint2D(vertex, point);
151         AffineTransform at = getTransform();
152         return new Rectangle2D.Double(calcPoint.getX(), calcPoint.getY(), width / at.getScaleX(), height / at.getScaleY()).getBounds2D();
153     }
154
155     private static Point2D calculatePoint2D(DistrictNetworkVertex vertex, Point2D result) {
156         Point2D point = vertex.getPoint();
157         double x = ModelledCRS.longitudeToX(point.getX());
158         double y = ModelledCRS.latitudeToY(-point.getY()); // Inverse because Simantics Diagram is inverted
159         if (result == null)
160             result = new Point2D.Double(x, y);
161         else
162             result.setLocation(x, y);
163         return result;
164     }
165
166     public void setVertex(DistrictNetworkVertex vertex) {
167         this.vertex = vertex;
168         updateBounds();
169     }
170
171     public boolean hover(boolean hover) {
172 //        if (hover && LOGGER.isDebugEnabled())
173 //            LOGGER.debug("Hovering " + this);
174         boolean changed = false;
175         if (this.hover != hover) {
176             this.hover = hover;
177             changed = true;
178         }
179         return changed;
180     }
181
182     public void setColor(Color color) {
183         this.color = color;
184     }
185
186     public Color getColor() {
187         return color;
188     }
189
190     @PropertySetter(value = "size")
191     public void setSize(Double size) {
192         boolean changed = false;
193         if (size != null) {
194             changed = size != this.nodeSize;
195             this.nodeSize = size;
196         } else {
197             changed = this.nodeSize != 1.0;
198             this.nodeSize = 1.0;
199         }
200         if (changed)
201             updateBounds();
202     }
203
204     @PropertySetter(value = "dynamicColor")
205     public void setDynamicColor(Color color) {
206         this.dynamicColor = color;
207     }
208
209 }