]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram/src/org/simantics/diagram/elements/ResizeRectangularSceneGraph.java
Merge "(refs #7519) Added old constructor back to ConnectionVisuals."
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / elements / ResizeRectangularSceneGraph.java
1 package org.simantics.diagram.elements;
2
3 import java.awt.BasicStroke;
4 import java.awt.geom.AffineTransform;
5 import java.awt.geom.Rectangle2D;
6 import java.util.Map;
7
8 import org.simantics.diagram.elements.ResizeNode.ResizeListener;
9 import org.simantics.diagram.elements.ResizeNode.TranslateEdge;
10 import org.simantics.g2d.canvas.Hints;
11 import org.simantics.g2d.diagram.DiagramUtils;
12 import org.simantics.g2d.diagram.IDiagram;
13 import org.simantics.g2d.element.ElementHints;
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.PropertySetter;
18 import org.simantics.g2d.element.handler.SceneGraph;
19 import org.simantics.scenegraph.g2d.G2DNode;
20 import org.simantics.scenegraph.g2d.G2DParentNode;
21 import org.simantics.utils.datastructures.hints.IHintContext.Key;
22
23 /**
24  * Scenegraph for resizing rectangular elements. Contains an invisible ResizeNode and 
25  * handlers for setting bounds and transforms according to resize commands.
26  * 
27  * @author Teemu Lempinen
28  *
29  */
30 public class ResizeRectangularSceneGraph implements SceneGraph {
31
32         private static final long serialVersionUID = -972741261034892976L;
33
34         public static final ResizeRectangularSceneGraph INSTANCE = new ResizeRectangularSceneGraph();
35
36         public static final Key KEY_SG_NODE = new SceneGraphNodeKey(ResizeNode.class, "RESIZE_RECTANGULAR_SG_NODE");
37
38         private Key resizedNodeKey;
39         private Key transformKey;
40         private Key boundsKey;
41         private TranslateEdge xTranslateEdge;
42         private TranslateEdge yTranslateEdge;
43         
44         
45         public ResizeRectangularSceneGraph() {
46             this(null);
47         }
48         
49         public ResizeRectangularSceneGraph(Key sgNode) {
50             this(sgNode, TranslateEdge.WEST, TranslateEdge.NORTH, ElementHints.KEY_TRANSFORM, ElementHints.KEY_BOUNDS);
51         }
52         
53     public ResizeRectangularSceneGraph(Key sgNode, TranslateEdge xTranslateEdge, TranslateEdge yTranslateEdge, Key transformKey, Key boundsKey) {
54         this.resizedNodeKey = sgNode; 
55         this.xTranslateEdge = xTranslateEdge;
56         this.yTranslateEdge = yTranslateEdge;
57         this.transformKey = transformKey;
58         this.boundsKey = boundsKey;
59     }
60
61         @Override
62         public void init(final IElement e, G2DParentNode parent) {
63             
64             if(!ElementUtils.getHintOrDefault(e, ElementHints.KEY_RESIZABLE, false))
65                 return;
66                 
67                 ResizeNode node = (ResizeNode) e.getHint(KEY_SG_NODE);
68                 if (node == null) {
69                         node = parent.addNode(ResizeNode.class);
70                         
71                         e.setHint(KEY_SG_NODE, node);
72
73                         node.setStroke(new BasicStroke(1f));
74                         node.setZIndex(-1500);
75
76                         // Add a resize listener for updating bounds and transform information to graph after resizing
77                         node.setResizeListener(new ResizeListener() {
78
79                                 @Override
80                                 public void elementResized(Rectangle2D newBounds, AffineTransform transform, boolean synchronizeToBackend) {
81                                         Map<Key, Object> hints = e.getHints();
82                                         AffineTransform at = new AffineTransform((AffineTransform) hints.get(transformKey));
83                                         at.concatenate(transform);
84                                         hints.put(transformKey, at);
85                                         hints.put(boundsKey, newBounds);
86                                         hints.put(Hints.KEY_DIRTY, Hints.VALUE_SG_DIRTY);
87                                         e.setHints(hints);
88                                         if(synchronizeToBackend) {
89                                                 IDiagram diagram = ElementUtils.getDiagram(e);
90                                                 DiagramUtils.synchronizeHintsToBackend(diagram, e);
91                                         }
92                                 }
93                         });
94                 }
95
96                 if(node != null) {
97                     node.setxTranslateEdge(xTranslateEdge);
98                     node.setYTranslateEdge(yTranslateEdge);
99                     
100                     AffineTransform at = ElementUtils.getTransform(e);
101                     Rectangle2D b = null; //= (Rectangle2D)e.getHint(ElementHints.KEY_BOUNDS);
102                     
103                     if(b == null) {
104                         if(resizedNodeKey != null) {
105                             Object resizedNode = e.getHint(resizedNodeKey);
106                             if(resizedNode != null && resizedNode instanceof G2DNode) {
107                                 G2DNode n = (G2DNode)resizedNode;
108                                 b = n.getBoundsInLocal();
109                                 AffineTransform nodeTransform = n.getTransform();
110                                 at = new AffineTransform(nodeTransform);
111                             }
112                         }
113                     }
114                     
115                     if(b == null)
116                         b = ElementUtils.getElementBounds(e);
117                     
118                     Rectangle2D bounds = new Rectangle2D.Double(b.getX(), b.getY(), b.getWidth(), b.getHeight()); 
119                     
120                     node.setBounds(bounds);
121                     
122                     if(at != null)
123                         node.setTransform(at);
124                 }
125                 
126                 update(e);
127         }
128         
129         public void update(IElement e) {
130                 PropertySetter setter = e.getElementClass().getSingleItem(PropertySetter.class);
131                 setter.syncPropertiesToNode(e);
132         }
133
134         @Override
135         public void cleanup(IElement e) {
136                 ElementUtils.removePossibleNode(e, KEY_SG_NODE);
137         }
138         
139         
140         /**
141          * Set the edge for X-axis translation. If this edge
142          * is dragged during resize, the x-translation for
143          * axis is also changed keeping the other edge in place.
144          * 
145          * @param xTranslateEdge TranslateEdge NONE, EAST or WEST
146          */
147         public void setXTranslateEdge(TranslateEdge xTranslateEdge) {
148             this.xTranslateEdge = xTranslateEdge;
149         }
150         
151         /**
152      * Set the edge for Y-axis translation. If this edge
153      * is dragged during resize, the y-translation for
154      * axis is also changed keeping the other edge in place.
155      * 
156      * @param xTranslateEdge TranslateEdge NONE, NORTH or SOUTH
157      */
158     public void setYTranslateEdge(TranslateEdge yTranslateEdge) {
159         this.yTranslateEdge = yTranslateEdge;
160     }
161
162 }