From 39684a05baa1b599b8cc306cdd8a07ea6eb3cfdb Mon Sep 17 00:00:00 2001 From: Antti Villberg Date: Thu, 10 Aug 2017 10:44:27 +0300 Subject: [PATCH] Diagram to SVG to support selection cycling refs #7421 Change-Id: I0d9a0d54b38595d946e8f599136a59a3eff8e429 --- .../org/simantics/modeling/SCLScenegraph.java | 185 ++++++++++++------ 1 file changed, 124 insertions(+), 61 deletions(-) diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/SCLScenegraph.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/SCLScenegraph.java index 6345a1329..5f375095f 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/SCLScenegraph.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/SCLScenegraph.java @@ -82,6 +82,13 @@ import org.w3c.dom.NodeList; public class SCLScenegraph { private static final Logger LOGGER = LoggerFactory.getLogger(SCLScenegraph.class); + + private static final String MAIN_SECTION = "main"; + private static final String SELECTION_SECTION = "selection"; + private static final String SELECTION_MASK_SECTION = "selectionMask"; + + private static final String[] ALL_SECTIONS = { MAIN_SECTION, SELECTION_SECTION, SELECTION_MASK_SECTION }; + public static ICanvasSceneGraphProvider getICanvasSceneGraphProvider(Resource model, Resource diagram, String diagramRVI) throws DatabaseException, InterruptedException { ICanvasSceneGraphProvider provider = DiagramNodeUtil.loadSceneGraphProvider(model, diagram, diagramRVI); @@ -536,6 +543,37 @@ public class SCLScenegraph { }); } + static class RenderSVGContext { + + Map documents = new HashMap<>(); + + public void append(String[] keys, String svgText) { + for(String key : keys) append(key, svgText); + } + + public void append(String key, String svgText) { + StringBuilder builder = documents.get(key); + if(builder == null) { + builder = new StringBuilder(); + documents.put(key, builder); + } + builder.append(svgText); + } + + public void append(RenderSVGContext other) { + for(String key : other.documents.keySet()) { + append(key, other.get(key)); + } + } + + public String get(String key) { + StringBuilder builder = documents.get(key); + if(builder == null) return ""; + else return builder.toString(); + } + + } + private static String renderSVG0(ICanvasContext ctx, Function1, Map> mappingFunction) { // Get a DOMImplementation. @@ -548,7 +586,7 @@ public class SCLScenegraph { // Create an instance of the SVG Generator. SVGGraphics2D svgGenerator = new Generator(document); - StringBuilder result = new StringBuilder(); + RenderSVGContext result = new RenderSVGContext(); try { @@ -593,9 +631,17 @@ public class SCLScenegraph { double trX = -1 * content.getX(); double trY = -1 * content.getY(); + + result.append(MAIN_SECTION, ""); - result.append(""); - + result.append(SELECTION_SECTION, ""); + + result.append(SELECTION_MASK_SECTION, ""); + KeyVisitor keyVisitor = new KeyVisitor(); sg.accept(keyVisitor); @@ -604,16 +650,30 @@ public class SCLScenegraph { Map mappings = mappingFunction.apply(keys); IG2DNodeVisitor visitor = new PrintingVisitor(result, mappings); + sg.accept(visitor); } catch (Throwable t) { LOGGER.error("Problems rendering canvas context to SVG", t); } - result.append(""); - //System.err.println(" == FINAL RESULT == "); - //System.err.println(b); - return result.toString(); + + result.append(SELECTION_SECTION, ""); + result.append(SELECTION_MASK_SECTION, ""); + result.append(MAIN_SECTION, ""); + + StringBuilder res = new StringBuilder(); + res.append(""); + res.append(result.get(MAIN_SECTION)); + res.append(result.get(SELECTION_SECTION)); + res.append(result.get(SELECTION_MASK_SECTION)); + res.append(result.get("")); + +// System.err.println(" == FINAL RESULT == "); +// System.err.println(res.toString()); + + return res.toString(); + } @@ -646,13 +706,13 @@ public class SCLScenegraph { int indent = 0; - HashMap senBuilders = new HashMap<>(); + HashMap senBuilders = new HashMap<>(); - private StringBuilder result; + private RenderSVGContext result; private Map mappings; - public PrintingVisitor(StringBuilder result, Map mappings) { + public PrintingVisitor(RenderSVGContext result, Map mappings) { this.result = result; this.mappings = mappings; } @@ -669,7 +729,7 @@ public class SCLScenegraph { @Override public void enter(IG2DNode node) { - StringBuilder parentBuilder = getParentBuilder(node); + RenderSVGContext parentBuilder = getParentBuilder(node); indent++; if(node instanceof ConnectionNode) { @@ -679,34 +739,35 @@ public class SCLScenegraph { } String key = getKey((ConnectionNode) node); - parentBuilder.append("\n"); + parentBuilder.append(MAIN_SECTION, "\n"); + parentBuilder.append(SELECTION_SECTION, "\n"); + parentBuilder.append(SELECTION_MASK_SECTION, "\n"); + Element doc = renderSVGNode((IG2DNode)node); String svg = printSVGDocument(doc); - parentBuilder.append(svg); + parentBuilder.append(MAIN_SECTION, svg); for(RouteGraphNode n : NodeUtil.collectNodes(node, RouteGraphNode.class)) { n.setIgnoreSelection(false); } - parentBuilder.append("\n"); doc = renderSVGNode((IG2DNode)node); svg = printSVGDocument(doc); - parentBuilder.append(svg); - parentBuilder.append("\n"); + parentBuilder.append(SELECTION_SECTION, svg); - BasicStroke bs = new BasicStroke(5f); + BasicStroke bs = new BasicStroke(10f); for(RouteGraphNode n : NodeUtil.collectNodes(node, RouteGraphNode.class)) { n.setDynamicStroke(bs); } - parentBuilder.append("\n"); doc = renderSVGNode((IG2DNode)node); svg = printSVGDocument(doc); - parentBuilder.append(svg); - parentBuilder.append("\n"); + parentBuilder.append(SELECTION_MASK_SECTION, svg); - parentBuilder.append("\n"); + parentBuilder.append(SELECTION_MASK_SECTION, "\n"); + parentBuilder.append(SELECTION_SECTION, "\n"); + parentBuilder.append(MAIN_SECTION, "\n"); } else if (node instanceof SelectionNode) { @@ -714,44 +775,49 @@ public class SCLScenegraph { SingleElementNode parentSEN = (SingleElementNode)NodeUtil.getNearestParentOfType(node, SingleElementNode.class); if(parentSEN != null && parentSEN.getKey() != null) { - StringBuilder parentBuilder2 = getParentBuilder(parentSEN); + RenderSVGContext parentBuilder2 = getParentBuilder(parentSEN); String key = getKey(parentSEN); Element doc = renderSVGNode((IG2DNode)node); String svg = printSVGDocument(doc); - parentBuilder2.append("\n"); - parentBuilder2.append(svg); - parentBuilder2.append("\n"); - parentBuilder2.append("\n"); + parentBuilder2.append(SELECTION_SECTION, "\n"); + parentBuilder2.append(SELECTION_SECTION, svg); + parentBuilder2.append(SELECTION_SECTION, "\n"); + parentBuilder2.append(SELECTION_MASK_SECTION, "\n"); Rectangle2D rect = n.getRect(); - parentBuilder2.append(""); - parentBuilder2.append("\n"); + parentBuilder2.append(SELECTION_MASK_SECTION,""); + parentBuilder2.append(SELECTION_MASK_SECTION,"\n"); } } else if (node instanceof SVGNode) { SVGNode svg = (SVGNode)node; - parentBuilder.append(svg.getSVGText()); + parentBuilder.append(MAIN_SECTION, svg.getSVGText()); } else if (node instanceof G2DParentNode) { AffineTransform at = node.getTransform(); if(node instanceof SingleElementNode) { SingleElementNode sen = (SingleElementNode)node; if(sen.getKey() != null) { String key = getKey(sen); - parentBuilder.append("\n"); + String typeClass = sen.getTypeClass(); + String clazz = "definedElement"; + if(typeClass != null && !typeClass.isEmpty()) + clazz = clazz + " " + typeClass; + + parentBuilder.append(MAIN_SECTION, "\n"); } - senBuilders.put(sen, new StringBuilder()); + senBuilders.put(sen, new RenderSVGContext()); } if(!at.isIdentity()) { if(at.getScaleX() == 1.0 && at.getScaleY() == 1.0 && at.getShearX() == 0.0 && at.getShearY() == 0.0) { String m = "translate(" + at.getTranslateX() + " " + at.getTranslateY() + ")"; - parentBuilder.append("\n"); + parentBuilder.append(ALL_SECTIONS, "\n"); } else { double[] ds = new double[6]; at.getMatrix(ds); String m = "matrix(" + ds[0] + " " + ds[1] + " " + ds[2] + " " + ds[3] + " " + ds[4] + " " + ds[5] + ")"; - parentBuilder.append("\n"); + parentBuilder.append(ALL_SECTIONS, "\n"); } } } @@ -760,12 +826,12 @@ public class SCLScenegraph { } - private StringBuilder getParentBuilder(IG2DNode node) { + private RenderSVGContext getParentBuilder(IG2DNode node) { INode parentSEN = NodeUtil.getNearestParentOfType(node, SingleElementNode.class); if(parentSEN instanceof G2DSceneGraph) return result; - StringBuilder parentBuilder = senBuilders.get(parentSEN); + RenderSVGContext parentBuilder = senBuilders.get(parentSEN); if(parentBuilder == null) return result; return parentBuilder; @@ -779,39 +845,36 @@ public class SCLScenegraph { // We are done } else if (node instanceof G2DParentNode) { - StringBuilder parentBuilder = getParentBuilder(node); + RenderSVGContext parentBuilder = getParentBuilder(node); if(node instanceof SingleElementNode) { - SingleElementNode sen = (SingleElementNode)node; -// if(sen.getKey() != null) { - StringBuilder b = senBuilders.get(sen); - String content = b.toString(); - if(content.isEmpty()) { - if(sen.getKey() != null) { - - for(SelectionNode n : NodeUtil.collectNodes(node, SelectionNode.class)) { - n.setIgnore(true); - } - - Element doc = renderSVGNode((IG2DNode)node); - String svg = printSVGDocument(doc); - parentBuilder.append(svg); - } - } else { - parentBuilder.append(content); - } -// } + SingleElementNode sen = (SingleElementNode)node; + RenderSVGContext b = senBuilders.get(sen); + String content = b.get(MAIN_SECTION); + if(content.isEmpty()) { + if(sen.getKey() != null) { + + for(SelectionNode n : NodeUtil.collectNodes(node, SelectionNode.class)) { + n.setIgnore(true); + } + + Element doc = renderSVGNode((IG2DNode)node); + String svg = printSVGDocument(doc); + parentBuilder.append(MAIN_SECTION, svg); + } + } else { + parentBuilder.append(b); + } } - AffineTransform at = node.getTransform(); if(!at.isIdentity()) { - parentBuilder.append(""); + parentBuilder.append(ALL_SECTIONS, ""); } if(node instanceof SingleElementNode) { SingleElementNode sen = (SingleElementNode)node; if(sen.getKey() != null) { - parentBuilder.append(""); + parentBuilder.append(MAIN_SECTION, ""); } } } -- 2.43.2