source: josm/src/org/openstreetmap/josm/actions/mapmode/AddSegmentAction.java@ 140

Last change on this file since 140 was 140, checked in by imi, 18 years ago
  • when creating a segment, add to selection instead of replace
File size: 4.6 KB
Line 
1package org.openstreetmap.josm.actions.mapmode;
2
3import static org.openstreetmap.josm.tools.I18n.tr;
4
5import java.awt.Color;
6import java.awt.Graphics;
7import java.awt.Point;
8import java.awt.event.ActionEvent;
9import java.awt.event.KeyEvent;
10import java.awt.event.MouseEvent;
11import java.awt.event.MouseListener;
12import java.util.Collection;
13
14import org.openstreetmap.josm.Main;
15import org.openstreetmap.josm.command.AddCommand;
16import org.openstreetmap.josm.data.osm.Node;
17import org.openstreetmap.josm.data.osm.OsmPrimitive;
18import org.openstreetmap.josm.data.osm.Segment;
19import org.openstreetmap.josm.gui.MapFrame;
20import org.openstreetmap.josm.tools.ImageProvider;
21
22/**
23 * The user can add a new segment between two nodes by pressing on the
24 * starting node and dragging to the ending node.
25 *
26 * No segment can be created if there is already a segment containing
27 * both nodes.
28 *
29 * @author imi
30 */
31public class AddSegmentAction extends MapMode implements MouseListener {
32
33 /**
34 * The first node the user pressed the button onto.
35 */
36 private Node first;
37 /**
38 * The second node used if the user releases the button.
39 */
40 private Node second;
41
42 /**
43 * Whether the hint is currently drawn on screen.
44 */
45 private boolean hintDrawn = false;
46
47 /**
48 * Create a new AddSegmentAction.
49 * @param mapFrame The MapFrame this action belongs to.
50 */
51 public AddSegmentAction(MapFrame mapFrame) {
52 super(tr("Add segment"),
53 "addsegment",
54 tr("Add a segment between two nodes."),
55 KeyEvent.VK_G,
56 mapFrame,
57 ImageProvider.getCursor("normal", "segment"));
58 }
59
60 @Override public void enterMode() {
61 super.enterMode();
62 Main.map.mapView.addMouseListener(this);
63 Main.map.mapView.addMouseMotionListener(this);
64 }
65
66 @Override public void exitMode() {
67 super.exitMode();
68 Main.map.mapView.removeMouseListener(this);
69 Main.map.mapView.removeMouseMotionListener(this);
70 drawHint(false);
71 }
72
73
74 @Override public void actionPerformed(ActionEvent e) {
75 super.actionPerformed(e);
76 makeSegment();
77 }
78
79 /**
80 * If user clicked on a node, from the dragging with that node.
81 */
82 @Override public void mousePressed(MouseEvent e) {
83 if (e.getButton() != MouseEvent.BUTTON1)
84 return;
85
86 OsmPrimitive clicked = Main.map.mapView.getNearest(e.getPoint(), true);
87 if (clicked == null || !(clicked instanceof Node))
88 return;
89
90 drawHint(false);
91 first = second = (Node)clicked;
92 }
93
94 /**
95 * Draw a hint which nodes will get connected if the user release
96 * the mouse button now.
97 */
98 @Override public void mouseDragged(MouseEvent e) {
99 if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) == 0)
100 return;
101
102 OsmPrimitive clicked = Main.map.mapView.getNearest(e.getPoint(), (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0);
103 if (clicked == null || clicked == second || !(clicked instanceof Node))
104 return;
105
106 drawHint(false);
107
108 second = (Node)clicked;
109 drawHint(true);
110 }
111
112 /**
113 * If left button was released, try to create the segment.
114 */
115 @Override public void mouseReleased(MouseEvent e) {
116 if (e.getButton() == MouseEvent.BUTTON1) {
117 makeSegment();
118 first = null; // release segment drawing
119 }
120 }
121
122 /**
123 * Create the segment if first and second are different and there is
124 * not already a segment.
125 */
126 private void makeSegment() {
127 if (first == null || second == null) {
128 first = null;
129 second = null;
130 return;
131 }
132
133 drawHint(false);
134
135 Node start = first;
136 Node end = second;
137 first = second;
138 second = null;
139
140 if (start != end) {
141 // try to find a segment
142 for (Segment ls : Main.ds.segments)
143 if (!ls.deleted && ((start == ls.from && end == ls.to) || (end == ls.from && start == ls.to)))
144 return; // already a segment here - be happy, do nothing.
145
146 Segment ls = new Segment(start, end);
147 Main.main.editLayer().add(new AddCommand(ls));
148 Collection<OsmPrimitive> sel = Main.ds.getSelected();
149 sel.add(ls);
150 Main.ds.setSelected(sel);
151 }
152
153 Main.map.mapView.repaint();
154 }
155
156 /**
157 * Draw or remove the hint line, depending on the parameter.
158 */
159 private void drawHint(boolean draw) {
160 if (draw == hintDrawn)
161 return;
162 if (first == null || second == null)
163 return;
164 if (second == first)
165 return;
166
167 Graphics g = Main.map.mapView.getGraphics();
168 g.setColor(Color.BLACK);
169 g.setXORMode(Color.WHITE);
170 Point firstDrawn = Main.map.mapView.getPoint(first.eastNorth);
171 Point secondDrawn = Main.map.mapView.getPoint(second.eastNorth);
172 g.drawLine(firstDrawn.x, firstDrawn.y, secondDrawn.x, secondDrawn.y);
173 hintDrawn = !hintDrawn;
174 }
175}
Note: See TracBrowser for help on using the repository browser.