Add finer step sizes to parameters
This commit is contained in:
parent
8885713ea1
commit
e583b8e777
|
@ -6,6 +6,13 @@ new and what's changed, this document lists all breaking changes in reverse
|
|||
chronological order. If a new feature did not require any changes to existing
|
||||
code then it will not be listed here.
|
||||
|
||||
## [2022-11-08]
|
||||
|
||||
- The `Param::{next_previous}{_step,_normalized_step}()` functions now take an
|
||||
additional boolean argument to indicate that the range must be finer. This is
|
||||
used for floating point parameters to chop the range up into smaller segments
|
||||
when using Shift+scroll.
|
||||
|
||||
## [2022-11-07]
|
||||
|
||||
- `Param::plain_value()` and `Param::normalized_value()` have been renamed to
|
||||
|
|
|
@ -219,8 +219,8 @@ impl ParamWidgetBase {
|
|||
param_ptr_forward!(pub fn default_plain_value(&self) -> f32);
|
||||
param_ptr_forward!(pub fn default_normalized_value(&self) -> f32);
|
||||
param_ptr_forward!(pub fn step_count(&self) -> Option<usize>);
|
||||
param_ptr_forward!(pub fn previous_normalized_step(&self, from: f32) -> f32);
|
||||
param_ptr_forward!(pub fn next_normalized_step(&self, from: f32) -> f32);
|
||||
param_ptr_forward!(pub fn previous_normalized_step(&self, from: f32, finer: bool) -> f32);
|
||||
param_ptr_forward!(pub fn next_normalized_step(&self, from: f32, finer: bool) -> f32);
|
||||
param_ptr_forward!(pub fn normalized_value_to_string(&self, normalized: f32, include_unit: bool) -> String);
|
||||
param_ptr_forward!(pub fn string_to_normalized_value(&self, string: &str) -> Option<f32>);
|
||||
param_ptr_forward!(pub fn preview_normalized(&self, plain: f32) -> f32);
|
||||
|
|
|
@ -364,8 +364,8 @@ impl ParamSlider {
|
|||
(previous_step, discrete_values.recip())
|
||||
}
|
||||
ParamSliderStyle::CurrentStep { .. } | ParamSliderStyle::CurrentStepLabeled { .. } => {
|
||||
let previous_step = param.previous_normalized_step(current_value);
|
||||
let next_step = param.next_normalized_step(current_value);
|
||||
let previous_step = param.previous_normalized_step(current_value, false);
|
||||
let next_step = param.next_normalized_step(current_value, false);
|
||||
|
||||
(
|
||||
(previous_step + current_value) / 2.0,
|
||||
|
@ -570,13 +570,15 @@ impl View for ParamSlider {
|
|||
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);
|
||||
current_value = self.param_base.next_normalized_step(current_value, false);
|
||||
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);
|
||||
current_value = self
|
||||
.param_base
|
||||
.previous_normalized_step(current_value, false);
|
||||
self.param_base.set_normalized_value(cx, current_value);
|
||||
self.scrolled_lines += 1.0;
|
||||
}
|
||||
|
|
|
@ -120,24 +120,28 @@ pub trait Param: Display {
|
|||
/// `from` if the value is at the start of its range. This is mainly used for scroll wheel
|
||||
/// interaction in plugin GUIs. When the parameter is not discrete then a step should cover one
|
||||
/// hundredth of the normalized range instead.
|
||||
fn previous_step(&self, from: Self::Plain) -> Self::Plain;
|
||||
///
|
||||
/// If `finer` is true, then the step size should be decreased if the parameter is continuous.
|
||||
fn previous_step(&self, from: Self::Plain, finer: bool) -> Self::Plain;
|
||||
|
||||
/// Returns the next step from a specific value for this parameter. This can be the same as
|
||||
/// `from` if the value is at the end of its range. This is mainly used for scroll wheel
|
||||
/// interaction in plugin GUIs. When the parameter is not discrete then a step should cover one
|
||||
/// hundredth of the normalized range instead.
|
||||
fn next_step(&self, from: Self::Plain) -> Self::Plain;
|
||||
///
|
||||
/// If `finer` is true, then the step size should be decreased if the parameter is continuous.
|
||||
fn next_step(&self, from: Self::Plain, finer: bool) -> Self::Plain;
|
||||
|
||||
/// The same as [`previous_step()`][Self::previous_step()], but for normalized values. This is
|
||||
/// mostly useful for GUI widgets.
|
||||
fn previous_normalized_step(&self, from: f32) -> f32 {
|
||||
self.preview_normalized(self.previous_step(self.preview_plain(from)))
|
||||
fn previous_normalized_step(&self, from: f32, finer: bool) -> f32 {
|
||||
self.preview_normalized(self.previous_step(self.preview_plain(from), finer))
|
||||
}
|
||||
|
||||
/// The same as [`next_step()`][Self::next_step()], but for normalized values. This is mostly
|
||||
/// useful for GUI widgets.
|
||||
fn next_normalized_step(&self, from: f32) -> f32 {
|
||||
self.preview_normalized(self.next_step(self.preview_plain(from)))
|
||||
fn next_normalized_step(&self, from: f32, finer: bool) -> f32 {
|
||||
self.preview_normalized(self.next_step(self.preview_plain(from), finer))
|
||||
}
|
||||
|
||||
/// Get the string representation for a normalized value. Used as part of the wrappers. Most
|
||||
|
|
|
@ -105,11 +105,11 @@ impl Param for BoolParam {
|
|||
Some(1)
|
||||
}
|
||||
|
||||
fn previous_step(&self, _from: Self::Plain) -> Self::Plain {
|
||||
fn previous_step(&self, _from: Self::Plain, _finer: bool) -> Self::Plain {
|
||||
false
|
||||
}
|
||||
|
||||
fn next_step(&self, _from: Self::Plain) -> Self::Plain {
|
||||
fn next_step(&self, _from: Self::Plain, _finer: bool) -> Self::Plain {
|
||||
true
|
||||
}
|
||||
|
||||
|
|
|
@ -154,12 +154,12 @@ impl<T: Enum + PartialEq> Param for EnumParam<T> {
|
|||
self.inner.step_count()
|
||||
}
|
||||
|
||||
fn previous_step(&self, from: Self::Plain) -> Self::Plain {
|
||||
T::from_index(self.inner.previous_step(T::to_index(from) as i32) as usize)
|
||||
fn previous_step(&self, from: Self::Plain, finer: bool) -> Self::Plain {
|
||||
T::from_index(self.inner.previous_step(T::to_index(from) as i32, finer) as usize)
|
||||
}
|
||||
|
||||
fn next_step(&self, from: Self::Plain) -> Self::Plain {
|
||||
T::from_index(self.inner.next_step(T::to_index(from) as i32) as usize)
|
||||
fn next_step(&self, from: Self::Plain, finer: bool) -> Self::Plain {
|
||||
T::from_index(self.inner.next_step(T::to_index(from) as i32, finer) as usize)
|
||||
}
|
||||
|
||||
fn normalized_value_to_string(&self, normalized: f32, include_unit: bool) -> String {
|
||||
|
@ -232,12 +232,12 @@ impl Param for EnumParamInner {
|
|||
Some(self.len() - 1)
|
||||
}
|
||||
|
||||
fn previous_step(&self, from: Self::Plain) -> Self::Plain {
|
||||
self.inner.previous_step(from)
|
||||
fn previous_step(&self, from: Self::Plain, finer: bool) -> Self::Plain {
|
||||
self.inner.previous_step(from, finer)
|
||||
}
|
||||
|
||||
fn next_step(&self, from: Self::Plain) -> Self::Plain {
|
||||
self.inner.next_step(from)
|
||||
fn next_step(&self, from: Self::Plain, finer: bool) -> Self::Plain {
|
||||
self.inner.next_step(from, finer)
|
||||
}
|
||||
|
||||
fn normalized_value_to_string(&self, normalized: f32, _include_unit: bool) -> String {
|
||||
|
|
|
@ -130,12 +130,12 @@ impl Param for FloatParam {
|
|||
None
|
||||
}
|
||||
|
||||
fn previous_step(&self, from: Self::Plain) -> Self::Plain {
|
||||
self.range.previous_step(from, self.step_size)
|
||||
fn previous_step(&self, from: Self::Plain, finer: bool) -> Self::Plain {
|
||||
self.range.previous_step(from, self.step_size, finer)
|
||||
}
|
||||
|
||||
fn next_step(&self, from: Self::Plain) -> Self::Plain {
|
||||
self.range.next_step(from, self.step_size)
|
||||
fn next_step(&self, from: Self::Plain, finer: bool) -> Self::Plain {
|
||||
self.range.next_step(from, self.step_size, finer)
|
||||
}
|
||||
|
||||
fn normalized_value_to_string(&self, normalized: f32, include_unit: bool) -> String {
|
||||
|
|
|
@ -122,11 +122,11 @@ impl Param for IntParam {
|
|||
Some(self.range.step_count())
|
||||
}
|
||||
|
||||
fn previous_step(&self, from: Self::Plain) -> Self::Plain {
|
||||
fn previous_step(&self, from: Self::Plain, _finer: bool) -> Self::Plain {
|
||||
self.range.previous_step(from)
|
||||
}
|
||||
|
||||
fn next_step(&self, from: Self::Plain) -> Self::Plain {
|
||||
fn next_step(&self, from: Self::Plain, _finer: bool) -> Self::Plain {
|
||||
self.range.next_step(from)
|
||||
}
|
||||
|
||||
|
|
|
@ -68,8 +68,8 @@ impl ParamPtr {
|
|||
param_ptr_forward!(pub unsafe fn unmodulated_normalized_value(&self) -> f32);
|
||||
param_ptr_forward!(pub unsafe fn default_normalized_value(&self) -> f32);
|
||||
param_ptr_forward!(pub unsafe fn step_count(&self) -> Option<usize>);
|
||||
param_ptr_forward!(pub unsafe fn previous_normalized_step(&self, from: f32) -> f32);
|
||||
param_ptr_forward!(pub unsafe fn next_normalized_step(&self, from: f32) -> f32);
|
||||
param_ptr_forward!(pub unsafe fn previous_normalized_step(&self, from: f32, finer: bool) -> f32);
|
||||
param_ptr_forward!(pub unsafe fn next_normalized_step(&self, from: f32, finer: bool) -> f32);
|
||||
param_ptr_forward!(pub unsafe fn normalized_value_to_string(&self, normalized: f32, include_unit: bool) -> String);
|
||||
param_ptr_forward!(pub unsafe fn string_to_normalized_value(&self, string: &str) -> Option<f32>);
|
||||
param_ptr_forward!(pub unsafe fn flags(&self) -> ParamFlags);
|
||||
|
|
|
@ -130,17 +130,20 @@ impl FloatRange {
|
|||
}
|
||||
}
|
||||
|
||||
/// The range's previous discrete step from a certain value with a certain step size. If the step
|
||||
/// size is not set, then the normalized range is split into 100 segments instead.
|
||||
pub fn previous_step(&self, from: f32, step_size: Option<f32>) -> f32 {
|
||||
/// The range's previous discrete step from a certain value with a certain step size. If the
|
||||
/// step size is not set, then the normalized range is split into 50 segments instead. If
|
||||
/// `finer` is true, then this is upped to 200 segments.
|
||||
pub fn previous_step(&self, from: f32, step_size: Option<f32>, finer: bool) -> f32 {
|
||||
// This one's slightly more involved than the integer version. We'll split the normalized
|
||||
// range up into 100 segments, but if `self.step_size` would cause the range to be devided
|
||||
// into less than 100 segments then we'll use that.
|
||||
// range up into 50 segments, but if `self.step_size` would cause the range to be devided
|
||||
// into less than 50 segments then we'll use that.
|
||||
match self {
|
||||
FloatRange::Linear { min, max }
|
||||
| FloatRange::Skewed { min, max, .. }
|
||||
| FloatRange::SymmetricalSkewed { min, max, .. } => {
|
||||
let naive_step = self.unnormalize(self.normalize(from) - 0.01);
|
||||
let normalized_naive_step_size = if finer { 0.005 } else { 0.02 };
|
||||
let naive_step =
|
||||
self.unnormalize(self.normalize(from) - normalized_naive_step_size);
|
||||
|
||||
match step_size {
|
||||
// Use the naive step size if it is larger than the configured step size
|
||||
|
@ -152,19 +155,21 @@ impl FloatRange {
|
|||
}
|
||||
.clamp(*min, *max)
|
||||
}
|
||||
FloatRange::Reversed(range) => range.next_step(from, step_size),
|
||||
FloatRange::Reversed(range) => range.next_step(from, step_size, finer),
|
||||
}
|
||||
}
|
||||
|
||||
/// The range's next discrete step from a certain value with a certain step size. If the step
|
||||
/// size is not set, then the normalized range is split into 100 segments instead.
|
||||
pub fn next_step(&self, from: f32, step_size: Option<f32>) -> f32 {
|
||||
pub fn next_step(&self, from: f32, step_size: Option<f32>, finer: bool) -> f32 {
|
||||
// See above
|
||||
match self {
|
||||
FloatRange::Linear { min, max }
|
||||
| FloatRange::Skewed { min, max, .. }
|
||||
| FloatRange::SymmetricalSkewed { min, max, .. } => {
|
||||
let naive_step = self.unnormalize(self.normalize(from) + 0.01);
|
||||
let normalized_naive_step_size = if finer { 0.005 } else { 0.02 };
|
||||
let naive_step =
|
||||
self.unnormalize(self.normalize(from) + normalized_naive_step_size);
|
||||
|
||||
match step_size {
|
||||
Some(step_size) if (naive_step - from).abs() > step_size => {
|
||||
|
@ -175,7 +180,7 @@ impl FloatRange {
|
|||
}
|
||||
.clamp(*min, *max)
|
||||
}
|
||||
FloatRange::Reversed(range) => range.previous_step(from, step_size),
|
||||
FloatRange::Reversed(range) => range.previous_step(from, step_size, finer),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue