From 5e94ec7f1de3e343b7a6128a2c331d9689fd915f Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Tue, 22 Mar 2022 19:44:40 +0100 Subject: [PATCH] Add an evenly distributed CurrentStep mode --- nih_plug_vizia/src/widgets/generic_ui.rs | 8 ++++-- nih_plug_vizia/src/widgets/param_slider.rs | 33 +++++++++++++++++----- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/nih_plug_vizia/src/widgets/generic_ui.rs b/nih_plug_vizia/src/widgets/generic_ui.rs index 446a980f..413ca94b 100644 --- a/nih_plug_vizia/src/widgets/generic_ui.rs +++ b/nih_plug_vizia/src/widgets/generic_ui.rs @@ -52,8 +52,12 @@ impl GenericUi { .set_style(match unsafe { param_ptr.step_count() } { // This looks nice for boolean values, but it's too crowded for anything beyond // that without making the widget wider - Some(step_count) if step_count <= 1 => ParamSliderStyle::CurrentStepLabeled, - Some(step_count) if step_count <= 64 => ParamSliderStyle::CurrentStep, + Some(step_count) if step_count <= 1 => { + ParamSliderStyle::CurrentStepLabeled { even: true } + } + Some(step_count) if step_count <= 64 => { + ParamSliderStyle::CurrentStep { even: true } + } Some(_) => ParamSliderStyle::FromLeft, // This is already the default, but continuous parameters should be drawn from // the center if the default is also centered, or from the left if it is not diff --git a/nih_plug_vizia/src/widgets/param_slider.rs b/nih_plug_vizia/src/widgets/param_slider.rs index 21045252..3cf18ff7 100644 --- a/nih_plug_vizia/src/widgets/param_slider.rs +++ b/nih_plug_vizia/src/widgets/param_slider.rs @@ -44,12 +44,15 @@ pub enum ParamSliderStyle { Centered, /// Always fill the bar starting from the left. FromLeft, - /// Show the current step instead of filling a portion fothe bar, useful for discrete - /// parameters. - CurrentStep, + /// Show the current step instead of filling a portion of the bar, useful for discrete + /// parameters. Set `even` to `true` to distribute the ticks evenly instead of following the + /// parameter's distribution. This can be desireable because discrete parameters have smaller + /// ranges near the edges (they'll span only half the range, which can make the display look + /// odd). + CurrentStep { even: bool }, /// The same as `CurrentStep`, but overlay the labels over the steps instead of showing the /// active value. Only useful for discrete parameters with two, maybe three possible values. - CurrentStepLabeled, + CurrentStepLabeled { even: bool }, } enum ParamSliderEvent { @@ -205,8 +208,21 @@ impl ParamSlider { } ParamSliderStyle::Centered | ParamSliderStyle::FromLeft => (0.0, current_value), - ParamSliderStyle::CurrentStep - | ParamSliderStyle::CurrentStepLabeled => { + ParamSliderStyle::CurrentStep { even: true } + | ParamSliderStyle::CurrentStepLabeled { even: true } + if step_count.is_some() => + { + // Assume the normalized value is distributed evenly + // across the range. + let step_count = step_count.unwrap() as f32; + let discrete_values = step_count + 1.0; + let previous_step = (current_value * step_count) + .floor() + / discrete_values; + (previous_step, discrete_values.recip()) + } + ParamSliderStyle::CurrentStep { .. } + | ParamSliderStyle::CurrentStepLabeled { .. } => { let previous_step = unsafe { param_ptr .previous_normalized_step(current_value) @@ -237,7 +253,10 @@ impl ParamSlider { // text overlapping the fill area slightly differently. We can // set the cip region directly in vizia. match (style, step_count) { - (ParamSliderStyle::CurrentStepLabeled, Some(step_count)) => { + ( + ParamSliderStyle::CurrentStepLabeled { .. }, + Some(step_count), + ) => { HStack::new(cx, |cx| { // There are step_count + 1 possible values for a // discrete parameter