1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
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
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.g2d.elementclass;
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;
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;
49 * @author Tuukka Lehtonen
51 public class BranchPointClass {
53 private static final Key KEY_DIRECTION = new KeyOf(BranchPoint.Direction.class, "BRANCH_POINT_DIRECTION");
55 private static final BranchPoint BRANCH_POINT = new BranchPoint() {
56 private static final long serialVersionUID = 8529882246314074853L;
59 public Direction getDirectionPreference(IElement e, Direction defaultValue) {
60 Direction d = e.getHint(KEY_DIRECTION);
61 return d != null ? d : defaultValue;
65 public void setDirectionPreference(IElement e, Direction value) {
67 e.removeHint(KEY_DIRECTION);
69 e.setHint(KEY_DIRECTION, value);
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);
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;
80 private final Collection<Topology.Connection> connections = new ArrayList<Topology.Connection>();
83 public Shape getTerminalShape(IElement e, Terminal t) {
84 IDiagram d = ElementUtils.peekDiagram(e);
87 Topology topology = d.getDiagramClass().getAtMostOneItemOfClass(Topology.class);
88 // NOTE: this is thread-safe because painting is single-threaded
90 topology.getConnections(e, TERMINAL, connections);
91 int degree = connections.size();
94 return BranchPointNode.SHAPE;
97 return BranchPointNode.SHAPE2;
102 private static final ImageElementHandler DEFAULT_IMAGE_ELEMENT_HANDLER = new ImageElementHandler() {
104 private static final long serialVersionUID = 68445770951872084L;
107 public void init(final IElement e, final G2DParentNode parent) {
108 BranchPointNode node = (BranchPointNode)e.getHint(KEY_SG_NODE);
110 node = parent.addNode("bp_" + e.hashCode(), BranchPointNode.class);
111 e.setHint(KEY_SG_NODE, node);
114 Transform transform = e.getElementClass().getSingleItem(Transform.class);
115 AffineTransform at = transform.getTransform(e);
117 node.setTransform((AffineTransform) at.clone());
119 node.setDegree( getDegree(e) );
120 node.setDirection( getDirection(e) );
123 private byte getDirection(IElement e) {
124 return (byte) ElementUtils.getHintOrDefault(e, KEY_DIRECTION, Direction.Any).ordinal();
127 private final Collection<Topology.Connection> connections = new ArrayList<Topology.Connection>();
128 private int getDegree(IElement e) {
129 IDiagram d = ElementUtils.peekDiagram(e);
133 Topology t = d.getDiagramClass().getAtMostOneItemOfClass(Topology.class);
134 // NOTE: this is thread-safe because painting is single-threaded
136 t.getConnections(e, TERMINAL, connections);
137 int degree = connections.size();
143 public void cleanup(IElement e) {
144 e.removeHint(KEY_SG_NODE);
148 public static final ElementClass CLASS = ElementClass.compile(
151 DefaultTransform.INSTANCE,
152 DEFAULT_IMAGE_ELEMENT_HANDLER,
153 OutlinePick.INSTANCE,
154 StaticSymbolImageInitializer.INSTANCE,
155 new StaticSymbolImpl(DEFAULT_IMAGE),
157 SimpleElementLayers.INSTANCE,
159 ).setId(BranchPointClass.class.getSimpleName());