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.beans.PropertyChangeEvent; 007import java.beans.PropertyChangeListener; 008 009import javax.swing.JSlider; 010import javax.swing.event.ChangeEvent; 011import javax.swing.event.ChangeListener; 012 013import org.openstreetmap.josm.gui.help.Helpful; 014 015class MapSlider extends JSlider implements PropertyChangeListener, ChangeListener, Helpful { 016 017 private static final double zoomStep = 1.1; 018 private final MapView mv; 019 private boolean preventChange; 020 private int lastValue; 021 022 MapSlider(MapView mv) { 023 super(0, 150); 024 setOpaque(false); 025 this.mv = mv; 026 mv.addPropertyChangeListener("scale", this); 027 addChangeListener(this); 028 // Call this manually once so it gets setup correctly 029 propertyChange(null); 030 } 031 032 @Override 033 public void propertyChange(PropertyChangeEvent evt) { 034 double maxScale = this.mv.getMaxScale(); 035 int zoom = (int) Math.round(Math.log(maxScale/mv.getScale())/Math.log(zoomStep)); 036 preventChange = true; 037 setValue(zoom); 038 lastValue = zoom; 039 preventChange = false; 040 } 041 042 @Override 043 public void stateChanged(ChangeEvent e) { 044 if (preventChange) return; 045 046 if (!getModel().getValueIsAdjusting() && mv.getNativeScaleLayer() != null) { 047 if (getValue() < lastValue) { 048 mv.zoomOut(); 049 } else if (getValue() > lastValue) { 050 mv.zoomIn(); 051 } 052 } else { 053 double maxScale = this.mv.getMaxScale(); 054 double scale = maxScale/Math.pow(zoomStep, getValue()); 055 double snapped = mv.scaleFloor(scale); 056 mv.zoomTo(this.mv.getCenter(), snapped); 057 } 058 propertyChange(null); 059 } 060 061 @Override 062 public String helpTopic() { 063 return ht("/MapView/Slider"); 064 } 065}