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 }