Wrap Diopser safe mode boolean in a struct
This struct will also be used to limit the parameter ranges later.
This commit is contained in:
parent
9a77bd2918
commit
4eb7614ee7
|
@ -20,7 +20,6 @@ use nih_plug::prelude::{Editor, Plugin};
|
||||||
use nih_plug_vizia::vizia::prelude::*;
|
use nih_plug_vizia::vizia::prelude::*;
|
||||||
use nih_plug_vizia::widgets::*;
|
use nih_plug_vizia::widgets::*;
|
||||||
use nih_plug_vizia::{assets, create_vizia_editor, ViziaState, ViziaTheming};
|
use nih_plug_vizia::{assets, create_vizia_editor, ViziaState, ViziaTheming};
|
||||||
use std::sync::atomic::AtomicBool;
|
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use self::button::SafeModeButton;
|
use self::button::SafeModeButton;
|
||||||
|
@ -30,8 +29,11 @@ use crate::Diopser;
|
||||||
|
|
||||||
mod analyzer;
|
mod analyzer;
|
||||||
mod button;
|
mod button;
|
||||||
|
mod safe_mode;
|
||||||
mod xy_pad;
|
mod xy_pad;
|
||||||
|
|
||||||
|
pub use safe_mode::SafeModeClamper;
|
||||||
|
|
||||||
const EDITOR_WIDTH: u32 = 600;
|
const EDITOR_WIDTH: u32 = 600;
|
||||||
const EDITOR_HEIGHT: u32 = 490;
|
const EDITOR_HEIGHT: u32 = 490;
|
||||||
|
|
||||||
|
@ -49,8 +51,7 @@ pub(crate) struct Data {
|
||||||
pub(crate) spectrum: Arc<Mutex<SpectrumOutput>>,
|
pub(crate) spectrum: Arc<Mutex<SpectrumOutput>>,
|
||||||
/// Whether the safe mode button is enabled. The number of filter stages is capped at 40 while
|
/// Whether the safe mode button is enabled. The number of filter stages is capped at 40 while
|
||||||
/// this is active.
|
/// this is active.
|
||||||
/// TODO: Actually hook up safe mode
|
pub(crate) safe_mode_clamper: SafeModeClamper,
|
||||||
pub(crate) safe_mode: Arc<AtomicBool>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Model for Data {}
|
impl Model for Data {}
|
||||||
|
@ -106,7 +107,7 @@ fn top_bar(cx: &mut Context) {
|
||||||
.with_label("Automation Precision")
|
.with_label("Automation Precision")
|
||||||
.id("automation-precision");
|
.id("automation-precision");
|
||||||
|
|
||||||
SafeModeButton::new(cx, Data::safe_mode, "Safe mode").left(Pixels(10.0));
|
SafeModeButton::new(cx, Data::safe_mode_clamper, "Safe mode").left(Pixels(10.0));
|
||||||
|
|
||||||
ParamButton::new(cx, Data::params, |params| ¶ms.bypass)
|
ParamButton::new(cx, Data::params, |params| ¶ms.bypass)
|
||||||
.for_bypass()
|
.for_bypass()
|
||||||
|
|
|
@ -15,13 +15,13 @@
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use nih_plug_vizia::vizia::prelude::*;
|
use nih_plug_vizia::vizia::prelude::*;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
/// A custom toggleable button coupled to an `Arc<AtomicBool`. Otherwise this is very similar to the
|
use super::SafeModeClamper;
|
||||||
/// param button.
|
|
||||||
|
/// A custom toggleable button that toggles safe mode whenever it is Alt+clicked. Otherwise this is
|
||||||
|
/// very similar to the param button.
|
||||||
#[derive(Lens)]
|
#[derive(Lens)]
|
||||||
pub struct SafeModeButton<L: Lens<Target = Arc<AtomicBool>>> {
|
pub struct SafeModeButton<L: Lens<Target = SafeModeClamper>> {
|
||||||
lens: L,
|
lens: L,
|
||||||
|
|
||||||
/// The number of (fractional) scrolled lines that have not yet been turned into parameter
|
/// The number of (fractional) scrolled lines that have not yet been turned into parameter
|
||||||
|
@ -29,8 +29,8 @@ pub struct SafeModeButton<L: Lens<Target = Arc<AtomicBool>>> {
|
||||||
scrolled_lines: f32,
|
scrolled_lines: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<L: Lens<Target = Arc<AtomicBool>>> SafeModeButton<L> {
|
impl<L: Lens<Target = SafeModeClamper>> SafeModeButton<L> {
|
||||||
/// Creates a new button bound to the `Arc<AtomicBool>`.
|
/// Creates a new button bound to the [`SafeModeClamper`].
|
||||||
pub fn new<T>(cx: &mut Context, lens: L, label: impl Res<T>) -> Handle<Self>
|
pub fn new<T>(cx: &mut Context, lens: L, label: impl Res<T>) -> Handle<Self>
|
||||||
where
|
where
|
||||||
T: ToString,
|
T: ToString,
|
||||||
|
@ -42,13 +42,13 @@ impl<L: Lens<Target = Arc<AtomicBool>>> SafeModeButton<L> {
|
||||||
.build(cx, move |cx| {
|
.build(cx, move |cx| {
|
||||||
Label::new(cx, label);
|
Label::new(cx, label);
|
||||||
})
|
})
|
||||||
.checked(lens.map(|v| v.load(Ordering::Relaxed)))
|
.checked(lens.map(|v| v.status()))
|
||||||
// We'll pretend this is a param-button, so this class is used for assigning a unique color
|
// We'll pretend this is a param-button, so this class is used for assigning a unique color
|
||||||
.class("safe-mode")
|
.class("safe-mode")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<L: Lens<Target = Arc<AtomicBool>>> View for SafeModeButton<L> {
|
impl<L: Lens<Target = SafeModeClamper>> View for SafeModeButton<L> {
|
||||||
fn element(&self) -> Option<&'static str> {
|
fn element(&self) -> Option<&'static str> {
|
||||||
// Reuse the styling from param-button
|
// Reuse the styling from param-button
|
||||||
Some("param-button")
|
Some("param-button")
|
||||||
|
@ -60,9 +60,10 @@ impl<L: Lens<Target = Arc<AtomicBool>>> View for SafeModeButton<L> {
|
||||||
WindowEvent::MouseDown(MouseButton::Left)
|
WindowEvent::MouseDown(MouseButton::Left)
|
||||||
| WindowEvent::MouseDoubleClick(MouseButton::Left)
|
| WindowEvent::MouseDoubleClick(MouseButton::Left)
|
||||||
| WindowEvent::MouseTripleClick(MouseButton::Left) => {
|
| WindowEvent::MouseTripleClick(MouseButton::Left) => {
|
||||||
// We can just unconditionally toggle the boolean here
|
// We can just unconditionally toggle the boolean here. When safe mode is enabled
|
||||||
let atomic = self.lens.get(cx);
|
// this immediately clamps the affected parameters to their new range.
|
||||||
atomic.fetch_xor(true, Ordering::AcqRel);
|
let safe_mode_clamper = self.lens.get(cx);
|
||||||
|
safe_mode_clamper.toggle(cx);
|
||||||
|
|
||||||
meta.consume();
|
meta.consume();
|
||||||
}
|
}
|
||||||
|
@ -70,13 +71,13 @@ impl<L: Lens<Target = Arc<AtomicBool>>> View for SafeModeButton<L> {
|
||||||
self.scrolled_lines += scroll_y;
|
self.scrolled_lines += scroll_y;
|
||||||
|
|
||||||
if self.scrolled_lines.abs() >= 1.0 {
|
if self.scrolled_lines.abs() >= 1.0 {
|
||||||
let atomic = self.lens.get(cx);
|
let safe_mode_clamper = self.lens.get(cx);
|
||||||
|
|
||||||
if self.scrolled_lines >= 1.0 {
|
if self.scrolled_lines >= 1.0 {
|
||||||
atomic.store(true, Ordering::SeqCst);
|
safe_mode_clamper.enable(cx);
|
||||||
self.scrolled_lines -= 1.0;
|
self.scrolled_lines -= 1.0;
|
||||||
} else {
|
} else {
|
||||||
atomic.store(false, Ordering::SeqCst);
|
safe_mode_clamper.disable(cx);
|
||||||
self.scrolled_lines += 1.0;
|
self.scrolled_lines += 1.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
48
plugins/diopser/src/editor/safe_mode.rs
Normal file
48
plugins/diopser/src/editor/safe_mode.rs
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
//! Utilities for Diopser's safe-mode mechanism.
|
||||||
|
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use nih_plug_vizia::vizia::prelude::EventContext;
|
||||||
|
|
||||||
|
use crate::params::DiopserParams;
|
||||||
|
|
||||||
|
/// Restricts the ranges of several parameters when enabled. This makes it more difficult to
|
||||||
|
/// generate load resonances with Diopser's default settings.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct SafeModeClamper {
|
||||||
|
/// Whether the safe mode toggle has been enabled.
|
||||||
|
enabled: Arc<AtomicBool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SafeModeClamper {
|
||||||
|
pub fn new(params: Arc<DiopserParams>) -> Self {
|
||||||
|
Self {
|
||||||
|
enabled: params.safe_mode.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the current status of the safe mode swtich.
|
||||||
|
pub fn status(&self) -> bool {
|
||||||
|
self.enabled.load(Ordering::Relaxed)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enable or disable safe mode. Enabling safe mode immediately clamps the parameters to their
|
||||||
|
/// new restricted ranges.
|
||||||
|
pub fn toggle(&self, cx: &mut EventContext) {
|
||||||
|
// TODO: Restrict the parameter ranges when the button is enabled
|
||||||
|
self.enabled.fetch_xor(true, Ordering::Relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enable safe mode. Enabling safe mode immediately clamps the parameters to their new
|
||||||
|
/// restricted ranges.
|
||||||
|
pub fn enable(&self, cx: &mut EventContext) {
|
||||||
|
// TODO: Restrict the parameter ranges when the button is enabled
|
||||||
|
self.enabled.store(true, Ordering::Relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Disable safe mode.
|
||||||
|
pub fn disable(&self, cx: &mut EventContext) {
|
||||||
|
self.enabled.store(false, Ordering::Relaxed);
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,6 +20,7 @@
|
||||||
compile_error!("Compiling without SIMD support is currently not supported");
|
compile_error!("Compiling without SIMD support is currently not supported");
|
||||||
|
|
||||||
use atomic_float::AtomicF32;
|
use atomic_float::AtomicF32;
|
||||||
|
use editor::SafeModeClamper;
|
||||||
use nih_plug::prelude::*;
|
use nih_plug::prelude::*;
|
||||||
use std::simd::f32x2;
|
use std::simd::f32x2;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
@ -130,7 +131,7 @@ impl Plugin for Diopser {
|
||||||
|
|
||||||
sample_rate: self.sample_rate.clone(),
|
sample_rate: self.sample_rate.clone(),
|
||||||
spectrum: self.spectrum_output.clone(),
|
spectrum: self.spectrum_output.clone(),
|
||||||
safe_mode: self.params.safe_mode.clone(),
|
safe_mode_clamper: SafeModeClamper::new(self.params.clone()),
|
||||||
},
|
},
|
||||||
self.params.editor_state.clone(),
|
self.params.editor_state.clone(),
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue