// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.actions.mapmode; import java.awt.Cursor; import java.awt.event.ActionEvent; import java.awt.event.InputEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.actions.JosmAction; import org.openstreetmap.josm.data.Preferences.PreferenceChangeEvent; import org.openstreetmap.josm.data.Preferences.PreferenceChangedListener; import org.openstreetmap.josm.gui.MapFrame; import org.openstreetmap.josm.gui.layer.Layer; import org.openstreetmap.josm.tools.ImageProvider; import org.openstreetmap.josm.tools.Shortcut; /** * A class implementing MapMode is able to be selected as an mode for map editing. * As example scrolling the map is a MapMode, connecting Nodes to new Ways is another. * * MapModes should register/deregister all necessary listeners on the map's view control. */ public abstract class MapMode extends JosmAction implements MouseListener, MouseMotionListener, PreferenceChangedListener { protected final Cursor cursor; protected boolean ctrl; protected boolean alt; protected boolean shift; /** * Constructor for mapmodes without a menu * @param name the action's text * @param iconName icon filename in {@code mapmode} directory * @param tooltip a longer description of the action that will be displayed in the tooltip. * @param shortcut a ready-created shortcut object or null if you don't want a shortcut. * @param cursor cursor displayed when map mode is active * @since 11713 */ public MapMode(String name, String iconName, String tooltip, Shortcut shortcut, Cursor cursor) { super(name, "mapmode/"+iconName, tooltip, shortcut, false); this.cursor = cursor; putValue("active", Boolean.FALSE); } /** * Constructor for mapmodes with a menu (no shortcut will be registered) * @param name the action's text * @param iconName icon filename in {@code mapmode} directory * @param tooltip a longer description of the action that will be displayed in the tooltip. * @param cursor cursor displayed when map mode is active * @since 11713 */ public MapMode(String name, String iconName, String tooltip, Cursor cursor) { putValue(NAME, name); new ImageProvider("mapmode", iconName).getResource().attachImageIcon(this); putValue(SHORT_DESCRIPTION, tooltip); this.cursor = cursor; } /** * Constructor for mapmodes without a menu * @param name the action's text * @param iconName icon filename in {@code mapmode} directory * @param tooltip a longer description of the action that will be displayed in the tooltip. * @param shortcut a ready-created shortcut object or null if you don't want a shortcut. * @param mapFrame unused but kept for plugin compatibility. Can be {@code null} * @param cursor cursor displayed when map mode is active * @deprecated use {@link #MapMode(String, String, String, Shortcut, Cursor) instead} */ @Deprecated public MapMode(String name, String iconName, String tooltip, Shortcut shortcut, MapFrame mapFrame, Cursor cursor) { this(name, iconName, tooltip, shortcut, cursor); } /** * Constructor for mapmodes with a menu (no shortcut will be registered) * @param name the action's text * @param iconName icon filename in {@code mapmode} directory * @param tooltip a longer description of the action that will be displayed in the tooltip. * @param mapFrame unused but kept for plugin compatibility. Can be {@code null} * @param cursor cursor displayed when map mode is active * @deprecated use {@link #MapMode(String, String, String, Cursor) instead} */ @Deprecated public MapMode(String name, String iconName, String tooltip, MapFrame mapFrame, Cursor cursor) { this(name, iconName, tooltip, cursor); } /** * Makes this map mode active. */ public void enterMode() { putValue("active", Boolean.TRUE); Main.pref.addPreferenceChangeListener(this); readPreferences(); Main.map.mapView.setNewCursor(cursor, this); updateStatusLine(); } /** * Makes this map mode inactive. */ public void exitMode() { putValue("active", Boolean.FALSE); Main.pref.removePreferenceChangeListener(this); Main.map.mapView.resetCursor(this); } protected void updateStatusLine() { Main.map.statusLine.setHelpText(getModeHelpText()); Main.map.statusLine.repaint(); } public String getModeHelpText() { return ""; } protected void readPreferences() {} /** * Call selectMapMode(this) on the parent mapFrame. */ @Override public void actionPerformed(ActionEvent e) { if (Main.isDisplayingMapView()) { Main.map.selectMapMode(this); } } /** * Determines if layer {@code l} is supported by this map mode. * By default, all tools will work with all layers. * Can be overwritten to require a special type of layer * @param l layer * @return {@code true} if the layer is supported by this map mode */ public boolean layerIsSupported(Layer l) { return l != null; } protected void updateKeyModifiers(InputEvent e) { updateKeyModifiers(e.getModifiers()); } protected void updateKeyModifiers(MouseEvent e) { updateKeyModifiers(e.getModifiers()); } protected void updateKeyModifiers(int modifiers) { ctrl = (modifiers & ActionEvent.CTRL_MASK) != 0; alt = (modifiers & (ActionEvent.ALT_MASK | InputEvent.ALT_GRAPH_MASK)) != 0; shift = (modifiers & ActionEvent.SHIFT_MASK) != 0; } protected void requestFocusInMapView() { if (isEnabled()) { // request focus in order to enable the expected keyboard shortcuts (see #8710) Main.map.mapView.requestFocus(); } } @Override public void mouseReleased(MouseEvent e) { requestFocusInMapView(); } @Override public void mouseExited(MouseEvent e) { // Do nothing } @Override public void mousePressed(MouseEvent e) { requestFocusInMapView(); } @Override public void mouseClicked(MouseEvent e) { // Do nothing } @Override public void mouseEntered(MouseEvent e) { // Do nothing } @Override public void mouseMoved(MouseEvent e) { // Do nothing } @Override public void mouseDragged(MouseEvent e) { // Do nothing } @Override public void preferenceChanged(PreferenceChangeEvent e) { readPreferences(); } }