From 777904cb35eb8ab4baf3556c352fe6e23c288d72 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Fri, 30 Aug 2024 20:19:36 +0300 Subject: [PATCH] wrapper impls for Render and Handle --- crates/tek_core/src/handle.rs | 41 +++++- crates/tek_core/src/handle_focus.rs | 51 -------- crates/tek_core/src/lib.rs | 1 - crates/tek_sequencer/src/arranger_main.rs | 145 ++++++++++++---------- 4 files changed, 118 insertions(+), 120 deletions(-) delete mode 100644 crates/tek_core/src/handle_focus.rs diff --git a/crates/tek_core/src/handle.rs b/crates/tek_core/src/handle.rs index c95aef8a..0186694f 100644 --- a/crates/tek_core/src/handle.rs +++ b/crates/tek_core/src/handle.rs @@ -28,7 +28,7 @@ pub fn input_thread ( } /// Trait for things that handle input events. -pub trait Handle { +pub trait Handle: Send + Sync { /// Handle an input event. /// Returns Ok(true) if the device handled the event. /// This is the mechanism which allows nesting of components;. @@ -37,6 +37,45 @@ pub trait Handle { } } +impl Handle for &mut T { + fn handle (&mut self, e: &AppEvent) -> Usually { + (*self).handle(e) + } +} + +impl Handle for Option { + fn handle (&mut self, e: &AppEvent) -> Usually { + match self { + Some(handle) => handle.handle(e), + None => Ok(false) + } + } +} + +impl Handle for Mutex { + fn handle (&mut self, e: &AppEvent) -> Usually { + self.lock().unwrap().handle(e) + } +} + +impl Handle for Arc> { + fn handle (&mut self, e: &AppEvent) -> Usually { + self.lock().unwrap().handle(e) + } +} + +impl Handle for RwLock { + fn handle (&mut self, e: &AppEvent) -> Usually { + self.write().unwrap().handle(e) + } +} + +impl Handle for Arc> { + fn handle (&mut self, e: &AppEvent) -> Usually { + self.write().unwrap().handle(e) + } +} + /// Implement the `Handle` trait. #[macro_export] macro_rules! handle { ($T:ty) => { diff --git a/crates/tek_core/src/handle_focus.rs b/crates/tek_core/src/handle_focus.rs deleted file mode 100644 index 3aec81b5..00000000 --- a/crates/tek_core/src/handle_focus.rs +++ /dev/null @@ -1,51 +0,0 @@ -use crate::*; - -/// A collection of [Focusable] items. -pub struct Focus { - index: usize, - items: Vec -} - -impl Focus { - pub fn new (items: Vec) -> Self { - Self { - index: 0, - items - } - } - pub fn item_mut (&mut self) -> &mut impl Handle { - &mut self.items[self.index] - } - /// Select next item. - pub fn next (&mut self) -> Usually { - self.index = (self.index + 1) % self.items.len(); - Ok(true) - } - /// Select previous item. - pub fn prev (&mut self) -> Usually { - self.index = match self.index { - 0 => self.items.len().saturating_sub(1), - _ => self.index - 1 - }; - Ok(true) - } -} - -handle!(Focus |self, e| Ok( - handle_keymap(self, e, KEYMAP_FOCUS)? || self.item_mut().handle(e)? -)); - -pub const KEYMAP_FOCUS: &'static [KeyBinding] = keymap!(Focus { - [Tab, NONE, "focus_next", "focus next item", Focus::next], - [Tab, SHIFT, "focus_prev", "focus previous item", Focus::prev], -}); - -/// A wrapper around items that can be focused. -pub enum Focusable { - /// A monolithic focus item. - Mono(Arc), - /// A focus item that contains other focus items. - Poly(Box), -} - -handle!(Focusable |self, e| { todo!("{e:?}"); Ok(false) }); diff --git a/crates/tek_core/src/lib.rs b/crates/tek_core/src/lib.rs index 96e863d2..19557d8b 100644 --- a/crates/tek_core/src/lib.rs +++ b/crates/tek_core/src/lib.rs @@ -46,7 +46,6 @@ use crossterm::terminal::{ submod! { exit handle - handle_focus handle_keymap jack_core jack_device diff --git a/crates/tek_sequencer/src/arranger_main.rs b/crates/tek_sequencer/src/arranger_main.rs index d4cec845..5b29faf0 100644 --- a/crates/tek_sequencer/src/arranger_main.rs +++ b/crates/tek_sequencer/src/arranger_main.rs @@ -9,59 +9,76 @@ pub fn main () -> Usually<()> { struct ArrangerStandalone { /// Contains all the sequencers. - arranger: Arc, + arranger: Arranger, /// Controls the JACK transport. - transport: Option>>, + transport: Option, /// This allows the sequencer view to be moved or hidden. show_sequencer: Option, - /// Proxies input events to the currently active sequencer. - sequencer_proxy: SequencerProxy, /// - focus_order: Vec, + focus: usize, } -struct SequencerProxy; - -impl Focus for SequencerProxy {} +impl ArrangerStandalone { + fn focus_prev (&mut self) { + self.focus = if self.focus > 0 { 1 } else { self.focus - 1 }; + } + fn focus_next (&mut self) { + self.focus = if self.focus < 2 { self.focus + 1 } else { 0 }; + } + fn focused (&self) -> &dyn Render { + self.focusable()[self.focus] + } + fn focusable (&self) -> [&dyn Render;2] { + [ + &self.transport as &dyn Render, + &self.arranger as &dyn Render, + ] + } + fn focused_mut (&mut self) -> &mut dyn Handle { + let focus = self.focus; + self.focusable_mut()[focus] + } + fn focusable_mut (&mut self) -> [&mut dyn Handle;2] { + [ + &mut self.transport as &mut dyn Handle, + &mut self.arranger as &mut dyn Handle + ] + } +} #[derive(Debug, Parser)] #[command(version, about, long_about = None)] pub struct ArrangerCli { /// Name of JACK client - #[arg(short, long)] name: Option, + #[arg(short, long)] + name: Option, /// Pulses per quarter note (arruencer resolution; default: 96) - #[arg(short, long)] ppq: Option, + #[arg(short, long)] + ppq: Option, /// Whether to include a transport toolbar (default: true) - #[arg(short, long)] transport: Option, + #[arg(short, long)] + transport: Option, /// Number of tracks - #[arg(short = 'x', long, default_value_t = 8)] tracks: usize, + #[arg(short = 'x', long, default_value_t = 8)] + tracks: usize, /// Number of scenes - #[arg(short, long, default_value_t = 8)] scenes: usize, + #[arg(short, long, default_value_t = 8)] + scenes: usize, } -impl<'a> ArrangerStandalone<'a> { +impl ArrangerStandalone { pub fn from_args () -> Usually { let args = ArrangerCli::parse(); - let arranger = Arranger::new(""); + let mut arranger = Arranger::new(""); let transport = match args.transport { - Some(true) => Some(Arc::new(RwLock::new(TransportToolbar::new(None)))), + Some(true) => Some(TransportToolbar::new(None)), _ => None }; - let sequencer_proxy = SequencerProxy; - let mut app = ArrangerStandalone { - transport, - show_sequencer: Some(tek_core::Direction::Down), - arranger, - sequencer_proxy, - focus_order: vec![], - }; - app.focus_order.push(FocusItem::Mono(&app.arranger)); - app.focus_order.push(FocusItem::Poly(&app.sequencer_proxy)); if let Some(name) = args.name { - *app.arranger.name.write().unwrap() = name.clone(); + *arranger.name.write().unwrap() = name.clone(); } for _ in 0..args.tracks { - let track = app.arranger.track_add(None)?; + let track = arranger.track_add(None)?; for _ in 0..args.scenes { track.phrases.push( Arc::new(RwLock::new(Phrase::new("", 96 * 4, None))) @@ -69,30 +86,28 @@ impl<'a> ArrangerStandalone<'a> { } } for _ in 0..args.scenes { - let scene = app.arranger.scene_add(None)?; + let _scene = arranger.scene_add(None)?; //for i in 0..args.tracks { //scene.clips[i] = Some(i); //} } - Ok(app) + Ok(ArrangerStandalone { + transport, + show_sequencer: Some(tek_core::Direction::Down), + arranger, + focus: 0 + }) } } impl Render for ArrangerStandalone { fn render (&self, buf: &mut Buffer, area: Rect) -> Usually { - let mut layout = Split::down(); - if let Some(transport) = &self.transport { - layout = layout.add_ref(transport); - } let sequencer = self.arranger.sequencer(); - if let Some(direction) = self.show_sequencer { - layout = layout.add(Split::new(direction) - .add_ref(&self.arranger) - .add(sequencer)) - } else { - layout = layout.add_ref(&self.arranger) - } - let result = layout.render(buf, area)?; + let result = Split::down() + .add_ref(&self.transport) + .add_ref(&self.arranger) + .add_ref(&sequencer) + .render(buf, area)?; if let Some(ref modal) = self.arranger.modal { fill_bg(buf, area, Nord::bg_lo(false, false)); fill_fg(buf, area, Nord::bg_hi(false, false)); @@ -104,31 +119,27 @@ impl Render for ArrangerStandalone { impl Handle for ArrangerStandalone { fn handle (&mut self, e: &AppEvent) -> Usually { - if let Some(modal) = self.arranger.modal.as_mut() { - let result = modal.handle(e)?; - if modal.exited() { - self.arranger.modal = None; - } - Ok(result) - } else { - match e { - AppEvent::Input(Event::Key(k)) => { - Ok(false) - //if k.code == KeyCode::Tab { - //self.arranger.focus_sequencer = !self.arranger.focus_sequencer; - //Ok(true) - //} else if self.arranger.focus_sequencer { - //if let Some(sequencer) = self.arranger.sequencer_mut() { - //handle_keymap(sequencer, e, KEYMAP_SEQUENCER) - //} else { - //Ok(false) - //} - //} else { - //handle_keymap(&mut self.arranger, e, KEYMAP_ARRANGER) - //} - }, - _ => Ok(false), - } + match e { + AppEvent::Input(Event::Key(KeyEvent { code: KeyCode::Tab, .. })) => { + self.focus_next(); + Ok(true) + }, + AppEvent::Input(Event::Key(KeyEvent { code: KeyCode::BackTab, .. })) => { + self.focus_prev(); + Ok(true) + }, + _ => self.focused_mut().handle(e) + } + } +} + +struct SequencerProxy(Arc>); + +impl Handle for SequencerProxy { + fn handle (&mut self, e: &AppEvent) -> Usually { + match self.0.write().unwrap().sequencer_mut() { + Some(sequencer) => sequencer.handle(e), + None => Ok(false) } } }