]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.g2d/src/org/simantics/g2d/elementclass/BranchPointClass.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / elementclass / BranchPointClass.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.g2d.elementclass;\r
13 \r
14 import java.awt.Color;\r
15 import java.awt.Shape;\r
16 import java.awt.geom.AffineTransform;\r
17 import java.util.ArrayList;\r
18 import java.util.Collection;\r
19 import java.util.Collections;\r
20 \r
21 import org.simantics.g2d.diagram.IDiagram;\r
22 import org.simantics.g2d.diagram.handler.Topology;\r
23 import org.simantics.g2d.diagram.handler.Topology.Terminal;\r
24 import org.simantics.g2d.element.ElementClass;\r
25 import org.simantics.g2d.element.ElementUtils;\r
26 import org.simantics.g2d.element.IElement;\r
27 import org.simantics.g2d.element.handler.Transform;\r
28 import org.simantics.g2d.element.handler.impl.BranchPointTerminal;\r
29 import org.simantics.g2d.element.handler.impl.DefaultTransform;\r
30 import org.simantics.g2d.element.handler.impl.ObjectTerminal;\r
31 import org.simantics.g2d.element.handler.impl.OutlinePick;\r
32 import org.simantics.g2d.element.handler.impl.ParentImpl;\r
33 import org.simantics.g2d.element.handler.impl.SimpleElementLayers;\r
34 import org.simantics.g2d.element.handler.impl.StaticSymbolImageInitializer;\r
35 import org.simantics.g2d.element.handler.impl.StaticSymbolImpl;\r
36 import org.simantics.g2d.element.handler.impl.Terminals;\r
37 import org.simantics.g2d.element.handler.impl.TextImpl;\r
38 import org.simantics.g2d.elementclass.BranchPoint.Direction;\r
39 import org.simantics.g2d.elementclass.ImageClass.ImageElementHandler;\r
40 import org.simantics.g2d.image.Image;\r
41 import org.simantics.g2d.image.impl.ShapeImage;\r
42 import org.simantics.g2d.utils.geom.DirectionSet;\r
43 import org.simantics.scenegraph.g2d.G2DParentNode;\r
44 import org.simantics.scenegraph.g2d.nodes.BranchPointNode;\r
45 import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
46 import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;\r
47 \r
48 /**\r
49  * @author Tuukka Lehtonen\r
50  */\r
51 public class BranchPointClass {\r
52 \r
53     private static final Key KEY_DIRECTION = new KeyOf(BranchPoint.Direction.class, "BRANCH_POINT_DIRECTION");\r
54 \r
55     private static final BranchPoint BRANCH_POINT = new BranchPoint() {\r
56         private static final long serialVersionUID = 8529882246314074853L;\r
57 \r
58         @Override\r
59         public Direction getDirectionPreference(IElement e, Direction defaultValue) {\r
60             Direction d = e.getHint(KEY_DIRECTION);\r
61             return d != null ? d : defaultValue;\r
62         }\r
63 \r
64         @Override\r
65         public void setDirectionPreference(IElement e, Direction value) {\r
66             if (value == null)\r
67                 e.removeHint(KEY_DIRECTION);\r
68             else\r
69                 e.setHint(KEY_DIRECTION, value);\r
70         }\r
71     };\r
72 \r
73     public static final Image DEFAULT_IMAGE = new ShapeImage(BranchPointNode.SHAPE, Color.BLACK, null, Image.VOLATILE_VECTOR);\r
74     public static final Image DEFAULT_IMAGE2 = new ShapeImage(BranchPointNode.SHAPE2, Color.LIGHT_GRAY, null, Image.VOLATILE_VECTOR);\r
75 \r
76     private static final ObjectTerminal TERMINAL = BranchPointTerminal.existingTerminal(new AffineTransform(), DirectionSet.ANY, DEFAULT_IMAGE.getOutline());\r
77     private static final Terminals TERMINALS = new Terminals( Collections.singletonList(TERMINAL) ) {\r
78         private static final long serialVersionUID = -6094665667025529239L;\r
79 \r
80         private final Collection<Topology.Connection> connections = new ArrayList<Topology.Connection>();\r
81 \r
82         @Override\r
83         public Shape getTerminalShape(IElement e, Terminal t) {\r
84             IDiagram d = ElementUtils.peekDiagram(e);\r
85             if (d == null)\r
86                 return null;\r
87             Topology topology = d.getDiagramClass().getAtMostOneItemOfClass(Topology.class);\r
88             // NOTE: this is thread-safe because painting is single-threaded\r
89             connections.clear();\r
90             topology.getConnections(e, TERMINAL, connections);\r
91             int degree = connections.size();\r
92             connections.clear();\r
93             if (degree > 2) {\r
94                 return BranchPointNode.SHAPE;\r
95             } else {\r
96                 //return null;\r
97                 return BranchPointNode.SHAPE2;\r
98             }\r
99         }\r
100     };\r
101 \r
102     private static final ImageElementHandler DEFAULT_IMAGE_ELEMENT_HANDLER = new ImageElementHandler() {\r
103 \r
104         private static final long serialVersionUID = 68445770951872084L;\r
105 \r
106         @Override\r
107         public void init(final IElement e, final G2DParentNode parent) {\r
108             BranchPointNode node = (BranchPointNode)e.getHint(KEY_SG_NODE);\r
109             if (node == null) {\r
110                 node = parent.addNode("bp_" + e.hashCode(), BranchPointNode.class);\r
111                 e.setHint(KEY_SG_NODE, node);\r
112             }\r
113 \r
114             Transform transform = e.getElementClass().getSingleItem(Transform.class);\r
115             AffineTransform at = transform.getTransform(e);\r
116             if (at != null)\r
117                 node.setTransform((AffineTransform) at.clone());\r
118 \r
119             node.setDegree( getDegree(e) );\r
120             node.setDirection( getDirection(e) );\r
121         }\r
122 \r
123         private byte getDirection(IElement e) {\r
124             return (byte) ElementUtils.getHintOrDefault(e, KEY_DIRECTION, Direction.Any).ordinal();\r
125         }\r
126 \r
127         private final Collection<Topology.Connection> connections = new ArrayList<Topology.Connection>();\r
128         private int getDegree(IElement e) {\r
129             IDiagram d = ElementUtils.peekDiagram(e);\r
130             if (d == null)\r
131                 return 0;\r
132 \r
133             Topology t = d.getDiagramClass().getAtMostOneItemOfClass(Topology.class);\r
134             // NOTE: this is thread-safe because painting is single-threaded\r
135             connections.clear();\r
136             t.getConnections(e, TERMINAL, connections);\r
137             int degree = connections.size();\r
138             connections.clear();\r
139             return degree;\r
140         }\r
141 \r
142         @Override\r
143         public void cleanup(IElement e) {\r
144             e.removeHint(KEY_SG_NODE);\r
145         }\r
146     };\r
147 \r
148     public static final ElementClass CLASS = ElementClass.compile(\r
149             TextImpl.INSTANCE,\r
150             ParentImpl.INSTANCE,\r
151             DefaultTransform.INSTANCE,\r
152             DEFAULT_IMAGE_ELEMENT_HANDLER,\r
153             OutlinePick.INSTANCE,\r
154             StaticSymbolImageInitializer.INSTANCE,\r
155             new StaticSymbolImpl(DEFAULT_IMAGE),\r
156             TERMINALS,\r
157             SimpleElementLayers.INSTANCE,\r
158             BRANCH_POINT\r
159     ).setId(BranchPointClass.class.getSimpleName());\r
160 \r
161 }