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