diff --git a/Cargo.toml b/Cargo.toml index ac5b622..59cc33b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,10 +24,4 @@ nih_plug = { git = "https://github.com/robbert-vdh/nih-plug.git" } embedded-time = "0.12.1" # gui -nih_plug_egui = { git = "https://github.com/robbert-vdh/nih-plug.git" } - -# utility -strum = "0.24" -strum_macros = "0.24" -num-derive = "0.3" -num-traits = "0.2" \ No newline at end of file +nih_plug_egui = { git = "https://github.com/robbert-vdh/nih-plug.git" } \ No newline at end of file diff --git a/src/editor/gui.rs b/src/editor/gui.rs index d4711e7..004af32 100644 --- a/src/editor/gui.rs +++ b/src/editor/gui.rs @@ -1,10 +1,14 @@ -use std::sync::{Arc}; +use std::sync::Arc; use std::sync::atomic::AtomicBool; + use nih_plug::context::ParamSetter; +use nih_plug::param::Param; +use nih_plug::prelude::Enum; use nih_plug_egui::{egui, widgets}; -use nih_plug_egui::egui::{Context, DragValue, popup_below_widget, Response, Rounding, Slider, Ui, Vec2, Widget}; +use nih_plug_egui::egui::{Context, DragValue, popup_below_widget, Vec2}; use nih_plug_egui::egui::style::Margin; -use crate::{CategoricalIntParam, Clockwork, FrequencyType, PluginParams, TriggerMode}; + +use crate::{Clockwork, FrequencyType, PluginParams, TriggerMode}; use crate::editor::numpad::Numpad; pub trait GuiEditor { @@ -17,7 +21,6 @@ pub trait GuiEditor { params: &Arc, is_typing: &Arc, ); - } impl GuiEditor for Clockwork { @@ -27,13 +30,13 @@ impl GuiEditor for Clockwork { fn draw_ui(ctx: &Context, setter: &ParamSetter, params: &Arc, is_typing: &Arc) { egui::CentralPanel::default() .show(ctx, |ui| { - let freq_type = FrequencyType::from_int_param(¶ms.freq_type); + let freq_type = params.freq_type.value(); let freq_param = match freq_type { FrequencyType::Hertz => ¶ms.freq_hz, FrequencyType::Milliseconds => ¶ms.freq_ms, FrequencyType::Bpm => ¶ms.freq_bpm, }; - let trigger_mode = TriggerMode::from_int_param(¶ms.trigger_mode); + let trigger_mode = params.trigger_mode.value(); ui.style_mut().spacing.window_margin = Margin::from(Vec2::from([ Clockwork::WINDOW_HEIGHT as f32 * 0.05, @@ -46,7 +49,7 @@ impl GuiEditor for Clockwork { ui.horizontal(|ui| { ui.add(widgets::ParamSlider::for_param( freq_param, - setter + setter, ) .without_value() .with_width(Clockwork::WINDOW_WIDTH as f32 * 0.8) @@ -63,12 +66,12 @@ impl GuiEditor for Clockwork { ) { is_typing.store( false, - std::sync::atomic::Ordering::Relaxed + std::sync::atomic::Ordering::Relaxed, ); } else { is_typing.store( true, - std::sync::atomic::Ordering::Relaxed + std::sync::atomic::Ordering::Relaxed, ); } } @@ -85,7 +88,7 @@ impl GuiEditor for Clockwork { &dragval_widget, |ui| { ui.add(numpad); - } + }, ); if is_typing.load( @@ -96,22 +99,16 @@ impl GuiEditor for Clockwork { }; // Toggle for frequency type - + let text = FrequencyType::variants()[freq_type.clone().to_index()]; if ui - .add(egui::Button::new(freq_type.to_string())) + .add(egui::Button::new(text)) .clicked() { - match freq_type { - FrequencyType::Hertz => { - setter.set_parameter(¶ms.freq_type, FrequencyType::Milliseconds as i32); - }, - FrequencyType::Milliseconds => { - setter.set_parameter(¶ms.freq_type, FrequencyType::Bpm as i32); - }, - FrequencyType::Bpm => { - setter.set_parameter(¶ms.freq_type, FrequencyType::Hertz as i32); - } - } + if freq_type.clone().to_index() == FrequencyType::variants().len() - 1 { + setter.set_parameter(¶ms.freq_type, FrequencyType::from_index(0)); + } else { + setter.set_parameter(¶ms.freq_type, params.freq_type.next_step(freq_type.clone())) + } } }); }); @@ -120,22 +117,17 @@ impl GuiEditor for Clockwork { ui.separator(); ui.horizontal( |ui| { + let text = TriggerMode::variants()[trigger_mode.clone().to_index()]; if ui .add(egui::Button::new( - trigger_mode.to_string() + text )) .clicked() { - match trigger_mode { - TriggerMode::Continue => { - setter.set_parameter(¶ms.trigger_mode, TriggerMode::ReTrigger as i32); - }, - TriggerMode::ReTrigger => { - setter.set_parameter(¶ms.trigger_mode, TriggerMode::ReTriggerDelayed as i32); - }, - TriggerMode::ReTriggerDelayed => { - setter.set_parameter(¶ms.trigger_mode, TriggerMode::Continue as i32); - } + if trigger_mode.clone().to_index() == TriggerMode::variants().len() - 1 { + setter.set_parameter(¶ms.trigger_mode, TriggerMode::from_index(0)); + } else { + setter.set_parameter(¶ms.trigger_mode, params.trigger_mode.next_step(trigger_mode.clone())); } } let label = egui::Label::new(trigger_mode.description()).wrap(true); @@ -145,6 +137,5 @@ impl GuiEditor for Clockwork { }) }); } - } diff --git a/src/lib.rs b/src/lib.rs index 909ea43..2f027c2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,8 +9,6 @@ use std::time::SystemTime; use nih_plug_egui::{create_egui_editor, EguiState}; use crate::params::freq_type::{ FrequencyType }; use crate::params::trigger_mode::{TriggerMode}; -use crate::params::categorical_int_param::CategoricalIntParam; -use num_traits::FromPrimitive; use crate::editor::gui::{ GuiEditor }; // This is a shortened version of the gain example with most comments removed, check out @@ -38,9 +36,9 @@ pub struct PluginParams { #[id = "freq-bpm"] pub freq_bpm: FloatParam, #[id = "freq-type"] - pub freq_type: IntParam, + pub freq_type: EnumParam, #[id = "trigger-mode"] - pub trigger_mode: IntParam, + pub trigger_mode: EnumParam, #[persist = "editor-state"] editor_state: Arc, @@ -98,9 +96,15 @@ impl Default for PluginParams { .with_unit(" bpm"), // Frequency Type - freq_type: FrequencyType::new_int_param(), + freq_type: EnumParam::new( + "Frequency Type", + FrequencyType::Hertz, + ), // Trigger Mode - trigger_mode: TriggerMode::new_int_param(), + trigger_mode: EnumParam::new( + "Trigger Mode", + TriggerMode::Continue, + ), } } } @@ -111,7 +115,7 @@ impl Plugin for Clockwork { const URL: &'static str = "https://github.com/AlexW00/clockwork"; const EMAIL: &'static str = "alexanderweichart@icloud.com"; - const VERSION: &'static str = "1.0.0"; + const VERSION: &'static str = "1.0.2"; const DEFAULT_INPUT_CHANNELS: u32 = 0; const DEFAULT_OUTPUT_CHANNELS: u32 = 0; @@ -176,11 +180,11 @@ impl Plugin for Clockwork { impl Clockwork { fn on_note_on (&mut self, note_event: NoteEvent) { - match TriggerMode::from_i32(self.params.trigger_mode.value) { - Some(TriggerMode::ReTrigger) => { + match self.params.trigger_mode.value() { + TriggerMode::ReTrigger => { self.last_note_on_send = SystemTime::UNIX_EPOCH; } - Some(TriggerMode::ReTriggerDelayed) => { + TriggerMode::ReTriggerDelayed=> { self.last_note_on_send = SystemTime::now(); } _ => (), @@ -225,17 +229,16 @@ fn on_note_on (&mut self, note_event: NoteEvent) { } fn do_send_midi (&self) -> bool { - match FrequencyType::from_i32(self.params.freq_type.value) { - Some(FrequencyType::Milliseconds) => self.ms_since_last_midi_send() as f32 > self.params.freq_ms.value, - Some(FrequencyType::Hertz) => { + match self.params.freq_type.value() { + FrequencyType::Milliseconds => self.ms_since_last_midi_send() as f32 > self.params.freq_ms.value, + FrequencyType::Hertz => { let ms = 1000.0 / self.params.freq_hz.value; self.ms_since_last_midi_send() as f32 > ms } - Some(FrequencyType::Bpm) => { + FrequencyType::Bpm => { let ms = 60000.0 / self.params.freq_bpm.value; self.ms_since_last_midi_send() as f32 > ms } - _ => false } } diff --git a/src/params/categorical_int_param.rs b/src/params/categorical_int_param.rs deleted file mode 100644 index cf7c2de..0000000 --- a/src/params/categorical_int_param.rs +++ /dev/null @@ -1,52 +0,0 @@ -use std::sync::Arc; -use nih_plug::param::IntParam; -use nih_plug::prelude::IntRange; -use num_traits::ToPrimitive; - -pub trait CategoricalIntParam

