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.awt.Dimension; 007 008import javax.swing.JSlider; 009import javax.swing.UIManager; 010import javax.swing.event.ChangeEvent; 011import javax.swing.event.ChangeListener; 012 013import org.openstreetmap.josm.gui.NavigatableComponent.ZoomChangeListener; 014import org.openstreetmap.josm.gui.help.Helpful; 015import org.openstreetmap.josm.tools.Destroyable; 016 017/** 018 * This is the slider used in the top left corner of the map view. It allows the user to select the scale 019 */ 020class MapSlider extends JSlider implements ZoomChangeListener, ChangeListener, Helpful, Destroyable { 021 022 private static final double ZOOM_STEP = 1.1; 023 private final MapView mv; 024 private boolean preventChange; 025 private int lastValue; 026 027 MapSlider(MapView mv) { 028 super(0, 160); 029 setOpaque(false); 030 this.mv = mv; 031 NavigatableComponent.addZoomChangeListener(this); 032 addChangeListener(this); 033 // Call this manually once so it gets setup correctly 034 zoomChanged(); 035 int w = UIManager.getDefaults().getInt("Slider.thumbWidth") + 150; 036 setPreferredSize(new Dimension(w, 27)); 037 } 038 039 @Override 040 public void zoomChanged() { 041 double maxScale = this.mv.getMaxScale(); 042 int zoom = (int) Math.round(Math.log(maxScale/mv.getScale())/Math.log(ZOOM_STEP)); 043 preventChange = true; 044 setValue(zoom); 045 lastValue = zoom; 046 preventChange = false; 047 } 048 049 @Override 050 public void stateChanged(ChangeEvent e) { 051 if (preventChange) return; 052 053 if (!getModel().getValueIsAdjusting() && mv.getNativeScaleLayer() != null) { 054 if (getValue() < lastValue) { 055 mv.zoomOut(); 056 } else if (getValue() > lastValue) { 057 mv.zoomIn(); 058 } 059 } else { 060 double maxScale = this.mv.getMaxScale(); 061 double scale = maxScale/Math.pow(ZOOM_STEP, getValue()); 062 double snapped = mv.scaleFloor(scale); 063 mv.zoomTo(this.mv.getCenter(), snapped); 064 } 065 zoomChanged(); 066 } 067 068 @Override 069 public String helpTopic() { 070 return ht("/MapView/Slider"); 071 } 072 073 @Override 074 public void destroy() { 075 NavigatableComponent.removeZoomChangeListener(this); 076 } 077}