source: josm/src/org/openstreetmap/josm/actions/mapmode/AddLineSegmentAction.java@ 7

Last change on this file since 7 was 7, checked in by imi, 19 years ago

added mapmodes for adding and combining stuff. Reorganized images

File size: 4.7 KB
Line 
1package org.openstreetmap.josm.actions.mapmode;
2
3import java.awt.Color;
4import java.awt.Graphics;
5import java.awt.Point;
6import java.awt.event.KeyEvent;
7import java.awt.event.MouseEvent;
8import java.awt.event.MouseListener;
9
10import javax.swing.JOptionPane;
11
12import org.openstreetmap.josm.data.osm.LineSegment;
13import org.openstreetmap.josm.data.osm.Node;
14import org.openstreetmap.josm.data.osm.OsmPrimitive;
15import org.openstreetmap.josm.data.osm.Track;
16import org.openstreetmap.josm.gui.Main;
17import org.openstreetmap.josm.gui.MapFrame;
18
19/**
20 * The user can add a new line segment between two nodes by pressing on the
21 * starting node and dragging to the ending node.
22 *
23 * If the Alt key was pressed when releasing the mouse, this action tries to
24 * add the line segment to a track. The new line segment gets added to all tracks
25 * of the first node that end in the first node. If no tracks are found, the
26 * line segment gets added to all tracks in the second node that start with
27 * the second node.
28 *
29 * No line segment can be created if there is already a line segment containing
30 * both nodes in the same order.
31 *
32 * @author imi
33 */
34public class AddLineSegmentAction extends MapMode implements MouseListener {
35
36 /**
37 * The first node the user pressed the button onto.
38 */
39 private Node first;
40 /**
41 * The second node used if the user releases the button.
42 */
43 private Node second;
44
45 /**
46 * Whether the hint is currently drawn on screen.
47 */
48 private boolean hintDrawn = false;
49
50 /**
51 * Create a new AddLineSegmentAction.
52 * @param mapFrame The MapFrame this action belongs to.
53 */
54 public AddLineSegmentAction(MapFrame mapFrame) {
55 super("Add Line Segment", "addlinesegment", "Add a line segment between two nodes.", KeyEvent.VK_L, mapFrame);
56 }
57
58 @Override
59 public void registerListener() {
60 super.registerListener();
61 mv.addMouseListener(this);
62 mv.addMouseMotionListener(this);
63 }
64
65 @Override
66 public void unregisterListener() {
67 super.unregisterListener();
68 mv.removeMouseListener(this);
69 mv.removeMouseMotionListener(this);
70 drawHint(false);
71 }
72
73 /**
74 * If user clicked on a node, start the dragging with that node.
75 */
76 @Override
77 public void mousePressed(MouseEvent e) {
78 if (e.getButton() != MouseEvent.BUTTON1)
79 return;
80
81 OsmPrimitive clicked = mv.getNearest(e.getPoint(), false);
82 if (clicked == null || !(clicked instanceof Node))
83 return;
84
85 drawHint(false);
86 first = second = (Node)clicked;
87 }
88
89 /**
90 * Draw a hint which nodes will get connected if the user release
91 * the mouse button now.
92 */
93 @Override
94 public void mouseDragged(MouseEvent e) {
95 if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) == 0)
96 return;
97
98 OsmPrimitive clicked = mv.getNearest(e.getPoint(), (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0);
99 if (clicked == null || clicked == second || !(clicked instanceof Node))
100 return;
101
102 drawHint(false);
103
104 second = (Node)clicked;
105 drawHint(true);
106 }
107
108 /**
109 * Create the line segment if first and second are different and there is
110 * not already a line segment.
111 */
112 @Override
113 public void mouseReleased(MouseEvent e) {
114 if (e.getButton() != MouseEvent.BUTTON1)
115 return;
116
117 if (first == null || second == null) {
118 first = null;
119 second = null;
120 return;
121 }
122
123 drawHint(false);
124
125 Node start = first;
126 Node end = second;
127 first = null;
128 second = null;
129
130 if (start != end) {
131 // try to find a line segment
132 for (Track t : ds.tracks)
133 for (LineSegment ls : t.segments)
134 if (start == ls.start && end == ls.end) {
135 JOptionPane.showMessageDialog(Main.main, "There is already an line segment with the same direction between the selected nodes.");
136 return;
137 }
138
139 LineSegment ls = new LineSegment(start, end);
140 boolean foundTrack = false;
141
142 if (((e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0)) {
143 // find a track for the new line segment
144 for (Track t : ds.tracks) {
145 if (t.getEndingNode() == start) {
146 t.segments.add(ls);
147 foundTrack = true;
148 }
149 }
150 if (!foundTrack) {
151 for (Track t : ds.tracks) {
152 if (t.getStartingNode() == end) {
153 t.segments.add(0,ls);
154 foundTrack = true;
155 }
156 }
157 }
158 }
159 if (!foundTrack)
160 ds.pendingLineSegments.add(ls);
161 }
162
163 mv.repaint();
164 }
165
166 /**
167 * Draw or remove the hint line, depending on the parameter.
168 */
169 private void drawHint(boolean draw) {
170 if (draw == hintDrawn)
171 return;
172 if (first == null || second == null)
173 return;
174 if (second == first)
175 return;
176
177 Graphics g = mv.getGraphics();
178 g.setColor(Color.BLACK);
179 g.setXORMode(Color.WHITE);
180 Point firstDrawn = mv.getScreenPoint(first.coor);
181 Point secondDrawn = mv.getScreenPoint(second.coor);
182 g.drawLine(firstDrawn.x, firstDrawn.y, secondDrawn.x, secondDrawn.y);
183 hintDrawn = !hintDrawn;
184 }
185}
Note: See TracBrowser for help on using the repository browser.