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

Last change on this file since 68 was 68, checked in by imi, 18 years ago
  • Remove Alt from hotkeys ('n' for new node, not Alt-n)
  • use command line options to open files/start or download (--help for a list)
File size: 4.1 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.ActionEvent;
7import java.awt.event.KeyEvent;
8import java.awt.event.MouseEvent;
9import java.awt.event.MouseListener;
10
11import org.openstreetmap.josm.Main;
12import org.openstreetmap.josm.command.AddCommand;
13import org.openstreetmap.josm.data.osm.LineSegment;
14import org.openstreetmap.josm.data.osm.Node;
15import org.openstreetmap.josm.data.osm.OsmPrimitive;
16import org.openstreetmap.josm.gui.MapFrame;
17
18/**
19 * The user can add a new line segment between two nodes by pressing on the
20 * starting node and dragging to the ending node.
21 *
22 * No line segment can be created if there is already a line segment containing
23 * both nodes.
24 *
25 * @author imi
26 */
27public class AddLineSegmentAction extends MapMode implements MouseListener {
28
29 /**
30 * The first node the user pressed the button onto.
31 */
32 private Node first;
33 /**
34 * The second node used if the user releases the button.
35 */
36 private Node second;
37
38 /**
39 * Whether the hint is currently drawn on screen.
40 */
41 private boolean hintDrawn = false;
42
43 /**
44 * Create a new AddLineSegmentAction.
45 * @param mapFrame The MapFrame this action belongs to.
46 */
47 public AddLineSegmentAction(MapFrame mapFrame) {
48 super("Add Line Segment", "addlinesegment", "Add a line segment between two nodes.", "G", KeyEvent.VK_G, mapFrame);
49 }
50
51 @Override
52 public void registerListener() {
53 super.registerListener();
54 mv.addMouseListener(this);
55 mv.addMouseMotionListener(this);
56 }
57
58 @Override
59 public void unregisterListener() {
60 super.unregisterListener();
61 mv.removeMouseListener(this);
62 mv.removeMouseMotionListener(this);
63 drawHint(false);
64 }
65
66
67 @Override
68 public void actionPerformed(ActionEvent e) {
69 super.actionPerformed(e);
70 makeLineSegment();
71 }
72
73 /**
74 * If user clicked on a node, from 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(), true);
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 * If left button was released, try to create the line segment.
110 */
111 @Override
112 public void mouseReleased(MouseEvent e) {
113 if (e.getButton() == MouseEvent.BUTTON1) {
114 makeLineSegment();
115 first = null; // release line segment drawing
116 }
117 }
118
119 /**
120 * Create the line segment if first and second are different and there is
121 * not already a line segment.
122 */
123 private void makeLineSegment() {
124 if (first == null || second == null) {
125 first = null;
126 second = null;
127 return;
128 }
129
130 drawHint(false);
131
132 Node start = first;
133 Node end = second;
134 first = second;
135 second = null;
136
137 if (start != end) {
138 // try to find a line segment
139 for (LineSegment ls : Main.main.ds.lineSegments)
140 if ((start == ls.from && end == ls.to) || (end == ls.from && start == ls.to))
141 return; // already a line segment here - be happy, do nothing.
142
143 LineSegment ls = new LineSegment(start, end);
144 mv.editLayer().add(new AddCommand(Main.main.ds, ls));
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}
Note: See TracBrowser for help on using the repository browser.