From: jsimomaa Date: Fri, 7 Jul 2017 06:32:24 +0000 (+0300) Subject: Dynamic terminals and connections X-Git-Tag: v1.31.0~272 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F83%2F683%2F1;p=simantics%2Fplatform.git Dynamic terminals and connections Change-Id: I15242c8bf58a5b16529f924987fd8bf51cf69d0b --- diff --git a/bundles/org.simantics.diagram.ontology/graph/Diagram.pgraph b/bundles/org.simantics.diagram.ontology/graph/Diagram.pgraph index 7b7bb6b2e..bd99e8f98 100644 --- a/bundles/org.simantics.diagram.ontology/graph/Diagram.pgraph +++ b/bundles/org.simantics.diagram.ontology/graph/Diagram.pgraph @@ -41,6 +41,8 @@ DIA.Element -- DIA.Element.upProfileMonitors --> L0.Boolean """ : L0.String - + +TERMINALS.TargetedDynamicTerminal /* @ "Connection point to a child element" */ """ : L0.String + TERMINALS.CommandTerminal /* @ "Command termina" */ -- MOD.StructuralModel.HasSymbolDiagramType --> L0.Type -- MOD.StructuralModel.HasSymbolType --> L0.Type -- MOD.StructuralModel.HasConfigurationType --> L0.Type " createG2DNodeModification :: [SVGNodeAssignment] -> [TransformationAssignment] -> G2DNodeModification + @JavaName "" + createG2DNodeModification3 :: [SVGNodeAssignment] -> [TargetedSVGNodeAssignment] -> [TransformationAssignment] -> G2DNodeModification importJava "org.simantics.scenegraph.g2d.nodes.SVGNodeAssignment" where data SVGNodeAssignment + @JavaName "" + createSVGNodeAssignment :: String -> String -> String -> SVGNodeAssignment +importJava "org.simantics.scenegraph.g2d.nodes.TargetedSVGNodeAssignment" where + data TargetedSVGNodeAssignment + @JavaName "" + createTargetedSVGNodeAssignment :: a -> String -> String -> String -> TargetedSVGNodeAssignment + importJava "org.simantics.scenegraph.g2d.nodes.TransformationAssignment" where data TransformationAssignment @JavaName "" diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/ModelingUtils.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/ModelingUtils.java index 3054fcaa5..511eeb3fa 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/ModelingUtils.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/ModelingUtils.java @@ -183,7 +183,11 @@ public class ModelingUtils { } @Deprecated - public Resource createSymbol2(String name, Resource type) throws DatabaseException { + public Resource createSymbol2(String name, Resource diagramType) throws DatabaseException { + return createSymbol2(name, diagramType, dr.DefinedElement); + } + @Deprecated + public Resource createSymbol2(String name, Resource diagramType, Resource symbolType) throws DatabaseException { G2DResource g2d = G2DResource.getInstance(g); // Resource visibleTag = wg.newResource(); @@ -192,7 +196,7 @@ public class ModelingUtils { // wg.claim(focusableTag, b.SubrelationOf, null, dr.IsFocusable); Double boxDimension = 6.0; - Collection grid = g.getAssertedStatements(type, dr.HasGridSize); + Collection grid = g.getAssertedStatements(diagramType, dr.HasGridSize); if(grid.size() == 1) { Double d = g.getPossibleValue(grid.iterator().next().getObject(), Bindings.DOUBLE); if(d != null) boxDimension = 2*d; @@ -217,7 +221,7 @@ public class ModelingUtils { // wg.claim(element, visibleTag, element); // wg.claim(element, focusableTag, element); - Resource orderedSet = OrderedSetUtils.create(wg, type, element); + Resource orderedSet = OrderedSetUtils.create(wg, diagramType, element); // wg.claim(orderedSet, dr.HasLayer, GraphUtils.create2(wg, dr.Layer, // b.HasName, "Default", @@ -235,7 +239,7 @@ public class ModelingUtils { AddElement.claimFreshElementName(wg, orderedSet, element); wg.claim(orderedSet, b.ConsistsOf, element); - wg.claim(result, b.Inherits, null, dr.DefinedElement); + wg.claim(result, b.Inherits, null, symbolType); return result; } diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/NewComponentType.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/NewComponentType.java index 920c30453..813b6c3c1 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/NewComponentType.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/NewComponentType.java @@ -62,9 +62,12 @@ public class NewComponentType { Resource symbolDiagramType = graph.getPossibleObject(indexRoot, MOD.StructuralModel_HasSymbolDiagramType); if(symbolDiagramType == null) symbolDiagramType = DIA.Composite; - + + Resource symbolType = graph.getPossibleObject(indexRoot, MOD.StructuralModel_HasSymbolType); + if(symbolType == null) symbolType = DIA.DefinedElement; + // Symbol - Resource symbol = new ModelingUtils(graph).createSymbol2("Symbol", symbolDiagramType); + Resource symbol = new ModelingUtils(graph).createSymbol2("Symbol", symbolDiagramType, symbolType); graph.claim(componentType, MOD.ComponentTypeToSymbol, symbol); graph.claim(componentType, L0.ConsistsOf, symbol); diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/adapters/SymbolCodeStyle.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/adapters/SymbolCodeStyle.java index edc7aa9e1..4e7fe78d0 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/adapters/SymbolCodeStyle.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/adapters/SymbolCodeStyle.java @@ -18,6 +18,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.simantics.Simantics; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.exception.DatabaseException; @@ -28,12 +29,17 @@ import org.simantics.diagram.stubs.DiagramResource; import org.simantics.scenegraph.INode; import org.simantics.scenegraph.g2d.G2DNodeModification; import org.simantics.scenegraph.g2d.IG2DNode; +import org.simantics.scenegraph.g2d.nodes.ConnectionNode; import org.simantics.scenegraph.g2d.nodes.SVGNode; import org.simantics.scenegraph.g2d.nodes.SVGNodeAssignment; import org.simantics.scenegraph.g2d.nodes.SingleElementNode; +import org.simantics.scenegraph.g2d.nodes.TargetedSVGNodeAssignment; import org.simantics.scenegraph.g2d.nodes.TransformationAssignment; +import org.simantics.scenegraph.g2d.nodes.connection.RouteGraphNode; import org.simantics.scenegraph.profile.EvaluationContext; import org.simantics.scenegraph.utils.NodeUtil; +import org.simantics.scl.runtime.function.Function; +import org.simantics.structural.stubs.StructuralResource2; import org.simantics.utils.datastructures.Pair; /** @@ -51,8 +57,19 @@ public class SymbolCodeStyle extends StyleBase if (elementVariable == null) return null; Object modi = elementVariable.getPossiblePropertyValue(graph, DIA.symbolCode); - if (modi == null) - return null; + if (modi == null) { + if(graph.isInstanceOf(element, DIA.RouteGraphConnection)) { + StructuralResource2 STR = StructuralResource2.getInstance(graph); + Resource connectionType = graph.getPossibleObject(element, STR.HasConnectionType); + if(connectionType != null) { + Variable connectionTypeVariable = Variables.getPossibleVariable(graph, connectionType); + Function fn = connectionTypeVariable.getPossiblePropertyValue(graph, DIA.symbolFunction); + modi = Simantics.applySCLRead(graph, fn, elementVariable); + } + } + } + + if(modi == null) return null; // If element is moved, recalculate style Object transform = graph.getPossibleRelatedValue(element, DIA.HasTransform); @@ -71,33 +88,89 @@ public class SymbolCodeStyle extends StyleBase } } + private Map buildSingleElementMap(INode node) { + Map elements = new HashMap<>(); + NodeUtil.forChildrenDeep(node, SingleElementNode.class, n -> { + elements.put(n.getKey(), n); + return null; + }); + return elements; + } + @Override public void applyStyleForNode(EvaluationContext evaluationContext, INode node, Pair result) { - if (result == null || result.first == null) + + if (result == null || result.first == null) return; + Map elements = null; + G2DNodeModification modification = result.first; - if (modification.svgAssignments != null && !modification.svgAssignments.isEmpty()) { - for (SVGNode p : NodeUtil.collectNodes(node, SVGNode.class)) { - p.setAssignments(modification.svgAssignments); + + if(node instanceof ConnectionNode) { + + if (modification.svgAssignments != null && !modification.svgAssignments.isEmpty()) { + INode child = NodeUtil.getFirstChild(node); + if(child instanceof RouteGraphNode) { + RouteGraphNode rgn = (RouteGraphNode)child; + rgn.setAssignments(modification.svgAssignments); + } + } + + } else if(node instanceof SingleElementNode) { + + Map> assignmentMap = new HashMap<>(); + + if (modification.svgAssignments != null && !modification.svgAssignments.isEmpty()) { + for (SVGNode p : NodeUtil.collectNodes(node, SVGNode.class)) { + List list = assignmentMap.get(p); + if(list == null) { + list = new ArrayList<>(); + assignmentMap.put(p, list); + } + list.addAll(modification.svgAssignments); + } + } + + if(modification.targetedSVGAssignments != null && !modification.targetedSVGAssignments.isEmpty()) { + elements = buildSingleElementMap(node); + for(TargetedSVGNodeAssignment ass : modification.targetedSVGAssignments) { + SingleElementNode sen = elements.get(ass.singleElementKey); + for (SVGNode p : NodeUtil.collectNodes(sen, SVGNode.class)) { + List list = assignmentMap.get(p); + if(list == null) { + list = new ArrayList<>(); + assignmentMap.put(p, list); + } + list.add(ass); + } + } + } + + for(Map.Entry> entry : assignmentMap.entrySet()) { + SVGNode p = entry.getKey(); + p.setAssignments(entry.getValue()); p.cleanDiagramCache(); + } + + if (modification.transformAssignments != null) { + Map trs = new HashMap<>(); + for (TransformationAssignment ass : modification.transformAssignments) + trs.put(ass.key, ass.transform); + NodeUtil.forChildrenDeep(node, SingleElementNode.class, n -> { + Object key = n.getKey(); + AffineTransform tr = trs.get(key); + if (tr != null) { + IG2DNode[] children = n.getSortedNodes(); + if (children.length > 0) + children[0].setTransform(tr); + } + return null; + }); } + } - if (modification.transformAssignments != null) { - Map trs = new HashMap<>(); - for (TransformationAssignment ass : modification.transformAssignments) - trs.put(ass.key, ass.transform); - NodeUtil.forChildrenDeep(node, SingleElementNode.class, n -> { - Object key = n.getKey(); - AffineTransform tr = trs.get(key); - if (tr != null) { - IG2DNode[] children = n.getSortedNodes(); - if (children.length > 0) - children[0].setTransform(tr); - } - return null; - }); - } + } } diff --git a/bundles/org.simantics.scenegraph.profile/src/org/simantics/scenegraph/profile/request/ProfileEntryContributions.java b/bundles/org.simantics.scenegraph.profile/src/org/simantics/scenegraph/profile/request/ProfileEntryContributions.java index 4c3cd57b7..0cf54df32 100644 --- a/bundles/org.simantics.scenegraph.profile/src/org/simantics/scenegraph/profile/request/ProfileEntryContributions.java +++ b/bundles/org.simantics.scenegraph.profile/src/org/simantics/scenegraph/profile/request/ProfileEntryContributions.java @@ -34,7 +34,10 @@ public class ProfileEntryContributions extends ResourceRead ArrayList result = new ArrayList<>(); for(Resource contribution : query.find(graph, index)) { - result.add(graph.getSingleObject(contribution, DIA.ProfileEntryContribution_HasEntry)); + for(Resource entry : graph.getObjects(contribution, DIA.ProfileEntryContribution_HasEntry)) { + result.add(entry); + } + } return result; diff --git a/bundles/org.simantics.scenegraph/META-INF/MANIFEST.MF b/bundles/org.simantics.scenegraph/META-INF/MANIFEST.MF index dad71c00d..610990a02 100644 --- a/bundles/org.simantics.scenegraph/META-INF/MANIFEST.MF +++ b/bundles/org.simantics.scenegraph/META-INF/MANIFEST.MF @@ -13,7 +13,8 @@ Require-Bundle: gnu.trove3;bundle-version="3.0.0", org.simantics.scl.runtime;bundle-version="0.1.4", org.simantics.databoard;bundle-version="0.6.3", com.lowagie.text;bundle-version="2.1.7";resolution:=optional, - org.simantics.utils;bundle-version="1.1.0" + org.simantics.utils;bundle-version="1.1.0", + org.slf4j.api Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ClassPath: ., lib/svgSalamander-tiny.jar, diff --git a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/G2DNodeModification.java b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/G2DNodeModification.java index 4b68e1798..75c64ca62 100644 --- a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/G2DNodeModification.java +++ b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/G2DNodeModification.java @@ -14,6 +14,7 @@ package org.simantics.scenegraph.g2d; import java.util.List; import org.simantics.scenegraph.g2d.nodes.SVGNodeAssignment; +import org.simantics.scenegraph.g2d.nodes.TargetedSVGNodeAssignment; import org.simantics.scenegraph.g2d.nodes.TransformationAssignment; /** @@ -22,9 +23,18 @@ import org.simantics.scenegraph.g2d.nodes.TransformationAssignment; */ public class G2DNodeModification { public List svgAssignments; + public List targetedSVGAssignments; public List transformAssignments; public G2DNodeModification(List svgAssignments, List transformAssignments) { this.svgAssignments = svgAssignments; this.transformAssignments = transformAssignments; } + public G2DNodeModification(List svgAssignments, List targetedSVGAssignments, List transformAssignments) { + this.svgAssignments = svgAssignments; + this.targetedSVGAssignments = targetedSVGAssignments; + this.transformAssignments = transformAssignments; + } + public static G2DNodeModification create3(List svgAssignments, List targetedSVGAssignments, List transformAssignments) { + return new G2DNodeModification(svgAssignments, targetedSVGAssignments, transformAssignments); + } } diff --git a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/SVGNode.java b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/SVGNode.java index 2fc37b7d5..ec85fd75c 100644 --- a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/SVGNode.java +++ b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/SVGNode.java @@ -27,6 +27,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.WeakHashMap; import org.simantics.scenegraph.ExportableWidget.RasterOutputWidget; @@ -172,32 +173,55 @@ public class SVGNode extends G2DNode implements InitValueSupport, LoaderNode { diagramCache = null; } - // NOTE: hard-coded to assume all SVG data is encoded in UTF-8 - byte[] dataBytes = data.getBytes("UTF-8"); + + // Lets check for rootAssignment that contributes the whole SVG + SVGNodeAssignment rootAssignment = null; + if (!assignments.isEmpty()) { + for (SVGNodeAssignment ass : assignments) { + if (ass.attributeNameOrId.equals("$root")) { + rootAssignment = ass; + break; + } + } + } + byte[] dataBytes; + if (rootAssignment != null) { + dataBytes = rootAssignment.value.getBytes("UTF-8"); + } else { + // NOTE: hard-coded to assume all SVG data is encoded in UTF-8 + dataBytes = data.getBytes("UTF-8"); + } dataHash = digest(dataBytes, assignments); URI uri = univ.loadSVG(new ByteArrayInputStream(dataBytes), dataHash); diagramCache = univ.getDiagram(uri, false); if (diagramCache != null) { univ.incRefCount(diagramCache.getXMLBase()); - - if (diagramCache.getRoot() == null) { + SVGRoot root = diagramCache.getRoot(); + if (root == null) { univ.decRefCount(diagramCache.getXMLBase()); diagramCache = univ.getDiagram(univ.loadSVG(BROKEN_SVG_DATA), false); dataHash = "broken"; univ.incRefCount(diagramCache.getXMLBase()); bbox = (Rectangle2D) diagramCache.getRoot().getBoundingBox().clone(); } else { - bbox = diagramCache.getRoot().getBoundingBox(); + bbox = root.getBoundingBox(); if (bbox.isEmpty()) { - univ.decRefCount(diagramCache.getXMLBase()); - diagramCache = univ.getDiagram(univ.loadSVG(EMPTY_SVG_DATA), false); - dataHash = "empty"; - univ.incRefCount(diagramCache.getXMLBase()); - bbox = (Rectangle2D) diagramCache.getRoot().getBoundingBox().clone(); + // Lets check if this should be visible or not + Set presentationAttributes = root.getPresentationAttributes(); + if (!presentationAttributes.contains("display")) { + // TODO: fix this - How can one read values of attributes in SVG salamander??? + univ.decRefCount(diagramCache.getXMLBase()); + diagramCache = univ.getDiagram(univ.loadSVG(EMPTY_SVG_DATA), false); + dataHash = "empty"; + univ.incRefCount(diagramCache.getXMLBase()); + bbox = (Rectangle2D) root.getBoundingBox().clone(); + } else { + bbox = new Rectangle2D.Double(0, 0, 0, 0); + } } else { if (applyAssignments(diagramCache, assignments)) { - bbox = (Rectangle2D) diagramCache.getRoot().getBoundingBox().clone(); + bbox = (Rectangle2D) root.getBoundingBox().clone(); } else { bbox = (Rectangle2D) bbox.clone(); } @@ -227,6 +251,9 @@ public class SVGNode extends G2DNode implements InitValueSupport, LoaderNode { return false; boolean changed = false; for (SVGNodeAssignment ass : assignments) { +// System.err.println("assign: " + ass.elementId + " " + ass.attributeNameOrId + " " + ass.value); +// if("opacity".equals(ass.attributeNameOrId)) +// System.err.println("faaf"); SVGElement e = diagram.getElement(ass.elementId); if (e != null) { if ("$text".equals(ass.attributeNameOrId)) { diff --git a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/TargetedSVGNodeAssignment.java b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/TargetedSVGNodeAssignment.java new file mode 100644 index 000000000..0f279a6d5 --- /dev/null +++ b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/TargetedSVGNodeAssignment.java @@ -0,0 +1,55 @@ +package org.simantics.scenegraph.g2d.nodes; + +/** + * @author Antti Villberg + * @since 1.29.0 + */ +public class TargetedSVGNodeAssignment extends SVGNodeAssignment { + public Object singleElementKey; + public TargetedSVGNodeAssignment(Object singleElementKey, String elementId, String attributeNameOrId, String value) { + super(elementId, attributeNameOrId, value); + this.singleElementKey = singleElementKey; + } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((singleElementKey == null) ? 0 : singleElementKey.hashCode()); + result = prime * result + ((attributeNameOrId == null) ? 0 : attributeNameOrId.hashCode()); + result = prime * result + ((elementId == null) ? 0 : elementId.hashCode()); + result = prime * result + ((value == null) ? 0 : value.hashCode()); + return result; + } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + TargetedSVGNodeAssignment other = (TargetedSVGNodeAssignment) obj; + if (singleElementKey == null) { + if (other.singleElementKey != null) + return false; + } else if (!singleElementKey.equals(other.singleElementKey)) + return false; + if (attributeNameOrId == null) { + if (other.attributeNameOrId != null) + return false; + } else if (!attributeNameOrId.equals(other.attributeNameOrId)) + return false; + if (elementId == null) { + if (other.elementId != null) + return false; + } else if (!elementId.equals(other.elementId)) + return false; + if (value == null) { + if (other.value != null) + return false; + } else if (!value.equals(other.value)) + return false; + return true; + } + +} \ No newline at end of file diff --git a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/connection/RouteGraphNode.java b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/connection/RouteGraphNode.java index 687731f4c..0a2583fc6 100644 --- a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/connection/RouteGraphNode.java +++ b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/connection/RouteGraphNode.java @@ -23,7 +23,9 @@ import java.awt.geom.Path2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.lang.reflect.Constructor; +import java.util.ArrayList; import java.util.Collection; +import java.util.List; import java.util.Map; import org.simantics.diagram.connection.RouteGraph; @@ -59,12 +61,16 @@ import org.simantics.scenegraph.g2d.events.command.CommandEvent; import org.simantics.scenegraph.g2d.events.command.Commands; import org.simantics.scenegraph.g2d.nodes.GridNode; import org.simantics.scenegraph.g2d.nodes.LinkNode; +import org.simantics.scenegraph.g2d.nodes.SVGNodeAssignment; import org.simantics.scenegraph.g2d.nodes.connection.HighlightActionPointsAction.Action; import org.simantics.scenegraph.g2d.nodes.connection.HighlightActionPointsAction.Pick; import org.simantics.scenegraph.g2d.snap.ISnapAdvisor; +import org.simantics.scenegraph.utils.ColorUtil; import org.simantics.scenegraph.utils.GeometryUtils; import org.simantics.scenegraph.utils.InitValueSupport; import org.simantics.scenegraph.utils.NodeUtil; +import org.slf4j.LoggerFactory; +import org.slf4j.Logger; import gnu.trove.map.hash.THashMap; @@ -73,7 +79,9 @@ import gnu.trove.map.hash.THashMap; */ public class RouteGraphNode extends G2DNode implements ISelectionPainterNode, InitValueSupport { - private static final long serialVersionUID = -917194130412280965L; + private static final Logger LOGGER = LoggerFactory.getLogger(RouteGraphNode.class); + + private static final long serialVersionUID = -917194130412280965L; private static final double TOLERANCE = IAction.TOLERANCE; private static final Stroke SELECTION_STROKE = new BasicStroke(1f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER); @@ -123,7 +131,7 @@ public class RouteGraphNode extends G2DNode implements ISelectionPainterNode, In protected transient Map dynamicStyles = null; - + private transient boolean ignoreSelection = false; @Override @@ -132,6 +140,74 @@ public class RouteGraphNode extends G2DNode implements ISelectionPainterNode, In wrapRenderer(); } + private static float tryParseFloat(String s, float def) { + try { + return Float.parseFloat(s); + } catch (NumberFormatException e) { + LOGGER.error("Could not parse '" + s + "' into float."); + return def; + } + } + + /* + * 1.0 BUTT MITER 1.0 0.0 + */ + private static Stroke parseStroke(String definition) { + + float width = 1.0f; + int cap = BasicStroke.CAP_BUTT; + int join = BasicStroke.JOIN_MITER; + float miterLimit = 1.0f; + float[] dash = { 1, 0}; + float dash_phase = 0; + + String[] parts = definition.split(" "); + + if(parts.length > 0) { + width = tryParseFloat(parts[0], width); + } + if(parts.length > 1) { + if("BUTT".equals(parts[1])) cap = BasicStroke.CAP_BUTT; + else if("ROUND".equals(parts[1])) cap = BasicStroke.CAP_ROUND; + else if("SQUARE".equals(parts[1])) cap = BasicStroke.CAP_SQUARE; + } + if(parts.length > 2) { + if("BEVEL".equals(parts[2])) cap = BasicStroke.JOIN_BEVEL; + else if("MITER".equals(parts[2])) cap = BasicStroke.JOIN_MITER; + else if("ROUND".equals(parts[2])) cap = BasicStroke.JOIN_ROUND; + } + if(parts.length > 3) { + miterLimit = tryParseFloat(parts[3], miterLimit); + } + if(parts.length > 4) { + dash_phase = tryParseFloat(parts[4], dash_phase); + } + if(parts.length > 6) { + dash = new float[parts.length - 5]; + for(int i=5;i assignments) { + for(SVGNodeAssignment ass : assignments) { + if("dynamicColor".equals(ass.elementId)) { + setDynamicColor(ColorUtil.hexColor(ass.value)); + } else if("dynamicStroke".equals(ass.elementId)) { + setDynamicStroke(parseStroke(ass.value)); + } + } + } + public void setIgnoreSelection(boolean value) { ignoreSelection = value; } diff --git a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/utils/ColorUtil.java b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/utils/ColorUtil.java index 8479cd717..300938261 100644 --- a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/utils/ColorUtil.java +++ b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/utils/ColorUtil.java @@ -81,6 +81,20 @@ public class ColorUtil { if ( b > 255 ) b = 255; return new Color(r, g, b, c.getAlpha()); - } + } + + public static Color hexColor(String hex) { + if(hex.startsWith("#")) { + if(hex.length() == 4) { + int r = Character.digit(hex.charAt(1), 16); + int g = Character.digit(hex.charAt(2), 16); + int b = Character.digit(hex.charAt(3), 16); + return new Color(r+(r<<4), g+(g<<4), b+(b<<4)); + } else if(hex.length() == 7) { + return new Color(Integer.parseInt(hex.substring(1), 16)); + } + } + return Color.BLACK; + } }