From bb276b4193eccb248d027b9d3ee74abf1ba33ec9 Mon Sep 17 00:00:00 2001 From: weisj Date: Sat, 24 Oct 2020 18:25:18 +0200 Subject: [PATCH] Enable slider adjustment through mouse wheel rotation. --- .../darklaf/ui/slider/DarkSliderListener.java | 83 +++++++++++++++++++ .../weisj/darklaf/ui/slider/DarkSliderUI.java | 59 +++++-------- 2 files changed, 102 insertions(+), 40 deletions(-) create mode 100644 core/src/main/java/com/github/weisj/darklaf/ui/slider/DarkSliderListener.java diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/slider/DarkSliderListener.java b/core/src/main/java/com/github/weisj/darklaf/ui/slider/DarkSliderListener.java new file mode 100644 index 00000000..1e142464 --- /dev/null +++ b/core/src/main/java/com/github/weisj/darklaf/ui/slider/DarkSliderListener.java @@ -0,0 +1,83 @@ +/* + * MIT License + * + * Copyright (c) 2020 Jannis Weis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ +package com.github.weisj.darklaf.ui.slider; + +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseWheelEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import javax.swing.*; + +public class DarkSliderListener extends MouseAdapter implements PropertyChangeListener { + + private final DarkSliderUI ui; + private final JSlider slider; + private boolean muted = false; + private int oldValue; + + public DarkSliderListener(final DarkSliderUI ui, final JSlider slider) { + this.ui = ui; + this.slider = slider; + } + + @Override + public void mouseWheelMoved(final MouseWheelEvent e) { + super.mouseWheelMoved(e); + if (!slider.hasFocus()) return; + if (e.getScrollType() == MouseWheelEvent.WHEEL_BLOCK_SCROLL) return; + int amount = e.getWheelRotation(); + boolean ltr = slider.getComponentOrientation().isLeftToRight(); + if (ltr) amount *= -1; + if (slider.getSnapToTicks()) { + int spacing = slider.getMinorTickSpacing(); + amount *= spacing; + } + ui.setValue(slider.getValue() + amount); + } + + @Override + public void mouseClicked(final MouseEvent e) { + if (slider.isEnabled() && ui.showVolumeIcon(slider) && ui.iconRect.contains(e.getPoint())) { + if (muted && slider.getValue() == slider.getMinimum()) { + ui.setValue(oldValue); + muted = false; + } else { + oldValue = slider.getValue(); + ui.setValue(slider.getMinimum()); + muted = true; + } + } + } + + @Override + public void propertyChange(final PropertyChangeEvent evt) { + String key = evt.getPropertyName(); + if (DarkSliderUI.KEY_VARIANT.equals(key)) { + slider.repaint(); + } else if (DarkSliderUI.KEY_SHOW_VOLUME_ICON.equals(key)) { + ui.calculateGeometry(); + slider.repaint(); + } + } +} diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/slider/DarkSliderUI.java b/core/src/main/java/com/github/weisj/darklaf/ui/slider/DarkSliderUI.java index 92f43111..edbb90e5 100644 --- a/core/src/main/java/com/github/weisj/darklaf/ui/slider/DarkSliderUI.java +++ b/core/src/main/java/com/github/weisj/darklaf/ui/slider/DarkSliderUI.java @@ -23,10 +23,7 @@ package com.github.weisj.darklaf.ui.slider; import java.awt.*; import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; import java.awt.geom.RoundRectangle2D; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; import java.util.Dictionary; import java.util.Enumeration; @@ -38,14 +35,13 @@ import com.github.weisj.darklaf.graphics.GraphicsContext; import com.github.weisj.darklaf.graphics.GraphicsUtil; import com.github.weisj.darklaf.graphics.PaintUtil; import com.github.weisj.darklaf.icons.RotatableIcon; -import com.github.weisj.darklaf.listener.MouseClickListener; import com.github.weisj.darklaf.util.Alignment; import com.github.weisj.darklaf.util.DarkUIUtil; import com.github.weisj.darklaf.util.PropertyKey; import com.github.weisj.darklaf.util.PropertyUtil; /** @author Jannis Weis */ -public class DarkSliderUI extends BasicSliderUI implements PropertyChangeListener { +public class DarkSliderUI extends BasicSliderUI { protected static final String KEY_PREFIX = "JSlider."; public static final String KEY_THUMB_ARROW_SHAPE = KEY_PREFIX + "paintThumbArrowShape"; @@ -55,25 +51,9 @@ public class DarkSliderUI extends BasicSliderUI implements PropertyChangeListene public static final String KEY_MANUAL_LABEL_ALIGN = KEY_PREFIX + "manualLabelAlign"; public static final String VARIANT_VOLUME = "volume"; - private final Rectangle iconRect = new Rectangle(0, 0, 0, 0); - private final MouseListener mouseListener = new MouseClickListener() { - private boolean muted = false; - private int oldValue; + protected final Rectangle iconRect = new Rectangle(0, 0, 0, 0); + private DarkSliderListener sliderListener; - @Override - public void mouseClicked(final MouseEvent e) { - if (slider.isEnabled() && showVolumeIcon(slider) && iconRect.contains(e.getPoint())) { - if (muted && slider.getValue() == slider.getMinimum()) { - setValue(oldValue); - muted = false; - } else { - oldValue = slider.getValue(); - setValue(slider.getMinimum()); - muted = true; - } - } - } - }; protected int plainThumbRadius; protected int arcSize; protected int trackSize; @@ -126,11 +106,11 @@ public class DarkSliderUI extends BasicSliderUI implements PropertyChangeListene return new DarkSliderUI((JSlider) c); } - private static boolean showVolumeIcon(final JComponent c) { + protected boolean showVolumeIcon(final JComponent c) { return PropertyUtil.getBooleanProperty(c, KEY_SHOW_VOLUME_ICON); } - private static boolean isVolumeSlider(final JComponent c) { + protected boolean isVolumeSlider(final JComponent c) { return PropertyUtil.isPropertyEqual(c, KEY_VARIANT, VARIANT_VOLUME); } @@ -142,15 +122,25 @@ public class DarkSliderUI extends BasicSliderUI implements PropertyChangeListene @Override protected void installListeners(final JSlider slider) { super.installListeners(slider); - slider.addMouseListener(mouseListener); - slider.addPropertyChangeListener(this); + if (sliderListener == null) { + sliderListener = createSliderListener(); + } + slider.addMouseListener(sliderListener); + slider.addMouseWheelListener(sliderListener); + slider.addPropertyChangeListener(sliderListener); + } + + protected DarkSliderListener createSliderListener() { + return new DarkSliderListener(this, slider); } @Override protected void uninstallListeners(final JSlider slider) { super.uninstallListeners(slider); - slider.removeMouseListener(mouseListener); - slider.removePropertyChangeListener(this); + slider.removeMouseListener(sliderListener); + slider.removeMouseWheelListener(sliderListener); + slider.removePropertyChangeListener(sliderListener); + sliderListener = null; } @Override @@ -760,17 +750,6 @@ public class DarkSliderUI extends BasicSliderUI implements PropertyChangeListene return new Rectangle(thumbRect); } - @Override - public void propertyChange(final PropertyChangeEvent evt) { - String key = evt.getPropertyName(); - if (KEY_VARIANT.equals(key)) { - slider.repaint(); - } else if (DarkSliderUI.KEY_SHOW_VOLUME_ICON.equals(key)) { - calculateGeometry(); - slider.repaint(); - } - } - private int getSnappedValue(final int value) { // Now calculate if we should adjust the value int snappedValue = value;