]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram/src/org/simantics/diagram/participant/ConnectionCrossingsParticipant.java
4dd5144757dc7c3843256bef976b0b5ad6c883aa
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / participant / ConnectionCrossingsParticipant.java
1 /*******************************************************************************
2  * Copyright (c) 2020 Association for Decentralized Information Management in
3  * Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     Semantum Oy - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.diagram.participant;
13
14 import org.simantics.Simantics;
15 import org.simantics.db.ReadGraph;
16 import org.simantics.db.Resource;
17 import org.simantics.db.common.request.UnaryRead;
18 import org.simantics.db.exception.DatabaseException;
19 import org.simantics.db.procedure.Listener;
20 import org.simantics.diagram.connection.rendering.ConnectionCrossings;
21 import org.simantics.diagram.stubs.DiagramResource;
22 import org.simantics.g2d.canvas.ICanvasContext;
23 import org.simantics.g2d.canvas.SGDesignation;
24 import org.simantics.g2d.canvas.impl.SGNodeReflection.SGCleanup;
25 import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;
26 import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant;
27 import org.simantics.scenegraph.g2d.G2DParentNode;
28 import org.simantics.scenegraph.g2d.nodes.ConnectionCrossingsNode;
29 import org.simantics.utils.datastructures.Pair;
30 import org.simantics.utils.ui.ErrorLogger;
31
32 public class ConnectionCrossingsParticipant extends AbstractDiagramParticipant {
33     private static final String CONNECTION_CROSSINGS_NODE_KEY = "connection-crossings";
34
35     private ConnectionCrossingsNode ccNode;
36     private final ConnectionCrossings crossings = new ConnectionCrossings();
37     private ConnectionCrossingStyleListener listener;
38     private Resource diagram;
39     
40     public ConnectionCrossingsParticipant(Resource diagram) {
41         this.diagram = diagram;
42     }
43     public ConnectionCrossingsParticipant(double width, ConnectionCrossings.Type type) {
44         crossings.setWidth(width);
45         crossings.setType(type);
46     }
47     
48     public ConnectionCrossingsParticipant(double width, ConnectionCrossings.Type type, boolean keepLines) {
49         crossings.setWidth(width);
50         crossings.setType(type);
51         crossings.setKeepLines(keepLines);
52     }
53
54     @SGInit(designation = SGDesignation.CONTROL)
55     public void initSG(G2DParentNode parent) {
56         ccNode = parent.addNode(CONNECTION_CROSSINGS_NODE_KEY, ConnectionCrossingsNode.class);
57         ccNode.setCrossings(crossings);
58         ccNode.setZIndex(Integer.MIN_VALUE / 4);
59     }
60
61     @SGCleanup
62     public void cleanupSG() {
63         if (ccNode != null) {
64             ccNode.remove();
65             ccNode = null;
66         }
67     }
68
69     @Override
70     public void addedToContext(ICanvasContext ctx) {
71         super.addedToContext(ctx);
72
73         if (diagram != null) {
74             listener = new ConnectionCrossingStyleListener(ctx);
75             Simantics.getSession().async(new UnaryRead<Resource, Pair<Double, ConnectionCrossings.Type>>(diagram){
76     
77                 @Override
78                 public Pair<Double, ConnectionCrossings.Type> perform(ReadGraph graph) throws DatabaseException {
79                     DiagramResource DIA = DiagramResource.getInstance(graph);
80                     Double gap = graph.getPossibleRelatedValue(diagram, DIA.ConnectionCrossingStyle_Width);
81                     Resource typeRes = graph.getPossibleObject(diagram, DIA.ConnectionCrossingStyle_HasType);
82                     ConnectionCrossings.Type type;
83                     if (DIA.ConnectionCrossingStyle_Type_Gap.equals(typeRes)) {
84                         type = ConnectionCrossings.Type.GAP;
85                     } else if (DIA.ConnectionCrossingStyle_Type_Arc.equals(typeRes)) {
86                         type = ConnectionCrossings.Type.ARC;
87                     } else if (DIA.ConnectionCrossingStyle_Type_Square.equals(typeRes)) {
88                         type = ConnectionCrossings.Type.SQUARE;
89                     } else { 
90                         type = ConnectionCrossings.Type.NONE;
91                     }
92                     return new Pair<>(gap, type);
93                 }
94                 
95             }, listener);
96         }
97     }
98
99     @Override
100     public void removedFromContext(ICanvasContext ctx) {
101         if (listener != null) {
102             listener.dispose();
103             listener = null;
104         }
105         super.removedFromContext(ctx);
106     }
107
108     class ConnectionCrossingStyleListener implements Listener<Pair<Double, ConnectionCrossings.Type>> {
109         ICanvasContext context;
110         public ConnectionCrossingStyleListener(ICanvasContext context) {
111             this.context = context;
112         }
113         @Override
114         public void execute(final Pair<Double, ConnectionCrossings.Type> result) {
115             context.getThreadAccess().asyncExec(new Runnable() {
116                 @Override
117                 public void run() {
118                     ICanvasContext ctx = context;
119                     if (ctx == null)
120                         return;
121                     if (ctx.isDisposed())
122                         return;
123                     crossings.setWidth(result.first != null ? result.first : 0.0);
124                     crossings.setType(result.second);
125                     ccNode.repaint();
126                 }
127             });
128         }
129         public void dispose() {
130             context = null;
131         }
132         @Override
133         public boolean isDisposed() {
134             return context == null || context.isDisposed();
135         }
136         @Override
137         public void exception(Throwable t) {
138             ErrorLogger.defaultLogError(t);
139         }
140     }
141     
142     public ConnectionCrossings getCrossings() {
143                 return crossings;
144         }
145
146 }