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

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

starting restructure of dataset. Checkpoint is broken!

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