]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.diagram/src/org/simantics/diagram/participant/ConnectionCrossingsParticipant.java
Configurable connection crossing styles
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / participant / ConnectionCrossingsParticipant.java
diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/participant/ConnectionCrossingsParticipant.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/participant/ConnectionCrossingsParticipant.java
new file mode 100644 (file)
index 0000000..10949ca
--- /dev/null
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.diagram.participant;
+
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.request.UnaryRead;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.procedure.Listener;
+import org.simantics.diagram.connection.rendering.ConnectionCrossings;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.g2d.canvas.ICanvasContext;
+import org.simantics.g2d.canvas.SGDesignation;
+import org.simantics.g2d.canvas.impl.SGNodeReflection.SGCleanup;
+import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;
+import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant;
+import org.simantics.scenegraph.g2d.G2DParentNode;
+import org.simantics.scenegraph.g2d.nodes.ConnectionCrossingsNode;
+import org.simantics.utils.datastructures.Pair;
+import org.simantics.utils.ui.ErrorLogger;
+
+public class ConnectionCrossingsParticipant extends AbstractDiagramParticipant {
+    private static final String CONNECTION_CROSSINGS_NODE_KEY = "connection-crossings";
+
+    private ConnectionCrossingsNode ccNode;
+    private final ConnectionCrossings crossings = new ConnectionCrossings();
+    private ConnectionCrossingStyleListener listener;
+    private Resource diagram;
+    
+    public ConnectionCrossingsParticipant(Resource diagram) {
+        this.diagram = diagram;
+    }
+    public ConnectionCrossingsParticipant(double width, ConnectionCrossings.Type type) {
+        crossings.setWidth(width);
+        crossings.setType(type);
+    }
+
+    @SGInit(designation = SGDesignation.CONTROL)
+    public void initSG(G2DParentNode parent) {
+        ccNode = parent.addNode(CONNECTION_CROSSINGS_NODE_KEY, ConnectionCrossingsNode.class);
+        ccNode.setCrossings(crossings);
+        ccNode.setZIndex(Integer.MIN_VALUE / 4);
+    }
+
+    @SGCleanup
+    public void cleanupSG() {
+        if (ccNode != null) {
+            ccNode.remove();
+            ccNode = null;
+        }
+    }
+
+    @Override
+    public void addedToContext(ICanvasContext ctx) {
+        super.addedToContext(ctx);
+
+        if (diagram != null) {
+            listener = new ConnectionCrossingStyleListener(ctx);
+            Simantics.getSession().async(new UnaryRead<Resource, Pair<Double, ConnectionCrossings.Type>>(diagram){
+    
+                @Override
+                public Pair<Double, ConnectionCrossings.Type> perform(ReadGraph graph) throws DatabaseException {
+                    DiagramResource DIA = DiagramResource.getInstance(graph);
+                    Double gap = graph.getPossibleRelatedValue(diagram, DIA.ConnectionCrossingStyle_Width);
+                    Resource typeRes = graph.getPossibleObject(diagram, DIA.ConnectionCrossingStyle_HasType);
+                    ConnectionCrossings.Type type;
+                    if (DIA.ConnectionCrossingStyle_Type_Gap.equals(typeRes)) {
+                        type = ConnectionCrossings.Type.GAP;
+                    } else if (DIA.ConnectionCrossingStyle_Type_Arc.equals(typeRes)) {
+                        type = ConnectionCrossings.Type.ARC;
+                    } else if (DIA.ConnectionCrossingStyle_Type_Square.equals(typeRes)) {
+                        type = ConnectionCrossings.Type.SQUARE;
+                    } else { 
+                        type = ConnectionCrossings.Type.NONE;
+                    }
+                    return new Pair<>(gap, type);
+                }
+                
+            }, listener);
+        }
+    }
+
+    @Override
+    public void removedFromContext(ICanvasContext ctx) {
+        if (listener != null) {
+            listener.dispose();
+            listener = null;
+        }
+        super.removedFromContext(ctx);
+    }
+
+    class ConnectionCrossingStyleListener implements Listener<Pair<Double, ConnectionCrossings.Type>> {
+        ICanvasContext context;
+        public ConnectionCrossingStyleListener(ICanvasContext context) {
+            this.context = context;
+        }
+        @Override
+        public void execute(final Pair<Double, ConnectionCrossings.Type> result) {
+            context.getThreadAccess().asyncExec(new Runnable() {
+                @Override
+                public void run() {
+                    ICanvasContext ctx = context;
+                    if (ctx == null)
+                        return;
+                    if (ctx.isDisposed())
+                        return;
+                    crossings.setWidth(result.first != null ? result.first : 0.0);
+                    crossings.setType(result.second);
+                    ccNode.repaint();
+                }
+            });
+        }
+        public void dispose() {
+            context = null;
+        }
+        @Override
+        public boolean isDisposed() {
+            return context == null || context.isDisposed();
+        }
+        @Override
+        public void exception(Throwable t) {
+            ErrorLogger.defaultLogError(t);
+        }
+    }
+
+}