]> gerrit.simantics Code Review - simantics/district.git/blob
147442343c13b6b7c3dfa42ab04694757aa4f834
[simantics/district.git] /
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.KeyEvent.KeyPressedEvent;
28 import org.simantics.scenegraph.g2d.events.MouseEvent;
29 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseClickEvent;
30 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDoubleClickedEvent;
31 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;
32 import org.simantics.scenegraph.utils.GeometryUtils;
33 import org.simantics.scenegraph.utils.NodeUtil;
34
35 public class NetworkDrawingNode extends G2DNode {
36
37     private static final long serialVersionUID = -3475301184009620573L;
38     
39     private Point2D currentMousePos = null;
40     
41     private List<Point2D> nodes = new ArrayList<>();
42
43     private Resource diagramResource;
44
45     private boolean committed;
46
47     private NetworkDrawingParticipant participant;
48
49     private IDiagram diagram;
50
51     private static final Stroke DASHED_STROKE = new BasicStroke(2.0f,
52             BasicStroke.CAP_ROUND,
53             BasicStroke.JOIN_ROUND,
54             4.0f, new float[]{4.0f}, 0.0f);
55
56     private static final Color BLUE_ALPHA = new Color(0, 0, 255, 100);
57
58     private boolean scaleStroke = true;
59     
60     @Override
61     public void init() {
62         super.init();
63         addEventHandler(this);
64     }
65     
66     public void setNetworkDrawingParticipant(NetworkDrawingParticipant participant) {
67         this.participant = participant;
68     }
69     
70     public void setDiagram(IDiagram diagram) {
71         if (diagram != null) {
72             this.diagram = diagram;
73             this.diagramResource = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE);
74         }
75     }
76
77     @Override
78     public void render(Graphics2D g2d) {
79         if (nodes.isEmpty())
80             return;
81         
82         Path2D path = new Path2D.Double();
83         Iterator<Point2D> nodeIter = nodes.iterator();
84         if (nodeIter.hasNext()) {
85             Point2D node = nodeIter.next();
86             path.moveTo(node.getX(), node.getY());
87         }
88         while (nodeIter.hasNext()) {
89             Point2D node = nodeIter.next();
90             path.lineTo(node.getX(), node.getY());
91         }
92         if (currentMousePos != null)
93             path.lineTo(currentMousePos.getX(), currentMousePos.getY());
94         
95         Color old = g2d.getColor();
96         Stroke oldStroke = g2d.getStroke();
97         
98         if (DASHED_STROKE != null) {
99             if (scaleStroke && DASHED_STROKE instanceof BasicStroke) {
100                 BasicStroke bs = GeometryUtils.scaleStroke(DASHED_STROKE, (float) (1.0 / GeometryUtils.getScale(g2d.getTransform())));
101                 g2d.setStroke(bs);
102             } else {
103                 g2d.setStroke(DASHED_STROKE);
104             }
105         }
106         
107         g2d.setColor(BLUE_ALPHA);
108
109         g2d.draw(path);
110         
111         g2d.setStroke(oldStroke);
112         g2d.setColor(old);
113     }
114
115     @Override
116     public Rectangle2D getBoundsInLocal() {
117         return null;
118     }
119     
120     @Override
121     public int getEventMask() {
122         return EventTypes.AnyMask;
123     }
124     
125     @Override
126     protected boolean mouseDoubleClicked(MouseDoubleClickedEvent e) {
127         // nodes to path2d
128         IToolMode mode = getToolMode();
129         if (mode == Hints.CONNECTTOOL || e.hasAnyModifier(MouseEvent.ALT_MASK | MouseEvent.ALT_GRAPH_MASK)) {
130             Point2D start = null;
131             Point2D end = null;
132             Iterator<Point2D> nodeIter = nodes.iterator();
133             while (nodeIter.hasNext()) {
134                 if (end == null) {
135                     start = nodeIter.next();
136                 } else {
137                     start = end;
138                 }
139                 end = nodeIter.next();
140                 
141                 createEdge(start, end);
142             }
143             
144             nodes.clear();
145             committed = true;
146             
147             repaint();
148             
149             return true;
150         }
151         return super.mouseDoubleClicked(e);
152     }
153     
154     private void createEdge(Point2D start, Point2D end) {
155         
156         double padding = GeometryUtils.getScale(getTransform());
157         
158         double[] startCoords = new double[] { start.getX(), start.getY() };
159         double[] endCoords = new double[] { end.getX(), end.getY() };
160         
161         DNEdgeBuilder builder = new DNEdgeBuilder(diagramResource, diagram);
162         Simantics.getSession().asyncRequest(new WriteRequest() {
163             
164             @Override
165             public void perform(WriteGraph graph) throws DatabaseException {
166                 builder.create(graph, startCoords, endCoords, padding);
167             }
168         });
169         
170     }
171
172     @Override
173     protected boolean mouseClicked(MouseClickEvent e) {
174         // check ToolMode
175         IToolMode mode = getToolMode();
176         if (mode == Hints.CONNECTTOOL || e.hasAnyModifier(MouseEvent.ALT_MASK | MouseEvent.ALT_GRAPH_MASK)) {
177             if (committed) {
178                 committed = false;
179                 return false;
180             }
181             if (e.button == MouseEvent.RIGHT_BUTTON && !nodes.isEmpty()) {
182                 nodes.remove(nodes.size() - 1);
183             } else if (e.button == MouseEvent.LEFT_BUTTON) {
184                 Point2D localPos = NodeUtil.worldToLocal(this, e.controlPosition, new Point2D.Double());
185                 nodes.add(new Point2D.Double(localPos.getX(), localPos.getY()));
186             }
187             repaint();
188             return true;
189         }
190         return super.mouseClicked(e);
191     }
192     
193     private IToolMode getToolMode() {
194         return participant.getHint(Hints.KEY_TOOL);
195     }
196
197     @Override
198     protected boolean mouseMoved(MouseMovedEvent e) {
199         IToolMode mode = getToolMode();
200         if (mode == Hints.CONNECTTOOL || e.hasAnyModifier(MouseEvent.ALT_MASK | MouseEvent.ALT_GRAPH_MASK)) {
201             boolean repaint = false;
202             Point2D p = NodeUtil.worldToLocal(this, e.controlPosition, new Point2D.Double());
203             if (participant.pickHoveredElement(p)) {
204                 repaint = true;
205             }
206             if (!nodes.isEmpty()) {
207                 currentMousePos = p;
208                 
209                 repaint();
210                 return true;
211             }
212             currentMousePos = null;
213             if (repaint == true)
214                 repaint();
215         }
216         return super.mouseMoved(e);
217     }
218     
219     @Override
220     protected boolean keyPressed(KeyPressedEvent e) {
221         if (e.keyCode == java.awt.event.KeyEvent.VK_ESCAPE) {
222             nodes.clear();
223             repaint();
224             return true;
225         }
226         return super.keyPressed(e);
227             
228     }
229 }