/******************************************************************************* * 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.modeling.ui.diagram.style; import java.awt.Color; import java.awt.Font; import java.awt.geom.AffineTransform; import org.simantics.databoard.Bindings; import org.simantics.datatypes.literal.Vec2d; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.variable.Variable; import org.simantics.diagram.elements.TextNode; import org.simantics.diagram.profile.StyleBase; import org.simantics.diagram.synchronization.graph.DiagramGraphUtil; import org.simantics.g2d.utils.Alignment; import org.simantics.layer0.Layer0; import org.simantics.modeling.ModelingResources; import org.simantics.scenegraph.INode; import org.simantics.scenegraph.g2d.IG2DNode; import org.simantics.scenegraph.g2d.nodes.SingleElementNode; import org.simantics.scenegraph.profile.EvaluationContext; import org.simantics.scenegraph.profile.common.ProfileVariables; import org.simantics.scenegraph.utils.NodeUtil; import org.simantics.utils.datastructures.map.Tuple; /** * @author Tuukka Lehtonen */ public class SymbolTerminalNameStyle extends StyleBase { static final Font FONT = Font.decode("Arial 6"); //$NON-NLS-1$ private static final String NODE_NAME = "terminalName"; //$NON-NLS-1$ /** * Must override the StyleBase implementation because terminals do not * depend on runtime variable. They need to be shown regardless of variable * existence. */ @Override public SymbolNameResult calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException { return calculateStyle(graph, runtimeDiagram, entry, groupItem, null); } @Override public SymbolNameResult calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource element, Variable configuration) throws DatabaseException { AffineTransform transform = DiagramGraphUtil.getAffineTransform(graph, element); Layer0 L0 = Layer0.getInstance(graph); ModelingResources MOD = ModelingResources.getInstance(graph); Resource binds = DiagramGraphUtil.getPossibleConnectionPointOfTerminal(graph, element); if (binds == null) return null; Resource conn = graph.getPossibleObject(binds, MOD.DiagramConnectionRelationToConnectionRelation); String name = graph.getPossibleRelatedValue(conn, L0.HasName, Bindings.STRING); if (conn == null || name == null) return null; return new SymbolNameResult(name, transform); } private AffineTransform translateAndScaleIfNeeded(AffineTransform tr, Vec2d offset, double scale) { if(!offset.isZero() || scale != 1.0) { tr = new AffineTransform(tr); tr.translate(offset.x, offset.y); tr.scale(scale, scale); } return tr; } private AffineTransform getSymbolTransform(INode node, Vec2d offset, double size) { if(node instanceof SingleElementNode) { SingleElementNode s = (SingleElementNode)node; INode symbol = NodeUtil.findChildByPrefix(s, "composite_image"); //$NON-NLS-1$ return translateAndScaleIfNeeded(symbol != null ? ((IG2DNode)symbol).getTransform() : new AffineTransform(), offset, size); } return null; } @Override public void applyStyleForNode(EvaluationContext observer, INode _node, SymbolNameResult result) { if (result == null) { ProfileVariables.denyChild(_node, "", NODE_NAME); //$NON-NLS-1$ return; } TextNode node = ProfileVariables.claimChild(_node, "", NODE_NAME, TextNode.class, observer); //$NON-NLS-1$ node.setZIndex( Integer.MAX_VALUE ); node.setTransform( getSymbolTransform(_node, new Vec2d(0, -1), 0.08) ); node.setText(result.getName()); node.setHorizontalAlignment((byte)Alignment.CENTER.ordinal()); node.setBackgroundColor(Color.WHITE); node.setPadding(0.2, 0); } @Override protected void cleanupStyleForNode(INode node) { ProfileVariables.denyChild(node, "", NODE_NAME); //$NON-NLS-1$ } } /** * This is needed to keep the issue decoration up-to-date when its parent * element moves. */ class SymbolNameResult extends Tuple { public SymbolNameResult(String name, AffineTransform transform) { super(name, transform); } public String getName() { return (String) getField(0); } }