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