1 package org.simantics.district.network.ui.nodes;
3 import java.awt.geom.Point2D;
4 import java.util.Collections;
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.PendingVariableException;
15 import org.simantics.db.layer0.util.Layer0Utils;
16 import org.simantics.db.layer0.variable.Variable;
17 import org.simantics.db.layer0.variable.Variables;
18 import org.simantics.diagram.profile.StyleBase;
19 import org.simantics.diagram.stubs.DiagramResource;
20 import org.simantics.district.network.DistrictNetworkUtil;
21 import org.simantics.district.network.ontology.DistrictNetworkResource;
22 import org.simantics.layer0.Layer0;
23 import org.simantics.modeling.ModelingResources;
24 import org.simantics.scenegraph.INode;
25 import org.simantics.scenegraph.profile.EvaluationContext;
26 import org.simantics.scenegraph.profile.common.ProfileVariables;
27 import org.simantics.scl.compiler.top.ValueNotFound;
28 import org.simantics.scl.osgi.SCLOsgi;
29 import org.simantics.scl.runtime.SCLContext;
30 import org.simantics.scl.runtime.function.Function1;
31 import org.simantics.scl.runtime.tuple.Tuple3;
32 import org.simantics.structural.stubs.StructuralResource2;
34 public class DistrictNetworkHoverInfoStyle extends StyleBase<DistrictNetworkHoverInfoStyle.StyleResult> {
36 private static final String ACTIONS_MODULE = "Actions";
37 private static final String HOVER_CONTRIBUTION = "hoverContribution";
39 public class StyleResult {
43 public StyleResult(Point2D origin, List<Tuple3> labels) {
48 public Point2D getOrigin() {
52 public List<Tuple3> getLabels() {
57 public DistrictNetworkHoverInfoStyle(Resource style) throws DatabaseException {
63 protected Resource getConfigurationComponent(ReadGraph graph, Resource element) throws DatabaseException {
64 ModelingResources MOD = ModelingResources.getInstance(graph);
65 DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
67 Resource mappedElement = graph.getPossibleObject(element, DN.MappedComponent);
68 return mappedElement != null ? graph.getPossibleObject(mappedElement, MOD.ElementToComponent) : null;
72 public StyleResult calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry,
73 Resource mapElement, Variable configuration) throws DatabaseException {
74 DiagramResource DIA = DiagramResource.getInstance(graph);
75 StructuralResource2 STR = StructuralResource2.getInstance(graph);
77 String variableURI = graph.getPossibleRelatedValue(runtimeDiagram, DIA.RuntimeDiagram_HasVariable, Bindings.STRING);
78 Variable activeVariable = org.simantics.db.layer0.variable.Variables.getPossibleVariable(graph, variableURI);
79 if (activeVariable == null)
82 Resource module = DistrictNetworkUtil.getMappedComponentCached(graph, mapElement);
86 Resource moduleType = graph.getPossibleType(module, STR.Component);
87 if (moduleType == null)
90 Function1<Variable, List<Tuple3>> function = getUCTextGridFunctionCached(graph, moduleType);
96 Variable variable = Variables.getVariable(graph, module);
97 Variable moduleVariable = Variables.possibleActiveVariable(graph, variable);
98 if (moduleVariable == null)
99 moduleVariable = variable;
101 result = Simantics.applySCLRead(graph, function, moduleVariable);
102 } catch (PendingVariableException e) {
103 result = Collections.singletonList(new Tuple3("<pending>", "", ""));
107 DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
108 if (graph.isInstanceOf(mapElement, DN.Vertex)) {
109 double[] coords = graph.getRelatedValue(mapElement, DIA.HasLocation);
110 point = DistrictNetworkNodeUtils.calculatePoint2D(new Point2D.Double(coords[0], coords[1]), null);
112 else if (graph.isInstanceOf(mapElement, DN.Edge)) {
113 Resource v1 = graph.getSingleObject(mapElement, DN.HasStartVertex);
114 double[] coords1 = graph.getRelatedValue(v1, DIA.HasLocation);
115 Resource v2 = graph.getSingleObject(mapElement, DN.HasEndVertex);
116 double[] coords2 = graph.getRelatedValue(v2, DIA.HasLocation);
117 point = DistrictNetworkNodeUtils.calculatePoint2D(new Point2D.Double((coords1[0] + coords2[0]) / 2, (coords1[1] + coords2[1]) / 2), null);
123 return new StyleResult(point, result);
127 public void applyStyleForNode(EvaluationContext observer, INode parent, StyleResult results) {
128 if (results == null) {
129 cleanupStyleForNode(observer, parent);
133 DistrictNetworkHoverInfoNode node = ProfileVariables.claimChild(parent, "*", DistrictNetworkHoverInfoNode.NODE_KEY, DistrictNetworkHoverInfoNode.class, observer);
137 node.setLabels(results.getLabels());
138 node.setOrigin(results.getOrigin());
142 protected void cleanupStyleForNode(EvaluationContext observer, INode node) {
143 ProfileVariables.denyChild(node, "*", DistrictNetworkHoverInfoNode.NODE_KEY);
146 private static Function1<Variable, List<Tuple3>> getUCTextGridFunctionCached(ReadGraph graph, Resource componentType)
147 throws DatabaseException {
148 return graph.syncRequest(new UCTextGridFunctionRequest(componentType), TransientCacheListener.instance());
151 private static final class UCTextGridFunctionRequest extends ResourceRead<Function1<Variable, List<Tuple3>>> {
152 public UCTextGridFunctionRequest(Resource resource) {
156 @SuppressWarnings("unchecked")
158 public Function1<Variable, List<Tuple3>> perform(ReadGraph graph) throws DatabaseException {
159 Resource actionsModule = Layer0Utils.getPossibleChild(graph, resource, ACTIONS_MODULE);
160 if (actionsModule == null || !graph.isInstanceOf(actionsModule, Layer0.getInstance(graph).SCLModule))
163 String uri = graph.getURI(actionsModule);
164 SCLContext sclContext = SCLContext.getCurrent();
165 Object oldGraph = sclContext.get("graph");
167 sclContext.put("graph", graph);
168 return (Function1<Variable, List<Tuple3>>) SCLOsgi.MODULE_REPOSITORY.getValue(uri, HOVER_CONTRIBUTION);
169 } catch (ValueNotFound e1) {
172 sclContext.put("graph", oldGraph);