001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui;
003
004import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
005
006import java.beans.PropertyChangeEvent;
007import java.beans.PropertyChangeListener;
008
009import javax.swing.JSlider;
010import javax.swing.event.ChangeEvent;
011import javax.swing.event.ChangeListener;
012
013import org.openstreetmap.josm.data.ProjectionBounds;
014import org.openstreetmap.josm.gui.help.Helpful;
015
016class MapSlider extends JSlider implements PropertyChangeListener, ChangeListener, Helpful {
017
018    private final MapView mv;
019    boolean preventChange = false;
020
021    public MapSlider(MapView mv) {
022        super(35, 150);
023        setOpaque(false);
024        this.mv = mv;
025        mv.addPropertyChangeListener("scale", this);
026        addChangeListener(this);
027        // Call this manually once so it gets setup correctly
028        propertyChange(null);
029    }
030
031    @Override
032    public void propertyChange(PropertyChangeEvent evt) {
033        if (getModel().getValueIsAdjusting()) return;
034
035        ProjectionBounds world = this.mv.getMaxProjectionBounds();
036        ProjectionBounds current = this.mv.getProjectionBounds();
037
038        double cur_e = current.maxEast-current.minEast;
039        double cur_n = current.maxNorth-current.minNorth;
040        double e = world.maxEast-world.minEast;
041        double n = world.maxNorth-world.minNorth;
042        int zoom = 0;
043
044        while(zoom <= 150) {
045            e /= 1.1;
046            n /= 1.1;
047            if(e < cur_e && n < cur_n) {
048                break;
049            }
050            ++zoom;
051        }
052        preventChange=true;
053        setValue(zoom);
054        preventChange=false;
055    }
056
057    @Override
058    public void stateChanged(ChangeEvent e) {
059        if (preventChange) return;
060
061        ProjectionBounds world = this.mv.getMaxProjectionBounds();
062        double fact = Math.pow(1.1, getValue());
063        double es = world.maxEast-world.minEast;
064        double n = world.maxNorth-world.minNorth;
065
066        this.mv.zoomTo(new ProjectionBounds(this.mv.getCenter(), es/fact, n/fact));
067    }
068
069    @Override
070    public String helpTopic() {
071        return ht("/MapView/Slider");
072    }
073}