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