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