Add stepping functions to Param
This can be useful for GUI widgets.
This commit is contained in:
parent
629619256e
commit
d9330628c0
15
src/param.rs
15
src/param.rs
|
@ -30,9 +30,22 @@ pub trait Param: Display {
|
||||||
/// Get the unit label for this parameter, if any.
|
/// Get the unit label for this parameter, if any.
|
||||||
fn unit(&self) -> &'static str;
|
fn unit(&self) -> &'static str;
|
||||||
|
|
||||||
/// Get the number of steps for this paramter, if it is stepped. Used for the host's generic UI.
|
/// Get the number of steps for this paramter, if it is discrete. Used for the host's generic
|
||||||
|
/// UI.
|
||||||
fn step_count(&self) -> Option<usize>;
|
fn step_count(&self) -> Option<usize>;
|
||||||
|
|
||||||
|
/// Return the previous step from a specific value for this parameter. This can be the same as
|
||||||
|
/// `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;
|
||||||
|
|
||||||
|
/// Return 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;
|
||||||
|
|
||||||
/// Get the unnormalized value for this parameter.
|
/// Get the unnormalized value for this parameter.
|
||||||
fn plain_value(&self) -> Self::Plain;
|
fn plain_value(&self) -> Self::Plain;
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,14 @@ impl Param for BoolParam {
|
||||||
Some(1)
|
Some(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn previous_step(&self, _from: Self::Plain) -> Self::Plain {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next_step(&self, _from: Self::Plain) -> Self::Plain {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
fn plain_value(&self) -> Self::Plain {
|
fn plain_value(&self) -> Self::Plain {
|
||||||
self.value
|
self.value
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,6 +113,14 @@ impl<T: Enum + PartialEq> Param for EnumParam<T> {
|
||||||
self.inner.step_count()
|
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 next_step(&self, from: Self::Plain) -> Self::Plain {
|
||||||
|
T::from_index(self.inner.next_step(T::to_index(from) as i32) as usize)
|
||||||
|
}
|
||||||
|
|
||||||
fn plain_value(&self) -> Self::Plain {
|
fn plain_value(&self) -> Self::Plain {
|
||||||
T::from_index(self.inner.plain_value() as usize)
|
T::from_index(self.inner.plain_value() as usize)
|
||||||
}
|
}
|
||||||
|
@ -174,6 +182,14 @@ impl Param for EnumParamInner {
|
||||||
Some(self.len() - 1)
|
Some(self.len() - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn previous_step(&self, from: Self::Plain) -> Self::Plain {
|
||||||
|
self.inner.previous_step(from)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next_step(&self, from: Self::Plain) -> Self::Plain {
|
||||||
|
self.inner.next_step(from)
|
||||||
|
}
|
||||||
|
|
||||||
fn plain_value(&self) -> Self::Plain {
|
fn plain_value(&self) -> Self::Plain {
|
||||||
self.inner.plain_value()
|
self.inner.plain_value()
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,6 +107,29 @@ impl Param for FloatParam {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn previous_step(&self, from: Self::Plain) -> Self::Plain {
|
||||||
|
// This one's slightly more involved. We'll split the normalized range up into 100 segments,
|
||||||
|
// but if `self.step_size` is set then we'll use that. Ideally we might want to split the
|
||||||
|
// range up into at most 100 segments, falling back to the step size if the total number of
|
||||||
|
// steps would be smaller than that, but since ranges can be nonlienar that's a bit
|
||||||
|
// difficult to pull off.
|
||||||
|
// TODO: At some point, implement the above mentioned step size quantization
|
||||||
|
match self.step_size {
|
||||||
|
Some(step_size) => from - step_size,
|
||||||
|
None => self.preview_plain(self.preview_normalized(from) - 0.01),
|
||||||
|
}
|
||||||
|
.clamp(self.range.min(), self.range.max())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next_step(&self, from: Self::Plain) -> Self::Plain {
|
||||||
|
// See above
|
||||||
|
match self.step_size {
|
||||||
|
Some(step_size) => from + step_size,
|
||||||
|
None => self.preview_plain(self.preview_normalized(from) + 0.01),
|
||||||
|
}
|
||||||
|
.clamp(self.range.min(), self.range.max())
|
||||||
|
}
|
||||||
|
|
||||||
fn plain_value(&self) -> Self::Plain {
|
fn plain_value(&self) -> Self::Plain {
|
||||||
self.value
|
self.value
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,15 @@ impl Param for IntParam {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn step_count(&self) -> Option<usize> {
|
fn step_count(&self) -> Option<usize> {
|
||||||
self.range.step_count()
|
Some(self.range.step_count())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn previous_step(&self, from: Self::Plain) -> Self::Plain {
|
||||||
|
(from - 1).clamp(self.range.min(), self.range.max())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next_step(&self, from: Self::Plain) -> Self::Plain {
|
||||||
|
(from + 1).clamp(self.range.min(), self.range.max())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn plain_value(&self) -> Self::Plain {
|
fn plain_value(&self) -> Self::Plain {
|
||||||
|
|
|
@ -118,6 +118,24 @@ impl FloatRange {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The minimum value in this range.
|
||||||
|
pub fn min(&self) -> f32 {
|
||||||
|
match self {
|
||||||
|
FloatRange::Linear { min, .. }
|
||||||
|
| FloatRange::Skewed { min, .. }
|
||||||
|
| FloatRange::SymmetricalSkewed { min, .. } => *min,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The maximum value in this range.
|
||||||
|
pub fn max(&self) -> f32 {
|
||||||
|
match self {
|
||||||
|
FloatRange::Linear { max, .. }
|
||||||
|
| FloatRange::Skewed { max, .. }
|
||||||
|
| FloatRange::SymmetricalSkewed { max, .. } => *max,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Snap a vlue to a step size, clamping to the minimum and maximum value of the range.
|
/// Snap a vlue to a step size, clamping to the minimum and maximum value of the range.
|
||||||
pub fn snap_to_step(&self, value: f32, step_size: f32) -> f32 {
|
pub fn snap_to_step(&self, value: f32, step_size: f32) -> f32 {
|
||||||
let (min, max) = match &self {
|
let (min, max) = match &self {
|
||||||
|
@ -149,10 +167,24 @@ impl IntRange {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The number of steps in this range, if it is stepped. Used for the host's generic UI.
|
/// The minimum value in this range.
|
||||||
pub fn step_count(&self) -> Option<usize> {
|
pub fn min(&self) -> i32 {
|
||||||
match self {
|
match self {
|
||||||
IntRange::Linear { min, max } => Some((max - min) as usize),
|
IntRange::Linear { min, .. } => *min,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The maximum value in this range.
|
||||||
|
pub fn max(&self) -> i32 {
|
||||||
|
match self {
|
||||||
|
IntRange::Linear { max, .. } => *max,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The number of steps in this range. Used for the host's generic UI.
|
||||||
|
pub fn step_count(&self) -> usize {
|
||||||
|
match self {
|
||||||
|
IntRange::Linear { min, max } => (max - min) as usize,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue