/******************************************************************************* * Copyright (c) 2011 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.diagram.profile; import java.awt.Font; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import org.simantics.common.color.Color; import org.simantics.databoard.Bindings; 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.synchronization.graph.DiagramGraphUtil; import org.simantics.g2d.utils.Alignment; import org.simantics.modeling.ModelingResources; import org.simantics.scenegraph.INode; import org.simantics.scenegraph.profile.EvaluationContext; import org.simantics.scenegraph.profile.common.ProfileVariables; import org.simantics.scenegraph.utils.GeometryUtils; import org.simantics.scenegraph.utils.NodeUtil; import org.simantics.ui.colors.Colors; /** * @author Tuukka Lehtonen * @author Marko Luukkainen */ public abstract class TextStyle extends StyleBase { private final Font FONT = Font.decode("Arial 12"); private final java.awt.Color BACKGROUND_COLOR = new java.awt.Color(255, 255, 255, 192); protected double xOffset; protected double yOffset; public TextStyle() { this(0.0, -2.2); } public TextStyle(double xOffset, double yOffset) { this.xOffset = xOffset; this.yOffset = yOffset; } public abstract Resource getPropertyRelation(ReadGraph g, Resource module); /** * @return the name of the scene graph node to create to represent the text * element created by this style */ public abstract String getNodeName(); /** * Override to customize. * * @param graph * @param element * @return * @throws DatabaseException */ protected Resource getConfigurationComponent(ReadGraph graph, Resource element) throws DatabaseException { ModelingResources mr = ModelingResources.getInstance(graph); Resource config = graph.getPossibleObject(element, mr.ElementToComponent); return config; } /** * Override to customize. * * @param graph * @param element * @return * @throws DatabaseException */ protected String getConfigurationComponentNameForElement(ReadGraph graph, Resource element) throws DatabaseException { Resource config = getConfigurationComponent(graph, element); if (config == null) return null; String name = graph.getPossibleRelatedValue(config, getPropertyRelation(graph,element), Bindings.STRING); return name; } public AffineTransform getTransform(AffineTransform parentTransform, Rectangle2D elementBounds, int location) { double scale = GeometryUtils.getScale(parentTransform); AffineTransform at = AffineTransform.getTranslateInstance( parentTransform.getTranslateX() + elementBounds.getCenterX() * scale + xOffset, parentTransform.getTranslateY() + elementBounds.getMinY() * scale + yOffset*location ); at.scale(0.15, 0.15); return at; } @Override public MonitorTextResult calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource element, Variable configuration) throws DatabaseException { String name = getConfigurationComponentNameForElement(graph, element); if (name == null) return null; AffineTransform transform = DiagramGraphUtil.getAffineTransform(graph, element); return new MonitorTextResult(name, transform); } @Override public void applyStyleForNode(EvaluationContext observer, INode _node, MonitorTextResult result) { String value = result != null ? result.getText() : null; if (value != null && !value.isEmpty() && !value.trim().isEmpty()) { TextNode node = ProfileVariables.claimChild(_node, "", getNodeName(), TextNode.class, observer); if (node == null) return; Integer location = observer.getTemporaryProperty(_node, "location"); if(location == null) location = 1; Rectangle2D bounds = NodeUtil.getLocalElementBounds(_node); // Rectangle2D elementBounds = _node.getElementUtils.getElementBounds(element); AffineTransform at = getTransform(result.getParentTransform(), bounds, location); Color color = result.getColor(); observer.setTemporaryProperty(_node, "location", location+1); node.setTransform(at); node.setHorizontalAlignment((byte) Alignment.CENTER.ordinal()); node.setZIndex(3000); if(color != null) node.setColor(Colors.awt(color)); else node.setColor(java.awt.Color.DARK_GRAY); node.setEditable(false); node.setFont(FONT); node.setText(value); node.setBackgroundColor(BACKGROUND_COLOR); // node.setBorderColor(Color.LIGHT_GRAY); // node.setBorderWidth(1.0f); } else { cleanupStyleForNode(observer, _node); } } @Override protected void cleanupStyleForNode(EvaluationContext observer, INode node) { ProfileVariables.denyChild(node, "", getNodeName()); } }