From 355b34c73806fe4dbe533b3cae5292437283291e Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sun, 10 Nov 2024 19:58:16 +0100 Subject: [PATCH] wip: refactor pt.10, 165 errors --- crates/tek_api/src/arrange.rs | 33 ++++++++ crates/tek_tui/src/lib.rs | 4 +- crates/tek_tui/src/tui_app.rs | 4 +- crates/tek_tui/src/tui_arranger.rs | 52 ------------ crates/tek_tui/src/tui_arranger_bar.rs | 1 - crates/tek_tui/src/tui_arranger_cmd.rs | 106 ++++-------------------- crates/tek_tui/src/tui_sequencer_cmd.rs | 80 +++++++----------- crates/tek_tui/src/tui_sequencer_foc.rs | 2 +- crates/tek_tui/src/tui_transport_cmd.rs | 18 ++-- 9 files changed, 96 insertions(+), 204 deletions(-) diff --git a/crates/tek_api/src/arrange.rs b/crates/tek_api/src/arrange.rs index dd6c2757..6179c5c0 100644 --- a/crates/tek_api/src/arrange.rs +++ b/crates/tek_api/src/arrange.rs @@ -117,4 +117,37 @@ impl ArrangementScene { //clips, //}) //} + pub fn ppqs (scenes: &[Self], factor: usize) -> Vec<(usize, usize)> { + let mut total = 0; + if factor == 0 { + scenes.iter().map(|scene|{ + let pulses = scene.pulses().max(PPQ); + total = total + pulses; + (pulses, total - pulses) + }).collect() + } else { + (0..=scenes.len()).map(|i|{ + (factor*PPQ, factor*PPQ*i) + }).collect() + } + } + pub fn longest_name (scenes: &[Self]) -> usize { + scenes.iter().map(|s|s.name.read().unwrap().len()).fold(0, usize::max) + } +} + +impl ArrangementTrack { + pub fn longest_name (tracks: &[Self]) -> usize { + tracks.iter().map(|s|s.name.read().unwrap().len()).fold(0, usize::max) + } + + pub const MIN_WIDTH: usize = 3; + pub fn width_inc (&mut self) { + self.width += 1; + } + pub fn width_dec (&mut self) { + if self.width > Self::MIN_WIDTH { + self.width -= 1; + } + } } diff --git a/crates/tek_tui/src/lib.rs b/crates/tek_tui/src/lib.rs index 6805652a..269f7d5d 100644 --- a/crates/tek_tui/src/lib.rs +++ b/crates/tek_tui/src/lib.rs @@ -41,8 +41,8 @@ submod! { tui_pool_length tui_pool_rename - tui_sampler - tui_sampler_cmd + //tui_sampler // TODO + //tui_sampler_cmd tui_sequencer tui_sequencer_bar diff --git a/crates/tek_tui/src/tui_app.rs b/crates/tek_tui/src/tui_app.rs index ffe51b6f..1d6fda4a 100644 --- a/crates/tek_tui/src/tui_app.rs +++ b/crates/tek_tui/src/tui_app.rs @@ -25,7 +25,7 @@ where C: Command, U: From>> + Widget + Handle, A: From>> + Audio, - S: From>> + Widget + S: From>> + StatusBar { fn from (model: T) -> Self { let model = Arc::new(RwLock::new(model)); @@ -35,7 +35,7 @@ where menu_bar: None, status_bar: None, history: vec![], - size: (0, 0).into(), + size: Measure::new(), ui: U::from(model.clone()), audio: A::from(model.clone()), model, diff --git a/crates/tek_tui/src/tui_arranger.rs b/crates/tek_tui/src/tui_arranger.rs index 7610b34e..da2048da 100644 --- a/crates/tek_tui/src/tui_arranger.rs +++ b/crates/tek_tui/src/tui_arranger.rs @@ -447,28 +447,6 @@ impl Arrangement { } } -impl ArrangementTrack { - pub fn new ( - jack: &Arc>, - clock: &Arc, - name: &str, - color: Option - ) -> Usually { - Ok(Self { - name: Arc::new(RwLock::new(name.into())), - width: name.len() + 2, - color: color.unwrap_or_else(ItemColor::random), - player: PhrasePlayer::new(&jack, clock, name)?, - }) - } - pub fn longest_name (tracks: &[Self]) -> usize { - tracks.iter().map(|s|s.name.read().unwrap().len()).fold(0, usize::max) - } - pub const MIN_WIDTH: usize = 3; - pub fn width_inc (&mut self) { self.width += 1; } - pub fn width_dec (&mut self) { if self.width > Self::MIN_WIDTH { self.width -= 1; } } -} - /// Arranger display mode can be cycled impl ArrangementEditorMode { /// Cycle arranger display mode @@ -482,33 +460,3 @@ impl ArrangementEditorMode { } } } -impl ArrangementScene { - pub fn new ( - name: impl AsRef, - clips: impl AsRef<[Option>>]>, - color: Option, - ) -> Self { - Self { - name: Arc::new(RwLock::new(name.as_ref().into())), - clips: clips.as_ref().iter().map(|x|x.clone()).collect(), - color: color.unwrap_or_else(ItemColor::random), - } - } - pub fn ppqs (scenes: &[Self], factor: usize) -> Vec<(usize, usize)> { - let mut total = 0; - if factor == 0 { - scenes.iter().map(|scene|{ - let pulses = scene.pulses().max(PPQ); - total = total + pulses; - (pulses, total - pulses) - }).collect() - } else { - (0..=scenes.len()).map(|i|{ - (factor*PPQ, factor*PPQ*i) - }).collect() - } - } - pub fn longest_name (scenes: &[Self]) -> usize { - scenes.iter().map(|s|s.name.read().unwrap().len()).fold(0, usize::max) - } -} diff --git a/crates/tek_tui/src/tui_arranger_bar.rs b/crates/tek_tui/src/tui_arranger_bar.rs index 2118af03..e9a05a73 100644 --- a/crates/tek_tui/src/tui_arranger_bar.rs +++ b/crates/tek_tui/src/tui_arranger_bar.rs @@ -118,7 +118,6 @@ impl Content for ArrangerStatusBar { //.cmd("s", "Save project", ArrangerViewCommand::Arrangement(Save)) //}) //.add({ - //use TransportViewCommand::*; //Menu::new("Transport") //.cmd("p", "Play", TransportCommand::Transport(Play(None))) //.cmd("P", "Play from start", TransportCommand::Transport(Play(Some(0)))) diff --git a/crates/tek_tui/src/tui_arranger_cmd.rs b/crates/tek_tui/src/tui_arranger_cmd.rs index 10760817..d0b8464f 100644 --- a/crates/tek_tui/src/tui_arranger_cmd.rs +++ b/crates/tek_tui/src/tui_arranger_cmd.rs @@ -3,27 +3,16 @@ use crate::*; #[derive(Clone)] pub enum ArrangerViewCommand { Focus(FocusCommand), - Transport(TransportCommand), Arrangement(ArrangementEditorCommand), - EditPhrase(Option>>), + Transport(TransportCommand), Phrases(PhrasePoolCommand), Editor(PhraseEditorCommand), + EditPhrase(Option>>), } /// Handle top-level events in standalone arranger. impl Handle for ArrangerView { fn handle (&mut self, i: &TuiInput) -> Perhaps { - if let Some(entered) = self.entered() { - use ArrangerViewFocus::*; - if let Some(true) = match entered { - Transport => self.sequencer.transport.map(|t|t.handle(i)).transpose()?.flatten(), - Arrangement => self.arrangement.handle(i)?, - PhrasePool => self.sequencer.phrases.handle(i)?, - PhraseEditor => self.sequencer.editor.handle(i)?, - } { - return Ok(Some(true)) - } - } ArrangerViewCommand::execute_with_state(self, i) } } @@ -70,87 +59,28 @@ impl InputToCommand> for ArrangerViewCommand { } } -//impl ArrangerView { - ///// Helper for event passthru to focused component - //fn handle_focused (&mut self, from: &TuiInput) -> Perhaps { - //match self.focused() { - //ArrangerViewFocus::Transport => self.transport.handle(from), - //ArrangerViewFocus::PhrasePool => self.handle_pool(from), - //ArrangerViewFocus::PhraseEditor => self.editor.handle(from), - //ArrangerViewFocus::Arrangement => self.handle_arrangement(from) - //.and_then(|result|{self.show_phrase();Ok(result)}), - //} - //} - ///// Helper for phrase event passthru when phrase pool is focused - //fn handle_pool (&mut self, from: &TuiInput) -> Perhaps { - //match from.event() { - //key!(KeyCode::Char('<')) => { - //self.phrases_split = self.phrases_split.saturating_sub(1).max(12); - //}, - //key!(KeyCode::Char('>')) => { - //self.phrases_split = self.phrases_split + 1; - //}, - //_ => return self.phrases.handle(from) - //} - //Ok(Some(true)) - //} - ///// Helper for phrase event passthru when arrangement is focused - //fn handle_arrangement (&mut self, from: &TuiInput) -> Perhaps { - //let mut handle_phrase = ||{ - //let result = self.phrases.handle(from); - //self.arrangement.phrase_put(); - //result - //}; - //match from.event() { - //key!(KeyCode::Char('a')) => return handle_phrase(), - //key!(KeyCode::Char('i')) => return handle_phrase(), - //key!(KeyCode::Char('d')) => return handle_phrase(), - //key!(KeyCode::Char('<')) => if self.arrangement.selected == ArrangementFocus::Mix { - //self.arrangement_split = self.arrangement_split.saturating_sub(1).max(12); - //} else { - //return self.arrangement.handle(from) - //}, - //key!(KeyCode::Char('>')) => if self.arrangement.selected == ArrangementFocus::Mix { - //self.arrangement_split = self.arrangement_split + 1; - //} else { - //return self.arrangement.handle(from) - //}, - //_ => return self.arrangement.handle(from) - //} - //self.show_phrase(); - //Ok(Some(true)) - //} -//} - impl Command> for ArrangerViewCommand { - fn execute (self, state: &mut ArrangerView) -> Perhaps { + fn execute (self, view: &mut ArrangerView) -> Perhaps { let undo = match self { - Self::Focus(cmd) => { - delegate(cmd, Self::Focus, state) - }, - Self::Phrases(cmd) => { - delegate(cmd, Self::Phrases, &mut*state.sequencer.phrases.write().unwrap()) - }, - Self::Editor(cmd) => { - delegate(cmd, Self::Editor, &mut state.sequencer.editor) - }, - Self::Arrangement(cmd) => { - delegate(cmd, Self::Arrangement, &mut state.arrangement) - }, - Self::Transport(cmd) => if let Some(ref transport) = state.sequencer.transport { - delegate(cmd, Self::Transport, &mut*transport.write().unwrap()) - } else { - Ok(None) - }, + Self::Focus(cmd) => + delegate(cmd, Self::Focus, view), + Self::Phrases(cmd) => + delegate(cmd, Self::Phrases, &mut view.sequencer.phrases), + Self::Editor(cmd) => + delegate(cmd, Self::Editor, &mut view.sequencer.editor), + Self::Transport(cmd) => + delegate(cmd, Self::Transport, &mut view.sequencer.transport.state), + Self::Arrangement(cmd) => + delegate(cmd, Self::Arrangement, &mut view.arrangement), Self::EditPhrase(phrase) => { - state.sequencer.editor.phrase = phrase.clone(); - state.focus(ArrangerViewFocus::PhraseEditor); - state.focus_enter(); + view.sequencer.editor.phrase = phrase.clone(); + view.focus(ArrangerViewFocus::PhraseEditor); + view.focus_enter(); Ok(None) } }?; - state.sequencer.show_phrase(); - state.sequencer.update_status(); + view.sequencer.show_phrase(); + view.sequencer.update_status(); return Ok(undo); } } diff --git a/crates/tek_tui/src/tui_sequencer_cmd.rs b/crates/tek_tui/src/tui_sequencer_cmd.rs index 4ec6c25a..973d5230 100644 --- a/crates/tek_tui/src/tui_sequencer_cmd.rs +++ b/crates/tek_tui/src/tui_sequencer_cmd.rs @@ -3,77 +3,55 @@ use crate::*; #[derive(Clone, PartialEq)] pub enum SequencerViewCommand { Focus(FocusCommand), - Transport(TransportCommand), - Phrases(PhrasePoolCommand), + Transport(TransportViewCommand), + Phrases(PhrasePoolViewCommand), Editor(PhraseEditorCommand), } impl Handle for SequencerView { fn handle (&mut self, i: &TuiInput) -> Perhaps { - if let Some(entered) = self.entered() { - use SequencerFocus::*; - if let Some(true) = match entered { - Transport => self.transport.as_mut().map(|t|t.handle(i)).transpose()?.flatten(), - PhrasePool => self.phrases.write().unwrap().handle(i)?, - PhraseEditor => self.editor.handle(i)?, - } { - return Ok(Some(true)) - } - } - if let Some(command) = SequencerCommand::input_to_command(self, i) { - let _undo = command.execute(self)?; - return Ok(Some(true)) - } - Ok(None) + SequencerViewCommand::execute_with_state(self, i) } } impl Command> for SequencerViewCommand { fn execute (self, state: &mut SequencerView) -> Perhaps { match self { - Self::Focus(cmd) => { - return delegate(cmd, Self::Focus, state) - }, - Self::Phrases(cmd) => { - return delegate(cmd, Self::Phrases, &mut*state.phrases.write().unwrap()) - }, - Self::Editor(cmd) => { - return delegate(cmd, Self::Editor, &mut state.editor) - }, - Self::Transport(cmd) => if let Some(ref transport) = state.transport { - return delegate(cmd, Self::Transport, &mut*transport.write().unwrap()) - }, + Self::Focus(cmd) => + delegate(cmd, Self::Focus, state), + Self::Phrases(cmd) => + delegate(cmd, Self::Phrases, &mut state.phrases), + Self::Editor(cmd) => + delegate(cmd, Self::Editor, &mut state.editor), + Self::Transport(cmd) => + delegate(cmd, Self::Transport, &mut state.transport) } - Ok(None) } } impl InputToCommand> for SequencerViewCommand { fn input_to_command (state: &SequencerView, input: &TuiInput) -> Option { - use SequencerViewCommand::*; use FocusCommand::*; match input.event() { - key!(KeyCode::Tab) => Some(Focus(Next)), - key!(Shift-KeyCode::Tab) => Some(Focus(Prev)), - key!(KeyCode::BackTab) => Some(Focus(Prev)), - key!(Shift-KeyCode::BackTab) => Some(Focus(Prev)), - key!(KeyCode::Up) => Some(Focus(Up)), - key!(KeyCode::Down) => Some(Focus(Down)), - key!(KeyCode::Left) => Some(Focus(Left)), - key!(KeyCode::Right) => Some(Focus(Right)), - //key!(KeyCode::Char(' ')) => Some(Transport(TransportViewCommand::PlayToggle)), + key!(KeyCode::Tab) => Some(Self::Focus(Next)), + key!(Shift-KeyCode::Tab) => Some(Self::Focus(Prev)), + key!(KeyCode::BackTab) => Some(Self::Focus(Prev)), + key!(Shift-KeyCode::BackTab) => Some(Self::Focus(Prev)), + key!(KeyCode::Up) => Some(Self::Focus(Up)), + key!(KeyCode::Down) => Some(Self::Focus(Down)), + key!(KeyCode::Left) => Some(Self::Focus(Left)), + key!(KeyCode::Right) => Some(Self::Focus(Right)), _ => match state.focused() { - SequencerFocus::Transport => if let Some(t) = state.transport.as_ref() { - TransportViewCommand::input_to_command(&*t.read().unwrap(), input).map(Transport) - } else { - None - }, - SequencerFocus::PhrasePool => - PhrasePoolCommand::input_to_command(&*state.phrases.read().unwrap(), input) - .map(Phrases), - SequencerFocus::PhraseEditor => - PhraseEditorCommand::input_to_command(&state.editor, input) - .map(Editor), + SequencerFocus::Transport => TransportViewCommand::input_to_command( + &state.transport, input + ).map(Self::Transport), + SequencerFocus::PhrasePool => PhrasePoolViewCommand::input_to_command( + &state.phrases, input + ).map(Self::Phrases), + SequencerFocus::PhraseEditor => PhraseEditorCommand::input_to_command( + &state.editor, input + ).map(Self::Editor), + } } } diff --git a/crates/tek_tui/src/tui_sequencer_foc.rs b/crates/tek_tui/src/tui_sequencer_foc.rs index bf13b381..fb763f4c 100644 --- a/crates/tek_tui/src/tui_sequencer_foc.rs +++ b/crates/tek_tui/src/tui_sequencer_foc.rs @@ -11,7 +11,7 @@ use crate::*; } /// Focus layout of sequencer app -impl FocusGrid for Sequencer { +impl FocusGrid for SequencerView { type Item = SequencerFocus; fn cursor (&self) -> (usize, usize) { self.focus_cursor diff --git a/crates/tek_tui/src/tui_transport_cmd.rs b/crates/tek_tui/src/tui_transport_cmd.rs index a63340b6..e1f70ca5 100644 --- a/crates/tek_tui/src/tui_transport_cmd.rs +++ b/crates/tek_tui/src/tui_transport_cmd.rs @@ -1,14 +1,17 @@ use crate::*; + #[derive(Copy, Clone, PartialEq)] pub enum TransportViewCommand { Focus(FocusCommand), Transport(TransportCommand), } + impl Handle for TransportView { fn handle (&mut self, from: &TuiInput) -> Perhaps { TransportViewCommand::execute_with_state(self, from) } } + impl InputToCommand> for TransportViewCommand { fn input_to_command (state: &TransportView, input: &TuiInput) -> Option { use TransportViewFocus as Focus; @@ -19,7 +22,7 @@ impl InputToCommand> for TransportViewCommand { key!(KeyCode::Left) => Self::Focus(FocusCmd::Prev), key!(KeyCode::Right) => Self::Focus(FocusCmd::Next), - key!(KeyCode::Char('.')) => Self::Transport(match state.focus { + key!(KeyCode::Char('.')) => Self::Transport(match state.focus { Focus::Bpm => Cmd::SetBpm(state.state.clock.timebase().bpm.get() + 1.0), Focus::Quant => Cmd::SetQuant(next_note_length(state.state.clock.quant.get()as usize)as f64), Focus::Sync => Cmd::SetSync(next_note_length(state.state.clock.sync.get()as usize)as f64+1.), @@ -55,15 +58,16 @@ impl InputToCommand> for TransportViewCommand { impl Command> for TransportViewCommand { fn execute (self, state: &mut TransportView) -> Perhaps { - Ok(match self { - Self::Focus(command) => { + Ok(Some(match self { + Self::Focus(command) => Self::Focus({ use FocusCommand::*; match command { Next => { todo!() }, Prev => { todo!() }, + _ => { todo!() } } - }, - Self::Transport(command) => { + }), + Self::Transport(command) => Self::Transport({ use TransportCommand::*; match command { SetBpm(bpm) => SetBpm(state.state.clock.timebase().bpm.set(bpm)), @@ -71,7 +75,7 @@ impl Command> for TransportViewCommand { SetSync(sync) => SetSync(state.state.clock.sync.set(sync)), _ => { todo!() } } - }, - }) + }), + })) } }