]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/NetworkDrawingNode.java
Implement district features to Simantics platform
[simantics/district.git] / org.simantics.district.network.ui / src / org / simantics / district / network / ui / nodes / NetworkDrawingNode.java
1 package org.simantics.district.network.ui.nodes;
2
3 import java.awt.BasicStroke;
4 import java.awt.Color;
5 import java.awt.Graphics2D;
6 import java.awt.Stroke;
7 import java.awt.geom.Path2D;
8 import java.awt.geom.Point2D;
9 import java.awt.geom.Rectangle2D;
10 import java.util.ArrayList;
11 import java.util.Iterator;
12 import java.util.List;
13
14 import org.simantics.Simantics;
15 import org.simantics.db.Resource;
16 import org.simantics.db.WriteGraph;
17 import org.simantics.db.common.request.WriteRequest;
18 import org.simantics.db.exception.DatabaseException;
19 import org.simantics.diagram.ui.DiagramModelHints;
20 import org.simantics.district.network.ui.DNEdgeBuilder;
21 import org.simantics.district.network.ui.NetworkDrawingParticipant;
22 import org.simantics.g2d.canvas.Hints;
23 import org.simantics.g2d.canvas.IToolMode;
24 import org.simantics.g2d.diagram.IDiagram;
25 import org.simantics.scenegraph.g2d.G2DNode;
26 import org.simantics.scenegraph.g2d.events.EventTypes;
27 import org.simantics.scenegraph.g2d.events.MouseEvent;
28 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseClickEvent;
29 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDoubleClickedEvent;
30 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;
31 import org.simantics.scenegraph.utils.GeometryUtils;
32 import org.simantics.scenegraph.utils.NodeUtil;
33
34 public class NetworkDrawingNode extends G2DNode {
35
36     private static final long serialVersionUID = -3475301184009620573L;
37     
38     private List<Point2D> nodes = new ArrayList<>();
39
40     private Resource diagramResource;
41
42     private boolean committed;
43
44     private NetworkDrawingParticipant participant;
45
46     private IDiagram diagram;
47
48     private static final Stroke DASHED_STROKE = new BasicStroke(2.0f,
49             BasicStroke.CAP_ROUND,
50             BasicStroke.JOIN_ROUND,
51             4.0f, new float[]{4.0f}, 0.0f);
52
53     private static final Color BLUE_ALPHA = new Color(0, 0, 255, 100);
54
55     private boolean scaleStroke = true;
56     
57     @Override
58     public void init() {
59         super.init();
60         addEventHandler(this);
61     }
62     
63     public void setNetworkDrawingParticipant(NetworkDrawingParticipant participant) {
64         this.participant = participant;
65     }
66     
67     public void setDiagram(IDiagram diagram) {
68         if (diagram != null) {
69             this.diagram = diagram;
70             this.diagramResource = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE);
71         }
72     }
73
74     @Override
75     public void render(Graphics2D g2d) {
76         
77         Path2D path = new Path2D.Double();
78         Iterator<Point2D> nodeIter = nodes.iterator();
79         if (nodeIter.hasNext()) {
80             Point2D node = nodeIter.next();
81             path.moveTo(node.getX(), node.getY());
82         }
83         while (nodeIter.hasNext()) {
84             Point2D node = nodeIter.next();
85             path.lineTo(node.getX(), node.getY());
86         }
87         
88         Color old = g2d.getColor();
89         Stroke oldStroke = g2d.getStroke();
90         
91         if (DASHED_STROKE != null) {
92             if (scaleStroke && DASHED_STROKE instanceof BasicStroke) {
93                 BasicStroke bs = GeometryUtils.scaleStroke(DASHED_STROKE, (float) (1.0 / GeometryUtils.getScale(g2d.getTransform())));
94                 g2d.setStroke(bs);
95             } else {
96                 g2d.setStroke(DASHED_STROKE);
97             }
98         }
99         
100         g2d.setColor(BLUE_ALPHA);
101
102         g2d.draw(path);
103         
104         g2d.setStroke(oldStroke);
105         g2d.setColor(old);
106     }
107
108     @Override
109     public Rectangle2D getBoundsInLocal() {
110         return null;
111     }
112     
113     @Override
114     public int getEventMask() {
115         return EventTypes.MouseMask;
116     }
117     
118     @Override
119     protected boolean mouseDoubleClicked(MouseDoubleClickedEvent e) {
120         // nodes to path2d
121         IToolMode mode = getToolMode();
122         if (mode == Hints.CONNECTTOOL || e.hasAnyModifier(MouseEvent.ALT_MASK | MouseEvent.ALT_GRAPH_MASK)) {
123             Point2D start = null;
124             Point2D end = null;
125             Iterator<Point2D> nodeIter = nodes.iterator();
126             while (nodeIter.hasNext()) {
127                 if (end == null) {
128                     start = nodeIter.next();
129                 } else {
130                     start = end;
131                 }
132                 end = nodeIter.next();
133                 
134                 createEdge(start, end);
135             }
136             
137             nodes.clear();
138             committed = true;
139             
140             repaint();
141             
142             return true;
143         }
144         return super.mouseDoubleClicked(e);
145     }
146     
147     private void createEdge(Point2D start, Point2D end) {
148         double[] startCoords = new double[] { start.getX(), start.getY() };
149         double[] endCoords = new double[] { end.getX(), end.getY() };
150         
151         DNEdgeBuilder builder = new DNEdgeBuilder(diagramResource, diagram);
152         Simantics.getSession().asyncRequest(new WriteRequest() {
153             
154             @Override
155             public void perform(WriteGraph graph) throws DatabaseException {
156                 builder.create(graph, startCoords, endCoords);
157             }
158         });
159         
160     }
161     
162     @Override
163     protected boolean mouseClicked(MouseClickEvent e) {
164         // check ToolMode
165         IToolMode mode = getToolMode();
166         if (mode == Hints.CONNECTTOOL || e.hasAnyModifier(MouseEvent.ALT_MASK | MouseEvent.ALT_GRAPH_MASK)) {
167             if (committed) {
168                 committed = false;
169                 return false;
170             }
171             Point2D localPos = NodeUtil.worldToLocal(this, e.controlPosition, new Point2D.Double());
172             nodes.add(new Point2D.Double(localPos.getX(), localPos.getY()));
173             
174             repaint();
175             return true;
176         }
177         return super.mouseClicked(e);
178     }
179     
180     private IToolMode getToolMode() {
181         return participant.getHint(Hints.KEY_TOOL);
182     }
183
184     @Override
185     protected boolean mouseMoved(MouseMovedEvent e) {
186         return super.mouseMoved(e);
187     }
188 }