X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.district.network.ui%2Fsrc%2Forg%2Fsimantics%2Fdistrict%2Fnetwork%2Fui%2Fstyles%2FDistrictNetworkStaticInfoStyle.java;fp=org.simantics.district.network.ui%2Fsrc%2Forg%2Fsimantics%2Fdistrict%2Fnetwork%2Fui%2Fstyles%2FDistrictNetworkStaticInfoStyle.java;h=e452a17b1f52188d8ab43b48de2a4302c5ad2a8a;hb=38cb4b0b42c4c35a696bb46ffcf8129ca8d89103;hp=0000000000000000000000000000000000000000;hpb=4e9851013456ea1a8aa20eee5e33ccb97eed03ef;p=simantics%2Fdistrict.git diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/styles/DistrictNetworkStaticInfoStyle.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/styles/DistrictNetworkStaticInfoStyle.java new file mode 100644 index 00000000..e452a17b --- /dev/null +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/styles/DistrictNetworkStaticInfoStyle.java @@ -0,0 +1,181 @@ +package org.simantics.district.network.ui.styles; + +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.district.network.ui.nodes.DistrictNetworkNodeUtils; +import org.simantics.district.network.ui.nodes.DistrictNetworkStaticInfoNode; +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 { + + 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); + + boolean isEdge = graph.isInstanceOf(mapElement, DN.Edge); + boolean isVertex = graph.isInstanceOf(mapElement, DN.Vertex); + if (!isEdge && !isVertex) + return null; + + if (isEdge) { + Resource diagram = graph.getSingleObject(mapElement, Layer0.getInstance(graph).PartOf); + Set 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 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; + } + + if (isVertex) { + double[] coords = graph.getRelatedValue(mapElement, DIA.HasLocation); + Point2D p = DistrictNetworkNodeUtils.calculatePoint2D(new Point2D.Double(coords[0], coords[1]), null); + return new StyleResult(p, p, result); + } + else if (isEdge) { + 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); + } + + return null; + } + + @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; + + if (p1.equals(p2)) { + node.setLocation(p1, new Point2D.Double(1.0, 0.0)); + } + else { + 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 getUCPipelineInfoFunctionCached(ReadGraph graph, Resource componentType) + throws DatabaseException { + return graph.syncRequest(new UCPipelineInfoRequest(componentType), TransientCacheListener.instance()); + } + + private static final class UCPipelineInfoRequest extends ResourceRead> { + public UCPipelineInfoRequest(Resource resource) { + super(resource); + } + + @SuppressWarnings("unchecked") + @Override + public Function1 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) 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); + } +}