]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scenegraph.swing/src/org/simantics/scenegraph/swing/SymbolMonitorClass.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.scenegraph.swing / src / org / simantics / scenegraph / swing / SymbolMonitorClass.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.scenegraph.swing;
13
14 import java.awt.Rectangle;
15 import java.awt.Shape;
16 import java.awt.geom.AffineTransform;
17 import java.awt.geom.Path2D;
18 import java.awt.geom.Rectangle2D;
19 import java.util.Collection;
20 import java.util.EnumSet;
21 import java.util.Map;
22
23 import org.simantics.g2d.element.ElementClass;
24 import org.simantics.g2d.element.ElementHints;
25 import org.simantics.g2d.element.IElement;
26 import org.simantics.g2d.element.SceneGraphNodeKey;
27 import org.simantics.g2d.element.handler.ElementHandler;
28 import org.simantics.g2d.element.handler.InternalSize;
29 import org.simantics.g2d.element.handler.Outline;
30 import org.simantics.g2d.element.handler.SceneGraph;
31 import org.simantics.g2d.element.handler.StaticSymbol;
32 import org.simantics.g2d.element.handler.Transform;
33 import org.simantics.g2d.element.handler.impl.SimpleElementLayers;
34 import org.simantics.g2d.element.handler.impl.StaticSymbolImpl;
35 import org.simantics.g2d.elementclass.MonitorHandler;
36 import org.simantics.g2d.image.Image;
37 import org.simantics.g2d.image.ProviderUtils;
38 import org.simantics.g2d.image.impl.AbstractImage;
39 import org.simantics.scenegraph.Node;
40 import org.simantics.scenegraph.g2d.G2DParentNode;
41 import org.simantics.utils.datastructures.cache.IFactory;
42 import org.simantics.utils.datastructures.cache.IProvider;
43 import org.simantics.utils.datastructures.cache.ProvisionException;
44 import org.simantics.utils.datastructures.hints.IHintContext.Key;
45
46 /**
47  * @author Tuukka Lehtonen
48  */
49 public class SymbolMonitorClass {
50
51     public static final Key  KEY_SG_NODE             = new SceneGraphNodeKey(Node.class, "SYMBOL_MONITOR_SG_NODE");
52
53     public static class MonitorHandlerImpl implements MonitorHandler {
54         private static final long          serialVersionUID = -4258875745321808416L;
55         public static final MonitorHandler INSTANCE         = new MonitorHandlerImpl();
56     }
57
58     public static void update(IElement e) {
59         SymbolMonitorSGNode node = e.getElementClass().getAtMostOneItemOfClass(SymbolMonitorSGNode.class);
60         node.update(e);
61     }
62
63     public static void cleanup(IElement e) {
64         SymbolMonitorSGNode node = e.getElementClass().getAtMostOneItemOfClass(SymbolMonitorSGNode.class);
65         node.cleanup(e);
66     }
67
68     static final Rectangle2D DEFAULT_BOX = new Rectangle2D.Double(0, 0, 0, 0);
69
70     static Shape createMonitor(IElement e) {
71
72         return DEFAULT_BOX;
73
74     }
75
76     static Path2D makePath(double x, double y, double w, double h) {
77         Path2D path = new Path2D.Double();
78         path.moveTo(x, y);
79         path.lineTo(x+w, y);
80         path.lineTo(x+w, y+h);
81         path.lineTo(x, y+h);
82         path.closePath();
83         return path;
84     }
85
86     public static final Shape BOX_SHAPE = new Rectangle(-1, -1, 2, 2);
87
88     public static class SymbolMonitorSGNode implements SceneGraph, InternalSize, Outline {
89
90         private static final long serialVersionUID = -106278359626957687L;
91
92         static final SymbolMonitorSGNode INSTANCE = new SymbolMonitorSGNode();
93
94         @Override
95         public void init(final IElement e, final G2DParentNode parent) {
96             // Create node if it doesn't exist yet
97             SymbolMonitorNode node = (SymbolMonitorNode)e.getHint(KEY_SG_NODE);
98             if(node == null || node.getBounds() == null || node.getParent() != parent) {
99                 // FIXME : symbol monitor node is not disposed properly, so currently this code is commented out.
100                 //node = parent.addNode(ElementUtils.generateNodeId(e), SymbolMonitorNode.class);
101                 //e.setHint(KEY_SG_NODE, node);
102             }
103             update(e);
104         }
105
106         public void update(IElement e) {
107         }
108
109         @Override
110         public void cleanup(IElement e) {
111             SymbolMonitorNode node = (SymbolMonitorNode)e.removeHint(KEY_SG_NODE);
112             if (node != null)
113                 node.remove();
114         }
115
116         @Override
117         public Rectangle2D getBounds(IElement e, Rectangle2D size) {
118             Rectangle2D shape = new Rectangle2D.Double(0, 0, 0, 0);
119
120             SymbolMonitorNode node = (SymbolMonitorNode)e.getHint(KEY_SG_NODE);
121             if(node != null && node.getBounds() != null) {
122                 shape = node.getBounds().getBounds2D();
123             }
124
125             if(size != null) size.setRect(shape);
126             return shape;
127         }
128
129         @Override
130         public Shape getElementShape(IElement e) {
131             Shape shape = new Rectangle2D.Double(0, 0, 0, 0);
132
133             SymbolMonitorNode node = (SymbolMonitorNode)e.getHint(KEY_SG_NODE);
134             if(node != null && node.getBounds() != null) {
135                 shape = node.getBounds();
136             }
137
138             return shape;
139         }
140
141     }
142
143     public static class Transformer implements Transform {
144
145         private static final long serialVersionUID = -3704887325602085677L;
146
147         public static final Transformer INSTANCE = new Transformer(null);
148
149         Double aspectRatio;
150
151         public Transformer() {
152             this(null);
153         }
154
155         public Transformer(Double aspectRatio) {
156             this.aspectRatio = aspectRatio;
157         }
158
159         @Override
160         public AffineTransform getTransform(IElement e) {
161             AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM);
162
163             IElement parentElement = e.getHint(ElementHints.KEY_PARENT_ELEMENT);
164             if (parentElement == null)
165                 return at;
166
167             Transform parentTransform = parentElement.getElementClass().getSingleItem(Transform.class);
168             assert(parentTransform!=null);
169
170             AffineTransform result = (AffineTransform)at.clone();
171             result.preConcatenate(parentTransform.getTransform(parentElement));
172
173             return result;
174         }
175
176         @Override
177         public void setTransform(IElement e, AffineTransform at) {
178             e.setHint(ElementHints.KEY_TRANSFORM, at.clone());
179         }
180
181     }
182
183     static class MonitorImageFactory implements IFactory<Image> {
184
185         private double staticScaleX = 1, staticScaleY = 1;
186
187         public MonitorImageFactory(double staticScaleX, double staticScaleY) {
188             this.staticScaleX = staticScaleX;
189             this.staticScaleY = staticScaleY;
190         }
191
192         @Override
193         public Image get() throws ProvisionException {
194
195             return new AbstractImage() {
196
197                 Shape path = BOX_SHAPE;
198
199                 @Override
200                 public Rectangle2D getBounds() {
201                     return path.getBounds2D();
202                 }
203
204                 @Override
205                 public EnumSet<Feature> getFeatures() {
206                     return EnumSet.of(Feature.Vector);
207                 }
208
209                 @Override
210                 public Shape getOutline() {
211                     return path;
212                 }
213
214                 @Override
215                 public Node init(G2DParentNode parent) {
216                     SymbolMonitorNode node = parent.getOrCreateNode(""+hashCode(), SymbolMonitorNode.class);
217                     node.setText("");
218                     node.setBounds(new Rectangle2D.Double(0, 0, 50, 22));
219                     node.setText("Drop Me");
220                     node.setTransform(AffineTransform.getScaleInstance(staticScaleX, staticScaleY));
221                     return node;
222                 }
223             };
224         }
225     }
226
227     static final IProvider<Image> MONITOR_IMAGE =
228         ProviderUtils.reference(
229                 ProviderUtils.cache(
230                         ProviderUtils.rasterize(
231                                 new MonitorImageFactory(0.5, 0.5)
232                         )));
233
234     static final StaticSymbol MONITOR_SYMBOL = new StaticSymbolImpl( MONITOR_IMAGE.get() );
235
236     public static final ElementClass MONITOR_CLASS =
237         ElementClass.compile(
238                 MonitorHandlerImpl.INSTANCE,
239                 Transformer.INSTANCE,
240                 SymbolMonitorSGNode.INSTANCE,
241                 SimpleElementLayers.INSTANCE,
242                 MONITOR_SYMBOL
243         );
244
245     // staticScale{X,Y} define the scale of the static monitor image
246     public static ElementClass create(IElement parentElement, Map<String, String> substitutions, Collection<Object> path, double staticScaleX, double staticScaleY, ElementHandler... extraHandlers) {
247         // Bit of a hack to be able to define the scale
248         IProvider<Image> staticMonitorSymbolProvider = ProviderUtils.reference(
249                 ProviderUtils.cache(
250                         ProviderUtils
251                         .rasterize(
252                                 new MonitorImageFactory(staticScaleX, staticScaleY))));
253         StaticSymbol staticMonitorSymbol = new StaticSymbolImpl( staticMonitorSymbolProvider.get() );
254         return ElementClass.compile(
255                 MonitorHandlerImpl.INSTANCE,
256                 Transformer.INSTANCE,
257                 SymbolMonitorSGNode.INSTANCE,
258                 SimpleElementLayers.INSTANCE,
259                 staticMonitorSymbol
260         ).newClassWith(extraHandlers);
261     }
262
263 }