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:
parent
a844051054
commit
f084f14095
|
@ -124,9 +124,8 @@ impl<'a, P: Param> ParamSlider<'a, P> {
|
||||||
|
|
||||||
/// Begin and end drag still need to be called when using this..
|
/// Begin and end drag still need to be called when using this..
|
||||||
fn reset_param(&self) {
|
fn reset_param(&self) {
|
||||||
let normalized_default = self.setter.default_normalized_param_value(self.param);
|
|
||||||
self.setter
|
self.setter
|
||||||
.set_parameter_normalized(self.param, normalized_default);
|
.set_parameter(self.param, self.param.default_plain_value());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn granular_drag(&self, ui: &Ui, drag_delta: Vec2) {
|
fn granular_drag(&self, ui: &Ui, drag_delta: Vec2) {
|
||||||
|
|
|
@ -216,10 +216,6 @@ pub trait IcedEditor: 'static + Send + Sync + Sized {
|
||||||
ParamMessage::SetParameterNormalized(p, v) => unsafe {
|
ParamMessage::SetParameterNormalized(p, v) => unsafe {
|
||||||
context.raw_set_parameter_normalized(p, v)
|
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) },
|
ParamMessage::EndSetParameter(p) => unsafe { context.raw_end_set_parameter(p) },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,9 +27,6 @@ pub enum ParamMessage {
|
||||||
/// Set a parameter to a new normalized value. This needs to be surrounded by a matching
|
/// Set a parameter to a new normalized value. This needs to be surrounded by a matching
|
||||||
/// `BeginSetParameter` and `EndSetParameter`.
|
/// `BeginSetParameter` and `EndSetParameter`.
|
||||||
SetParameterNormalized(ParamPtr, f32),
|
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.
|
/// End an automation gesture for a parameter.
|
||||||
EndSetParameter(ParamPtr),
|
EndSetParameter(ParamPtr),
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ use std::marker::PhantomData;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
|
|
||||||
use nih_plug::param::internals::ParamPtr;
|
use nih_plug::param::internals::ParamPtr;
|
||||||
use nih_plug::prelude::{GuiContext, Param, Params};
|
use nih_plug::prelude::{Param, Params};
|
||||||
|
|
||||||
use super::{ParamMessage, ParamSlider};
|
use super::{ParamMessage, ParamSlider};
|
||||||
use crate::backend::Renderer;
|
use crate::backend::Renderer;
|
||||||
|
@ -27,7 +27,6 @@ pub trait ParamWidget {
|
||||||
/// Create an [`Element`] for a widget for the specified parameter.
|
/// Create an [`Element`] for a widget for the specified parameter.
|
||||||
fn into_widget_element<'a, P: Param>(
|
fn into_widget_element<'a, P: Param>(
|
||||||
param: &'a P,
|
param: &'a P,
|
||||||
context: &'a dyn GuiContext,
|
|
||||||
state: &'a mut Self::State,
|
state: &'a mut Self::State,
|
||||||
) -> Element<'a, ParamMessage>;
|
) -> Element<'a, ParamMessage>;
|
||||||
|
|
||||||
|
@ -38,14 +37,13 @@ pub trait ParamWidget {
|
||||||
/// Undefined behavior of the `ParamPtr` does not point to a valid parameter.
|
/// Undefined behavior of the `ParamPtr` does not point to a valid parameter.
|
||||||
unsafe fn into_widget_element_raw<'a>(
|
unsafe fn into_widget_element_raw<'a>(
|
||||||
param: &ParamPtr,
|
param: &ParamPtr,
|
||||||
context: &'a dyn GuiContext,
|
|
||||||
state: &'a mut Self::State,
|
state: &'a mut Self::State,
|
||||||
) -> Element<'a, ParamMessage> {
|
) -> Element<'a, ParamMessage> {
|
||||||
match param {
|
match param {
|
||||||
ParamPtr::FloatParam(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, context, state),
|
ParamPtr::IntParam(p) => Self::into_widget_element(&**p, state),
|
||||||
ParamPtr::BoolParam(p) => Self::into_widget_element(&**p, context, state),
|
ParamPtr::BoolParam(p) => Self::into_widget_element(&**p, state),
|
||||||
ParamPtr::EnumParam(p) => Self::into_widget_element(&**p, context, 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>,
|
state: &'a mut State<W>,
|
||||||
|
|
||||||
params: Pin<&'a dyn Params>,
|
params: Pin<&'a dyn Params>,
|
||||||
context: &'a dyn GuiContext,
|
|
||||||
|
|
||||||
width: Length,
|
width: Length,
|
||||||
height: Length,
|
height: Length,
|
||||||
|
@ -89,16 +86,11 @@ where
|
||||||
W: ParamWidget,
|
W: ParamWidget,
|
||||||
{
|
{
|
||||||
/// Creates a new [`GenericUi`] for all provided parameters.
|
/// Creates a new [`GenericUi`] for all provided parameters.
|
||||||
pub fn new(
|
pub fn new(state: &'a mut State<W>, params: Pin<&'a dyn Params>) -> Self {
|
||||||
state: &'a mut State<W>,
|
|
||||||
params: Pin<&'a dyn Params>,
|
|
||||||
context: &'a dyn GuiContext,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
state,
|
state,
|
||||||
|
|
||||||
params,
|
params,
|
||||||
context,
|
|
||||||
|
|
||||||
width: Length::Fill,
|
width: Length::Fill,
|
||||||
height: Length::Fill,
|
height: Length::Fill,
|
||||||
|
@ -193,9 +185,7 @@ where
|
||||||
.horizontal_alignment(alignment::Horizontal::Right)
|
.horizontal_alignment(alignment::Horizontal::Right)
|
||||||
.vertical_alignment(alignment::Vertical::Center),
|
.vertical_alignment(alignment::Vertical::Center),
|
||||||
)
|
)
|
||||||
.push(unsafe {
|
.push(unsafe { W::into_widget_element_raw(¶m_ptr, widget_state) });
|
||||||
W::into_widget_element_raw(¶m_ptr, self.context, widget_state)
|
|
||||||
});
|
|
||||||
if self.pad_scrollbar {
|
if self.pad_scrollbar {
|
||||||
// There's already spacing applied, so this element doesn't actually need to hae any
|
// There's already spacing applied, so this element doesn't actually need to hae any
|
||||||
// size of its own
|
// size of its own
|
||||||
|
@ -279,10 +269,9 @@ impl ParamWidget for GenericSlider {
|
||||||
|
|
||||||
fn into_widget_element<'a, P: Param>(
|
fn into_widget_element<'a, P: Param>(
|
||||||
param: &'a P,
|
param: &'a P,
|
||||||
context: &'a dyn GuiContext,
|
|
||||||
state: &'a mut Self::State,
|
state: &'a mut Self::State,
|
||||||
) -> Element<'a, ParamMessage> {
|
) -> Element<'a, ParamMessage> {
|
||||||
ParamSlider::new(state, param, context).into()
|
ParamSlider::new(state, param).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! A slider that integrates with NIH-plug's [`Param`] types.
|
//! A slider that integrates with NIH-plug's [`Param`] types.
|
||||||
|
|
||||||
use atomic_refcell::AtomicRefCell;
|
use atomic_refcell::AtomicRefCell;
|
||||||
use nih_plug::prelude::{GuiContext, Param, ParamSetter};
|
use nih_plug::prelude::Param;
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
|
|
||||||
use crate::backend::widget;
|
use crate::backend::widget;
|
||||||
|
@ -31,9 +31,6 @@ pub struct ParamSlider<'a, P: Param> {
|
||||||
state: &'a mut State,
|
state: &'a mut State,
|
||||||
|
|
||||||
param: &'a P,
|
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,
|
height: Length,
|
||||||
width: Length,
|
width: Length,
|
||||||
|
@ -102,14 +99,11 @@ impl widget::text_input::StyleSheet for TextInputStyle {
|
||||||
|
|
||||||
impl<'a, P: Param> ParamSlider<'a, P> {
|
impl<'a, P: Param> ParamSlider<'a, P> {
|
||||||
/// Creates a new [`ParamSlider`] for the given parameter.
|
/// Creates a new [`ParamSlider`] for the given parameter.
|
||||||
pub fn new(state: &'a mut State, param: &'a P, context: &'a dyn GuiContext) -> Self {
|
pub fn new(state: &'a mut State, param: &'a P) -> Self {
|
||||||
let setter = ParamSetter::new(context);
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
state,
|
state,
|
||||||
|
|
||||||
param,
|
param,
|
||||||
setter,
|
|
||||||
|
|
||||||
width: Length::Units(180),
|
width: Length::Units(180),
|
||||||
height: Length::Units(30),
|
height: Length::Units(30),
|
||||||
|
@ -328,10 +322,7 @@ impl<'a, P: Param> Widget<ParamMessage, Renderer> for ParamSlider<'a, P> {
|
||||||
self.state.drag_active = false;
|
self.state.drag_active = false;
|
||||||
|
|
||||||
shell.publish(ParamMessage::BeginSetParameter(self.param.as_ptr()));
|
shell.publish(ParamMessage::BeginSetParameter(self.param.as_ptr()));
|
||||||
self.set_normalized_value(
|
self.set_normalized_value(shell, self.param.default_normalized_value());
|
||||||
shell,
|
|
||||||
self.setter.default_normalized_param_value(self.param),
|
|
||||||
);
|
|
||||||
shell.publish(ParamMessage::EndSetParameter(self.param.as_ptr()));
|
shell.publish(ParamMessage::EndSetParameter(self.param.as_ptr()));
|
||||||
} else if self.state.keyboard_modifiers.shift() {
|
} else if self.state.keyboard_modifiers.shift() {
|
||||||
shell.publish(ParamMessage::BeginSetParameter(self.param.as_ptr()));
|
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
|
// default value lies somewhere in the middle and the parameter is continuous. Otherwise
|
||||||
// this appraoch looks a bit jarring.
|
// this appraoch looks a bit jarring.
|
||||||
let current_value = self.param.normalized_value();
|
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(
|
let fill_start_x = util::remap_rect_x_t(
|
||||||
&bounds_without_borders,
|
&bounds_without_borders,
|
||||||
if self.param.step_count().is_none() && (0.45..=0.55).contains(&default_value) {
|
if self.param.step_count().is_none() && (0.45..=0.55).contains(&default_value) {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use baseview::{WindowHandle, WindowScalePolicy};
|
use baseview::{WindowHandle, WindowScalePolicy};
|
||||||
use crossbeam::atomic::AtomicCell;
|
use crossbeam::atomic::AtomicCell;
|
||||||
use nih_plug::prelude::{Editor, GuiContext, ParamSetter, ParentWindowHandle};
|
use nih_plug::prelude::{Editor, GuiContext, ParentWindowHandle};
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use vizia::{Application, Color, Context, Entity, Model, PropSet, WindowDescription};
|
use vizia::{Application, Color, Context, Entity, Model, PropSet, WindowDescription};
|
||||||
|
@ -23,7 +23,7 @@ pub mod widgets;
|
||||||
/// See [VIZIA](https://github.com/vizia/vizia)'s repository for examples on how to use this.
|
/// See [VIZIA](https://github.com/vizia/vizia)'s repository for examples on how to use this.
|
||||||
pub fn create_vizia_editor<F>(vizia_state: Arc<ViziaState>, app: F) -> Option<Box<dyn Editor>>
|
pub fn create_vizia_editor<F>(vizia_state: Arc<ViziaState>, app: F) -> Option<Box<dyn Editor>>
|
||||||
where
|
where
|
||||||
F: Fn(&mut Context, &ParamSetter) + 'static + Send + Sync,
|
F: Fn(&mut Context) + 'static + Send + Sync,
|
||||||
{
|
{
|
||||||
Some(Box::new(ViziaEditor {
|
Some(Box::new(ViziaEditor {
|
||||||
vizia_state,
|
vizia_state,
|
||||||
|
@ -66,7 +66,7 @@ impl ViziaState {
|
||||||
struct ViziaEditor {
|
struct ViziaEditor {
|
||||||
vizia_state: Arc<ViziaState>,
|
vizia_state: Arc<ViziaState>,
|
||||||
/// The user's app function.
|
/// The user's app function.
|
||||||
app: Arc<dyn Fn(&mut Context, &ParamSetter) + 'static + Send + Sync>,
|
app: Arc<dyn Fn(&mut Context) + 'static + Send + Sync>,
|
||||||
|
|
||||||
/// The scaling factor reported by the host, if any. On macOS this will never be set and we
|
/// The scaling factor reported by the host, if any. On macOS this will never be set and we
|
||||||
/// should use the system scaling factor instead.
|
/// should use the system scaling factor instead.
|
||||||
|
@ -87,8 +87,6 @@ impl Editor for ViziaEditor {
|
||||||
WindowDescription::new().with_inner_size(unscaled_width, unscaled_height);
|
WindowDescription::new().with_inner_size(unscaled_width, unscaled_height);
|
||||||
|
|
||||||
let window = Application::new(window_description, move |cx| {
|
let window = Application::new(window_description, move |cx| {
|
||||||
let setter = ParamSetter::new(context.as_ref());
|
|
||||||
|
|
||||||
// Set some default styles to match the iced integration
|
// Set some default styles to match the iced integration
|
||||||
// TODO: Maybe add a way to override this behavior
|
// TODO: Maybe add a way to override this behavior
|
||||||
// NOTE: vizia's font rendering looks way too dark and thick. Going one font weight
|
// NOTE: vizia's font rendering looks way too dark and thick. Going one font weight
|
||||||
|
@ -112,7 +110,7 @@ impl Editor for ViziaEditor {
|
||||||
}
|
}
|
||||||
.build(cx);
|
.build(cx);
|
||||||
|
|
||||||
app(cx, &setter)
|
app(cx)
|
||||||
})
|
})
|
||||||
.with_scale_policy(
|
.with_scale_policy(
|
||||||
scaling_factor
|
scaling_factor
|
||||||
|
|
|
@ -38,9 +38,6 @@ pub enum ParamEvent<'a, P: Param> {
|
||||||
/// Set a parameter to a new normalized value. This needs to be surrounded by a matching
|
/// Set a parameter to a new normalized value. This needs to be surrounded by a matching
|
||||||
/// `BeginSetParameter` and `EndSetParameter`.
|
/// `BeginSetParameter` and `EndSetParameter`.
|
||||||
SetParameterNormalized(&'a P, f32),
|
SetParameterNormalized(&'a P, f32),
|
||||||
/// Reset a parameter to its default value. This needs to be surrounded by a matching
|
|
||||||
/// `BeginSetParameter` and `EndSetParameter`.
|
|
||||||
ResetParameter(&'a P),
|
|
||||||
/// End an automation gesture for a parameter.
|
/// End an automation gesture for a parameter.
|
||||||
EndSetParameter(&'a P),
|
EndSetParameter(&'a P),
|
||||||
}
|
}
|
||||||
|
@ -53,9 +50,6 @@ pub enum RawParamEvent {
|
||||||
/// Set a parameter to a new normalized value. This needs to be surrounded by a matching
|
/// Set a parameter to a new normalized value. This needs to be surrounded by a matching
|
||||||
/// `BeginSetParameter` and `EndSetParameter`.
|
/// `BeginSetParameter` and `EndSetParameter`.
|
||||||
SetParameterNormalized(ParamPtr, f32),
|
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.
|
/// End an automation gesture for a parameter.
|
||||||
EndSetParameter(ParamPtr),
|
EndSetParameter(ParamPtr),
|
||||||
}
|
}
|
||||||
|
@ -78,10 +72,6 @@ impl Model for ParamModel {
|
||||||
RawParamEvent::SetParameterNormalized(p, v) => unsafe {
|
RawParamEvent::SetParameterNormalized(p, v) => unsafe {
|
||||||
self.context.raw_set_parameter_normalized(p, v)
|
self.context.raw_set_parameter_normalized(p, v)
|
||||||
},
|
},
|
||||||
RawParamEvent::ResetParameter(p) => unsafe {
|
|
||||||
let default_value = self.context.raw_default_normalized_param_value(p);
|
|
||||||
self.context.raw_set_parameter_normalized(p, default_value);
|
|
||||||
},
|
|
||||||
RawParamEvent::EndSetParameter(p) => unsafe {
|
RawParamEvent::EndSetParameter(p) => unsafe {
|
||||||
self.context.raw_end_set_parameter(p)
|
self.context.raw_end_set_parameter(p)
|
||||||
},
|
},
|
||||||
|
@ -100,7 +90,6 @@ impl<P: Param> From<ParamEvent<'_, P>> for RawParamEvent {
|
||||||
ParamEvent::SetParameterNormalized(p, v) => {
|
ParamEvent::SetParameterNormalized(p, v) => {
|
||||||
RawParamEvent::SetParameterNormalized(p.as_ptr(), v)
|
RawParamEvent::SetParameterNormalized(p.as_ptr(), v)
|
||||||
}
|
}
|
||||||
ParamEvent::ResetParameter(p) => RawParamEvent::ResetParameter(p.as_ptr()),
|
|
||||||
ParamEvent::EndSetParameter(p) => RawParamEvent::EndSetParameter(p.as_ptr()),
|
ParamEvent::EndSetParameter(p) => RawParamEvent::EndSetParameter(p.as_ptr()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! A slider that integrates with NIH-plug's [`Param`] types.
|
//! A slider that integrates with NIH-plug's [`Param`] types.
|
||||||
|
|
||||||
use nih_plug::param::internals::ParamPtr;
|
use nih_plug::param::internals::ParamPtr;
|
||||||
use nih_plug::prelude::{Param, ParamSetter};
|
use nih_plug::prelude::Param;
|
||||||
use vizia::*;
|
use vizia::*;
|
||||||
|
|
||||||
use super::util::{self, ModifiersExt};
|
use super::util::{self, ModifiersExt};
|
||||||
|
@ -76,13 +76,15 @@ enum ParamSliderInternalEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Model for ParamSliderInternal {
|
impl Model for ParamSliderInternal {
|
||||||
fn event(&mut self, cx: &mut Context, event: &mut Event) {
|
fn event(&mut self, _cx: &mut Context, event: &mut Event) {
|
||||||
if let Some(param_slider_internal_event) = event.message.downcast() {
|
if let Some(param_slider_internal_event) = event.message.downcast() {
|
||||||
match param_slider_internal_event {
|
match param_slider_internal_event {
|
||||||
ParamSliderInternalEvent::SetStyle(style) => self.style = *style,
|
ParamSliderInternalEvent::SetStyle(style) => self.style = *style,
|
||||||
ParamSliderInternalEvent::SetTextInputActive(value) => {
|
ParamSliderInternalEvent::SetTextInputActive(active) => {
|
||||||
cx.current.set_active(cx, *value);
|
self.text_input_active = *active;
|
||||||
self.text_input_active = *value;
|
if *active {
|
||||||
|
// TODO: Interact with the Textbox widget
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,17 +94,17 @@ impl Model for ParamSliderInternal {
|
||||||
impl ParamSlider {
|
impl ParamSlider {
|
||||||
/// Creates a new [`ParamSlider`] for the given parameter. To accomdate VIZIA's mapping system,
|
/// Creates a new [`ParamSlider`] for the given parameter. To accomdate VIZIA's mapping system,
|
||||||
/// you'll need to provide a lens containing your `Params` implementation object (check out how
|
/// you'll need to provide a lens containing your `Params` implementation object (check out how
|
||||||
/// the `Data` struct is used in `gain_gui_vizia`), the `ParamSetter` for retrieving the
|
/// the `Data` struct is used in `gain_gui_vizia`) and a projection function that maps the
|
||||||
/// parameter's default value, and a projection function that maps the `Params` object to the
|
/// `Params` object to the parameter you want to display a widget for. Parameter changes are
|
||||||
/// parameter you want to display a widget for.
|
/// handled by emitting [`ParamEvent`][super::ParamEvent]s which are automatically handled by
|
||||||
|
/// the VIZIA wrapper.
|
||||||
///
|
///
|
||||||
/// See [`ParamSliderExt`] for additonal options.
|
/// See [`ParamSliderExt`] for additonal options.
|
||||||
pub fn new<'a, L, Params, P, F>(
|
pub fn new<L, Params, P, F>(
|
||||||
cx: &'a mut Context,
|
cx: &mut Context,
|
||||||
params: L,
|
params: L,
|
||||||
setter: &ParamSetter,
|
|
||||||
params_to_param: F,
|
params_to_param: F,
|
||||||
) -> Handle<'a, ParamSlider>
|
) -> Handle<'_, ParamSlider>
|
||||||
where
|
where
|
||||||
L: Lens<Target = Params> + Copy,
|
L: Lens<Target = Params> + Copy,
|
||||||
F: 'static + Fn(&Params) -> &P + Copy,
|
F: 'static + Fn(&Params) -> &P + Copy,
|
||||||
|
@ -117,11 +119,9 @@ impl ParamSlider {
|
||||||
let param_ptr = *params
|
let param_ptr = *params
|
||||||
.map(move |params| params_to_param(params).as_ptr())
|
.map(move |params| params_to_param(params).as_ptr())
|
||||||
.get(cx);
|
.get(cx);
|
||||||
let default_value = unsafe {
|
let default_value = *params
|
||||||
setter
|
.map(move |params| params_to_param(params).default_normalized_value())
|
||||||
.raw_context
|
.get(cx);
|
||||||
.raw_default_normalized_param_value(param_ptr)
|
|
||||||
};
|
|
||||||
let step_count = *params
|
let step_count = *params
|
||||||
.map(move |params| params_to_param(params).step_count())
|
.map(move |params| params_to_param(params).step_count())
|
||||||
.get(cx);
|
.get(cx);
|
||||||
|
@ -320,7 +320,10 @@ impl View for ParamSlider {
|
||||||
// Ctrl+Click and double click should reset the parameter instead of initiating
|
// Ctrl+Click and double click should reset the parameter instead of initiating
|
||||||
// a drag operation
|
// a drag operation
|
||||||
cx.emit(RawParamEvent::BeginSetParameter(self.param_ptr));
|
cx.emit(RawParamEvent::BeginSetParameter(self.param_ptr));
|
||||||
cx.emit(RawParamEvent::ResetParameter(self.param_ptr));
|
cx.emit(RawParamEvent::SetParameterNormalized(
|
||||||
|
self.param_ptr,
|
||||||
|
unsafe { self.param_ptr.default_normalized_value() },
|
||||||
|
));
|
||||||
cx.emit(RawParamEvent::EndSetParameter(self.param_ptr));
|
cx.emit(RawParamEvent::EndSetParameter(self.param_ptr));
|
||||||
} else {
|
} else {
|
||||||
self.drag_active = true;
|
self.drag_active = true;
|
||||||
|
|
|
@ -85,11 +85,7 @@ impl IcedEditor for CrispEditor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view(&mut self) -> Element<'_, Self::Message> {
|
fn view(&mut self) -> Element<'_, Self::Message> {
|
||||||
GenericUi::new(
|
GenericUi::new(&mut self.generic_ui_state, self.params.as_ref())
|
||||||
&mut self.generic_ui_state,
|
|
||||||
self.params.as_ref(),
|
|
||||||
self.context.as_ref(),
|
|
||||||
)
|
|
||||||
.pad_scrollbar()
|
.pad_scrollbar()
|
||||||
.map(Message::ParamUpdate)
|
.map(Message::ParamUpdate)
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,12 +84,7 @@ impl IcedEditor for DiopserEditor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view(&mut self) -> Element<'_, Self::Message> {
|
fn view(&mut self) -> Element<'_, Self::Message> {
|
||||||
GenericUi::new(
|
GenericUi::new(&mut self.generic_ui_state, self.params.as_ref()).map(Message::ParamUpdate)
|
||||||
&mut self.generic_ui_state,
|
|
||||||
self.params.as_ref(),
|
|
||||||
self.context.as_ref(),
|
|
||||||
)
|
|
||||||
.map(Message::ParamUpdate)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn background_color(&self) -> nih_plug_iced::Color {
|
fn background_color(&self) -> nih_plug_iced::Color {
|
||||||
|
|
|
@ -95,11 +95,7 @@ impl IcedEditor for GainEditor {
|
||||||
.vertical_alignment(alignment::Vertical::Center),
|
.vertical_alignment(alignment::Vertical::Center),
|
||||||
)
|
)
|
||||||
.push(
|
.push(
|
||||||
nih_widgets::ParamSlider::new(
|
nih_widgets::ParamSlider::new(&mut self.gain_slider_state, &self.params.gain)
|
||||||
&mut self.gain_slider_state,
|
|
||||||
&self.params.gain,
|
|
||||||
self.context.as_ref(),
|
|
||||||
)
|
|
||||||
.map(Message::ParamUpdate),
|
.map(Message::ParamUpdate),
|
||||||
)
|
)
|
||||||
.push(Space::with_height(10.into()))
|
.push(Space::with_height(10.into()))
|
||||||
|
|
|
@ -32,7 +32,7 @@ pub(crate) fn create(
|
||||||
peak_meter: Arc<AtomicF32>,
|
peak_meter: Arc<AtomicF32>,
|
||||||
editor_state: Arc<ViziaState>,
|
editor_state: Arc<ViziaState>,
|
||||||
) -> Option<Box<dyn Editor>> {
|
) -> Option<Box<dyn Editor>> {
|
||||||
create_vizia_editor(editor_state, move |cx, setter| {
|
create_vizia_editor(editor_state, move |cx| {
|
||||||
cx.add_theme(STYLE);
|
cx.add_theme(STYLE);
|
||||||
|
|
||||||
Data {
|
Data {
|
||||||
|
@ -53,13 +53,13 @@ pub(crate) fn create(
|
||||||
Label::new(cx, "Gain").bottom(Pixels(-1.0));
|
Label::new(cx, "Gain").bottom(Pixels(-1.0));
|
||||||
|
|
||||||
VStack::new(cx, |cx| {
|
VStack::new(cx, |cx| {
|
||||||
ParamSlider::new(cx, Data::params, setter, |params| ¶ms.gain);
|
ParamSlider::new(cx, Data::params, |params| ¶ms.gain);
|
||||||
ParamSlider::new(cx, Data::params, setter, |params| ¶ms.gain)
|
ParamSlider::new(cx, Data::params, |params| ¶ms.gain)
|
||||||
.set_style(ParamSliderStyle::FromLeft);
|
.set_style(ParamSliderStyle::FromLeft);
|
||||||
ParamSlider::new(cx, Data::params, setter, |params| ¶ms.foo);
|
ParamSlider::new(cx, Data::params, |params| ¶ms.foo);
|
||||||
ParamSlider::new(cx, Data::params, setter, |params| ¶ms.foo)
|
ParamSlider::new(cx, Data::params, |params| ¶ms.foo)
|
||||||
.set_style(ParamSliderStyle::CurrentStep);
|
.set_style(ParamSliderStyle::CurrentStep);
|
||||||
ParamSlider::new(cx, Data::params, setter, |params| ¶ms.foo)
|
ParamSlider::new(cx, Data::params, |params| ¶ms.foo)
|
||||||
.set_style(ParamSliderStyle::CurrentStepLabeled);
|
.set_style(ParamSliderStyle::CurrentStepLabeled);
|
||||||
})
|
})
|
||||||
.row_between(Pixels(5.0));
|
.row_between(Pixels(5.0));
|
||||||
|
|
|
@ -71,16 +71,6 @@ pub trait GuiContext: Send + Sync + 'static {
|
||||||
/// The implementing function still needs to check if `param` actually exists. This function is
|
/// The implementing function still needs to check if `param` actually exists. This function is
|
||||||
/// mostly marked as unsafe for API reasons.
|
/// mostly marked as unsafe for API reasons.
|
||||||
unsafe fn raw_end_set_parameter(&self, param: ParamPtr);
|
unsafe fn raw_end_set_parameter(&self, param: ParamPtr);
|
||||||
|
|
||||||
/// Retrieve the default value for a parameter, in case you forgot. This does not perform a
|
|
||||||
/// callback Create a [`ParamSetter`] and use [`ParamSetter::default_param_value()`] instead for
|
|
||||||
/// a safe, user friendly API.
|
|
||||||
///
|
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// The implementing function still needs to check if `param` actually exists. This function is
|
|
||||||
/// mostly marked as unsafe for API reasons.
|
|
||||||
unsafe fn raw_default_normalized_param_value(&self, param: ParamPtr) -> f32;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Information about the plugin's transport. Depending on the plugin API and the host not all
|
/// Information about the plugin's transport. Depending on the plugin API and the host not all
|
||||||
|
@ -385,19 +375,4 @@ impl<'a> ParamSetter<'a> {
|
||||||
pub fn end_set_parameter<P: Param>(&self, param: &P) {
|
pub fn end_set_parameter<P: Param>(&self, param: &P) {
|
||||||
unsafe { self.raw_context.raw_end_set_parameter(param.as_ptr()) };
|
unsafe { self.raw_context.raw_end_set_parameter(param.as_ptr()) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve the default value for a parameter, in case you forgot. The value is already
|
|
||||||
/// normalized to `[0, 1]`. This is useful when implementing GUIs, and it does not perform a callback.
|
|
||||||
pub fn default_normalized_param_value<P: Param>(&self, param: &P) -> f32 {
|
|
||||||
unsafe {
|
|
||||||
self.raw_context
|
|
||||||
.raw_default_normalized_param_value(param.as_ptr())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The same as [`default_normalized_param_value()`][Self::default_normalized_param_value()],
|
|
||||||
/// but without the normalization.
|
|
||||||
pub fn default_param_value<P: Param>(&self, param: &P) -> P::Plain {
|
|
||||||
param.preview_plain(self.default_normalized_param_value(param))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,16 +75,6 @@ impl<P: ClapPlugin> GuiContext for WrapperGuiContext<P> {
|
||||||
None => nih_debug_assert_failure!("Unknown parameter: {:?}", param),
|
None => nih_debug_assert_failure!("Unknown parameter: {:?}", param),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn raw_default_normalized_param_value(&self, param: ParamPtr) -> f32 {
|
|
||||||
match self.wrapper.param_ptr_to_hash.get(¶m) {
|
|
||||||
Some(hash) => self.wrapper.param_defaults_normalized[hash],
|
|
||||||
None => {
|
|
||||||
nih_debug_assert_failure!("Unknown parameter: {:?}", param);
|
|
||||||
0.5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: ClapPlugin> ProcessContext for WrapperProcessContext<'_, P> {
|
impl<P: ClapPlugin> ProcessContext for WrapperProcessContext<'_, P> {
|
||||||
|
|
|
@ -178,10 +178,6 @@ pub struct Wrapper<P: ClapPlugin> {
|
||||||
/// by slashes, and they're only used to allow the DAW to display parameters in a tree
|
/// by slashes, and they're only used to allow the DAW to display parameters in a tree
|
||||||
/// structure.
|
/// structure.
|
||||||
param_group_by_hash: HashMap<u32, String>,
|
param_group_by_hash: HashMap<u32, String>,
|
||||||
/// The default normalized parameter value for every parameter in `param_ids`. We need to store
|
|
||||||
/// this in case the host requeries the parmaeter later. This is also indexed by the hash so we
|
|
||||||
/// can retrieve them later for the UI if needed.
|
|
||||||
pub param_defaults_normalized: HashMap<u32, f32>,
|
|
||||||
/// Mappings from string parameter indentifiers to parameter hashes. Useful for debug logging
|
/// Mappings from string parameter indentifiers to parameter hashes. Useful for debug logging
|
||||||
/// and when storing and restoring plugin state.
|
/// and when storing and restoring plugin state.
|
||||||
param_id_to_hash: HashMap<String, u32>,
|
param_id_to_hash: HashMap<String, u32>,
|
||||||
|
@ -370,10 +366,6 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(_, hash, _, group)| (*hash, group.clone()))
|
.map(|(_, hash, _, group)| (*hash, group.clone()))
|
||||||
.collect();
|
.collect();
|
||||||
let param_defaults_normalized = param_id_hashes_ptrs_groups
|
|
||||||
.iter()
|
|
||||||
.map(|(_, hash, ptr, _)| (*hash, unsafe { ptr.normalized_value() }))
|
|
||||||
.collect();
|
|
||||||
let param_id_to_hash = param_id_hashes_ptrs_groups
|
let param_id_to_hash = param_id_hashes_ptrs_groups
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(id, hash, _, _)| (id.clone(), *hash))
|
.map(|(id, hash, _, _)| (id.clone(), *hash))
|
||||||
|
@ -509,7 +501,6 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
param_hashes,
|
param_hashes,
|
||||||
param_by_hash,
|
param_by_hash,
|
||||||
param_group_by_hash,
|
param_group_by_hash,
|
||||||
param_defaults_normalized,
|
|
||||||
param_id_to_hash,
|
param_id_to_hash,
|
||||||
param_ptr_to_hash,
|
param_ptr_to_hash,
|
||||||
output_parameter_events: ArrayQueue::new(OUTPUT_EVENT_QUEUE_CAPACITY),
|
output_parameter_events: ArrayQueue::new(OUTPUT_EVENT_QUEUE_CAPACITY),
|
||||||
|
@ -1746,8 +1737,8 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
} else {
|
} else {
|
||||||
let param_hash = &wrapper.param_hashes[param_index as usize];
|
let param_hash = &wrapper.param_hashes[param_index as usize];
|
||||||
let param_group = &wrapper.param_group_by_hash[param_hash];
|
let param_group = &wrapper.param_group_by_hash[param_hash];
|
||||||
let default_value = &wrapper.param_defaults_normalized[param_hash];
|
|
||||||
let param_ptr = &wrapper.param_by_hash[param_hash];
|
let param_ptr = &wrapper.param_by_hash[param_hash];
|
||||||
|
let default_value = param_ptr.default_normalized_value();
|
||||||
let step_count = param_ptr.step_count();
|
let step_count = param_ptr.step_count();
|
||||||
|
|
||||||
param_info.id = *param_hash;
|
param_info.id = *param_hash;
|
||||||
|
@ -1767,7 +1758,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
// range option
|
// range option
|
||||||
// TODO: This should probably be encapsulated in some way so we don't forget about this in one place
|
// TODO: This should probably be encapsulated in some way so we don't forget about this in one place
|
||||||
param_info.max_value = step_count.unwrap_or(1) as f64;
|
param_info.max_value = step_count.unwrap_or(1) as f64;
|
||||||
param_info.default_value = *default_value as f64 * step_count.unwrap_or(1) as f64;
|
param_info.default_value = default_value as f64 * step_count.unwrap_or(1) as f64;
|
||||||
}
|
}
|
||||||
|
|
||||||
true
|
true
|
||||||
|
|
|
@ -80,16 +80,6 @@ impl<P: Vst3Plugin> GuiContext for WrapperGuiContext<P> {
|
||||||
None => nih_debug_assert_failure!("Component handler not yet set"),
|
None => nih_debug_assert_failure!("Component handler not yet set"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn raw_default_normalized_param_value(&self, param: ParamPtr) -> f32 {
|
|
||||||
match self.inner.param_ptr_to_hash.get(¶m) {
|
|
||||||
Some(hash) => self.inner.param_defaults_normalized[hash],
|
|
||||||
None => {
|
|
||||||
nih_debug_assert_failure!("Unknown parameter: {:?}", param);
|
|
||||||
0.5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: Vst3Plugin> ProcessContext for WrapperProcessContext<'_, P> {
|
impl<P: Vst3Plugin> ProcessContext for WrapperProcessContext<'_, P> {
|
||||||
|
|
|
@ -86,10 +86,6 @@ pub(crate) struct WrapperInner<P: Vst3Plugin> {
|
||||||
/// addresses will remain stable, as they are obtained from a pinned object.
|
/// addresses will remain stable, as they are obtained from a pinned object.
|
||||||
pub param_by_hash: HashMap<u32, ParamPtr>,
|
pub param_by_hash: HashMap<u32, ParamPtr>,
|
||||||
pub param_units: ParamUnits,
|
pub param_units: ParamUnits,
|
||||||
/// The default normalized parameter value for every parameter in `param_ids`. We need to store
|
|
||||||
/// this in case the host requeries the parmaeter later. This is also indexed by the hash so we
|
|
||||||
/// can retrieve them later for the UI if needed.
|
|
||||||
pub param_defaults_normalized: HashMap<u32, f32>,
|
|
||||||
/// Mappings from string parameter indentifiers to parameter hashes. Useful for debug logging
|
/// Mappings from string parameter indentifiers to parameter hashes. Useful for debug logging
|
||||||
/// and when storing and restorign plugin state.
|
/// and when storing and restorign plugin state.
|
||||||
pub param_id_to_hash: HashMap<String, u32>,
|
pub param_id_to_hash: HashMap<String, u32>,
|
||||||
|
@ -182,10 +178,6 @@ impl<P: Vst3Plugin> WrapperInner<P> {
|
||||||
.map(|(_, hash, _, group_name)| (*hash, group_name.as_str())),
|
.map(|(_, hash, _, group_name)| (*hash, group_name.as_str())),
|
||||||
)
|
)
|
||||||
.expect("Inconsistent parameter groups");
|
.expect("Inconsistent parameter groups");
|
||||||
let param_defaults_normalized = param_id_hashes_ptrs_groups
|
|
||||||
.iter()
|
|
||||||
.map(|(_, hash, ptr, _)| (*hash, unsafe { ptr.normalized_value() }))
|
|
||||||
.collect();
|
|
||||||
let param_id_to_hash = param_id_hashes_ptrs_groups
|
let param_id_to_hash = param_id_hashes_ptrs_groups
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(id, hash, _, _)| (id.clone(), *hash))
|
.map(|(id, hash, _, _)| (id.clone(), *hash))
|
||||||
|
@ -231,7 +223,6 @@ impl<P: Vst3Plugin> WrapperInner<P> {
|
||||||
param_hashes,
|
param_hashes,
|
||||||
param_by_hash,
|
param_by_hash,
|
||||||
param_units,
|
param_units,
|
||||||
param_defaults_normalized,
|
|
||||||
param_id_to_hash,
|
param_id_to_hash,
|
||||||
param_ptr_to_hash,
|
param_ptr_to_hash,
|
||||||
};
|
};
|
||||||
|
|
|
@ -340,15 +340,15 @@ impl<P: Vst3Plugin> IEditController for Wrapper<P> {
|
||||||
.param_units
|
.param_units
|
||||||
.get_vst3_unit_id(*param_hash)
|
.get_vst3_unit_id(*param_hash)
|
||||||
.expect("Inconsistent parameter data");
|
.expect("Inconsistent parameter data");
|
||||||
let default_value = &self.inner.param_defaults_normalized[param_hash];
|
|
||||||
let param_ptr = &self.inner.param_by_hash[param_hash];
|
let param_ptr = &self.inner.param_by_hash[param_hash];
|
||||||
|
let default_value = param_ptr.default_normalized_value();
|
||||||
|
|
||||||
info.id = *param_hash;
|
info.id = *param_hash;
|
||||||
u16strlcpy(&mut info.title, param_ptr.name());
|
u16strlcpy(&mut info.title, param_ptr.name());
|
||||||
u16strlcpy(&mut info.short_title, param_ptr.name());
|
u16strlcpy(&mut info.short_title, param_ptr.name());
|
||||||
u16strlcpy(&mut info.units, param_ptr.unit());
|
u16strlcpy(&mut info.units, param_ptr.unit());
|
||||||
info.step_count = param_ptr.step_count().unwrap_or(0) as i32;
|
info.step_count = param_ptr.step_count().unwrap_or(0) as i32;
|
||||||
info.default_normalized_value = *default_value as f64;
|
info.default_normalized_value = default_value as f64;
|
||||||
info.unit_id = *param_unit;
|
info.unit_id = *param_unit;
|
||||||
info.flags = vst3_sys::vst::ParameterFlags::kCanAutomate as i32;
|
info.flags = vst3_sys::vst::ParameterFlags::kCanAutomate as i32;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue