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 }