package org.simantics.diagram.flag; import java.awt.Color; import java.awt.Font; import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import org.simantics.databoard.util.Bean; import org.simantics.diagram.adapter.FlagTextInfo; import org.simantics.diagram.adapter.SVGImageInfo; import org.simantics.diagram.elements.SVGNode; import org.simantics.diagram.elements.TextNode; import org.simantics.g2d.element.ElementUtils; import org.simantics.g2d.element.IElement; import org.simantics.g2d.element.SceneGraphNodeKey; import org.simantics.g2d.element.handler.Outline; import org.simantics.g2d.element.handler.SceneGraph; import org.simantics.g2d.element.handler.Text; import org.simantics.g2d.elementclass.FlagClass; import org.simantics.g2d.elementclass.FlagClass.Type; import org.simantics.g2d.utils.Alignment; import org.simantics.scenegraph.Node; import org.simantics.scenegraph.g2d.G2DParentNode; import org.simantics.scenegraph.g2d.nodes.FlagNode; import org.simantics.ui.colors.Colors; import org.simantics.ui.fonts.Fonts; import org.simantics.utils.datastructures.hints.IHintContext.Key; import org.simantics.utils.datastructures.hints.IHintContext.KeyOf; public class FlagSceneGraph implements SceneGraph { private static final long serialVersionUID = 35208146123929197L; public static final FlagSceneGraph INSTANCE = new FlagSceneGraph(); /** * References an array of {@link FlagTextInfo} instances and * {@link SVGImageInfo}. */ public static final Key KEY_FLAG_VISUALS = new KeyOf(Bean[].class, "FLAG_MONITORS"); public static final Key KEY_VISUAL_SG_NODE = new SceneGraphNodeKey(Node.class, "FLAG_VISUAL_NODE"); private static final String VISUAL_ROOT = "visual"; @Override public void cleanup(IElement e) { ElementUtils.removePossibleNode(e, FlagClass.KEY_SG_NODE); ElementUtils.removePossibleNode(e, KEY_VISUAL_SG_NODE); } @Override public void init(IElement e, G2DParentNode parent) { Bean[] flagVisuals = e.getHint(KEY_FLAG_VISUALS); if (flagVisuals == null || flagVisuals.length == 0) { Color fc = ElementUtils.getFillColor(e, Color.WHITE); Color bc = ElementUtils.getBorderColor(e, Color.BLACK); Color tc = ElementUtils.getTextColor(e, Color.BLACK); Outline outline = e.getElementClass().getSingleItem(Outline.class); Shape shape = outline.getElementShape(e); Type type = FlagClass.getType(e); double dir = FlagClass.getDirection(e); double width = e.getHint(FlagClass.KEY_FLAG_WIDTH); double height = e.getHint(FlagClass.KEY_FLAG_HEIGHT); double beakAngle = e.getHint(FlagClass.KEY_FLAG_BEAK_ANGLE); String[] flagText = e.getHint(FlagClass.KEY_FLAG_TEXT); if (flagText == null) { // fallback option. Text t = e.getElementClass().getAtMostOneItemOfClass(Text.class); if (t != null) { String text = t.getText(e); if (text != null) flagText = new String[] { text }; } } // DEBUG TEXT //flagText = new String[] { String.format("%3.1f", dir) + " deg", "FOO"}; Rectangle2D textArea = e.getHint(FlagClass.KEY_FLAG_TEXT_AREA); if (textArea == null) { double beakLength = FlagClass.getBeakLength(height, beakAngle); textArea = type == Type.In ? new Rectangle2D.Double(-width-beakLength, -height*0.5, width, height) : new Rectangle2D.Double(0, -height*0.5, width, height); } Alignment horizAlign = ElementUtils.getHintOrDefault(e, FlagClass.KEY_TEXT_HORIZONTAL_ALIGN, Alignment.LEADING); Alignment vertAlign = ElementUtils.getHintOrDefault(e, FlagClass.KEY_TEXT_VERTICAL_ALIGN, Alignment.CENTER); Font font = ElementUtils.getHintOrDefault(e, FlagClass.KEY_FLAG_FONT, FlagNode.DEFAULT_FONT); ElementUtils.removePossibleNode(e, KEY_VISUAL_SG_NODE); e.removeHint(KEY_VISUAL_SG_NODE); FlagNode flag = ElementUtils.getOrCreateNode(e, parent, FlagClass.KEY_SG_NODE, ElementUtils.generateNodeId(e), FlagNode.class); flag.init(shape, flagText, FlagClass.STROKE, bc, fc, tc, (float) width, (float) height, (float) dir, (float) beakAngle, textArea, horizAlign.ordinal(), vertAlign.ordinal(), font); AffineTransform at = ElementUtils.getTransform(e); if(at != null) flag.setTransform(at); } else { ElementUtils.removePossibleNode(e, FlagClass.KEY_SG_NODE); e.removeHint(FlagClass.KEY_SG_NODE); G2DParentNode par = ElementUtils.getOrCreateNode(e, parent, KEY_VISUAL_SG_NODE, VISUAL_ROOT, G2DParentNode.class); if (par.getNodeCount() > 0) par.removeNodes(); AffineTransform at = ElementUtils.getTransform(e); if(at != null) par.setTransform(at); for (Bean visual : flagVisuals) { if (visual instanceof FlagTextInfo) { FlagTextInfo info = (FlagTextInfo) visual; String text = info.text; TextNode cellNode = par.getOrCreateNode(info.id, TextNode.class); if (info.width >= 0.0f) cellNode.setFixedWidth(info.width); cellNode.setWrapText(info.wrapText); cellNode.setHorizontalAlignment((byte)info.hAlignment.ordinal()); cellNode.setVerticalAlignment((byte)info.vAlignment.ordinal()); if (info.borderWidth >= 0.0f) cellNode.setBorderWidth(info.borderWidth); if (info.borderColor != null && info.borderWidth > 0.0f) cellNode.setBorderColor(Colors.awt(info.borderColor)); if (info.backgroundColor != null) cellNode.setBackgroundColor(Colors.awt(info.backgroundColor)); if (info.font != null) cellNode.setFont(Fonts.awt(info.font)); if (info.color != null) cellNode.setColor(Colors.awt(info.color)); if (info.transform != null) cellNode.setTransform(new AffineTransform(info.transform)); if (text != null) cellNode.setText(text); } else if (visual instanceof SVGImageInfo) { SVGImageInfo info = (SVGImageInfo) visual; SVGNode svgNode = par.getOrCreateNode(info.id, SVGNode.class); if (info.svgDocument != null && !info.svgDocument.isEmpty()) svgNode.setData(info.svgDocument); if (info.transform != null) svgNode.setTransform(new AffineTransform(info.transform)); } } } } }