From 39407c9760f698f6dcb2e6aa5104ddf349f8b55c Mon Sep 17 00:00:00 2001 From: unspeaker Date: Tue, 10 Sep 2024 11:59:14 +0300 Subject: [PATCH] turn Plugin keymap to match statement --- crates/tek_core/src/audio.rs | 22 ++--- crates/tek_core/src/tui/tui_colors.rs | 3 - crates/tek_core/src/tui/tui_layout.rs | 8 +- crates/tek_mixer/src/plugin.rs | 27 +++--- crates/tek_mixer/src/plugin_handle.rs | 120 +++++++++++++------------- crates/tek_mixer/src/plugin_vst2.rs | 4 +- crates/tek_mixer/src/sample_add.rs | 65 +++++++------- crates/tek_mixer/src/track.rs | 4 +- 8 files changed, 124 insertions(+), 129 deletions(-) diff --git a/crates/tek_core/src/audio.rs b/crates/tek_core/src/audio.rs index 27ca19c6..50a94923 100644 --- a/crates/tek_core/src/audio.rs +++ b/crates/tek_core/src/audio.rs @@ -25,15 +25,15 @@ pub trait Ports { } /// A UI component that may be associated with a JACK client by the `Jack` factory. -pub trait Device: Component + Audio { +pub trait AudioComponent: Component + Audio { /// Perform type erasure for collecting heterogeneous devices. - fn boxed (self) -> Box> where Self: Sized + 'static { + fn boxed (self) -> Box> where Self: Sized + 'static { Box::new(self) } } -/// All things that implement the required traits can be treated as `Device`. -impl + Audio> Device for W {} +/// All things that implement the required traits can be treated as `AudioComponent`. +impl + Audio> AudioComponent for W {} /// Wraps [Client] or [DynamicAsyncClient] in place. pub enum JackClient { @@ -112,7 +112,7 @@ pub fn jack_run (name: &str, app: &Arc>) -> Usually, @@ -137,7 +137,7 @@ impl Jack { pub fn run <'a: 'static, D, E> ( self, state: impl FnOnce(JackPorts)->Box ) -> Usually> - where D: Device + Sized + 'static, + where D: AudioComponent + Sized + 'static, E: Engine + 'static, { let owned_ports = JackPorts { @@ -154,7 +154,7 @@ impl Jack { .map(|p|Ok(p.name()?)).collect::>>()?; let audio_ins = owned_ports.audio_ins.values() .map(|p|Ok(p.name()?)).collect::>>()?; - let state = Arc::new(RwLock::new(state(owned_ports) as Box>)); + let state = Arc::new(RwLock::new(state(owned_ports) as Box>)); let client = self.client.activate_async( Notifications(Box::new({ let _state = state.clone(); @@ -288,12 +288,12 @@ impl NotificationHandler for Notifications { } } -/// A [Device] bound to a JACK client and a set of ports. +/// A [AudioComponent] bound to a JACK client and a set of ports. pub struct JackDevice { /// The active JACK client of this device. pub client: DynamicAsyncClient, /// The device state, encapsulated for sharing between threads. - pub state: Arc>>>, + pub state: Arc>>>, /// Unowned copies of the device's JACK ports, for connecting to the device. /// The "real" readable/writable `Port`s are owned by the `state`. pub ports: UnownedJackPorts, @@ -338,11 +338,11 @@ impl Ports for JackDevice { impl JackDevice { /// Returns a locked mutex of the state's contents. - pub fn state (&self) -> LockResult>>> { + pub fn state (&self) -> LockResult>>> { self.state.read() } /// Returns a locked mutex of the state's contents. - pub fn state_mut (&self) -> LockResult>>> { + pub fn state_mut (&self) -> LockResult>>> { self.state.write() } pub fn connect_midi_in (&self, index: usize, port: &Port) -> Usually<()> { diff --git a/crates/tek_core/src/tui/tui_colors.rs b/crates/tek_core/src/tui/tui_colors.rs index a73185d5..80677470 100644 --- a/crates/tek_core/src/tui/tui_colors.rs +++ b/crates/tek_core/src/tui/tui_colors.rs @@ -31,9 +31,6 @@ pub struct FillBg(pub Color); impl Widget for FillBg { type Engine = Tui; - fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> { - Ok(Some(area)) - } fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { to.fill_bg(to.area(), self.0); Ok(Some(to.area)) diff --git a/crates/tek_core/src/tui/tui_layout.rs b/crates/tek_core/src/tui/tui_layout.rs index 427a6f74..06819a13 100644 --- a/crates/tek_core/src/tui/tui_layout.rs +++ b/crates/tek_core/src/tui/tui_layout.rs @@ -59,12 +59,8 @@ where { type Engine = Tui; fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { - let area = to.area(); - to.blit(&format!("L1 {area:?}"), 10, 10, None)?; - let area = self.layout(to.area())?; - to.blit(&format!("L2 {area:?}"), 10, 11, None)?; - area.map(|area|(self.0)(&mut |layer| { - to.blit(&format!("L3 {area:?}"), 10, 12, None)?; + self.layout(to.area())? + .map(|area|(self.0)(&mut |layer| { to.render_in(area, &layer)?; Ok(()) }).map(|_|area)) diff --git a/crates/tek_mixer/src/plugin.rs b/crates/tek_mixer/src/plugin.rs index 4ddbc939..7132323e 100644 --- a/crates/tek_mixer/src/plugin.rs +++ b/crates/tek_mixer/src/plugin.rs @@ -12,6 +12,21 @@ pub struct Plugin { } impl Plugin { + /// Create a plugin host device. + pub fn new (name: &str) -> Usually { + Ok(Self { + _engine: Default::default(), + name: name.into(), + path: None, + plugin: None, + selected: 0, + mapping: false, + ports: JackPorts::default() + }) + } +} + +impl Plugin { pub fn new_lv2 (name: &str, path: &str) -> Usually> { let plugin = LV2Plugin::new(path)?; jack_from_lv2(name, &plugin.plugin)? @@ -25,18 +40,6 @@ impl Plugin { ports })) } - /// Create a plugin host device. - pub fn new (name: &str) -> Usually { - Ok(Self { - _engine: Default::default(), - name: name.into(), - path: None, - plugin: None, - selected: 0, - mapping: false, - ports: JackPorts::default() - }) - } } impl Audio for Plugin { diff --git a/crates/tek_mixer/src/plugin_handle.rs b/crates/tek_mixer/src/plugin_handle.rs index 6f5a1e0a..38f326e7 100644 --- a/crates/tek_mixer/src/plugin_handle.rs +++ b/crates/tek_mixer/src/plugin_handle.rs @@ -2,66 +2,64 @@ use crate::*; impl Handle for Plugin { fn handle (&mut self, from: &Tui) -> Perhaps { - handle_keymap(self, &from.event(), KEYMAP_PLUGIN).map(|x|Some(x)) + match from.event() { + key!(KeyCode::Up) => { + self.selected = self.selected.saturating_sub(1); + Ok(Some(true)) + }, + key!(KeyCode::Down) => { + self.selected = (self.selected + 1).min(match &self.plugin { + Some(PluginKind::LV2(LV2Plugin { port_list, .. })) => port_list.len() - 1, + _ => unimplemented!() + }); + Ok(Some(true)) + }, + key!(KeyCode::PageUp) => { + self.selected = self.selected.saturating_sub(8); + Ok(Some(true)) + }, + key!(KeyCode::PageDown) => { + self.selected = (self.selected + 10).min(match &self.plugin { + Some(PluginKind::LV2(LV2Plugin { port_list, .. })) => port_list.len() - 1, + _ => unimplemented!() + }); + Ok(Some(true)) + }, + key!(KeyCode::Char(',')) => { + match self.plugin.as_mut() { + Some(PluginKind::LV2(LV2Plugin { port_list, ref mut instance, .. })) => { + let index = port_list[self.selected].index; + if let Some(value) = instance.control_input(index) { + instance.set_control_input(index, value - 0.01); + } + }, + _ => {} + } + Ok(Some(true)) + }, + key!(KeyCode::Char('.')) => { + match self.plugin.as_mut() { + Some(PluginKind::LV2(LV2Plugin { port_list, ref mut instance, .. })) => { + let index = port_list[self.selected].index; + if let Some(value) = instance.control_input(index) { + instance.set_control_input(index, value + 0.01); + } + }, + _ => {} + } + Ok(Some(true)) + }, + key!(KeyCode::Char('g')) => { + match self.plugin { + Some(PluginKind::LV2(ref mut plugin)) => { + plugin.ui_thread = Some(run_lv2_ui(LV2PluginUI::new()?)?); + }, + Some(_) => unreachable!(), + None => {} + } + Ok(Some(true)) + }, + _ => Ok(None) + } } } - -/// Key bindings for plugin device. -pub const KEYMAP_PLUGIN: &'static [KeyBinding] = keymap!(Plugin { - [Up, NONE, "/plugin/cursor_up", "move cursor up", |s: &mut Plugin|{ - s.selected = s.selected.saturating_sub(1); - Ok(true) - }], - [Down, NONE, "/plugin/cursor_down", "move cursor down", |s: &mut Plugin|{ - s.selected = (s.selected + 1).min(match &s.plugin { - Some(PluginKind::LV2(LV2Plugin { port_list, .. })) => port_list.len() - 1, - _ => unimplemented!() - }); - Ok(true) - }], - [PageUp, NONE, "/plugin/cursor_page_up", "move cursor up", |s: &mut Plugin|{ - s.selected = s.selected.saturating_sub(8); - Ok(true) - }], - [PageDown, NONE, "/plugin/cursor_page_down", "move cursor down", |s: &mut Plugin|{ - s.selected = (s.selected + 10).min(match &s.plugin { - Some(PluginKind::LV2(LV2Plugin { port_list, .. })) => port_list.len() - 1, - _ => unimplemented!() - }); - Ok(true) - }], - [Char(','), NONE, "/plugin/decrement", "decrement value", |s: &mut Plugin|{ - match s.plugin.as_mut() { - Some(PluginKind::LV2(LV2Plugin { port_list, ref mut instance, .. })) => { - let index = port_list[s.selected].index; - if let Some(value) = instance.control_input(index) { - instance.set_control_input(index, value - 0.01); - } - }, - _ => {} - } - Ok(true) - }], - [Char('.'), NONE, "/plugin/decrement", "increment value", |s: &mut Plugin|{ - match s.plugin.as_mut() { - Some(PluginKind::LV2(LV2Plugin { port_list, ref mut instance, .. })) => { - let index = port_list[s.selected].index; - if let Some(value) = instance.control_input(index) { - instance.set_control_input(index, value + 0.01); - } - }, - _ => {} - } - Ok(true) - }], - [Char('g'), NONE, "/plugin/gui_toggle", "toggle plugin UI", |s: &mut Plugin|{ - match s.plugin { - Some(PluginKind::LV2(ref mut plugin)) => { - plugin.ui_thread = Some(run_lv2_ui(LV2PluginUI::new()?)?); - }, - Some(_) => unreachable!(), - None => {} - } - Ok(true) - }], -}); diff --git a/crates/tek_mixer/src/plugin_vst2.rs b/crates/tek_mixer/src/plugin_vst2.rs index 269b2766..cb04e7e0 100644 --- a/crates/tek_mixer/src/plugin_vst2.rs +++ b/crates/tek_mixer/src/plugin_vst2.rs @@ -1,8 +1,8 @@ use crate::*; -impl ::vst::host::Host for Plugin {} +impl ::vst::host::Host for Plugin {} -fn set_vst_plugin (host: &Arc>, _path: &str) -> Usually { +fn set_vst_plugin (host: &Arc>>, _path: &str) -> Usually { let mut loader = ::vst::host::PluginLoader::load( &std::path::Path::new("/nix/store/ij3sz7nqg5l7v2dygdvzy3w6cj62bd6r-helm-0.9.0/lib/lxvst/helm.so"), host.clone() diff --git a/crates/tek_mixer/src/sample_add.rs b/crates/tek_mixer/src/sample_add.rs index 1df09006..919b27aa 100644 --- a/crates/tek_mixer/src/sample_add.rs +++ b/crates/tek_mixer/src/sample_add.rs @@ -26,39 +26,41 @@ impl Widget for AddSampleModal { type Engine = Tui; fn layout (&self, to: [u16;4]) -> Perhaps<[u16;4]> { todo!() + //Align::Center(()).layout(to) } fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { - let area = to.area(); - to.make_dim(); - let area = center_box( - area, - 64.max(area.w().saturating_sub(8)), - 20.max(area.w().saturating_sub(8)), - ); - to.fill_fg(area, Color::Reset); - to.fill_bg(area, Nord::bg_lo(true, true)); - to.fill_char(area, ' '); - to.blit(&format!("{}", &self.dir.to_string_lossy()), area.x()+2, area.y()+1, Some(Style::default().bold()))?; - to.blit(&"Select sample:", area.x()+2, area.y()+2, Some(Style::default().bold()))?; - for (i, (is_dir, name)) in self.subdirs.iter() - .map(|path|(true, path)) - .chain(self.files.iter().map(|path|(false, path))) - .enumerate() - .skip(self.offset) - { - if i >= area.h() as usize - 4 { - break - } - let t = if is_dir { "" } else { "" }; - let line = format!("{t} {}", name.to_string_lossy()); - let line = &line[..line.len().min(area.w() as usize - 4)]; - to.blit(&line, area.x() + 2, area.y() + 3 + i as u16, Some(if i == self.cursor { - Style::default().green() - } else { - Style::default().white() - }))?; - } - Lozenge(Style::default()).draw(to) + todo!() + //let area = to.area(); + //to.make_dim(); + //let area = center_box( + //area, + //64.max(area.w().saturating_sub(8)), + //20.max(area.w().saturating_sub(8)), + //); + //to.fill_fg(area, Color::Reset); + //to.fill_bg(area, Nord::bg_lo(true, true)); + //to.fill_char(area, ' '); + //to.blit(&format!("{}", &self.dir.to_string_lossy()), area.x()+2, area.y()+1, Some(Style::default().bold()))?; + //to.blit(&"Select sample:", area.x()+2, area.y()+2, Some(Style::default().bold()))?; + //for (i, (is_dir, name)) in self.subdirs.iter() + //.map(|path|(true, path)) + //.chain(self.files.iter().map(|path|(false, path))) + //.enumerate() + //.skip(self.offset) + //{ + //if i >= area.h() as usize - 4 { + //break + //} + //let t = if is_dir { "" } else { "" }; + //let line = format!("{t} {}", name.to_string_lossy()); + //let line = &line[..line.len().min(area.w() as usize - 4)]; + //to.blit(&line, area.x() + 2, area.y() + 3 + i as u16, Some(if i == self.cursor { + //Style::default().green() + //} else { + //Style::default().white() + //}))?; + //} + //Lozenge(Style::default()).draw(to) } } impl Handle for AddSampleModal { @@ -282,4 +284,3 @@ impl Sample { Ok(sample) } } - diff --git a/crates/tek_mixer/src/track.rs b/crates/tek_mixer/src/track.rs index b38e24d1..b7746beb 100644 --- a/crates/tek_mixer/src/track.rs +++ b/crates/tek_mixer/src/track.rs @@ -21,10 +21,10 @@ impl Track { device: 0, }) } - fn get_device_mut (&self, i: usize) -> Option>>> { + fn get_device_mut (&self, i: usize) -> Option>>> { self.devices.get(i).map(|d|d.state.write().unwrap()) } - pub fn device_mut (&self) -> Option>>> { + pub fn device_mut (&self) -> Option>>> { self.get_device_mut(self.device) } /// Add a device to the end of the chain.