001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.actions.mapmode; 003 004import java.awt.Cursor; 005import java.awt.event.ActionEvent; 006import java.awt.event.InputEvent; 007import java.awt.event.MouseEvent; 008import java.awt.event.MouseListener; 009import java.awt.event.MouseMotionListener; 010 011import org.openstreetmap.josm.Main; 012import org.openstreetmap.josm.actions.JosmAction; 013import org.openstreetmap.josm.gui.MapFrame; 014import org.openstreetmap.josm.gui.layer.Layer; 015import org.openstreetmap.josm.tools.ImageProvider; 016import org.openstreetmap.josm.tools.Shortcut; 017 018/** 019 * A class implementing MapMode is able to be selected as an mode for map editing. 020 * As example scrolling the map is a MapMode, connecting Nodes to new Ways 021 * is another. 022 * 023 * MapModes should register/deregister all necessary listeners on the map's view control. 024 */ 025public abstract class MapMode extends JosmAction implements MouseListener, MouseMotionListener { 026 protected final Cursor cursor; 027 protected boolean ctrl; 028 protected boolean alt; 029 protected boolean shift; 030 031 /** 032 * Constructor for mapmodes without an menu 033 * @param mapFrame unused but kept for plugin compatibility. Can be {@code null} 034 */ 035 public MapMode(String name, String iconName, String tooltip, Shortcut shortcut, MapFrame mapFrame, Cursor cursor) { 036 super(name, "mapmode/"+iconName, tooltip, shortcut, false); 037 this.cursor = cursor; 038 putValue("active", Boolean.FALSE); 039 } 040 041 /** 042 * Constructor for mapmodes with an menu (no shortcut will be registered) 043 * @param mapFrame unused but kept for plugin compatibility. Can be {@code null} 044 */ 045 public MapMode(String name, String iconName, String tooltip, MapFrame mapFrame, Cursor cursor) { 046 putValue(NAME, name); 047 putValue(SMALL_ICON, ImageProvider.get("mapmode", iconName)); 048 putValue(SHORT_DESCRIPTION, tooltip); 049 this.cursor = cursor; 050 } 051 052 /** 053 * Makes this map mode active. 054 */ 055 public void enterMode() { 056 putValue("active", Boolean.TRUE); 057 Main.map.mapView.setNewCursor(cursor, this); 058 updateStatusLine(); 059 } 060 061 /** 062 * Makes this map mode inactive. 063 */ 064 public void exitMode() { 065 putValue("active", Boolean.FALSE); 066 Main.map.mapView.resetCursor(this); 067 } 068 069 protected void updateStatusLine() { 070 Main.map.statusLine.setHelpText(getModeHelpText()); 071 Main.map.statusLine.repaint(); 072 } 073 074 public String getModeHelpText() { 075 return ""; 076 } 077 078 /** 079 * Call selectMapMode(this) on the parent mapFrame. 080 */ 081 @Override 082 public void actionPerformed(ActionEvent e) { 083 if (Main.isDisplayingMapView()) { 084 Main.map.selectMapMode(this); 085 } 086 } 087 088 /** 089 * Determines if layer {@code l} is supported by this map mode. 090 * By default, all tools will work with all layers. 091 * Can be overwritten to require a special type of layer 092 * @param l layer 093 * @return {@code true} if the layer is supported by this map mode 094 */ 095 public boolean layerIsSupported(Layer l) { 096 return l != null; 097 } 098 099 protected void updateKeyModifiers(InputEvent e) { 100 updateKeyModifiers(e.getModifiers()); 101 } 102 103 protected void updateKeyModifiers(MouseEvent e) { 104 updateKeyModifiers(e.getModifiers()); 105 } 106 107 protected void updateKeyModifiers(int modifiers) { 108 ctrl = (modifiers & ActionEvent.CTRL_MASK) != 0; 109 alt = (modifiers & (ActionEvent.ALT_MASK | InputEvent.ALT_GRAPH_MASK)) != 0; 110 shift = (modifiers & ActionEvent.SHIFT_MASK) != 0; 111 } 112 113 protected void requestFocusInMapView() { 114 if (isEnabled()) { 115 // request focus in order to enable the expected keyboard shortcuts (see #8710) 116 Main.map.mapView.requestFocus(); 117 } 118 } 119 120 @Override 121 public void mouseReleased(MouseEvent e) { 122 requestFocusInMapView(); 123 } 124 125 @Override 126 public void mouseExited(MouseEvent e) { 127 // Do nothing 128 } 129 130 @Override 131 public void mousePressed(MouseEvent e) { 132 requestFocusInMapView(); 133 } 134 135 @Override 136 public void mouseClicked(MouseEvent e) { 137 // Do nothing 138 } 139 140 @Override 141 public void mouseEntered(MouseEvent e) { 142 // Do nothing 143 } 144 145 @Override 146 public void mouseMoved(MouseEvent e) { 147 // Do nothing 148 } 149 150 @Override 151 public void mouseDragged(MouseEvent e) { 152 // Do nothing 153 } 154}