--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.g2d.elementclass;\r
+\r
+import java.awt.Color;\r
+import java.awt.Shape;\r
+import java.awt.geom.AffineTransform;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+\r
+import org.simantics.g2d.diagram.IDiagram;\r
+import org.simantics.g2d.diagram.handler.Topology;\r
+import org.simantics.g2d.diagram.handler.Topology.Terminal;\r
+import org.simantics.g2d.element.ElementClass;\r
+import org.simantics.g2d.element.ElementUtils;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.handler.Transform;\r
+import org.simantics.g2d.element.handler.impl.BranchPointTerminal;\r
+import org.simantics.g2d.element.handler.impl.DefaultTransform;\r
+import org.simantics.g2d.element.handler.impl.ObjectTerminal;\r
+import org.simantics.g2d.element.handler.impl.OutlinePick;\r
+import org.simantics.g2d.element.handler.impl.ParentImpl;\r
+import org.simantics.g2d.element.handler.impl.SimpleElementLayers;\r
+import org.simantics.g2d.element.handler.impl.StaticSymbolImageInitializer;\r
+import org.simantics.g2d.element.handler.impl.StaticSymbolImpl;\r
+import org.simantics.g2d.element.handler.impl.Terminals;\r
+import org.simantics.g2d.element.handler.impl.TextImpl;\r
+import org.simantics.g2d.elementclass.BranchPoint.Direction;\r
+import org.simantics.g2d.elementclass.ImageClass.ImageElementHandler;\r
+import org.simantics.g2d.image.Image;\r
+import org.simantics.g2d.image.impl.ShapeImage;\r
+import org.simantics.g2d.utils.geom.DirectionSet;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+import org.simantics.scenegraph.g2d.nodes.BranchPointNode;\r
+import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
+import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;\r
+\r
+/**\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class BranchPointClass {\r
+\r
+ private static final Key KEY_DIRECTION = new KeyOf(BranchPoint.Direction.class, "BRANCH_POINT_DIRECTION");\r
+\r
+ private static final BranchPoint BRANCH_POINT = new BranchPoint() {\r
+ private static final long serialVersionUID = 8529882246314074853L;\r
+\r
+ @Override\r
+ public Direction getDirectionPreference(IElement e, Direction defaultValue) {\r
+ Direction d = e.getHint(KEY_DIRECTION);\r
+ return d != null ? d : defaultValue;\r
+ }\r
+\r
+ @Override\r
+ public void setDirectionPreference(IElement e, Direction value) {\r
+ if (value == null)\r
+ e.removeHint(KEY_DIRECTION);\r
+ else\r
+ e.setHint(KEY_DIRECTION, value);\r
+ }\r
+ };\r
+\r
+ public static final Image DEFAULT_IMAGE = new ShapeImage(BranchPointNode.SHAPE, Color.BLACK, null, Image.VOLATILE_VECTOR);\r
+ public static final Image DEFAULT_IMAGE2 = new ShapeImage(BranchPointNode.SHAPE2, Color.LIGHT_GRAY, null, Image.VOLATILE_VECTOR);\r
+\r
+ private static final ObjectTerminal TERMINAL = BranchPointTerminal.existingTerminal(new AffineTransform(), DirectionSet.ANY, DEFAULT_IMAGE.getOutline());\r
+ private static final Terminals TERMINALS = new Terminals( Collections.singletonList(TERMINAL) ) {\r
+ private static final long serialVersionUID = -6094665667025529239L;\r
+\r
+ private final Collection<Topology.Connection> connections = new ArrayList<Topology.Connection>();\r
+\r
+ @Override\r
+ public Shape getTerminalShape(IElement e, Terminal t) {\r
+ IDiagram d = ElementUtils.peekDiagram(e);\r
+ if (d == null)\r
+ return null;\r
+ Topology topology = d.getDiagramClass().getAtMostOneItemOfClass(Topology.class);\r
+ // NOTE: this is thread-safe because painting is single-threaded\r
+ connections.clear();\r
+ topology.getConnections(e, TERMINAL, connections);\r
+ int degree = connections.size();\r
+ connections.clear();\r
+ if (degree > 2) {\r
+ return BranchPointNode.SHAPE;\r
+ } else {\r
+ //return null;\r
+ return BranchPointNode.SHAPE2;\r
+ }\r
+ }\r
+ };\r
+\r
+ private static final ImageElementHandler DEFAULT_IMAGE_ELEMENT_HANDLER = new ImageElementHandler() {\r
+\r
+ private static final long serialVersionUID = 68445770951872084L;\r
+\r
+ @Override\r
+ public void init(final IElement e, final G2DParentNode parent) {\r
+ BranchPointNode node = (BranchPointNode)e.getHint(KEY_SG_NODE);\r
+ if (node == null) {\r
+ node = parent.addNode("bp_" + e.hashCode(), BranchPointNode.class);\r
+ e.setHint(KEY_SG_NODE, node);\r
+ }\r
+\r
+ Transform transform = e.getElementClass().getSingleItem(Transform.class);\r
+ AffineTransform at = transform.getTransform(e);\r
+ if (at != null)\r
+ node.setTransform((AffineTransform) at.clone());\r
+\r
+ node.setDegree( getDegree(e) );\r
+ node.setDirection( getDirection(e) );\r
+ }\r
+\r
+ private byte getDirection(IElement e) {\r
+ return (byte) ElementUtils.getHintOrDefault(e, KEY_DIRECTION, Direction.Any).ordinal();\r
+ }\r
+\r
+ private final Collection<Topology.Connection> connections = new ArrayList<Topology.Connection>();\r
+ private int getDegree(IElement e) {\r
+ IDiagram d = ElementUtils.peekDiagram(e);\r
+ if (d == null)\r
+ return 0;\r
+\r
+ Topology t = d.getDiagramClass().getAtMostOneItemOfClass(Topology.class);\r
+ // NOTE: this is thread-safe because painting is single-threaded\r
+ connections.clear();\r
+ t.getConnections(e, TERMINAL, connections);\r
+ int degree = connections.size();\r
+ connections.clear();\r
+ return degree;\r
+ }\r
+\r
+ @Override\r
+ public void cleanup(IElement e) {\r
+ e.removeHint(KEY_SG_NODE);\r
+ }\r
+ };\r
+\r
+ public static final ElementClass CLASS = ElementClass.compile(\r
+ TextImpl.INSTANCE,\r
+ ParentImpl.INSTANCE,\r
+ DefaultTransform.INSTANCE,\r
+ DEFAULT_IMAGE_ELEMENT_HANDLER,\r
+ OutlinePick.INSTANCE,\r
+ StaticSymbolImageInitializer.INSTANCE,\r
+ new StaticSymbolImpl(DEFAULT_IMAGE),\r
+ TERMINALS,\r
+ SimpleElementLayers.INSTANCE,\r
+ BRANCH_POINT\r
+ ).setId(BranchPointClass.class.getSimpleName());\r
+\r
+}
\ No newline at end of file