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        MainApplication.getLayerManager().addLayerChangeListener(slippyMap);
041    }
042
043    @Override
044    public void showDialog() {
045        initialize();
046        NavigatableComponent.addZoomChangeListener(this);
047        super.showDialog();
048    }
049
050    @Override
051    public void hideDialog() {
052        NavigatableComponent.removeZoomChangeListener(this);
053        super.hideDialog();
054    }
055
056    @Override
057    public void zoomChanged() {
058        if (!skipEvents && MainApplication.isDisplayingMapView()) {
059            MapView mv = MainApplication.getMap().mapView;
060            final Bounds currentBounds = new Bounds(
061                    mv.getLatLon(0, mv.getHeight()),
062                    mv.getLatLon(mv.getWidth(), 0)
063            );
064            skipEvents = true;
065            slippyMap.setBoundingBox(currentBounds);
066            slippyMap.zoomOut(); // to give a better overview
067            skipEvents = false;
068        }
069    }
070
071    @Override
072    public void propertyChange(PropertyChangeEvent evt) {
073        if (!skipEvents) {
074            skipEvents = true;
075            MainApplication.getMap().mapView.zoomTo(slippyMap.getBoundingBox());
076            skipEvents = false;
077        }
078    }
079}