001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.actions.mapmode;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.Rectangle;
007import java.awt.event.KeyEvent;
008import java.awt.event.MouseEvent;
009
010import org.openstreetmap.josm.gui.MainApplication;
011import org.openstreetmap.josm.gui.MapFrame;
012import org.openstreetmap.josm.gui.MapView;
013import org.openstreetmap.josm.gui.SelectionManager;
014import org.openstreetmap.josm.gui.SelectionManager.SelectionEnded;
015import org.openstreetmap.josm.tools.ImageProvider;
016import org.openstreetmap.josm.tools.Shortcut;
017
018/**
019 * Enable the zoom mode within the MapFrame.
020 *
021 * Holding down the left mouse button select a rectangle with the same aspect
022 * ratio than the current map view.
023 * Holding down left and right let the user move the former selected rectangle.
024 * Releasing the left button zoom to the selection.
025 *
026 * Rectangle selections with either height or width smaller than 3 pixels
027 * are ignored.
028 *
029 * @author imi
030 * @since 1
031 */
032public class ZoomAction extends MapMode implements SelectionEnded {
033
034    /**
035     * Manager that manages the selection rectangle with the aspect ratio of the MapView.
036     */
037    private final transient SelectionManager selectionManager;
038
039    /**
040     * Construct a ZoomAction without a label.
041     * @param mapFrame The MapFrame, whose zoom mode should be enabled.
042     */
043    public ZoomAction(MapFrame mapFrame) {
044        super(tr("Zoom"), "zoom", tr("Zoom and move map"),
045                Shortcut.registerShortcut("mapmode:zoom", tr("Mode: {0}", tr("Zoom")), KeyEvent.CHAR_UNDEFINED, Shortcut.NONE),
046                ImageProvider.getCursor("normal", "zoom"));
047        selectionManager = new SelectionManager(this, true, mapFrame.mapView);
048    }
049
050    /**
051     * Zoom to the rectangle on the map.
052     */
053    @Override
054    public void selectionEnded(Rectangle r, MouseEvent e) {
055        if (r.width >= 3 && r.height >= 3 && MainApplication.isDisplayingMapView()) {
056            MapView mv = MainApplication.getMap().mapView;
057            mv.zoomToFactor(mv.getEastNorth(r.x+r.width/2, r.y+r.height/2), r.getWidth()/mv.getWidth());
058        }
059    }
060
061    @Override public void enterMode() {
062        super.enterMode();
063        selectionManager.register(MainApplication.getMap().mapView, false);
064    }
065
066    @Override public void exitMode() {
067        super.exitMode();
068        selectionManager.unregister(MainApplication.getMap().mapView);
069    }
070
071    @Override public String getModeHelpText() {
072        return tr("Zoom by dragging or Ctrl+. or Ctrl+,; move with Ctrl+up, left, down, right; move zoom with right button");
073    }
074}