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

Last change on this file since 4067 was 3919, checked in by stoecker, 13 years ago

unify cursor handling, hopefully fix #5381

  • Property svn:eol-style set to native
File size: 8.8 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.JComponent;
18import javax.swing.JPanel;
19
20import org.openstreetmap.josm.Main;
21import org.openstreetmap.josm.data.coor.EastNorth;
22import org.openstreetmap.josm.tools.PlatformHookOsx;
23import org.openstreetmap.josm.tools.Shortcut;
24
25/**
26 * Enables moving of the map by holding down the right mouse button and drag
27 * the mouse. Also, enables zooming by the mouse wheel.
28 *
29 * @author imi
30 */
31public class MapMover extends MouseAdapter implements MouseMotionListener, MouseWheelListener {
32
33 private final class ZoomerAction extends AbstractAction {
34 private final String action;
35 public ZoomerAction(String action) {
36 this.action = action;
37 }
38 public void actionPerformed(ActionEvent e) {
39 if (action.equals(".") || action.equals(",")) {
40 Point mouse = nc.getMousePosition();
41 if (mouse == null)
42 mouse = new Point((int)nc.getBounds().getCenterX(), (int)nc.getBounds().getCenterY());
43 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);
44 mouseWheelMoved(we);
45 } else {
46 EastNorth center = nc.getCenter();
47 EastNorth newcenter = nc.getEastNorth(nc.getWidth()/2+nc.getWidth()/5, nc.getHeight()/2+nc.getHeight()/5);
48 if (action.equals("left"))
49 nc.zoomTo(new EastNorth(2*center.east()-newcenter.east(), center.north()));
50 else if (action.equals("right"))
51 nc.zoomTo(new EastNorth(newcenter.east(), center.north()));
52 else if (action.equals("up"))
53 nc.zoomTo(new EastNorth(center.east(), 2*center.north()-newcenter.north()));
54 else if (action.equals("down"))
55 nc.zoomTo(new EastNorth(center.east(), newcenter.north()));
56 }
57 }
58 }
59
60 /**
61 * The point in the map that was the under the mouse point
62 * when moving around started.
63 */
64 private EastNorth mousePosMove;
65 /**
66 * The map to move around.
67 */
68 private final NavigatableComponent nc;
69
70 private boolean movementInPlace = false;
71
72 /**
73 * Create a new MapMover
74 */
75 public MapMover(NavigatableComponent navComp, JPanel contentPane) {
76 this.nc = navComp;
77 nc.addMouseListener(this);
78 nc.addMouseMotionListener(this);
79 nc.addMouseWheelListener(this);
80
81 if (contentPane != null) {
82 contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
83 Shortcut.registerShortcut("system:movefocusright", tr("Map: {0}", tr("Move right")), KeyEvent.VK_RIGHT, Shortcut.GROUP_HOTKEY).getKeyStroke(),
84 "MapMover.Zoomer.right");
85 contentPane.getActionMap().put("MapMover.Zoomer.right", new ZoomerAction("right"));
86
87 contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
88 Shortcut.registerShortcut("system:movefocusleft", tr("Map: {0}", tr("Move left")), KeyEvent.VK_LEFT, Shortcut.GROUP_HOTKEY).getKeyStroke(),
89 "MapMover.Zoomer.left");
90 contentPane.getActionMap().put("MapMover.Zoomer.left", new ZoomerAction("left"));
91
92 contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
93 Shortcut.registerShortcut("system:movefocusup", tr("Map: {0}", tr("Move up")), KeyEvent.VK_UP, Shortcut.GROUP_HOTKEY).getKeyStroke(),
94 "MapMover.Zoomer.up");
95 contentPane.getActionMap().put("MapMover.Zoomer.up", new ZoomerAction("up"));
96
97 contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
98 Shortcut.registerShortcut("system:movefocusdown", tr("Map: {0}", tr("Move down")), KeyEvent.VK_DOWN, Shortcut.GROUP_HOTKEY).getKeyStroke(),
99 "MapMover.Zoomer.down");
100 contentPane.getActionMap().put("MapMover.Zoomer.down", new ZoomerAction("down"));
101
102 contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
103 Shortcut.registerShortcut("view:zoominalternate", tr("Map: {0}", tr("Zoom in")), KeyEvent.VK_COMMA, Shortcut.GROUP_HOTKEY).getKeyStroke(),
104 "MapMover.Zoomer.in");
105 contentPane.getActionMap().put("MapMover.Zoomer.in", new ZoomerAction(","));
106
107 contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
108 Shortcut.registerShortcut("view:zoomoutalternate", tr("Map: {0}", tr("Zoom out")), KeyEvent.VK_PERIOD, Shortcut.GROUP_HOTKEY).getKeyStroke(),
109 "MapMover.Zoomer.out");
110 contentPane.getActionMap().put("MapMover.Zoomer.out", new ZoomerAction("."));
111 }
112 }
113
114 /**
115 * If the right (and only the right) mouse button is pressed, move the map
116 */
117 public void mouseDragged(MouseEvent e) {
118 int offMask = MouseEvent.BUTTON1_DOWN_MASK | MouseEvent.BUTTON2_DOWN_MASK;
119 if ((e.getModifiersEx() & (MouseEvent.BUTTON3_DOWN_MASK | offMask)) == MouseEvent.BUTTON3_DOWN_MASK) {
120 if (mousePosMove == null)
121 startMovement(e);
122 EastNorth center = nc.getCenter();
123 EastNorth mouseCenter = nc.getEastNorth(e.getX(), e.getY());
124 nc.zoomTo(new EastNorth(
125 mousePosMove.east() + center.east() - mouseCenter.east(),
126 mousePosMove.north() + center.north() - mouseCenter.north()));
127 } else
128 endMovement();
129 }
130
131 /**
132 * Start the movement, if it was the 3rd button (right button).
133 */
134 @Override public void mousePressed(MouseEvent e) {
135 int offMask = MouseEvent.BUTTON1_DOWN_MASK | MouseEvent.BUTTON2_DOWN_MASK;
136 int macMouseMask = MouseEvent.CTRL_DOWN_MASK | MouseEvent.BUTTON1_DOWN_MASK;
137 if (e.getButton() == MouseEvent.BUTTON3 && (e.getModifiersEx() & offMask) == 0) {
138 startMovement(e);
139 } else if (isPlatformOsx() && e.getModifiersEx() == macMouseMask) {
140 startMovement(e);
141 }
142 }
143
144 /**
145 * Change the cursor back to it's pre-move cursor.
146 */
147 @Override public void mouseReleased(MouseEvent e) {
148 if (e.getButton() == MouseEvent.BUTTON3) {
149 endMovement();
150 } else if (isPlatformOsx() && e.getButton() == MouseEvent.BUTTON1) {
151 endMovement();
152 }
153 }
154
155 /**
156 * Start movement by setting a new cursor and remember the current mouse
157 * position.
158 * @param e The mouse event that leat to the movement from.
159 */
160 private void startMovement(MouseEvent e) {
161 if (movementInPlace)
162 return;
163 movementInPlace = true;
164 mousePosMove = nc.getEastNorth(e.getX(), e.getY());
165 nc.setNewCursor(Cursor.MOVE_CURSOR, this);
166 }
167
168 /**
169 * End the movement. Setting back the cursor and clear the movement variables
170 */
171 private void endMovement() {
172 if (!movementInPlace)
173 return;
174 movementInPlace = false;
175 nc.resetCursor(this);
176 mousePosMove = null;
177 }
178
179 /**
180 * Zoom the map by 1/5th of current zoom per wheel-delta.
181 * @param e The wheel event.
182 */
183 public void mouseWheelMoved(MouseWheelEvent e) {
184 nc.zoomToFactor(e.getX(), e.getY(), Math.pow(0.8, - e.getWheelRotation()));
185 }
186
187 /**
188 * Emulates dragging on Mac OSX
189 */
190 public void mouseMoved(MouseEvent e) {
191 if (!movementInPlace)
192 return;
193 // Mac OSX simulates with ctrl + mouse 1 the second mouse button hence no dragging events get fired.
194 // Is only the selected mouse button pressed?
195 if (isPlatformOsx()) {
196 if (e.getModifiersEx() == MouseEvent.CTRL_DOWN_MASK) {
197 if (mousePosMove == null) {
198 startMovement(e);
199 }
200 EastNorth center = nc.getCenter();
201 EastNorth mouseCenter = nc.getEastNorth(e.getX(), e.getY());
202 nc.zoomTo(new EastNorth(mousePosMove.east() + center.east() - mouseCenter.east(), mousePosMove.north()
203 + center.north() - mouseCenter.north()));
204 } else {
205 endMovement();
206 }
207 }
208 }
209
210 /**
211 * Replies true if we are currently running on OSX
212 *
213 * @return true if we are currently running on OSX
214 */
215 public static boolean isPlatformOsx() {
216 return Main.platform != null && Main.platform instanceof PlatformHookOsx;
217 }
218
219}
Note: See TracBrowser for help on using the repository browser.