1
0
Fork 0

Notify nih_plug_vizia GUIs when parameters change

This could be useful in some cases when dealing with computed
properties.
This commit is contained in:
Robbert van der Helm 2022-11-15 16:43:13 +01:00
parent 1448388353
commit 98bd3add19
3 changed files with 31 additions and 4 deletions

View file

@ -3,10 +3,11 @@
use baseview::{WindowHandle, WindowScalePolicy};
use crossbeam::atomic::AtomicCell;
use nih_plug::prelude::{Editor, GuiContext, ParentWindowHandle};
use std::sync::atomic::Ordering;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use vizia::prelude::*;
use crate::widgets::RawParamEvent;
use crate::{assets, widgets, ViziaState, ViziaTheming};
/// An [`Editor`] implementation that calls an vizia draw loop.
@ -20,6 +21,13 @@ pub(crate) struct ViziaEditor {
/// 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.
pub(crate) scaling_factor: AtomicCell<Option<f32>>,
/// Whether to emit a parameters changed event during the next idle callback. This is set in the
/// `parameter_values_changed()` implementation and it can be used by widgets to explicitly
/// check for new parameter values. This is useful when the parameter value is (indirectly) used
/// to compute a property in an event handler. Like when positioning an element based on the
/// display value's width.
pub(crate) emit_parameters_changed_event: Arc<AtomicBool>,
}
impl Editor for ViziaEditor {
@ -72,7 +80,18 @@ impl Editor for ViziaEditor {
.unwrap_or(WindowScalePolicy::SystemScaleFactor),
)
.inner_size((unscaled_width, unscaled_height))
.user_scale_factor(user_scale_factor);
.user_scale_factor(user_scale_factor)
.on_idle({
let emit_parameters_changed_event = self.emit_parameters_changed_event.clone();
move |cx| {
if emit_parameters_changed_event
.compare_exchange(true, false, Ordering::AcqRel, Ordering::Relaxed)
.is_ok()
{
cx.emit(RawParamEvent::ParametersChanged);
}
}
});
// This way the plugin can decide to use none of the built in theming
if theming == ViziaTheming::None {
@ -102,8 +121,9 @@ impl Editor for ViziaEditor {
}
fn param_values_changed(&self) {
// TODO: Update the GUI when this happens, right now this happens automatically as a result
// of of the reactivity
// This will cause a future idle callback to send a parameters changed event.
self.emit_parameters_changed_event
.store(true, Ordering::Relaxed);
}
}

View file

@ -59,6 +59,8 @@ where
scaling_factor: AtomicCell::new(None),
#[cfg(not(target_os = "macos"))]
scaling_factor: AtomicCell::new(Some(1.0)),
emit_parameters_changed_event: Arc::new(AtomicBool::new(false)),
}))
}

View file

@ -61,6 +61,9 @@ pub enum RawParamEvent {
SetParameterNormalized(ParamPtr, f32),
/// End an automation gesture for a parameter.
EndSetParameter(ParamPtr),
/// Sent by the wrapper to indicate that one or more parameter values have changed. Useful when
/// using properties based on a parameter's value that are computed inside of an event handler.
ParametersChanged,
}
/// Handles parameter updates for VIZIA GUIs. Registered in
@ -89,6 +92,8 @@ impl Model for ParamModel {
self.context.raw_set_parameter_normalized(p, v)
},
RawParamEvent::EndSetParameter(p) => unsafe { self.context.raw_end_set_parameter(p) },
// This can be used by widgets to be notified when parameter values have changed
RawParamEvent::ParametersChanged => (),
});
}
}