From 72e1b4dbfd20b5d980eb2453a0f50c51c8223345 Mon Sep 17 00:00:00 2001 From: Reino Ruusu Date: Fri, 24 May 2019 18:35:20 +0300 Subject: [PATCH] Static information label profile definition. gitlab #47 APROS-15309 Change-Id: I67aa5fa278304aa7f0f824cbba3762a3712c6f71 --- .../graph/DistrictNetworkProfiles.pgraph | 3 + .../ontology/DistrictNetworkResource.java | 3 + .../adapters.xml | 4 + .../ui/nodes/DistrictNetworkEdgeNode.java | 3 +- .../nodes/DistrictNetworkStaticInfoNode.java | 94 ++++++++++ .../nodes/DistrictNetworkStaticInfoStyle.java | 160 ++++++++++++++++++ .../network/profile/ArrowLengthStyle.java | 16 -- .../profile/MidBranchEdgeSetRequest.java | 23 +++ 8 files changed, 289 insertions(+), 17 deletions(-) create mode 100644 org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkStaticInfoNode.java create mode 100644 org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkStaticInfoStyle.java create mode 100644 org.simantics.district.network/src/org/simantics/district/network/profile/MidBranchEdgeSetRequest.java diff --git a/org.simantics.district.network.ontology/graph/DistrictNetworkProfiles.pgraph b/org.simantics.district.network.ontology/graph/DistrictNetworkProfiles.pgraph index b25be6f5..144710aa 100644 --- a/org.simantics.district.network.ontology/graph/DistrictNetworkProfiles.pgraph +++ b/org.simantics.district.network.ontology/graph/DistrictNetworkProfiles.pgraph @@ -30,6 +30,9 @@ DN.ConnectionLineStyle : DIA.Style // Style for user component-specified text grid entries DN.DistrictNetworkHoverInfoStyle : DIA.Style +// Style for user component-specified static info text for network branches +DN.DistrictNetworkStaticInfoStyle : DIA.Style + // Function for dynamic selection of symbols for a vertex // The input of the function is a DN.Vertex // The output of the function should be SVG diff --git a/org.simantics.district.network.ontology/src/org/simantics/district/network/ontology/DistrictNetworkResource.java b/org.simantics.district.network.ontology/src/org/simantics/district/network/ontology/DistrictNetworkResource.java index 0409dcfc..bdcc330f 100644 --- a/org.simantics.district.network.ontology/src/org/simantics/district/network/ontology/DistrictNetworkResource.java +++ b/org.simantics.district.network.ontology/src/org/simantics/district/network/ontology/DistrictNetworkResource.java @@ -59,6 +59,7 @@ public class DistrictNetworkResource { public final Resource Diagram_trackChangesEnabled; public final Resource Diagram_trackChangesEnabled_Inverse; public final Resource DistrictNetworkHoverInfoStyle; + public final Resource DistrictNetworkStaticInfoStyle; public final Resource DistrictNodeGroup; public final Resource DistrictNodeGroup_hasComponentTypeName; public final Resource DistrictNodeGroup_hasComponentTypeName_Inverse; @@ -431,6 +432,7 @@ public class DistrictNetworkResource { public static final String Diagram_trackChangesEnabled = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/trackChangesEnabled"; public static final String Diagram_trackChangesEnabled_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/trackChangesEnabled/Inverse"; public static final String DistrictNetworkHoverInfoStyle = "http://www.simantics.org/DistrictNetwork-1.0/DistrictNetworkHoverInfoStyle"; + public static final String DistrictNetworkStaticInfoStyle = "http://www.simantics.org/DistrictNetwork-1.0/DistrictNetworkStaticInfoStyle"; public static final String DistrictNodeGroup = "http://www.simantics.org/DistrictNetwork-1.0/DistrictNodeGroup"; public static final String DistrictNodeGroup_hasComponentTypeName = "http://www.simantics.org/DistrictNetwork-1.0/DistrictNodeGroup/hasComponentTypeName"; public static final String DistrictNodeGroup_hasComponentTypeName_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/DistrictNodeGroup/hasComponentTypeName/Inverse"; @@ -813,6 +815,7 @@ public class DistrictNetworkResource { Diagram_trackChangesEnabled = getResourceOrNull(graph, URIs.Diagram_trackChangesEnabled); Diagram_trackChangesEnabled_Inverse = getResourceOrNull(graph, URIs.Diagram_trackChangesEnabled_Inverse); DistrictNetworkHoverInfoStyle = getResourceOrNull(graph, URIs.DistrictNetworkHoverInfoStyle); + DistrictNetworkStaticInfoStyle = getResourceOrNull(graph, URIs.DistrictNetworkStaticInfoStyle); DistrictNodeGroup = getResourceOrNull(graph, URIs.DistrictNodeGroup); DistrictNodeGroup_hasComponentTypeName = getResourceOrNull(graph, URIs.DistrictNodeGroup_hasComponentTypeName); DistrictNodeGroup_hasComponentTypeName_Inverse = getResourceOrNull(graph, URIs.DistrictNodeGroup_hasComponentTypeName_Inverse); diff --git a/org.simantics.district.network.ui/adapters.xml b/org.simantics.district.network.ui/adapters.xml index 77d82eb4..323f4597 100644 --- a/org.simantics.district.network.ui/adapters.xml +++ b/org.simantics.district.network.ui/adapters.xml @@ -27,6 +27,10 @@ class="org.simantics.district.network.ui.nodes.DistrictNetworkHoverInfoStyle"> + + + diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkEdgeNode.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkEdgeNode.java index 61aec5ce..4d54246d 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkEdgeNode.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkEdgeNode.java @@ -146,7 +146,8 @@ public class DistrictNetworkEdgeNode extends G2DParentNode implements ISelection for (INode nn : getNodes()) { G2DNode g2dNode = (G2DNode)nn; - g2dNode.setTransform(symbolTransform); + if (g2dNode instanceof SVGNode) + g2dNode.setTransform(symbolTransform); g2dNode.render(g2d); } diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkStaticInfoNode.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkStaticInfoNode.java new file mode 100644 index 00000000..fb7041e7 --- /dev/null +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkStaticInfoNode.java @@ -0,0 +1,94 @@ +package org.simantics.district.network.ui.nodes; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.geom.AffineTransform; +import java.awt.geom.NoninvertibleTransformException; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +import org.simantics.district.network.DistrictNetworkUtil; +import org.simantics.district.network.ui.DistrictNetworkUIUtil; +import org.simantics.maps.MapScalingTransform; +import org.simantics.scenegraph.g2d.G2DNode; +import org.simantics.scenegraph.g2d.G2DParentNode; +import org.simantics.scenegraph.utils.DPIUtil; + +public class DistrictNetworkStaticInfoNode extends G2DNode { + + private static final Font FONT = new Font("Tahoma", Font.PLAIN, (int)(DPIUtil.upscale(9) * MapScalingTransform.getScaleY() + 0.5)); + + private static final long serialVersionUID = 1L; + + private static final Point2D UNIT_X = new Point2D.Double(1.0, 0.0); + + public static final String NODE_KEY = "DISTRICT_NETWORK_STATIC_INFO"; + + String info = null; + Point2D origin = new Point2D.Double(); + Point2D direction = UNIT_X; + + @Override + public void render(Graphics2D g) { + if (info == null || "".equals(info)) + return; + + AffineTransform oldTransform = g.getTransform(); + + // There has to be a better way to calculate the zoom level in this context... + AffineTransform baseTransform; + try { + baseTransform = ((G2DParentNode)getParent()).getTransform().createInverse(); + } catch (NoninvertibleTransformException e) { + baseTransform = new AffineTransform(); + } + + baseTransform.preConcatenate(oldTransform); + int zoomLevel = MapScalingTransform.zoomLevel(baseTransform); + if (zoomLevel < 15) + return; + + Font oldFont = g.getFont(); + Color oldColor = g.getColor(); + Object oldAA = g.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + doRender(g); + + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldAA); + g.setTransform(oldTransform); + g.setColor(oldColor); + g.setFont(oldFont); + } + + private void doRender(Graphics2D g) { + g.translate(origin.getX(), origin.getY()); + double scale = 1.5 / g.getTransform().getScaleX(); + g.scale(scale, scale); + + g.setFont(FONT); + g.setColor(Color.BLACK); + + g.transform(AffineTransform.getRotateInstance(direction.getX(), direction.getY())); + g.translate(0, 10); + + int width1 = g.getFontMetrics().stringWidth(info); + g.drawString(info, -width1/2, 0); + } + + @Override + public Rectangle2D getBoundsInLocal() { + return null; + } + + public void setLocation(Point2D origin, Point2D direction) { + this.origin = origin; + this.direction = direction; + } + + public void setInfo(String info) { + this.info = info; + } +} diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkStaticInfoStyle.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkStaticInfoStyle.java new file mode 100644 index 00000000..49d524a4 --- /dev/null +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkStaticInfoStyle.java @@ -0,0 +1,160 @@ +package org.simantics.district.network.ui.nodes; + +import java.awt.geom.Point2D; +import java.util.Set; + +import org.simantics.Simantics; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.procedure.adapter.TransientCacheListener; +import org.simantics.db.common.request.ResourceRead; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.exception.MissingVariableValueException; +import org.simantics.db.layer0.exception.PendingVariableException; +import org.simantics.db.layer0.util.Layer0Utils; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.diagram.profile.StyleBase; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.district.network.DistrictNetworkUtil; +import org.simantics.district.network.ontology.DistrictNetworkResource; +import org.simantics.district.network.profile.MidBranchEdgeSetRequest; +import org.simantics.layer0.Layer0; +import org.simantics.scenegraph.INode; +import org.simantics.scenegraph.profile.EvaluationContext; +import org.simantics.scenegraph.profile.common.ProfileVariables; +import org.simantics.scl.compiler.top.ValueNotFound; +import org.simantics.scl.osgi.SCLOsgi; +import org.simantics.scl.runtime.SCLContext; +import org.simantics.scl.runtime.function.Function1; +import org.simantics.structural.stubs.StructuralResource2; + +public class DistrictNetworkStaticInfoStyle extends StyleBase { + + private static final String ACTIONS_MODULE = "Actions"; + private static final String PIPELINE_INFO = "pipelineInfo"; + + public static class StyleResult { + public StyleResult(Point2D p1, Point2D p2, String info) { + this.p1 = p1; + this.p2 = p2; + this.info = info; + } + + public Point2D p1; + public Point2D p2; + public String info; + } + + public DistrictNetworkStaticInfoStyle(Resource style) { + super(style); + } + + @Override + public StyleResult calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource mapElement) + throws DatabaseException { + DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); + + if (!graph.isInstanceOf(mapElement, DN.Edge)) + return null; + + Resource diagram = graph.getSingleObject(mapElement, Layer0.getInstance(graph).PartOf); + Set edgesToUse = graph.syncRequest(new MidBranchEdgeSetRequest(diagram), TransientCacheListener.instance()); + if (!edgesToUse.contains(mapElement)) + return null; + + DiagramResource DIA = DiagramResource.getInstance(graph); + StructuralResource2 STR = StructuralResource2.getInstance(graph); + + Resource module = DistrictNetworkUtil.getMappedComponentCached(graph, mapElement); + if (module == null) + return null; + + Resource moduleType = graph.getPossibleType(module, STR.Component); + if (moduleType == null) + return null; + + Function1 function = getUCPipelineInfoFunctionCached(graph, moduleType); + if (function == null) + return null; + + String result; + try { + Variable variable = Variables.getVariable(graph, module); + Variable moduleVariable = Variables.possibleActiveVariable(graph, variable); + if (moduleVariable == null) + moduleVariable = variable; + + result = Simantics.applySCLRead(graph, function, moduleVariable); + } catch (PendingVariableException | MissingVariableValueException e) { + result = null; + } + + Resource v1 = graph.getSingleObject(mapElement, DN.HasStartVertex); + double[] coords1 = graph.getRelatedValue(v1, DIA.HasLocation); + Resource v2 = graph.getSingleObject(mapElement, DN.HasEndVertex); + double[] coords2 = graph.getRelatedValue(v2, DIA.HasLocation); + Point2D p1 = DistrictNetworkNodeUtils.calculatePoint2D(new Point2D.Double(coords1[0], coords1[1]), null); + Point2D p2 = DistrictNetworkNodeUtils.calculatePoint2D(new Point2D.Double(coords2[0], coords2[1]), null); + + return new StyleResult(p1, p2, result); + } + + @Override + public void applyStyleForNode(EvaluationContext evaluationContext, INode parent, StyleResult result) { + if (result == null) { + cleanupStyleForNode(evaluationContext, parent); + return; + } + + DistrictNetworkStaticInfoNode node = ProfileVariables.claimChild(parent, "*", DistrictNetworkStaticInfoNode.NODE_KEY, DistrictNetworkStaticInfoNode.class, evaluationContext); + if (node == null) + return; + + Point2D p1 = result.p1; + Point2D p2 = result.p2; + + double sign = Math.signum(p1.getX() - p2.getX()); + Point2D.Double origin = new Point2D.Double(0.5 * (p1.getX() + p2.getX()), 0.5 * (p1.getY() + p2.getY())); + Point2D direction = new Point2D.Double(0.5 * sign * (p1.getX() - p2.getX()), 0.5 * sign * (p1.getY() - p2.getY())); + + node.setLocation(origin, direction); + node.setInfo(result.info); + } + + private static Function1 getUCPipelineInfoFunctionCached(ReadGraph graph, Resource componentType) + throws DatabaseException { + return graph.syncRequest(new UCPipelineInfoRequest(componentType), TransientCacheListener.instance()); + } + + private static final class UCPipelineInfoRequest extends ResourceRead> { + public UCPipelineInfoRequest(Resource resource) { + super(resource); + } + + @SuppressWarnings("unchecked") + @Override + public Function1 perform(ReadGraph graph) throws DatabaseException { + Resource actionsModule = Layer0Utils.getPossibleChild(graph, resource, ACTIONS_MODULE); + if (actionsModule == null || !graph.isInstanceOf(actionsModule, Layer0.getInstance(graph).SCLModule)) + return null; + + String uri = graph.getURI(actionsModule); + SCLContext sclContext = SCLContext.getCurrent(); + Object oldGraph = sclContext.get("graph"); + try { + sclContext.put("graph", graph); + return (Function1) SCLOsgi.MODULE_REPOSITORY.getValue(uri, PIPELINE_INFO); + } catch (ValueNotFound e1) { + return null; + } finally { + sclContext.put("graph", oldGraph); + } + } + } + + @Override + protected void cleanupStyleForNode(EvaluationContext evaluationContext, INode node) { + ProfileVariables.denyChild(node, DistrictNetworkStaticInfoNode.NODE_KEY); + } +} diff --git a/org.simantics.district.network/src/org/simantics/district/network/profile/ArrowLengthStyle.java b/org.simantics.district.network/src/org/simantics/district/network/profile/ArrowLengthStyle.java index 0201f0b1..d180d77b 100644 --- a/org.simantics.district.network/src/org/simantics/district/network/profile/ArrowLengthStyle.java +++ b/org.simantics.district.network/src/org/simantics/district/network/profile/ArrowLengthStyle.java @@ -1,14 +1,11 @@ package org.simantics.district.network.profile; -import java.util.HashSet; -import java.util.List; import java.util.Set; import org.simantics.Simantics; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.procedure.adapter.TransientCacheListener; -import org.simantics.db.common.request.ResourceRead; import org.simantics.db.exception.DatabaseException; import org.simantics.layer0.Layer0; import org.simantics.scenegraph.INode; @@ -65,17 +62,4 @@ public class ArrowLengthStyle extends ThrottledStyleBase { for (INode nn : n.getNodes()) ProfileVariables.claimNodeProperty(nn, "arrowLength", null, evaluationContext); } - - private static final class MidBranchEdgeSetRequest extends ResourceRead> { - private MidBranchEdgeSetRequest(Resource resource) { - super(resource); - } - - @Override - public Set perform(ReadGraph graph) throws DatabaseException { - List edges = Simantics.applySCL("Simantics/District/Algorithm", "midBranchEdges", graph, resource); - return new HashSet<>(edges); - } - } - } diff --git a/org.simantics.district.network/src/org/simantics/district/network/profile/MidBranchEdgeSetRequest.java b/org.simantics.district.network/src/org/simantics/district/network/profile/MidBranchEdgeSetRequest.java new file mode 100644 index 00000000..c1a9394f --- /dev/null +++ b/org.simantics.district.network/src/org/simantics/district/network/profile/MidBranchEdgeSetRequest.java @@ -0,0 +1,23 @@ +package org.simantics.district.network.profile; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.simantics.Simantics; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ResourceRead; +import org.simantics.db.exception.DatabaseException; + +public class MidBranchEdgeSetRequest extends ResourceRead> { + public MidBranchEdgeSetRequest(Resource resource) { + super(resource); + } + + @Override + public Set perform(ReadGraph graph) throws DatabaseException { + List edges = Simantics.applySCL("Simantics/District/Algorithm", "midBranchEdges", graph, resource); + return new HashSet<>(edges); + } +} -- 2.47.0