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

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