From 4ce5f359d6e2e93c215a52fb73de3214d44267ea Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Fri, 18 Mar 2022 15:26:19 +0100 Subject: [PATCH] Add parameter setting events for vizia --- nih_plug_vizia/src/assets.rs | 2 +- nih_plug_vizia/src/lib.rs | 10 ++++++- nih_plug_vizia/src/widgets.rs | 54 +++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 nih_plug_vizia/src/widgets.rs diff --git a/nih_plug_vizia/src/assets.rs b/nih_plug_vizia/src/assets.rs index e8f3e385..e0ca383a 100644 --- a/nih_plug_vizia/src/assets.rs +++ b/nih_plug_vizia/src/assets.rs @@ -1,7 +1,7 @@ //! Binary assets for use with `nih_plug_iced. These fonts first need to be registered by calling //! [`nih_plug_iced::assets::register_fonts()`][register_fonts()`]. -use crate::vizia::Context; +use vizia::Context; // This module provides a re-export and simple font wrappers around the re-exported fonts. pub use nih_plug_assets::*; diff --git a/nih_plug_vizia/src/lib.rs b/nih_plug_vizia/src/lib.rs index d183b78d..b3daac9f 100644 --- a/nih_plug_vizia/src/lib.rs +++ b/nih_plug_vizia/src/lib.rs @@ -5,12 +5,13 @@ use crossbeam::atomic::AtomicCell; use nih_plug::prelude::{Editor, GuiContext, ParamSetter, ParentWindowHandle}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; -use vizia::{Application, Context, WindowDescription}; +use vizia::{Application, Context, Model, WindowDescription}; // Re-export for convenience pub use vizia; pub mod assets; +pub mod widgets; /// Create an [`Editor`] instance using a [`vizia`][::vizia] GUI. The [`ViziaState`] passed to this /// function contains the GUI's intitial size, and this is kept in sync whenever the GUI gets @@ -88,6 +89,13 @@ impl Editor for ViziaEditor { let window = Application::new(window_description, move |cx| { let setter = ParamSetter::new(context.as_ref()); + // Any widget can change the parameters by emitting `ParamEvent` events. This model will + // handle them automatically. + widgets::ParamModel { + context: context.clone(), + } + .build(cx); + app(cx, &setter) }) .with_scale_policy( diff --git a/nih_plug_vizia/src/widgets.rs b/nih_plug_vizia/src/widgets.rs new file mode 100644 index 00000000..3fcd712b --- /dev/null +++ b/nih_plug_vizia/src/widgets.rs @@ -0,0 +1,54 @@ +//! Widgets and utilities for making widgets to integrate VIZIA with NIH-plug. +//! +//! # Note +//! +//! None of these widgets are finalized, and their sizes or looks can change at any point. Feel free +//! to copy the widgets and modify them to your personal taste. + +use nih_plug::{context::GuiContext, param::internals::ParamPtr}; +use std::sync::Arc; + +use vizia::Model; + +/// An event that updates a parameter's value. Since NIH-plug manages the parameters, interacting +/// with parameter values with VIZIA works a little different from updating any other state. These +/// events are automatically handled by `nih_plug_vizia`. +#[derive(Debug, Clone, Copy)] +pub enum ParamEvent { + /// Begin an automation gesture for a parameter. + BeginSetParameter(ParamPtr), + /// 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), +} + +/// Handles parameter updates for VIZIA GUIs. Registered in +/// [`ViziaEditor::spawn()`][super::ViziaEditor::spawn()]. +pub(crate) struct ParamModel { + pub context: Arc, +} + +impl Model for ParamModel { + fn event(&mut self, _cx: &mut vizia::Context, event: &mut vizia::Event) { + if let Some(param_event) = event.message.downcast() { + match *param_event { + ParamEvent::BeginSetParameter(p) => unsafe { + self.context.raw_begin_set_parameter(p) + }, + ParamEvent::SetParameterNormalized(p, v) => unsafe { + self.context.raw_set_parameter_normalized(p, v) + }, + ParamEvent::ResetParameter(p) => unsafe { + let default_value = self.context.raw_default_normalized_param_value(p); + self.context.raw_set_parameter_normalized(p, default_value); + }, + ParamEvent::EndSetParameter(p) => unsafe { self.context.raw_end_set_parameter(p) }, + } + } + } +}