001// License: GPL. For details, see Readme.txt file. 002package org.openstreetmap.gui.jmapviewer; 003 004import java.awt.Point; 005import java.awt.event.MouseEvent; 006import java.awt.event.MouseListener; 007import java.awt.event.MouseMotionListener; 008import java.awt.event.MouseWheelEvent; 009import java.awt.event.MouseWheelListener; 010 011/** 012 * Default map controller which implements map moving by pressing the right 013 * mouse button and zooming by double click or by mouse wheel. 014 * 015 * @author Jan Peter Stotz 016 * 017 */ 018public class DefaultMapController extends JMapController implements MouseListener, MouseMotionListener, 019MouseWheelListener { 020 021 private static final int MOUSE_BUTTONS_MASK = MouseEvent.BUTTON3_DOWN_MASK | MouseEvent.BUTTON1_DOWN_MASK 022 | MouseEvent.BUTTON2_DOWN_MASK; 023 024 private static final int MAC_MOUSE_BUTTON3_MASK = MouseEvent.CTRL_DOWN_MASK | MouseEvent.BUTTON1_DOWN_MASK; 025 public DefaultMapController(JMapViewer map) { 026 super(map); 027 } 028 029 private Point lastDragPoint; 030 031 private boolean isMoving = false; 032 033 private boolean movementEnabled = true; 034 035 private int movementMouseButton = MouseEvent.BUTTON3; 036 private int movementMouseButtonMask = MouseEvent.BUTTON3_DOWN_MASK; 037 038 private boolean wheelZoomEnabled = true; 039 private boolean doubleClickZoomEnabled = true; 040 041 public void mouseDragged(MouseEvent e) { 042 if (!movementEnabled || !isMoving) 043 return; 044 // Is only the selected mouse button pressed? 045 if ((e.getModifiersEx() & MOUSE_BUTTONS_MASK) == movementMouseButtonMask || isPlatformOsx() && e.getModifiersEx() == MAC_MOUSE_BUTTON3_MASK) { 046 Point p = e.getPoint(); 047 if (lastDragPoint != null) { 048 int diffx = lastDragPoint.x - p.x; 049 int diffy = lastDragPoint.y - p.y; 050 map.moveMap(diffx, diffy); 051 } 052 lastDragPoint = p; 053 } 054 } 055 056 public void mouseClicked(MouseEvent e) { 057 if (doubleClickZoomEnabled && e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1) { 058 map.zoomIn(e.getPoint()); 059 } 060 } 061 062 public void mousePressed(MouseEvent e) { 063 if (e.getButton() == movementMouseButton || isPlatformOsx() && e.getModifiersEx() == MAC_MOUSE_BUTTON3_MASK) { 064 lastDragPoint = null; 065 isMoving = true; 066 } 067 } 068 069 public void mouseReleased(MouseEvent e) { 070 if (e.getButton() == movementMouseButton || isPlatformOsx() && e.getButton() == MouseEvent.BUTTON1) { 071 lastDragPoint = null; 072 isMoving = false; 073 } 074 } 075 076 public void mouseWheelMoved(MouseWheelEvent e) { 077 if (wheelZoomEnabled) { 078 map.setZoom(map.getZoom() - e.getWheelRotation(), e.getPoint()); 079 } 080 } 081 082 public boolean isMovementEnabled() { 083 return movementEnabled; 084 } 085 086 /** 087 * Enables or disables that the map pane can be moved using the mouse. 088 * 089 * @param movementEnabled 090 */ 091 public void setMovementEnabled(boolean movementEnabled) { 092 this.movementEnabled = movementEnabled; 093 } 094 095 public int getMovementMouseButton() { 096 return movementMouseButton; 097 } 098 099 /** 100 * Sets the mouse button that is used for moving the map. Possible values 101 * are: 102 * <ul> 103 * <li>{@link MouseEvent#BUTTON1} (left mouse button)</li> 104 * <li>{@link MouseEvent#BUTTON2} (middle mouse button)</li> 105 * <li>{@link MouseEvent#BUTTON3} (right mouse button)</li> 106 * </ul> 107 * 108 * @param movementMouseButton 109 */ 110 public void setMovementMouseButton(int movementMouseButton) { 111 this.movementMouseButton = movementMouseButton; 112 switch (movementMouseButton) { 113 case MouseEvent.BUTTON1: 114 movementMouseButtonMask = MouseEvent.BUTTON1_DOWN_MASK; 115 break; 116 case MouseEvent.BUTTON2: 117 movementMouseButtonMask = MouseEvent.BUTTON2_DOWN_MASK; 118 break; 119 case MouseEvent.BUTTON3: 120 movementMouseButtonMask = MouseEvent.BUTTON3_DOWN_MASK; 121 break; 122 default: 123 throw new RuntimeException("Unsupported button"); 124 } 125 } 126 127 public boolean isWheelZoomEnabled() { 128 return wheelZoomEnabled; 129 } 130 131 public void setWheelZoomEnabled(boolean wheelZoomEnabled) { 132 this.wheelZoomEnabled = wheelZoomEnabled; 133 } 134 135 public boolean isDoubleClickZoomEnabled() { 136 return doubleClickZoomEnabled; 137 } 138 139 public void setDoubleClickZoomEnabled(boolean doubleClickZoomEnabled) { 140 this.doubleClickZoomEnabled = doubleClickZoomEnabled; 141 } 142 143 public void mouseEntered(MouseEvent e) { 144 } 145 146 public void mouseExited(MouseEvent e) { 147 } 148 149 public void mouseMoved(MouseEvent e) { 150 // Mac OSX simulates with ctrl + mouse 1 the second mouse button hence no dragging events get fired. 151 // 152 if (isPlatformOsx()) { 153 if (!movementEnabled || !isMoving) 154 return; 155 // Is only the selected mouse button pressed? 156 if (e.getModifiersEx() == MouseEvent.CTRL_DOWN_MASK) { 157 Point p = e.getPoint(); 158 if (lastDragPoint != null) { 159 int diffx = lastDragPoint.x - p.x; 160 int diffy = lastDragPoint.y - p.y; 161 map.moveMap(diffx, diffy); 162 } 163 lastDragPoint = p; 164 } 165 166 } 167 168 } 169 170 /** 171 * Replies true if we are currently running on OSX 172 * 173 * @return true if we are currently running on OSX 174 */ 175 public static boolean isPlatformOsx() { 176 String os = System.getProperty("os.name"); 177 return os != null && os.toLowerCase().startsWith("mac os x"); 178 } 179}