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

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