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

Last change on this file since 86 was 86, checked in by imi, 18 years ago
  • added conflicts and resolve conflict dialog

This is one of those "changed everything" checkpoint.

File size: 4.0 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.Segment;
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 segment between two nodes by pressing on the
20 * starting node and dragging to the ending node.
21 *
22 * No segment can be created if there is already a segment containing
23 * both nodes.
24 *
25 * @author imi
26 */
27public class AddSegmentAction 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 AddSegmentAction.
45 * @param mapFrame The MapFrame this action belongs to.
46 */
47 public AddSegmentAction(MapFrame mapFrame) {
48 super("Add segment", "addlinesegment", "Add a segment between two nodes.", "G", KeyEvent.VK_G, mapFrame);
49 }
50
51 @Override public void registerListener() {
52 super.registerListener();
53 mv.addMouseListener(this);
54 mv.addMouseMotionListener(this);
55 }
56
57 @Override public void unregisterListener() {
58 super.unregisterListener();
59 mv.removeMouseListener(this);
60 mv.removeMouseMotionListener(this);
61 drawHint(false);
62 }
63
64
65 @Override public void actionPerformed(ActionEvent e) {
66 super.actionPerformed(e);
67 makeSegment();
68 }
69
70 /**
71 * If user clicked on a node, from the dragging with that node.
72 */
73 @Override public void mousePressed(MouseEvent e) {
74 if (e.getButton() != MouseEvent.BUTTON1)
75 return;
76
77 OsmPrimitive clicked = mv.getNearest(e.getPoint(), true);
78 if (clicked == null || !(clicked instanceof Node))
79 return;
80
81 drawHint(false);
82 first = second = (Node)clicked;
83 }
84
85 /**
86 * Draw a hint which nodes will get connected if the user release
87 * the mouse button now.
88 */
89 @Override public void mouseDragged(MouseEvent e) {
90 if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) == 0)
91 return;
92
93 OsmPrimitive clicked = mv.getNearest(e.getPoint(), (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0);
94 if (clicked == null || clicked == second || !(clicked instanceof Node))
95 return;
96
97 drawHint(false);
98
99 second = (Node)clicked;
100 drawHint(true);
101 }
102
103 /**
104 * If left button was released, try to create the segment.
105 */
106 @Override public void mouseReleased(MouseEvent e) {
107 if (e.getButton() == MouseEvent.BUTTON1) {
108 makeSegment();
109 first = null; // release segment drawing
110 }
111 }
112
113 /**
114 * Create the segment if first and second are different and there is
115 * not already a segment.
116 */
117 private void makeSegment() {
118 if (first == null || second == null) {
119 first = null;
120 second = null;
121 return;
122 }
123
124 drawHint(false);
125
126 Node start = first;
127 Node end = second;
128 first = second;
129 second = null;
130
131 if (start != end) {
132 // try to find a segment
133 for (Segment ls : Main.ds.segments)
134 if ((start == ls.from && end == ls.to) || (end == ls.from && start == ls.to))
135 return; // already a segment here - be happy, do nothing.
136
137 Segment ls = new Segment(start, end);
138 mv.editLayer().add(new AddCommand(Main.ds, ls));
139 }
140
141 mv.repaint();
142 }
143
144 /**
145 * Draw or remove the hint line, depending on the parameter.
146 */
147 private void drawHint(boolean draw) {
148 if (draw == hintDrawn)
149 return;
150 if (first == null || second == null)
151 return;
152 if (second == first)
153 return;
154
155 Graphics g = mv.getGraphics();
156 g.setColor(Color.BLACK);
157 g.setXORMode(Color.WHITE);
158 Point firstDrawn = mv.getPoint(first.eastNorth);
159 Point secondDrawn = mv.getPoint(second.eastNorth);
160 g.drawLine(firstDrawn.x, firstDrawn.y, secondDrawn.x, secondDrawn.y);
161 hintDrawn = !hintDrawn;
162 }
163}
Note: See TracBrowser for help on using the repository browser.