Ticket #13814: smooth-scrolling.diff
| File smooth-scrolling.diff, 9.5 KB (added by , 9 months ago) |
|---|
-
src/org/openstreetmap/josm/gui/MapMover.java
20 20 import org.openstreetmap.josm.actions.mapmode.SelectAction; 21 21 import org.openstreetmap.josm.data.coor.EastNorth; 22 22 import org.openstreetmap.josm.data.preferences.BooleanProperty; 23 import org.openstreetmap.josm.data.preferences.DoubleProperty; 23 24 import org.openstreetmap.josm.gui.MapViewState.MapViewPoint; 24 25 import org.openstreetmap.josm.gui.layer.Layer; 25 26 import org.openstreetmap.josm.spi.preferences.Config; … … 42 43 * Zoom wheel is reversed. 43 44 */ 44 45 public static final BooleanProperty PROP_ZOOM_REVERSE_WHEEL = new BooleanProperty("zoom.reverse-wheel", false); 46 public static final BooleanProperty PROP_ZOOM_SMOOTH_SCROLL = new BooleanProperty("zoom.smooth-scroll", false); 47 public static final DoubleProperty PROP_ZOOM_SCROLL_SENSITIVITY = new DoubleProperty("zoom.scroll-sensitivity", 1.0); 45 48 46 49 static { 47 50 new JMapViewerUpdater(); … … 253 256 */ 254 257 @Override 255 258 public void mouseWheelMoved(MouseWheelEvent e) { 256 int rotation = Boolean.TRUE.equals(PROP_ZOOM_REVERSE_WHEEL.get()) ? -e.getWheelRotation() : e.getWheelRotation(); 257 nc.zoomManyTimes(e.getX(), e.getY(), rotation); 259 double scrollAmount = Boolean.TRUE.equals(PROP_ZOOM_SMOOTH_SCROLL.get()) 260 ? e.getScrollAmount() * e.getPreciseWheelRotation() 261 : e.getWheelRotation(); 262 scrollAmount *= PROP_ZOOM_SCROLL_SENSITIVITY.get(); 263 if (Boolean.TRUE.equals(PROP_ZOOM_REVERSE_WHEEL.get())) { 264 scrollAmount *= -1; 265 } 266 nc.zoomManyTimes(e.getX(), e.getY(), scrollAmount); 258 267 } 259 268 260 269 /** -
src/org/openstreetmap/josm/gui/NavigatableComponent.java
317 317 /** 318 318 * Get a new scale that is zoomed in/out a number of times 319 319 * from previous scale and snapped to selected native scale layer. 320 * @param times count of zoom operations, negative means zoom in320 * @param amount how much to zoom, negative means zoom in 321 321 * @return new scale 322 322 */ 323 public double scaleZoomManyTimes(int times) { 324 if (nativeScaleLayer != null) { 323 public double scaleZoomManyTimes(double amount) { 324 // Ignore native scale if smooth scrolling 325 if (nativeScaleLayer != null && Boolean.FALSE.equals(MapMover.PROP_ZOOM_SMOOTH_SCROLL.get())) { 325 326 ScaleList scaleList = nativeScaleLayer.getNativeScales(); 326 327 if (scaleList != null) { 327 328 if (Boolean.TRUE.equals(PROP_ZOOM_INTERMEDIATE_STEPS.get())) { 328 329 scaleList = scaleList.withIntermediateSteps(PROP_ZOOM_RATIO.get()); 329 330 } 330 Scale s = scaleList.scaleZoomTimes(getScale(), PROP_ZOOM_RATIO.get(), times);331 Scale s = scaleList.scaleZoomTimes(getScale(), PROP_ZOOM_RATIO.get(), (int) Math.ceil(amount)); 331 332 return s != null ? s.getScale() : 0; 332 333 } 333 334 } 334 return getScale() * Math.pow(PROP_ZOOM_RATIO.get(), times); 335 // It turns out with smooth scrolling this factor still feels nice 336 return getScale() * Math.pow(PROP_ZOOM_RATIO.get(), amount); 335 337 } 336 338 337 339 /** … … 363 365 * @return new scale 364 366 */ 365 367 public double scaleSnap(double scale, boolean floor) { 366 if (nativeScaleLayer != null) { 368 // Ignore native scale if smooth scrolling 369 if (nativeScaleLayer != null && Boolean.FALSE.equals(MapMover.PROP_ZOOM_SMOOTH_SCROLL.get())) { 367 370 ScaleList scaleList = nativeScaleLayer.getNativeScales(); 368 371 if (scaleList != null) { 369 372 if (Boolean.TRUE.equals(PROP_ZOOM_INTERMEDIATE_STEPS.get())) { … … 880 883 } 881 884 } 882 885 883 public void zoomManyTimes(double x, double y, int times) {886 public void zoomManyTimes(double x, double y, double amount) { 884 887 double oldScale = getScale(); 885 double newScale = scaleZoomManyTimes( times);888 double newScale = scaleZoomManyTimes(amount); 886 889 zoomToFactor(x, y, newScale / oldScale); 887 890 } 888 891 -
src/org/openstreetmap/josm/gui/preferences/display/LafPreference.java
99 99 private final JCheckBox dialogGeometry = new JCheckBox(tr("Remember dialog geometries")); 100 100 private final JCheckBox nativeFileChoosers = new JCheckBox(tr("Use native file choosers (nicer, but do not support file filters)")); 101 101 private final JCheckBox zoomReverseWheel = new JCheckBox(tr("Reverse zoom with mouse wheel")); 102 private final JCheckBox zoomSmooth = new JCheckBox(tr("Use smooth scroll zooming")); 102 103 private final JCheckBox zoomIntermediateSteps = new JCheckBox(tr("Intermediate steps between native resolutions")); 103 104 private JSpinner spinZoomRatio; 105 private JSpinner spinScrollSensitivity; 104 106 105 107 @Override 106 108 public void addGui(PreferenceTabbedPane gui) { … … 213 215 zoomReverseWheel.setSelected(MapMover.PROP_ZOOM_REVERSE_WHEEL.get()); 214 216 panel.add(zoomReverseWheel, GBC.eop().insets(20, 0, 0, 0)); 215 217 218 zoomSmooth.setToolTipText(tr("Check to zoom in by continuous amounts instead of discrete steps")); 219 zoomSmooth.setSelected(MapMover.PROP_ZOOM_SMOOTH_SCROLL.get()); 220 panel.add(zoomSmooth, GBC.eop().insets(20, 0, 0, 0)); 221 216 222 zoomIntermediateSteps.setToolTipText( 217 223 tr("Divide intervals between native resolution levels to smaller steps if they are much larger than zoom ratio")); 218 224 zoomIntermediateSteps.setSelected(NavigatableComponent.PROP_ZOOM_INTERMEDIATE_STEPS.get()); … … 221 227 222 228 panel.add(Box.createVerticalGlue(), GBC.eol().insets(0, 10, 0, 0)); 223 229 230 double sensitivity = MapMover.PROP_ZOOM_SCROLL_SENSITIVITY.get(); 231 spinScrollSensitivity = new JSpinner(new SpinnerNumberModel(sensitivity, 0.01, 2.0, 0.01)); 232 var zoomSensitivityToolTipText = tr("Higher values means faster zooming from scrolling"); 233 addSpinner(spinScrollSensitivity, tr("Zoom sensitivity"), zoomSensitivityToolTipText, 3); 234 224 235 double logZoomLevel = Math.log(2) / Math.log(NavigatableComponent.PROP_ZOOM_RATIO.get()); 225 236 logZoomLevel = Math.max(1, logZoomLevel); 226 237 logZoomLevel = Math.min(5, logZoomLevel); 227 JLabel labelZoomRatio = new JLabel(tr("Zoom steps to get double scale"));228 238 spinZoomRatio = new JSpinner(new SpinnerNumberModel(logZoomLevel, 1, 10, 1)); 229 Component spinZoomRatioEditor = spinZoomRatio.getEditor(); 230 JFormattedTextField jftf = ((JSpinner.DefaultEditor) spinZoomRatioEditor).getTextField(); 231 jftf.setColumns(2); 232 String zoomRatioToolTipText = tr("Higher value means more steps needed, therefore zoom steps will be smaller"); 233 spinZoomRatio.setToolTipText(zoomRatioToolTipText); 234 labelZoomRatio.setToolTipText(zoomRatioToolTipText); 235 labelZoomRatio.setLabelFor(spinZoomRatio); 236 panel.add(labelZoomRatio, GBC.std().insets(20, 0, 0, 0)); 237 panel.add(GBC.glue(5, 0), GBC.std().fill(GBC.HORIZONTAL)); 238 panel.add(spinZoomRatio, GBC.eol()); 239 String labelZoomRatio = tr("Zoom steps to get double scale"); 240 String zoomRatioToolTipText = tr("Higher value means more steps needed, therefore zoom steps will be " + 241 "smaller. Also slows down smooth scrolling"); 242 addSpinner(spinZoomRatio, labelZoomRatio, zoomRatioToolTipText, 2); 239 243 240 244 JScrollPane scrollpane = panel.getVerticalScrollPane(); 241 245 scrollpane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); … … 242 246 gui.getDisplayPreference().addSubTab(this, tr("Look and Feel"), scrollpane); 243 247 } 244 248 249 private void addSpinner(JSpinner spinner, String labelText, String tooltip, int columns) { 250 ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField().setColumns(columns); 251 var label = new JLabel(labelText); 252 spinner.setToolTipText(tooltip); 253 label.setToolTipText(tooltip); 254 label.setLabelFor(spinner); 255 256 panel.add(label, GBC.std().insets(20, 0, 0, 0)); 257 panel.add(GBC.glue(5, 0), GBC.std().fill(GBC.HORIZONTAL)); 258 panel.add(spinner, GBC.eol()); 259 } 260 245 261 @Override 246 262 public boolean ok() { 247 263 boolean mod = false; … … 259 275 WindowGeometry.GUI_GEOMETRY_ENABLED.put(dialogGeometry.isSelected()); 260 276 Config.getPref().putBoolean(FileChooserManager.PROP_USE_NATIVE_FILE_DIALOG.getKey(), nativeFileChoosers.isSelected()); 261 277 MapMover.PROP_ZOOM_REVERSE_WHEEL.put(zoomReverseWheel.isSelected()); 278 MapMover.PROP_ZOOM_SMOOTH_SCROLL.put(zoomSmooth.isSelected()); 262 279 NavigatableComponent.PROP_ZOOM_INTERMEDIATE_STEPS.put(zoomIntermediateSteps.isSelected()); 263 280 NavigatableComponent.PROP_ZOOM_RATIO.put(Math.pow(2, 1/(double) spinZoomRatio.getModel().getValue())); 281 MapMover.PROP_ZOOM_SCROLL_SENSITIVITY.put((double) spinScrollSensitivity.getValue()); 264 282 mod |= LAF.put(((LookAndFeelInfo) lafCombo.getSelectedItem()).getClassName()); 265 283 return mod; 266 284 }
