001    // License: GPL. Copyright 2007 by Immanuel Scholz and others
002    package org.openstreetmap.josm.gui;
003    
004    import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
005    
006    import java.beans.PropertyChangeEvent;
007    import java.beans.PropertyChangeListener;
008    
009    import javax.swing.JSlider;
010    import javax.swing.event.ChangeEvent;
011    import javax.swing.event.ChangeListener;
012    
013    import org.openstreetmap.josm.data.ProjectionBounds;
014    import org.openstreetmap.josm.gui.help.Helpful;
015    
016    class 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        public void propertyChange(PropertyChangeEvent evt) {
032            if (getModel().getValueIsAdjusting()) return;
033    
034            ProjectionBounds world = this.mv.getMaxProjectionBounds();
035            ProjectionBounds current = this.mv.getProjectionBounds();
036    
037            double cur_e = current.maxEast-current.minEast;
038            double cur_n = current.maxNorth-current.minNorth;
039            double e = world.maxEast-world.minEast;
040            double n = world.maxNorth-world.minNorth;
041            int zoom = 0;
042    
043            while(zoom <= 150) {
044                e /= 1.1;
045                n /= 1.1;
046                if(e < cur_e && n < cur_n) {
047                    break;
048                }
049                ++zoom;
050            }
051            preventChange=true;
052            setValue(zoom);
053            preventChange=false;
054        }
055    
056        public void stateChanged(ChangeEvent e) {
057            if (preventChange) return;
058    
059            ProjectionBounds world = this.mv.getMaxProjectionBounds();
060            double fact = Math.pow(1.1, getValue());
061            double es = world.maxEast-world.minEast;
062            double n = world.maxNorth-world.minNorth;
063    
064            this.mv.zoomTo(new ProjectionBounds(this.mv.getCenter(), es/fact, n/fact));
065        }
066    
067        public String helpTopic() {
068            return ht("/MapView/Slider");
069        }
070    }