Refactor GUIs to use param's own default value

This removes the need to pass a lot of these `ParamSetter`s and
`GuiContext`s around. We also don't need explicit events to reset a
parameter anymore since you can get this information from the parameter
itself.
This commit is contained in:
Robbert van der Helm
2022-03-21 13:09:51 +01:00
parent a844051054
commit f084f14095
18 changed files with 54 additions and 168 deletions

View File

@@ -216,10 +216,6 @@ pub trait IcedEditor: 'static + Send + Sync + Sized {
ParamMessage::SetParameterNormalized(p, v) => unsafe {
context.raw_set_parameter_normalized(p, v)
},
ParamMessage::ResetParameter(p) => unsafe {
let default_value = context.raw_default_normalized_param_value(p);
context.raw_set_parameter_normalized(p, default_value);
},
ParamMessage::EndSetParameter(p) => unsafe { context.raw_end_set_parameter(p) },
}
}

View File

@@ -27,9 +27,6 @@ pub enum ParamMessage {
/// Set a parameter to a new normalized value. This needs to be surrounded by a matching
/// `BeginSetParameter` and `EndSetParameter`.
SetParameterNormalized(ParamPtr, f32),
/// Reset a parameter to its default value. This needs to be surrounded by a matching
/// `BeginSetParameter` and `EndSetParameter`.
ResetParameter(ParamPtr),
/// End an automation gesture for a parameter.
EndSetParameter(ParamPtr),
}

View File

@@ -8,7 +8,7 @@ use std::marker::PhantomData;
use std::pin::Pin;
use nih_plug::param::internals::ParamPtr;
use nih_plug::prelude::{GuiContext, Param, Params};
use nih_plug::prelude::{Param, Params};
use super::{ParamMessage, ParamSlider};
use crate::backend::Renderer;
@@ -27,7 +27,6 @@ pub trait ParamWidget {
/// Create an [`Element`] for a widget for the specified parameter.
fn into_widget_element<'a, P: Param>(
param: &'a P,
context: &'a dyn GuiContext,
state: &'a mut Self::State,
) -> Element<'a, ParamMessage>;
@@ -38,14 +37,13 @@ pub trait ParamWidget {
/// Undefined behavior of the `ParamPtr` does not point to a valid parameter.
unsafe fn into_widget_element_raw<'a>(
param: &ParamPtr,
context: &'a dyn GuiContext,
state: &'a mut Self::State,
) -> Element<'a, ParamMessage> {
match param {
ParamPtr::FloatParam(p) => Self::into_widget_element(&**p, context, state),
ParamPtr::IntParam(p) => Self::into_widget_element(&**p, context, state),
ParamPtr::BoolParam(p) => Self::into_widget_element(&**p, context, state),
ParamPtr::EnumParam(p) => Self::into_widget_element(&**p, context, state),
ParamPtr::FloatParam(p) => Self::into_widget_element(&**p, state),
ParamPtr::IntParam(p) => Self::into_widget_element(&**p, state),
ParamPtr::BoolParam(p) => Self::into_widget_element(&**p, state),
ParamPtr::EnumParam(p) => Self::into_widget_element(&**p, state),
}
}
}
@@ -62,7 +60,6 @@ pub struct GenericUi<'a, W: ParamWidget> {
state: &'a mut State<W>,
params: Pin<&'a dyn Params>,
context: &'a dyn GuiContext,
width: Length,
height: Length,
@@ -89,16 +86,11 @@ where
W: ParamWidget,
{
/// Creates a new [`GenericUi`] for all provided parameters.
pub fn new(
state: &'a mut State<W>,
params: Pin<&'a dyn Params>,
context: &'a dyn GuiContext,
) -> Self {
pub fn new(state: &'a mut State<W>, params: Pin<&'a dyn Params>) -> Self {
Self {
state,
params,
context,
width: Length::Fill,
height: Length::Fill,
@@ -193,9 +185,7 @@ where
.horizontal_alignment(alignment::Horizontal::Right)
.vertical_alignment(alignment::Vertical::Center),
)
.push(unsafe {
W::into_widget_element_raw(&param_ptr, self.context, widget_state)
});
.push(unsafe { W::into_widget_element_raw(&param_ptr, widget_state) });
if self.pad_scrollbar {
// There's already spacing applied, so this element doesn't actually need to hae any
// size of its own
@@ -279,10 +269,9 @@ impl ParamWidget for GenericSlider {
fn into_widget_element<'a, P: Param>(
param: &'a P,
context: &'a dyn GuiContext,
state: &'a mut Self::State,
) -> Element<'a, ParamMessage> {
ParamSlider::new(state, param, context).into()
ParamSlider::new(state, param).into()
}
}

View File

@@ -1,7 +1,7 @@
//! A slider that integrates with NIH-plug's [`Param`] types.
use atomic_refcell::AtomicRefCell;
use nih_plug::prelude::{GuiContext, Param, ParamSetter};
use nih_plug::prelude::Param;
use std::borrow::Borrow;
use crate::backend::widget;
@@ -31,9 +31,6 @@ pub struct ParamSlider<'a, P: Param> {
state: &'a mut State,
param: &'a P,
/// We'll visualize the parameter's current value by drawing the difference between the current
/// normalized value and the default normalized value.
setter: ParamSetter<'a>,
height: Length,
width: Length,
@@ -102,14 +99,11 @@ impl widget::text_input::StyleSheet for TextInputStyle {
impl<'a, P: Param> ParamSlider<'a, P> {
/// Creates a new [`ParamSlider`] for the given parameter.
pub fn new(state: &'a mut State, param: &'a P, context: &'a dyn GuiContext) -> Self {
let setter = ParamSetter::new(context);
pub fn new(state: &'a mut State, param: &'a P) -> Self {
Self {
state,
param,
setter,
width: Length::Units(180),
height: Length::Units(30),
@@ -328,10 +322,7 @@ impl<'a, P: Param> Widget<ParamMessage, Renderer> for ParamSlider<'a, P> {
self.state.drag_active = false;
shell.publish(ParamMessage::BeginSetParameter(self.param.as_ptr()));
self.set_normalized_value(
shell,
self.setter.default_normalized_param_value(self.param),
);
self.set_normalized_value(shell, self.param.default_normalized_value());
shell.publish(ParamMessage::EndSetParameter(self.param.as_ptr()));
} else if self.state.keyboard_modifiers.shift() {
shell.publish(ParamMessage::BeginSetParameter(self.param.as_ptr()));
@@ -494,7 +485,7 @@ impl<'a, P: Param> Widget<ParamMessage, Renderer> for ParamSlider<'a, P> {
// default value lies somewhere in the middle and the parameter is continuous. Otherwise
// this appraoch looks a bit jarring.
let current_value = self.param.normalized_value();
let default_value = self.setter.default_normalized_param_value(self.param);
let default_value = self.param.default_normalized_value();
let fill_start_x = util::remap_rect_x_t(
&bounds_without_borders,
if self.param.step_count().is_none() && (0.45..=0.55).contains(&default_value) {