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

Last change on this file since 6113 was 6105, checked in by Don-vip, 11 years ago

see #8902 - Small performance enhancements / coding style (patch by shinigami):

  • removed useles null checks before instanceof
  • Property svn:eol-style set to native
File size: 10.0 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
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.data.coor.EastNorth;
25import org.openstreetmap.josm.tools.Destroyable;
26import org.openstreetmap.josm.tools.PlatformHookOsx;
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 public ZoomerAction(String action) {
40 this.action = action;
41 }
42 @Override
43 public void actionPerformed(ActionEvent e) {
44 if (action.equals(".") || action.equals(",")) {
45 Point mouse = nc.getMousePosition();
46 if (mouse == null)
47 mouse = new Point((int)nc.getBounds().getCenterX(), (int)nc.getBounds().getCenterY());
48 MouseWheelEvent we = new MouseWheelEvent(nc, e.getID(), e.getWhen(), e.getModifiers(), mouse.x, mouse.y, 0, false, MouseWheelEvent.WHEEL_UNIT_SCROLL, 1, action.equals(",") ? -1 : 1);
49 mouseWheelMoved(we);
50 } else {
51 EastNorth center = nc.getCenter();
52 EastNorth newcenter = nc.getEastNorth(nc.getWidth()/2+nc.getWidth()/5, nc.getHeight()/2+nc.getHeight()/5);
53 if (action.equals("left"))
54 nc.zoomTo(new EastNorth(2*center.east()-newcenter.east(), center.north()));
55 else if (action.equals("right"))
56 nc.zoomTo(new EastNorth(newcenter.east(), center.north()));
57 else if (action.equals("up"))
58 nc.zoomTo(new EastNorth(center.east(), 2*center.north()-newcenter.north()));
59 else if (action.equals("down"))
60 nc.zoomTo(new EastNorth(center.east(), newcenter.north()));
61 }
62 }
63 }
64
65 /**
66 * The point in the map that was the under the mouse point
67 * when moving around started.
68 */
69 private EastNorth mousePosMove;
70 /**
71 * The map to move around.
72 */
73 private final NavigatableComponent nc;
74 private final JPanel contentPane;
75
76 private boolean movementInPlace = false;
77
78 /**
79 * Create a new MapMover
80 */
81 public MapMover(NavigatableComponent navComp, JPanel contentPane) {
82 this.nc = navComp;
83 this.contentPane = contentPane;
84 nc.addMouseListener(this);
85 nc.addMouseMotionListener(this);
86 nc.addMouseWheelListener(this);
87
88 if (contentPane != null) {
89 contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
90 Shortcut.registerShortcut("system:movefocusright", tr("Map: {0}", tr("Move right")), KeyEvent.VK_RIGHT, Shortcut.CTRL).getKeyStroke(),
91 "MapMover.Zoomer.right");
92 contentPane.getActionMap().put("MapMover.Zoomer.right", new ZoomerAction("right"));
93
94 contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
95 Shortcut.registerShortcut("system:movefocusleft", tr("Map: {0}", tr("Move left")), KeyEvent.VK_LEFT, Shortcut.CTRL).getKeyStroke(),
96 "MapMover.Zoomer.left");
97 contentPane.getActionMap().put("MapMover.Zoomer.left", new ZoomerAction("left"));
98
99 contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
100 Shortcut.registerShortcut("system:movefocusup", tr("Map: {0}", tr("Move up")), KeyEvent.VK_UP, Shortcut.CTRL).getKeyStroke(),
101 "MapMover.Zoomer.up");
102 contentPane.getActionMap().put("MapMover.Zoomer.up", new ZoomerAction("up"));
103
104 contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
105 Shortcut.registerShortcut("system:movefocusdown", tr("Map: {0}", tr("Move down")), KeyEvent.VK_DOWN, Shortcut.CTRL).getKeyStroke(),
106 "MapMover.Zoomer.down");
107 contentPane.getActionMap().put("MapMover.Zoomer.down", new ZoomerAction("down"));
108
109 contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
110 Shortcut.registerShortcut("view:zoominalternate", tr("Map: {0}", tr("Zoom in")), KeyEvent.VK_COMMA, Shortcut.CTRL).getKeyStroke(),
111 "MapMover.Zoomer.in");
112 contentPane.getActionMap().put("MapMover.Zoomer.in", new ZoomerAction(","));
113
114 contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
115 Shortcut.registerShortcut("view:zoomoutalternate", tr("Map: {0}", tr("Zoom out")), KeyEvent.VK_PERIOD, Shortcut.CTRL).getKeyStroke(),
116 "MapMover.Zoomer.out");
117 contentPane.getActionMap().put("MapMover.Zoomer.out", new ZoomerAction("."));
118 }
119 }
120
121 /**
122 * If the right (and only the right) mouse button is pressed, move the map
123 */
124 @Override
125 public void mouseDragged(MouseEvent e) {
126 int offMask = MouseEvent.BUTTON1_DOWN_MASK | MouseEvent.BUTTON2_DOWN_MASK;
127 if ((e.getModifiersEx() & (MouseEvent.BUTTON3_DOWN_MASK | offMask)) == MouseEvent.BUTTON3_DOWN_MASK) {
128 if (mousePosMove == null)
129 startMovement(e);
130 EastNorth center = nc.getCenter();
131 EastNorth mouseCenter = nc.getEastNorth(e.getX(), e.getY());
132 nc.zoomTo(new EastNorth(
133 mousePosMove.east() + center.east() - mouseCenter.east(),
134 mousePosMove.north() + center.north() - mouseCenter.north()));
135 } else
136 endMovement();
137 }
138
139 /**
140 * Start the movement, if it was the 3rd button (right button).
141 */
142 @Override public void mousePressed(MouseEvent e) {
143 int offMask = MouseEvent.BUTTON1_DOWN_MASK | MouseEvent.BUTTON2_DOWN_MASK;
144 int macMouseMask = MouseEvent.CTRL_DOWN_MASK | MouseEvent.BUTTON1_DOWN_MASK;
145 if (e.getButton() == MouseEvent.BUTTON3 && (e.getModifiersEx() & offMask) == 0) {
146 startMovement(e);
147 } else if (isPlatformOsx() && e.getModifiersEx() == macMouseMask) {
148 startMovement(e);
149 }
150 }
151
152 /**
153 * Change the cursor back to it's pre-move cursor.
154 */
155 @Override public void mouseReleased(MouseEvent e) {
156 if (e.getButton() == MouseEvent.BUTTON3) {
157 endMovement();
158 } else if (isPlatformOsx() && e.getButton() == MouseEvent.BUTTON1) {
159 endMovement();
160 }
161 }
162
163 /**
164 * Start movement by setting a new cursor and remember the current mouse
165 * position.
166 * @param e The mouse event that leat to the movement from.
167 */
168 private void startMovement(MouseEvent e) {
169 if (movementInPlace)
170 return;
171 movementInPlace = true;
172 mousePosMove = nc.getEastNorth(e.getX(), e.getY());
173 nc.setNewCursor(Cursor.MOVE_CURSOR, this);
174 }
175
176 /**
177 * End the movement. Setting back the cursor and clear the movement variables
178 */
179 private void endMovement() {
180 if (!movementInPlace)
181 return;
182 movementInPlace = false;
183 nc.resetCursor(this);
184 mousePosMove = null;
185 }
186
187 /**
188 * Zoom the map by 1/5th of current zoom per wheel-delta.
189 * @param e The wheel event.
190 */
191 @Override
192 public void mouseWheelMoved(MouseWheelEvent e) {
193 nc.zoomToFactor(e.getX(), e.getY(), Math.pow(Math.sqrt(2), e.getWheelRotation()));
194 }
195
196 /**
197 * Emulates dragging on Mac OSX
198 */
199 @Override
200 public void mouseMoved(MouseEvent e) {
201 if (!movementInPlace)
202 return;
203 // Mac OSX simulates with ctrl + mouse 1 the second mouse button hence no dragging events get fired.
204 // Is only the selected mouse button pressed?
205 if (isPlatformOsx()) {
206 if (e.getModifiersEx() == MouseEvent.CTRL_DOWN_MASK) {
207 if (mousePosMove == null) {
208 startMovement(e);
209 }
210 EastNorth center = nc.getCenter();
211 EastNorth mouseCenter = nc.getEastNorth(e.getX(), e.getY());
212 nc.zoomTo(new EastNorth(mousePosMove.east() + center.east() - mouseCenter.east(), mousePosMove.north()
213 + center.north() - mouseCenter.north()));
214 } else {
215 endMovement();
216 }
217 }
218 }
219
220 /**
221 * Replies true if we are currently running on OSX
222 *
223 * @return true if we are currently running on OSX
224 */
225 public static boolean isPlatformOsx() {
226 return Main.platform instanceof PlatformHookOsx;
227 }
228
229 @Override
230 public void destroy() {
231 if (this.contentPane != null) {
232 InputMap inputMap = contentPane.getInputMap();
233 KeyStroke[] inputKeys = inputMap.keys();
234 if (inputKeys != null) {
235 for (KeyStroke key : inputKeys) {
236 Object binding = inputMap.get(key);
237 if (binding instanceof String && ((String)binding).startsWith("MapMover.")) {
238 inputMap.remove(key);
239 }
240 }
241 }
242 ActionMap actionMap = contentPane.getActionMap();
243 Object[] actionsKeys = actionMap.keys();
244 if (actionsKeys != null) {
245 for (Object key : actionsKeys) {
246 if (key instanceof String && ((String)key).startsWith("MapMover.")) {
247 actionMap.remove(key);
248 }
249 }
250 }
251 }
252 }
253}
Note: See TracBrowser for help on using the repository browser.