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

Last change on this file since 4932 was 4494, checked in by bastiK, 13 years ago

change zoom factor to something more suitable for TMS (2x zoom in increases scale by factor 2)

  • Property svn:eol-style set to native
File size: 8.9 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(Math.sqrt(2), 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.