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