]> gerrit.simantics Code Review - simantics/district.git/blobdiff - org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkHoverInfoStyle.java
Hover label profile for district elements.
[simantics/district.git] / org.simantics.district.network.ui / src / org / simantics / district / network / ui / nodes / DistrictNetworkHoverInfoStyle.java
diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkHoverInfoStyle.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkHoverInfoStyle.java
new file mode 100644 (file)
index 0000000..590903e
--- /dev/null
@@ -0,0 +1,176 @@
+package org.simantics.district.network.ui.nodes;
+
+import java.awt.geom.Point2D;
+import java.util.Collections;
+import java.util.List;
+
+import org.simantics.Simantics;
+import org.simantics.databoard.Bindings;
+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.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.layer0.Layer0;
+import org.simantics.modeling.ModelingResources;
+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.scl.runtime.tuple.Tuple3;
+import org.simantics.structural.stubs.StructuralResource2;
+
+public class DistrictNetworkHoverInfoStyle extends StyleBase<DistrictNetworkHoverInfoStyle.StyleResult> {
+
+       private static final String ACTIONS_MODULE = "Actions";
+       private static final String HOVER_CONTRIBUTION = "hoverContribution";
+
+       public class StyleResult {
+               Point2D origin;
+               List<Tuple3> labels;
+
+               public StyleResult(Point2D origin, List<Tuple3> labels) {
+                       this.origin = origin;
+                       this.labels = labels;
+               }
+
+               public Point2D getOrigin() {
+                       return origin;
+               }
+
+               public List<Tuple3> getLabels() {
+                       return labels;
+               }
+       }
+       
+       public DistrictNetworkHoverInfoStyle(Resource style) throws DatabaseException {
+               super(style);
+       }
+       
+       String currentRowKey;
+       
+       protected Resource getConfigurationComponent(ReadGraph graph, Resource element) throws DatabaseException {
+               ModelingResources MOD = ModelingResources.getInstance(graph);
+               DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+               
+               Resource mappedElement = graph.getPossibleObject(element, DN.MappedComponent);
+               return mappedElement != null ? graph.getPossibleObject(mappedElement, MOD.ElementToComponent) : null;
+       }
+       
+       @Override
+       public StyleResult calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry,
+                       Resource mapElement, Variable configuration) throws DatabaseException {
+               DiagramResource DIA = DiagramResource.getInstance(graph);
+               StructuralResource2 STR = StructuralResource2.getInstance(graph);
+
+               String variableURI = graph.getPossibleRelatedValue(runtimeDiagram, DIA.RuntimeDiagram_HasVariable, Bindings.STRING);
+               Variable activeVariable = org.simantics.db.layer0.variable.Variables.getPossibleVariable(graph, variableURI);
+               if (activeVariable == null)
+                       return null;
+
+               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, List<Tuple3>> function = getUCTextGridFunctionCached(graph, moduleType);
+               if (function == null)
+                       return null;
+               
+               List<Tuple3> 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 e) {
+                       result = Collections.singletonList(new Tuple3("<pending>", "", ""));
+               }
+               
+               Point2D point;
+               DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+               if (graph.isInstanceOf(mapElement, DN.Vertex)) {
+                       double[] coords = graph.getRelatedValue(mapElement, DIA.HasLocation);
+                       point = DistrictNetworkNodeUtils.calculatePoint2D(new Point2D.Double(coords[0], coords[1]), null);
+               }
+               else if (graph.isInstanceOf(mapElement, DN.Edge)) {
+                       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);
+                       point = DistrictNetworkNodeUtils.calculatePoint2D(new Point2D.Double((coords1[0] + coords2[0]) / 2, (coords1[1] + coords2[1]) / 2), null);
+               }
+               else {
+                       return null;
+               }
+               
+               return new StyleResult(point, result);
+       }
+       
+       @Override
+       public void applyStyleForNode(EvaluationContext observer, INode parent, StyleResult results) {
+               if (results == null) {
+                       cleanupStyleForNode(observer, parent);
+                       return;
+               }
+               
+               DistrictNetworkHoverInfoNode node = ProfileVariables.claimChild(parent, "*", DistrictNetworkHoverInfoNode.NODE_KEY, DistrictNetworkHoverInfoNode.class, observer);
+               if (node == null)
+                       return;
+               
+               node.setLabels(results.getLabels());
+               node.setOrigin(results.getOrigin());
+       }
+       
+       @Override
+       protected void cleanupStyleForNode(EvaluationContext observer, INode node) {
+               ProfileVariables.denyChild(node, "*", DistrictNetworkHoverInfoNode.NODE_KEY);
+       }
+       
+       private static Function1<Variable, List<Tuple3>> getUCTextGridFunctionCached(ReadGraph graph, Resource componentType)
+                       throws DatabaseException {
+               return graph.syncRequest(new UCTextGridFunctionRequest(componentType), TransientCacheListener.instance());
+       }
+       
+       private static final class UCTextGridFunctionRequest extends ResourceRead<Function1<Variable, List<Tuple3>>> {
+               public UCTextGridFunctionRequest(Resource resource) {
+                       super(resource);
+               }
+
+               @SuppressWarnings("unchecked")
+               @Override
+               public Function1<Variable, List<Tuple3>> 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, List<Tuple3>>) SCLOsgi.MODULE_REPOSITORY.getValue(uri, HOVER_CONTRIBUTION);
+                       } catch (ValueNotFound e1) {
+                               return null;
+                       } finally {
+                               sclContext.put("graph", oldGraph);
+                       }
+               }
+       }
+}