// 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
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;
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";
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);
class="org.simantics.district.network.ui.nodes.DistrictNetworkHoverInfoStyle">
<this />
</resource>
+ <resource uri="http://www.simantics.org/DistrictNetwork-1.0/DistrictNetworkStaticInfoStyle"
+ class="org.simantics.district.network.ui.nodes.DistrictNetworkStaticInfoStyle">
+ <this />
+ </resource>
</target>
<target interface="org.simantics.g2d.diagram.DiagramClass">
for (INode nn : getNodes()) {
G2DNode g2dNode = (G2DNode)nn;
- g2dNode.setTransform(symbolTransform);
+ if (g2dNode instanceof SVGNode)
+ g2dNode.setTransform(symbolTransform);
g2dNode.render(g2d);
}
--- /dev/null
+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;
+ }
+}
--- /dev/null
+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<DistrictNetworkStaticInfoStyle.StyleResult> {
+
+ 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<Resource> 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<Variable, String> 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<Variable, String> getUCPipelineInfoFunctionCached(ReadGraph graph, Resource componentType)
+ throws DatabaseException {
+ return graph.syncRequest(new UCPipelineInfoRequest(componentType), TransientCacheListener.instance());
+ }
+
+ private static final class UCPipelineInfoRequest extends ResourceRead<Function1<Variable, String>> {
+ public UCPipelineInfoRequest(Resource resource) {
+ super(resource);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Function1<Variable, String> 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<Variable, String>) 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);
+ }
+}
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;
for (INode nn : n.getNodes())
ProfileVariables.claimNodeProperty(nn, "arrowLength", null, evaluationContext);
}
-
- private static final class MidBranchEdgeSetRequest extends ResourceRead<Set<Resource>> {
- private MidBranchEdgeSetRequest(Resource resource) {
- super(resource);
- }
-
- @Override
- public Set<Resource> perform(ReadGraph graph) throws DatabaseException {
- List<Resource> edges = Simantics.applySCL("Simantics/District/Algorithm", "midBranchEdges", graph, resource);
- return new HashSet<>(edges);
- }
- }
-
}
--- /dev/null
+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<Set<Resource>> {
+ public MidBranchEdgeSetRequest(Resource resource) {
+ super(resource);
+ }
+
+ @Override
+ public Set<Resource> perform(ReadGraph graph) throws DatabaseException {
+ List<Resource> edges = Simantics.applySCL("Simantics/District/Algorithm", "midBranchEdges", graph, resource);
+ return new HashSet<>(edges);
+ }
+}