1 package org.simantics.district.network.ui.adapters;
5 import java.awt.geom.AffineTransform;
6 import java.awt.geom.Rectangle2D;
8 import org.simantics.diagram.elements.DiagramNodeUtil;
9 import org.simantics.district.network.ui.nodes.DistrictNetworkVertexNode;
10 import org.simantics.g2d.canvas.Hints;
11 import org.simantics.g2d.canvas.ICanvasContext;
12 import org.simantics.g2d.diagram.handler.PickRequest.PickPolicy;
13 import org.simantics.g2d.element.ElementClass;
14 import org.simantics.g2d.element.ElementUtils;
15 import org.simantics.g2d.element.IElement;
16 import org.simantics.g2d.element.SceneGraphNodeKey;
17 import org.simantics.g2d.element.handler.InternalSize;
18 import org.simantics.g2d.element.handler.Pick;
19 import org.simantics.g2d.element.handler.SceneGraph;
20 import org.simantics.g2d.element.handler.impl.DefaultTransform;
21 import org.simantics.g2d.element.handler.impl.SimpleElementLayers;
22 import org.simantics.scenegraph.INode;
23 import org.simantics.scenegraph.g2d.G2DParentNode;
24 import org.simantics.scenegraph.g2d.nodes.SVGNode;
25 import org.simantics.utils.datastructures.hints.IHintContext.Key;
26 import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;
28 public class DistrictNetworkVertexElement {
30 public static final Key KEY_DN_VERTEX = new KeyOf(DistrictNetworkVertex.class, "DN_VERTEX");
31 public static final Key KEY_DN_VERTEX_NODE = new SceneGraphNodeKey(DistrictNetworkVertexNode.class, "DN_VERTEX_NODE");
32 public static final Key KEY_DN_VERTEX_SYMBOL_NODE = new SceneGraphNodeKey(SVGNode.class, "DN_VERTEX_SYMBOL_NODE");
34 public static final ElementClass CLASS =
36 DefaultTransform.INSTANCE,
37 DNVertexInternalSize.INSTANCE,
38 DNVertexSceneGraph.INSTANCE,
39 SimpleElementLayers.INSTANCE,
40 DistrictNetworkAdditionalColor.INSTANCE
41 ).setId(DistrictNetworkVertexElement.class.getSimpleName());
43 static final class DNVertexSceneGraph implements SceneGraph {
45 public static final DNVertexSceneGraph INSTANCE = new DNVertexSceneGraph();
47 private static final long serialVersionUID = 8894367073815556871L;
50 public void init(IElement vertexElement, G2DParentNode parent) {
51 DistrictNetworkVertex vertex = vertexElement.getHint(KEY_DN_VERTEX);
53 cleanup(vertexElement);
55 DistrictNetworkVertexNode node = vertexElement.getHint(KEY_DN_VERTEX_NODE);
57 node = parent.addNode(ElementUtils.generateNodeId(vertexElement), DistrictNetworkVertexNode.class);
58 vertexElement.setHint(KEY_DN_VERTEX_NODE, node);
60 SVGNode symbol = node.addNode(ElementUtils.generateNodeId(vertexElement), SVGNode.class);
61 vertexElement.setHint(KEY_DN_VERTEX_SYMBOL_NODE, symbol);
64 node.setVertex(vertex);
66 node.setColor(ElementUtils.getAdditionalColor(vertexElement, Color.BLUE));
68 AffineTransform at = ElementUtils.getTransform(vertexElement);
70 node.setTransform(at);
75 public void cleanup(IElement edge) {
76 ElementUtils.removePossibleNode(edge, KEY_DN_VERTEX_SYMBOL_NODE);
77 INode node = ElementUtils.removePossibleNode(edge, KEY_DN_VERTEX_NODE);
79 node.getParent().remove();
81 edge.removeHint(KEY_DN_VERTEX_NODE);
82 edge.removeHint(KEY_DN_VERTEX_SYMBOL_NODE);
86 static final class DNVertexInternalSize implements InternalSize, Pick {
88 public static final DNVertexInternalSize INSTANCE = new DNVertexInternalSize();
90 private static final long serialVersionUID = 2625702114278956461L;
93 public Rectangle2D getBounds(IElement e, Rectangle2D size) {
94 DistrictNetworkVertexNode node = e.getHint(KEY_DN_VERTEX_NODE);
95 Rectangle2D boundsInLocal = node.getBoundsInLocal();
96 ICanvasContext ctx = DiagramNodeUtil.getCanvasContext(node);
97 AffineTransform canvasTransform = ctx.getHintStack().getHint(Hints.KEY_CANVAS_TRANSFORM);
98 // for some reason PickContextImpl expands the rectangle by 0.001 (too much) - let's counter it
99 double x = boundsInLocal.getX();
100 double y = boundsInLocal.getY();
101 double scaledWidth = boundsInLocal.getWidth();
102 double scaledHeight = boundsInLocal.getHeight();
103 if (canvasTransform != null) {
104 scaledWidth = boundsInLocal.getWidth() / canvasTransform.getScaleX();
105 scaledHeight= boundsInLocal.getHeight() / canvasTransform.getScaleY();
107 double width = scaledWidth;
108 double height = scaledHeight;
109 size.setFrame(x, y, width, height);
115 public boolean pickTest(IElement e, Shape s, PickPolicy policy) {
116 DistrictNetworkVertexNode node = e.getHint(KEY_DN_VERTEX_NODE);
117 Rectangle2D boundsInLocal = node.getBounds();
118 ICanvasContext ctx = DiagramNodeUtil.getCanvasContext(node);
119 AffineTransform canvasTransform = ctx.getHintStack().getHint(Hints.KEY_CANVAS_TRANSFORM);
120 Rectangle2D scaledBounds = new Rectangle2D.Double(boundsInLocal.getX(), boundsInLocal.getY(), boundsInLocal.getWidth() / canvasTransform.getScaleX() * 2, boundsInLocal.getHeight() / canvasTransform.getScaleY() * 2);
121 Rectangle2D bounds = getBounds(s);
123 case PICK_CONTAINED_OBJECTS:
124 return org.simantics.g2d.utils.GeometryUtils.contains(bounds, boundsInLocal);
125 case PICK_INTERSECTING_OBJECTS:
126 return org.simantics.g2d.utils.GeometryUtils.intersects(boundsInLocal, bounds);
131 private Rectangle2D getBounds(Shape shape) {
132 if (shape instanceof Rectangle2D)
133 return (Rectangle2D) shape;
134 return shape.getBounds2D();