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