001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.dialogs;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.beans.PropertyChangeEvent;
007import java.beans.PropertyChangeListener;
008import java.util.Collections;
009
010import org.openstreetmap.josm.data.Bounds;
011import org.openstreetmap.josm.gui.MainApplication;
012import org.openstreetmap.josm.gui.MapView;
013import org.openstreetmap.josm.gui.NavigatableComponent;
014import org.openstreetmap.josm.gui.bbox.BBoxChooser;
015import org.openstreetmap.josm.gui.bbox.SlippyMapBBoxChooser;
016
017/**
018 * A small map of the current edit location implemented as {@link ToggleDialog}.
019 */
020public class MinimapDialog extends ToggleDialog implements NavigatableComponent.ZoomChangeListener, PropertyChangeListener {
021
022    private SlippyMapBBoxChooser slippyMap;
023    private boolean skipEvents;
024
025    /**
026     * Constructs a new {@code MinimapDialog}.
027     */
028    public MinimapDialog() {
029        super(tr("Mini map"), "minimap", tr("Displays a small map of the current edit location"), null, 150);
030    }
031
032    private synchronized void initialize() {
033        if (slippyMap != null) {
034            return;
035        }
036        slippyMap = new SlippyMapBBoxChooser();
037        createLayout(slippyMap, false, Collections.emptyList());
038        slippyMap.setSizeButtonVisible(false);
039        slippyMap.addPropertyChangeListener(BBoxChooser.BBOX_PROP, this);
040    }
041
042    @Override
043    public void showDialog() {
044        initialize();
045        NavigatableComponent.addZoomChangeListener(this);
046        super.showDialog();
047    }
048
049    @Override
050    public void hideDialog() {
051        NavigatableComponent.removeZoomChangeListener(this);
052        super.hideDialog();
053    }
054
055    @Override
056    public void zoomChanged() {
057        if (!skipEvents && MainApplication.isDisplayingMapView()) {
058            MapView mv = MainApplication.getMap().mapView;
059            final Bounds currentBounds = new Bounds(
060                    mv.getLatLon(0, mv.getHeight()),
061                    mv.getLatLon(mv.getWidth(), 0)
062            );
063            skipEvents = true;
064            slippyMap.setBoundingBox(currentBounds);
065            slippyMap.zoomOut(); // to give a better overview
066            skipEvents = false;
067        }
068    }
069
070    @Override
071    public void propertyChange(PropertyChangeEvent evt) {
072        if (!skipEvents) {
073            skipEvents = true;
074            MainApplication.getMap().mapView.zoomTo(slippyMap.getBoundingBox());
075            skipEvents = false;
076        }
077    }
078}