]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/CompositeImage.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / adapter / CompositeImage.java
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
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.diagram.adapter;\r
13 \r
14 import java.awt.Shape;\r
15 import java.awt.geom.Rectangle2D;\r
16 import java.util.Collection;\r
17 import java.util.EnumSet;\r
18 import java.util.List;\r
19 \r
20 import org.simantics.g2d.element.ElementClass;\r
21 import org.simantics.g2d.element.ElementUtils;\r
22 import org.simantics.g2d.element.IElement;\r
23 import org.simantics.g2d.element.SceneGraphNodeKey;\r
24 import org.simantics.g2d.element.handler.SceneGraph;\r
25 import org.simantics.g2d.image.Image;\r
26 import org.simantics.scenegraph.Node;\r
27 import org.simantics.scenegraph.g2d.G2DParentNode;\r
28 import org.simantics.scenegraph.g2d.nodes.SingleElementNode;\r
29 import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
30 \r
31 /**\r
32  * Element Composition -> Image\r
33  *\r
34  * @author Toni Kalajainen <toni.kalajainen@vtt.fi>\r
35  */\r
36 public class CompositeImage implements Image {\r
37 \r
38     Collection<IElement> elements;\r
39     private Shape shape;\r
40     private Rectangle2D bounds;\r
41     //IHintContext parentHints;\r
42     static EnumSet<Feature> feats = VOLATILE_VECTOR;\r
43 \r
44     public static final Key  KEY_SG_NODE             = new SceneGraphNodeKey(Node.class, "COMPOSITE_IMAGE_SG_NODE");\r
45 \r
46     public CompositeImage(Collection<IElement> elements)\r
47     {\r
48         //this.nodeIdentifier = nodeIdentifier;\r
49         this.elements = elements;\r
50 //        ITask task = ThreadLogger.getInstance().begin("getElementShapesOnDiagram");\r
51         // getElementShapesOnDiagram is ridiculously slow with some input data..\r
52         // With Balas it took almost 2sec to calculate one Area.add() for the last terminal element.\r
53         //shape = ElementUtils.getElementShapesOnDiagram(elements);\r
54 //        shape = ElementUtils.getElementBoundsOnDiagram(elements);\r
55   //      task.finish();\r
56 //        bounds = shape.getBounds2D();\r
57     }\r
58 \r
59     @Override\r
60     public Rectangle2D getBounds() {\r
61         if(bounds == null) {\r
62             Shape shape = getShape();\r
63             // Shape may be null.\r
64             if (shape == null)\r
65                 return new Rectangle2D.Double();\r
66             bounds = shape.getBounds2D();\r
67         }\r
68         return bounds;\r
69     }\r
70 \r
71     @Override\r
72     public EnumSet<Feature> getFeatures() {\r
73         return feats;\r
74     }\r
75 \r
76     private final Shape getShape() {\r
77         if(shape == null) {\r
78             shape = ElementUtils.getElementBoundsOnDiagram(elements);\r
79         }\r
80         return shape;\r
81     }\r
82 \r
83     @Override\r
84     public Shape getOutline() {\r
85         return getShape();\r
86     }\r
87 \r
88     public Collection<IElement> getElements() {\r
89         return elements;\r
90     }\r
91 \r
92     @Override\r
93     public void addImageListener(ImageListener listener) {\r
94     }\r
95 \r
96     @Override\r
97     public void removeImageListener(ImageListener listener) {\r
98     }\r
99 \r
100 //    public void setParentHints(IHintContext hints) {\r
101 //        this.parentHints = hints;\r
102 //    }\r
103 \r
104     // Rendering is single-threaded, this is used while rendering.\r
105     Rectangle2D tempBounds = new Rectangle2D.Double(0, 0, 0, 0);\r
106 \r
107     @Override\r
108     public Node init(G2DParentNode parent) {\r
109         if (elements.size() < 2) {\r
110             // Optimization for 0..1 element composites\r
111             for (IElement e : elements) {\r
112                 ElementClass ec = e.getElementClass();\r
113                 G2DParentNode node = parent.getOrCreateNode("composite_image_"+this.hashCode(), G2DParentNode.class);\r
114                 List<SceneGraph> nodeHandlers = ec.getItemsByClass(SceneGraph.class);\r
115                 for (SceneGraph n : nodeHandlers) {\r
116 //                    n.init(e, parent);\r
117                     n.init(e, node);\r
118                 }\r
119                 return node; // Valid node must be returned because transform is set afterwards\r
120             }\r
121         }\r
122 \r
123         // For N element composites\r
124 \r
125         // Removed this grouping node as unnecessary, just use the given parent node\r
126         G2DParentNode node = parent.getOrCreateNode("composite_image_"+this.hashCode(), G2DParentNode.class);\r
127 \r
128 //        Rectangle2D bounds = tempBounds;\r
129 \r
130         int zIndex = 0;\r
131         for (IElement e : elements) {\r
132             ElementClass ec = e.getElementClass();\r
133 //            InternalSize size = ec.getSingleItem(InternalSize.class);\r
134 //            size.getBounds(e, bounds);\r
135 \r
136 //            Transform transform = e.getElementClass().getSingleItem(Transform.class);\r
137 //            AffineTransform at2 = transform.getTransform(e);\r
138 //            if (at2 == null)\r
139 //                continue;\r
140             SingleElementNode holder = node.getOrCreateNode(ElementUtils.generateNodeId(e), SingleElementNode.class);\r
141             //SingleElementNode holder = parent.getOrCreateNode(ElementUtils.generateNodeId(e), SingleElementNode.class);\r
142             holder.setZIndex(++zIndex);\r
143 \r
144             List<SceneGraph> nodeHandlers = ec.getItemsByClass(SceneGraph.class);\r
145             for(SceneGraph n : nodeHandlers) {\r
146                 n.init(e, holder);\r
147             }\r
148         }\r
149 \r
150         return node; // Valid node must be returned because transform is set afterwards\r
151     }\r
152 \r
153 //    public static class TypeProxyElement extends ProxyElement {\r
154 //        IHintContext instanceHints;\r
155 //        public TypeProxyElement(IElement orig, IHintContext instanceHints) {\r
156 //            super(orig);\r
157 //            this.instanceHints = instanceHints;\r
158 //        }\r
159 //        @Override\r
160 //        public <E> E getHint(Key key) {\r
161 //            // TODO: need some mechanism to tell whether it is allowed to look for this key in the instance hints or not\r
162 //            // This version is broken because some hints MUST come from the original element.\r
163 //            E e = null;\r
164 //            if (instanceHints != null)\r
165 //                e = instanceHints.getHint(key);\r
166 //            if (e == null)\r
167 //                e = orig.getHint(key);\r
168 //            return e;\r
169 //        }\r
170 //        @Override\r
171 //        public Map<Key, Object> getHints() {\r
172 //            throw new UnsupportedOperationException();\r
173 //        }\r
174 //        @Override\r
175 //        public <E extends Key> Map<E, Object> getHintsOfClass(Class<E> clazz) {\r
176 //            throw new UnsupportedOperationException();\r
177 //        }\r
178 //        @Override\r
179 //        public void setHint(Key key, Object value) {\r
180 //            if (instanceHints != null)\r
181 //                instanceHints.setHint(key, value);\r
182 //            else\r
183 //                orig.setHint(key, value);\r
184 //        }\r
185 //    }\r
186 \r
187 }\r