1
0
Fork 0

Add scrolling support to ParamSlider

This commit is contained in:
Robbert van der Helm 2022-11-08 21:20:40 +01:00
parent dfd5aa9a11
commit 3a064ae705

View file

@ -12,8 +12,6 @@ const GRANULAR_DRAG_MULTIPLIER: f32 = 0.1;
/// A slider that integrates with NIH-plug's [`Param`] types. Use the /// A slider that integrates with NIH-plug's [`Param`] types. Use the
/// [`set_style()`][ParamSliderExt::set_style()] method to change how the value gets displayed. /// [`set_style()`][ParamSliderExt::set_style()] method to change how the value gets displayed.
///
/// TODO: Handle scrolling for steps (and shift+scroll for smaller steps?)
#[derive(Lens)] #[derive(Lens)]
pub struct ParamSlider { pub struct ParamSlider {
param_base: ParamWidgetBase, param_base: ParamWidgetBase,
@ -30,6 +28,11 @@ pub struct ParamSlider {
granular_drag_start_x_value: Option<(f32, f32)>, granular_drag_start_x_value: Option<(f32, f32)>,
// These fields are set through modifiers: // These fields are set through modifiers:
/// Whether or not to listen to scroll events for changing the parameter's value in steps.
use_scroll_wheel: bool,
/// The number of (fractional) scrolled lines that have not yet been turned into parameter
/// change events. This is needed to support trackpads with smooth scrolling.
scrolled_lines: f32,
/// What style to use for the slider. /// What style to use for the slider.
style: ParamSliderStyle, style: ParamSliderStyle,
/// A specific label to use instead of displaying the parameter's value. /// A specific label to use instead of displaying the parameter's value.
@ -94,6 +97,8 @@ impl ParamSlider {
drag_active: false, drag_active: false,
granular_drag_start_x_value: None, granular_drag_start_x_value: None,
use_scroll_wheel: true,
scrolled_lines: 0.0,
style: ParamSliderStyle::Centered, style: ParamSliderStyle::Centered,
label_override: None, label_override: None,
} }
@ -551,6 +556,36 @@ impl View for ParamSlider {
); );
} }
} }
WindowEvent::MouseScroll(_scroll_x, scroll_y) if self.use_scroll_wheel => {
// With a regular scroll wheel `scroll_y` will only ever be -1 or 1, but with smooth
// scrolling trackpads being a thing `scroll_y` could be anything.
self.scrolled_lines += scroll_y;
if self.scrolled_lines.abs() >= 1.0 {
// Scrolling while dragging needs to be taken into account here
if !self.drag_active {
self.param_base.begin_set_parameter(cx);
}
let mut current_value = self.param_base.unmodulated_normalized_value();
while self.scrolled_lines >= 1.0 {
current_value = self.param_base.next_normalized_step(current_value);
self.param_base.set_normalized_value(cx, current_value);
self.scrolled_lines -= 1.0;
}
while self.scrolled_lines <= -1.0 {
current_value = self.param_base.previous_normalized_step(current_value);
self.param_base.set_normalized_value(cx, current_value);
self.scrolled_lines += 1.0;
}
if !self.drag_active {
self.param_base.end_set_parameter(cx);
}
}
}
_ => {} _ => {}
}); });
} }
@ -558,6 +593,10 @@ impl View for ParamSlider {
/// Extension methods for [`ParamSlider`] handles. /// Extension methods for [`ParamSlider`] handles.
pub trait ParamSliderExt { pub trait ParamSliderExt {
/// Don't respond to scroll wheel events. Useful when this slider is used as part of a scrolling
/// view.
fn disable_scroll_wheel(self) -> Self;
/// Change how the [`ParamSlider`] visualizes the current value. /// Change how the [`ParamSlider`] visualizes the current value.
fn set_style(self, style: ParamSliderStyle) -> Self; fn set_style(self, style: ParamSliderStyle) -> Self;
@ -567,6 +606,10 @@ pub trait ParamSliderExt {
} }
impl ParamSliderExt for Handle<'_, ParamSlider> { impl ParamSliderExt for Handle<'_, ParamSlider> {
fn disable_scroll_wheel(self) -> Self {
self.modify(|param_slider: &mut ParamSlider| param_slider.use_scroll_wheel = false)
}
fn set_style(self, style: ParamSliderStyle) -> Self { fn set_style(self, style: ParamSliderStyle) -> Self {
self.modify(|param_slider: &mut ParamSlider| param_slider.style = style) self.modify(|param_slider: &mut ParamSlider| param_slider.style = style)
} }