-where P : std::fmt::Display + num_traits::FromPrimitive + ToPrimitive + strum::EnumCount + strum::IntoEnumIterator + Default + CategoricalIntParam

{ - fn formatter() -> Arc String + Send + Sync> { - Arc::new(move |value| { - if let Some(category) = P::from_i32(value) { - category.to_string() - } else { - "Unknown".to_string() - } - }) - } - - fn count() -> i32 { - P::iter().count() as i32 - 1 - } - - fn title() -> String; - - fn next(param: &P) -> P { - let mut next = ToPrimitive::to_i32(param).unwrap() + 1; - if next > Self::count() { - next = 0; - } - P::from_i32(next).unwrap() - } - - fn new_int_param() -> IntParam { - IntParam::new( - P::title(), - ToPrimitive::to_i32(&P::default()).expect("Failed to convert default value to i32"), - IntRange::Linear { - min: 0, - max: P::count() - }, - ).with_value_to_string(P::formatter()) - } - - fn from_int_param(param: &IntParam) -> P { - P::from_i32(param.value).unwrap_or(P::default()) - } - - fn into_int_param(param: &P) -> IntParam { - let mut int_param = Self::new_int_param(); - int_param.value = ToPrimitive::to_i32(param).expect("Failed to convert value to i32"); - int_param - } -} diff --git a/src/params/freq_type.rs b/src/params/freq_type.rs index edf59a4..a788d21 100644 --- a/src/params/freq_type.rs +++ b/src/params/freq_type.rs @@ -1,32 +1,11 @@ -use std::borrow::Cow; -use num_derive::FromPrimitive; -use num_derive::ToPrimitive; -use strum_macros::{EnumCount, EnumIter}; -use strum::{EnumCount, IntoEnumIterator}; +use nih_plug::prelude::Enum; -use std::fmt::Display; -use crate::CategoricalIntParam; - -#[derive(FromPrimitive, ToPrimitive, Clone, Copy, EnumCount, EnumIter, Default)] +#[derive(PartialEq, Enum, Clone)] pub enum FrequencyType { + #[name="Hz"] Hertz, - #[default] + #[name="ms"] Milliseconds, + #[name="bpm"] Bpm -} - -impl Display for FrequencyType { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - FrequencyType::Hertz => write!(f, "Hz"), - FrequencyType::Milliseconds => write!(f, "ms"), - FrequencyType::Bpm => write!(f, "bpm"), - } - } -} - -impl CategoricalIntParam for FrequencyType { - fn title() -> String { - "Frequency type".to_string() - } } \ No newline at end of file diff --git a/src/params/mod.rs b/src/params/mod.rs index 38d9f7b..9043c82 100644 --- a/src/params/mod.rs +++ b/src/params/mod.rs @@ -1,3 +1,2 @@ pub mod freq_type; -pub mod trigger_mode; -pub mod categorical_int_param; \ No newline at end of file +pub mod trigger_mode; \ No newline at end of file diff --git a/src/params/trigger_mode.rs b/src/params/trigger_mode.rs index 8bc88f9..edc92b4 100644 --- a/src/params/trigger_mode.rs +++ b/src/params/trigger_mode.rs @@ -1,28 +1,15 @@ -use num_derive::FromPrimitive; -use num_derive::ToPrimitive; -use strum_macros::{EnumCount, EnumIter}; +use nih_plug::prelude::Enum; -use std::fmt::Display; -use crate::params::categorical_int_param::{CategoricalIntParam}; - -#[derive(FromPrimitive, ToPrimitive, Clone, Copy, EnumCount, EnumIter, Default)] +#[derive(PartialEq, Enum, Clone)] pub enum TriggerMode { - #[default] + #[name="Continue"] Continue, + #[name="Re-trigger"] ReTrigger, + #[name="Re-trigger delayed"] ReTriggerDelayed, } -impl Display for TriggerMode { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - TriggerMode::Continue => write!(f, "Continue"), - TriggerMode::ReTrigger => write!(f, "Re-trigger"), - TriggerMode::ReTriggerDelayed => write!(f, "Re-trigger delayed"), - } - } -} - impl TriggerMode { pub fn description(&self) -> &'static str { match self { @@ -32,9 +19,3 @@ impl TriggerMode { } } } - -impl CategoricalIntParam for TriggerMode { - fn title() -> String { - "Trigger mode".to_string() - } -} \ No newline at end of file