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
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.g2d.elementclass;
\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
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
49 * @author Tuukka Lehtonen
\r
51 public class BranchPointClass {
\r
53 private static final Key KEY_DIRECTION = new KeyOf(BranchPoint.Direction.class, "BRANCH_POINT_DIRECTION");
\r
55 private static final BranchPoint BRANCH_POINT = new BranchPoint() {
\r
56 private static final long serialVersionUID = 8529882246314074853L;
\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
65 public void setDirectionPreference(IElement e, Direction value) {
\r
67 e.removeHint(KEY_DIRECTION);
\r
69 e.setHint(KEY_DIRECTION, value);
\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
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
80 private final Collection<Topology.Connection> connections = new ArrayList<Topology.Connection>();
\r
83 public Shape getTerminalShape(IElement e, Terminal t) {
\r
84 IDiagram d = ElementUtils.peekDiagram(e);
\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
94 return BranchPointNode.SHAPE;
\r
97 return BranchPointNode.SHAPE2;
\r
102 private static final ImageElementHandler DEFAULT_IMAGE_ELEMENT_HANDLER = new ImageElementHandler() {
\r
104 private static final long serialVersionUID = 68445770951872084L;
\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
114 Transform transform = e.getElementClass().getSingleItem(Transform.class);
\r
115 AffineTransform at = transform.getTransform(e);
\r
117 node.setTransform((AffineTransform) at.clone());
\r
119 node.setDegree( getDegree(e) );
\r
120 node.setDirection( getDirection(e) );
\r
123 private byte getDirection(IElement e) {
\r
124 return (byte) ElementUtils.getHintOrDefault(e, KEY_DIRECTION, Direction.Any).ordinal();
\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
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
143 public void cleanup(IElement e) {
\r
144 e.removeHint(KEY_SG_NODE);
\r
148 public static final ElementClass CLASS = ElementClass.compile(
\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
157 SimpleElementLayers.INSTANCE,
\r
159 ).setId(BranchPointClass.class.getSimpleName());
\r