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

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

sonar - squid:S3052 - Fields should not be initialized to default values

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