]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkStaticInfoStyle.java
Enable static info labels for vertex elements
[simantics/district.git] / org.simantics.district.network.ui / src / org / simantics / district / network / ui / nodes / DistrictNetworkStaticInfoStyle.java
1 package org.simantics.district.network.ui.nodes;
2
3 import java.awt.geom.Point2D;
4 import java.util.Set;
5
6 import org.simantics.Simantics;
7 import org.simantics.db.ReadGraph;
8 import org.simantics.db.Resource;
9 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
10 import org.simantics.db.common.request.ResourceRead;
11 import org.simantics.db.exception.DatabaseException;
12 import org.simantics.db.layer0.exception.MissingVariableValueException;
13 import org.simantics.db.layer0.exception.PendingVariableException;
14 import org.simantics.db.layer0.util.Layer0Utils;
15 import org.simantics.db.layer0.variable.Variable;
16 import org.simantics.db.layer0.variable.Variables;
17 import org.simantics.diagram.profile.StyleBase;
18 import org.simantics.diagram.stubs.DiagramResource;
19 import org.simantics.district.network.DistrictNetworkUtil;
20 import org.simantics.district.network.ontology.DistrictNetworkResource;
21 import org.simantics.district.network.profile.MidBranchEdgeSetRequest;
22 import org.simantics.layer0.Layer0;
23 import org.simantics.scenegraph.INode;
24 import org.simantics.scenegraph.profile.EvaluationContext;
25 import org.simantics.scenegraph.profile.common.ProfileVariables;
26 import org.simantics.scl.compiler.top.ValueNotFound;
27 import org.simantics.scl.osgi.SCLOsgi;
28 import org.simantics.scl.runtime.SCLContext;
29 import org.simantics.scl.runtime.function.Function1;
30 import org.simantics.structural.stubs.StructuralResource2;
31
32 public class DistrictNetworkStaticInfoStyle extends StyleBase<DistrictNetworkStaticInfoStyle.StyleResult> {
33
34         private static final String ACTIONS_MODULE = "Actions";
35         private static final String PIPELINE_INFO = "pipelineInfo";
36         
37         public static class StyleResult {
38                 public StyleResult(Point2D p1, Point2D p2, String info) {
39                         this.p1 = p1;
40                         this.p2 = p2;
41                         this.info = info;
42                 }
43                 
44                 public Point2D p1;
45                 public Point2D p2;
46                 public String info;
47         }
48         
49         public DistrictNetworkStaticInfoStyle(Resource style) {
50                 super(style);
51         }
52         
53         @Override
54         public StyleResult calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource mapElement)
55                         throws DatabaseException {
56                 DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
57                 
58                 boolean isEdge = graph.isInstanceOf(mapElement, DN.Edge);
59                 boolean isVertex = graph.isInstanceOf(mapElement, DN.Vertex);
60                 if (!isEdge && !isVertex)
61                         return null;
62                 
63                 if (isEdge) {
64                         Resource diagram = graph.getSingleObject(mapElement, Layer0.getInstance(graph).PartOf);
65                         Set<Resource> edgesToUse = graph.syncRequest(new MidBranchEdgeSetRequest(diagram), TransientCacheListener.instance());
66                         if (!edgesToUse.contains(mapElement))
67                                 return null;
68                 }
69                 
70                 DiagramResource DIA = DiagramResource.getInstance(graph);
71                 StructuralResource2 STR = StructuralResource2.getInstance(graph);
72                 
73                 Resource module = DistrictNetworkUtil.getMappedComponentCached(graph, mapElement);
74                 if (module == null)
75                         return null;
76
77                 Resource moduleType = graph.getPossibleType(module, STR.Component);
78                 if (moduleType == null)
79                         return null;
80                 
81                 Function1<Variable, String> function = getUCPipelineInfoFunctionCached(graph, moduleType);
82                 if (function == null)
83                         return null;
84                 
85                 String result;
86                 try {
87                         Variable variable = Variables.getVariable(graph, module);
88                         Variable moduleVariable = Variables.possibleActiveVariable(graph, variable);
89                         if (moduleVariable == null)
90                                 moduleVariable = variable;
91
92                         result = Simantics.applySCLRead(graph, function, moduleVariable);
93                 } catch (PendingVariableException | MissingVariableValueException e) {
94                         result = null;
95                 }
96                 
97                 if (isVertex) {
98                         double[] coords = graph.getRelatedValue(mapElement, DIA.HasLocation);
99                         Point2D p = DistrictNetworkNodeUtils.calculatePoint2D(new Point2D.Double(coords[0], coords[1]), null);
100                         return new StyleResult(p, p, result);
101                 }
102                 else if (isEdge) {
103                         Resource v1 = graph.getSingleObject(mapElement, DN.HasStartVertex);
104                         double[] coords1 = graph.getRelatedValue(v1, DIA.HasLocation);
105                         Resource v2 = graph.getSingleObject(mapElement, DN.HasEndVertex);
106                         double[] coords2 = graph.getRelatedValue(v2, DIA.HasLocation);
107                         Point2D p1 = DistrictNetworkNodeUtils.calculatePoint2D(new Point2D.Double(coords1[0], coords1[1]), null);
108                         Point2D p2 = DistrictNetworkNodeUtils.calculatePoint2D(new Point2D.Double(coords2[0], coords2[1]), null);
109                         
110                         return new StyleResult(p1, p2, result);
111                 }
112                 
113                 return null;
114         }
115         
116         @Override
117         public void applyStyleForNode(EvaluationContext evaluationContext, INode parent, StyleResult result) {
118                 if (result == null) {
119                         cleanupStyleForNode(evaluationContext, parent);
120                         return;
121                 }
122                 
123                 DistrictNetworkStaticInfoNode node = ProfileVariables.claimChild(parent, "*", DistrictNetworkStaticInfoNode.NODE_KEY, DistrictNetworkStaticInfoNode.class, evaluationContext);
124                 if (node == null)
125                         return;
126
127                 Point2D p1 = result.p1;
128                 Point2D p2 = result.p2;
129                 
130                 if (p1.equals(p2)) {
131                         node.setLocation(p1, new Point2D.Double(1.0, 0.0));
132                 }
133                 else {
134                         double sign = Math.signum(p1.getX() - p2.getX());
135                         Point2D.Double origin = new Point2D.Double(0.5 * (p1.getX() + p2.getX()), 0.5 * (p1.getY() + p2.getY()));
136                         Point2D direction = new Point2D.Double(0.5 * sign * (p1.getX() - p2.getX()), 0.5 * sign * (p1.getY() - p2.getY()));
137                         
138                         node.setLocation(origin, direction);
139                 }
140                 
141                 node.setInfo(result.info);
142         }
143         
144         private static Function1<Variable, String> getUCPipelineInfoFunctionCached(ReadGraph graph, Resource componentType)
145                         throws DatabaseException {
146                 return graph.syncRequest(new UCPipelineInfoRequest(componentType), TransientCacheListener.instance());
147         }
148         
149         private static final class UCPipelineInfoRequest extends ResourceRead<Function1<Variable, String>> {
150                 public UCPipelineInfoRequest(Resource resource) {
151                         super(resource);
152                 }
153
154                 @SuppressWarnings("unchecked")
155                 @Override
156                 public Function1<Variable, String> perform(ReadGraph graph) throws DatabaseException {
157                         Resource actionsModule = Layer0Utils.getPossibleChild(graph, resource, ACTIONS_MODULE);
158                         if (actionsModule == null || !graph.isInstanceOf(actionsModule, Layer0.getInstance(graph).SCLModule))
159                                 return null;
160                         
161                         String uri = graph.getURI(actionsModule);
162                         SCLContext sclContext = SCLContext.getCurrent();
163                         Object oldGraph = sclContext.get("graph");
164                         try {
165                                 sclContext.put("graph", graph);
166                                 return (Function1<Variable, String>) SCLOsgi.MODULE_REPOSITORY.getValue(uri, PIPELINE_INFO);
167                         } catch (ValueNotFound e1) {
168                                 return null;
169                         } finally {
170                                 sclContext.put("graph", oldGraph);
171                         }
172                 }
173         }
174         
175         @Override
176         protected void cleanupStyleForNode(EvaluationContext evaluationContext, INode node) {
177                 ProfileVariables.denyChild(node, "*", DistrictNetworkStaticInfoNode.NODE_KEY);
178         }
179 }