source: josm/trunk/src/org/openstreetmap/josm/gui/MapMover.java@ 8510

Last change on this file since 8510 was 8510, checked in by Don-vip, 9 years ago

checkstyle: enable relevant whitespace checks and fix them

  • Property svn:eol-style set to native
File size: 10.6 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.Cursor;
7import java.awt.Point;
8import java.awt.event.ActionEvent;
9import java.awt.event.KeyEvent;
10import java.awt.event.MouseAdapter;
11import java.awt.event.MouseEvent;
12import java.awt.event.MouseMotionListener;
13import java.awt.event.MouseWheelEvent;
14import java.awt.event.MouseWheelListener;
15
16import javax.swing.AbstractAction;
17import javax.swing.ActionMap;
18import javax.swing.InputMap;
19import javax.swing.JComponent;
20import javax.swing.JPanel;
21import javax.swing.KeyStroke;
22
23import org.openstreetmap.josm.Main;
24import org.openstreetmap.josm.actions.mapmode.SelectAction;
25import org.openstreetmap.josm.data.coor.EastNorth;
26import org.openstreetmap.josm.tools.Destroyable;
27import org.openstreetmap.josm.tools.Shortcut;
28
29/**
30 * Enables moving of the map by holding down the right mouse button and drag
31 * the mouse. Also, enables zooming by the mouse wheel.
32 *
33 * @author imi
34 */
35public class MapMover extends MouseAdapter implements MouseMotionListener, MouseWheelListener, Destroyable {
36
37 private final class ZoomerAction extends AbstractAction {
38 private final String action;
39
40 public ZoomerAction(String action) {
41 this.action = action;
42 }
43
44 @Override
45 public void actionPerformed(ActionEvent e) {
46 if (".".equals(action) || ",".equals(action)) {
47 Point mouse = nc.getMousePosition();
48 if (mouse == null)
49 mouse = new Point((int) nc.getBounds().getCenterX(), (int) nc.getBounds().getCenterY());
50 MouseWheelEvent we = new MouseWheelEvent(nc, e.getID(), e.getWhen(), e.getModifiers(), mouse.x, mouse.y, 0, false,
51 MouseWheelEvent.WHEEL_UNIT_SCROLL, 1, ",".equals(action) ? -1 : 1);
52 mouseWheelMoved(we);
53 } else {
54 EastNorth center = nc.getCenter();
55 EastNorth newcenter = nc.getEastNorth(nc.getWidth()/2+nc.getWidth()/5, nc.getHeight()/2+nc.getHeight()/5);
56 switch(action) {
57 case "left":
58 nc.zoomTo(new EastNorth(2*center.east()-newcenter.east(), center.north()));
59 break;
60 case "right":
61 nc.zoomTo(new EastNorth(newcenter.east(), center.north()));
62 break;
63 case "up":
64 nc.zoomTo(new EastNorth(center.east(), 2*center.north()-newcenter.north()));
65 break;
66 case "down":
67 nc.zoomTo(new EastNorth(center.east(), newcenter.north()));
68 break;
69 }
70 }
71 }
72 }
73
74 /**
75 * The point in the map that was the under the mouse point
76 * when moving around started.
77 */
78 private EastNorth mousePosMove;
79 /**
80 * The map to move around.
81 */
82 private final NavigatableComponent nc;
83 private final JPanel contentPane;
84
85 private boolean movementInPlace = false;
86
87 /**
88 * Constructs a new {@code MapMover}.
89 * @param navComp the navigatable component
90 * @param contentPane the content pane
91 */
92 public MapMover(NavigatableComponent navComp, JPanel contentPane) {
93 this.nc = navComp;
94 this.contentPane = contentPane;
95 nc.addMouseListener(this);
96 nc.addMouseMotionListener(this);
97 nc.addMouseWheelListener(this);
98
99 if (contentPane != null) {
100 contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
101 Shortcut.registerShortcut("system:movefocusright", tr("Map: {0}", tr("Move right")), KeyEvent.VK_RIGHT, Shortcut.CTRL).getKeyStroke(),
102 "MapMover.Zoomer.right");
103 contentPane.getActionMap().put("MapMover.Zoomer.right", new ZoomerAction("right"));
104
105 contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
106 Shortcut.registerShortcut("system:movefocusleft", tr("Map: {0}", tr("Move left")), KeyEvent.VK_LEFT, Shortcut.CTRL).getKeyStroke(),
107 "MapMover.Zoomer.left");
108 contentPane.getActionMap().put("MapMover.Zoomer.left", new ZoomerAction("left"));
109
110 contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
111 Shortcut.registerShortcut("system:movefocusup", tr("Map: {0}", tr("Move up")), KeyEvent.VK_UP, Shortcut.CTRL).getKeyStroke(),
112 "MapMover.Zoomer.up");
113 contentPane.getActionMap().put("MapMover.Zoomer.up", new ZoomerAction("up"));
114
115 contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
116 Shortcut.registerShortcut("system:movefocusdown", tr("Map: {0}", tr("Move down")), KeyEvent.VK_DOWN, Shortcut.CTRL).getKeyStroke(),
117 "MapMover.Zoomer.down");
118 contentPane.getActionMap().put("MapMover.Zoomer.down", new ZoomerAction("down"));
119
120 // see #10592 - Disable these alternate shortcuts on OS X because of conflict with system shortcut
121 if (!Main.isPlatformOsx()) {
122 contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
123 Shortcut.registerShortcut("view:zoominalternate",
124 tr("Map: {0}", tr("Zoom in")), KeyEvent.VK_COMMA, Shortcut.CTRL).getKeyStroke(),
125 "MapMover.Zoomer.in");
126 contentPane.getActionMap().put("MapMover.Zoomer.in", new ZoomerAction(","));
127
128 contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
129 Shortcut.registerShortcut("view:zoomoutalternate",
130 tr("Map: {0}", tr("Zoom out")), KeyEvent.VK_PERIOD, Shortcut.CTRL).getKeyStroke(),
131 "MapMover.Zoomer.out");
132 contentPane.getActionMap().put("MapMover.Zoomer.out", new ZoomerAction("."));
133 }
134 }
135 }
136
137 /**
138 * If the right (and only the right) mouse button is pressed, move the map.
139 */
140 @Override
141 public void mouseDragged(MouseEvent e) {
142 int offMask = MouseEvent.BUTTON1_DOWN_MASK | MouseEvent.BUTTON2_DOWN_MASK;
143 int macMouseMask = MouseEvent.CTRL_DOWN_MASK | MouseEvent.BUTTON1_DOWN_MASK;
144 boolean stdMovement = (e.getModifiersEx() & (MouseEvent.BUTTON3_DOWN_MASK | offMask)) == MouseEvent.BUTTON3_DOWN_MASK;
145 boolean macMovement = Main.isPlatformOsx() && e.getModifiersEx() == macMouseMask;
146 boolean allowedMode = !Main.map.mapModeSelect.equals(Main.map.mapMode)
147 || SelectAction.Mode.SELECT.equals(Main.map.mapModeSelect.getMode());
148 if (stdMovement || (macMovement && allowedMode)) {
149 if (mousePosMove == null)
150 startMovement(e);
151 EastNorth center = nc.getCenter();
152 EastNorth mouseCenter = nc.getEastNorth(e.getX(), e.getY());
153 nc.zoomTo(new EastNorth(
154 mousePosMove.east() + center.east() - mouseCenter.east(),
155 mousePosMove.north() + center.north() - mouseCenter.north()));
156 } else {
157 endMovement();
158 }
159 }
160
161 /**
162 * Start the movement, if it was the 3rd button (right button).
163 */
164 @Override
165 public void mousePressed(MouseEvent e) {
166 int offMask = MouseEvent.BUTTON1_DOWN_MASK | MouseEvent.BUTTON2_DOWN_MASK;
167 int macMouseMask = MouseEvent.CTRL_DOWN_MASK | MouseEvent.BUTTON1_DOWN_MASK;
168 if (e.getButton() == MouseEvent.BUTTON3 && (e.getModifiersEx() & offMask) == 0 ||
169 Main.isPlatformOsx() && e.getModifiersEx() == macMouseMask) {
170 startMovement(e);
171 }
172 }
173
174 /**
175 * Change the cursor back to it's pre-move cursor.
176 */
177 @Override
178 public void mouseReleased(MouseEvent e) {
179 if (e.getButton() == MouseEvent.BUTTON3 || Main.isPlatformOsx() && e.getButton() == MouseEvent.BUTTON1) {
180 endMovement();
181 }
182 }
183
184 /**
185 * Start movement by setting a new cursor and remember the current mouse
186 * position.
187 * @param e The mouse event that leat to the movement from.
188 */
189 private void startMovement(MouseEvent e) {
190 if (movementInPlace)
191 return;
192 movementInPlace = true;
193 mousePosMove = nc.getEastNorth(e.getX(), e.getY());
194 nc.setNewCursor(Cursor.MOVE_CURSOR, this);
195 }
196
197 /**
198 * End the movement. Setting back the cursor and clear the movement variables
199 */
200 private void endMovement() {
201 if (!movementInPlace)
202 return;
203 movementInPlace = false;
204 nc.resetCursor(this);
205 mousePosMove = null;
206 }
207
208 /**
209 * Zoom the map by 1/5th of current zoom per wheel-delta.
210 * @param e The wheel event.
211 */
212 @Override
213 public void mouseWheelMoved(MouseWheelEvent e) {
214 nc.zoomToFactor(e.getX(), e.getY(), Math.pow(Math.sqrt(2), e.getWheelRotation()));
215 }
216
217 /**
218 * Emulates dragging on Mac OSX.
219 */
220 @Override
221 public void mouseMoved(MouseEvent e) {
222 if (!movementInPlace)
223 return;
224 // Mac OSX simulates with ctrl + mouse 1 the second mouse button hence no dragging events get fired.
225 // Is only the selected mouse button pressed?
226 if (Main.isPlatformOsx()) {
227 if (e.getModifiersEx() == MouseEvent.CTRL_DOWN_MASK) {
228 if (mousePosMove == null) {
229 startMovement(e);
230 }
231 EastNorth center = nc.getCenter();
232 EastNorth mouseCenter = nc.getEastNorth(e.getX(), e.getY());
233 nc.zoomTo(new EastNorth(mousePosMove.east() + center.east() - mouseCenter.east(), mousePosMove.north()
234 + center.north() - mouseCenter.north()));
235 } else {
236 endMovement();
237 }
238 }
239 }
240
241 @Override
242 public void destroy() {
243 if (this.contentPane != null) {
244 InputMap inputMap = contentPane.getInputMap();
245 KeyStroke[] inputKeys = inputMap.keys();
246 if (inputKeys != null) {
247 for (KeyStroke key : inputKeys) {
248 Object binding = inputMap.get(key);
249 if (binding instanceof String && ((String) binding).startsWith("MapMover.")) {
250 inputMap.remove(key);
251 }
252 }
253 }
254 ActionMap actionMap = contentPane.getActionMap();
255 Object[] actionsKeys = actionMap.keys();
256 if (actionsKeys != null) {
257 for (Object key : actionsKeys) {
258 if (key instanceof String && ((String) key).startsWith("MapMover.")) {
259 actionMap.remove(key);
260 }
261 }
262 }
263 }
264 }
265}
Note: See TracBrowser for help on using the repository browser.