diff --git a/crates/tek_tui/src/tui_command.rs b/crates/tek_tui/src/tui_command.rs index 4da9b754..92203079 100644 --- a/crates/tek_tui/src/tui_command.rs +++ b/crates/tek_tui/src/tui_command.rs @@ -34,11 +34,8 @@ pub enum SequencerCommand { Editor(PhraseCommand), } -impl Command for SequencerCommand -where - T: ClockApi + PhrasesControl + PhraseEditorControl + FocusGrid -{ - fn execute (self, state: &mut T) -> Perhaps { +impl Command for SequencerCommand { + fn execute (self, state: &mut SequencerTui) -> Perhaps { use SequencerCommand::*; Ok(match self { Focus(cmd) => cmd.execute(state)?.map(Focus), @@ -258,7 +255,7 @@ pub enum PhraseCommand { TimeZoomSet(usize), } -impl Command for PhraseCommand { +impl Command for PhraseCommand { fn execute (self, state: &mut T) -> Perhaps { use PhraseCommand::*; Ok(match self { diff --git a/crates/tek_tui/src/tui_control.rs b/crates/tek_tui/src/tui_control.rs index 4f9af61e..085be65c 100644 --- a/crates/tek_tui/src/tui_control.rs +++ b/crates/tek_tui/src/tui_control.rs @@ -1,24 +1,36 @@ use crate::*; pub trait TransportControl: ClockApi { - fn transport_focused (&self) -> TransportFocus; + fn transport_focused (&self) -> Option; } impl TransportControl for TransportTui { - fn transport_focused (&self) -> TransportFocus { - self.state.focus.inner() + fn transport_focused (&self) -> Option { + if let AppFocus::Content(focus) = self.focus.inner() { + Some(focus) + } else { + None + } } } impl TransportControl for SequencerTui { - fn transport_focused (&self) -> TransportFocus { - self.transport.focus.inner() + fn transport_focused (&self) -> Option { + if let AppFocus::Content(SequencerFocus::Transport(focus)) = self.focus.inner() { + Some(focus) + } else { + None + } } } impl TransportControl for ArrangerTui { - fn transport_focused (&self) -> TransportFocus { - self.transport.focus.inner() + fn transport_focused (&self) -> Option { + if let AppFocus::Content(ArrangerFocus::Transport(focus)) = self.focus.inner() { + Some(focus) + } else { + None + } } } diff --git a/crates/tek_tui/src/tui_debug.rs b/crates/tek_tui/src/tui_debug.rs index 712195e2..1228bbd3 100644 --- a/crates/tek_tui/src/tui_debug.rs +++ b/crates/tek_tui/src/tui_debug.rs @@ -21,7 +21,6 @@ impl Debug for TransportTui { fn fmt (&self, f: &mut Formatter<'_>) -> DebugResult { f.debug_struct("Measure") .field("jack", &self.jack) - .field("state", &self.state) .field("size", &self.size) .field("cursor", &self.cursor) .finish() diff --git a/crates/tek_tui/src/tui_focus.rs b/crates/tek_tui/src/tui_focus.rs index 99ead661..eb5363b2 100644 --- a/crates/tek_tui/src/tui_focus.rs +++ b/crates/tek_tui/src/tui_focus.rs @@ -118,16 +118,53 @@ impl_focus!(TransportTui TransportFocus [ ]); impl_focus!(SequencerTui SequencerFocus [ - &[Menu, Menu ], - &[Content(Transport), Content(Transport) ], - &[Content(Phrases), Content(PhraseEditor)], + &[ + Menu, + Menu, + Menu, + Menu, + Menu, + ], &[ + Content(Transport(TransportFocus::Bpm)), + Content(Transport(TransportFocus::Sync)), + Content(Transport(TransportFocus::PlayPause)), + Content(Transport(TransportFocus::Clock)), + Content(Transport(TransportFocus::Quant)) + ], &[ + Content(Phrases), + Content(Phrases), + Content(PhraseEditor), + Content(PhraseEditor), + Content(PhraseEditor), + ], ]); impl_focus!(ArrangerTui ArrangerFocus [ - &[Menu, Menu ], - &[Content(Transport), Content(Transport) ], - &[Content(Arranger), Content(Arranger) ], - &[Content(Phrases), Content(PhraseEditor)], + &[ + Menu, + Menu, + Menu, + Menu, + Menu, + ], &[ + Content(Transport(TransportFocus::Bpm)), + Content(Transport(TransportFocus::Sync)), + Content(Transport(TransportFocus::PlayPause)), + Content(Transport(TransportFocus::Clock)), + Content(Transport(TransportFocus::Quant)) + ], &[ + Content(Arranger), + Content(Arranger), + Content(Arranger), + Content(Arranger), + Content(Arranger), + ], &[ + Content(Phrases), + Content(Phrases), + Content(PhraseEditor), + Content(PhraseEditor), + Content(PhraseEditor), + ], ]); /// Focused field of `PhraseLength` diff --git a/crates/tek_tui/src/tui_impls.rs b/crates/tek_tui/src/tui_impls.rs index 022a607e..7b295b82 100644 --- a/crates/tek_tui/src/tui_impls.rs +++ b/crates/tek_tui/src/tui_impls.rs @@ -175,9 +175,9 @@ impl_jack_api!(TransportTui::jack); impl_jack_api!(SequencerTui::jack); impl_jack_api!(ArrangerTui::jack); -impl_clock_api!(TransportTui::state::clock); -impl_clock_api!(SequencerTui::transport::clock); -impl_clock_api!(ArrangerTui::transport::clock); +impl_clock_api!(TransportTui::clock); +impl_clock_api!(SequencerTui::clock); +impl_clock_api!(ArrangerTui::clock); impl_clock_api!(PhrasePlayerModel::clock); impl_clock_api!(ArrangerTrack::player::clock); @@ -192,5 +192,9 @@ impl_midi_player!(PhrasePlayerModel); impl_phrases_control!(SequencerTui); impl_phrases_control!(ArrangerTui); -impl_phrase_editor_control!(SequencerTui [SequencerFocus::PhraseEditor]); -impl_phrase_editor_control!(ArrangerTui [ArrangerFocus::PhraseEditor]); +impl_phrase_editor_control!(SequencerTui [ + AppFocus::Content(SequencerFocus::PhraseEditor) +]); +impl_phrase_editor_control!(ArrangerTui [ + AppFocus::Content(ArrangerFocus::PhraseEditor) +]); diff --git a/crates/tek_tui/src/tui_input.rs b/crates/tek_tui/src/tui_input.rs index 0dea5f84..e31ba8c9 100644 --- a/crates/tek_tui/src/tui_input.rs +++ b/crates/tek_tui/src/tui_input.rs @@ -6,7 +6,7 @@ impl InputToCommand for TransportCommand { use ClockCommand::{SetBpm, SetQuant, SetSync}; use TransportFocus as Focused; use TransportCommand::{Focus, Clock}; - let focused = state.transport_focused(); + let focused = state.transport_focused().unwrap(); Some(match input.event() { key!(Left) => Focus(FocusCommand::Prev), key!(Right) => Focus(FocusCommand::Next), @@ -47,39 +47,35 @@ impl InputToCommand for TransportCommand { } } -impl InputToCommand for SequencerCommand -where - T: SequencerControl + TransportControl + PhrasesControl + PhraseEditorControl - + HasFocus - + FocusGrid -{ - fn input_to_command (state: &T, input: &TuiInput) -> Option { +impl InputToCommand for SequencerCommand { + fn input_to_command (state: &SequencerTui, input: &TuiInput) -> Option { use FocusCommand::*; use SequencerCommand::*; - match input.event() { - 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)), - _ => Some(match state.focused() { - SequencerFocus::Transport => { + Some(match input.event() { + key!(KeyCode::Tab) => Self::Focus(Next), + key!(Shift-KeyCode::Tab) => Self::Focus(Prev), + key!(KeyCode::BackTab) => Self::Focus(Prev), + key!(Shift-KeyCode::BackTab) => Self::Focus(Prev), + key!(KeyCode::Up) => Self::Focus(Up), + key!(KeyCode::Down) => Self::Focus(Down), + key!(KeyCode::Left) => Self::Focus(Left), + key!(KeyCode::Right) => Self::Focus(Right), + _ => match state.focused() { + AppFocus::Menu => todo!(), + AppFocus::Content(SequencerFocus::Transport(_)) => { use TransportCommand::{Clock, Focus}; match TransportCommand::input_to_command(state, input)? { - Clock(command) => { todo!() }, - Focus(command) => { todo!() }, + Clock(command) => { todo!() }, + Focus(command) => { todo!() }, } }, - SequencerFocus::Phrases => + AppFocus::Content(SequencerFocus::Phrases) => Phrases(PhrasesCommand::input_to_command(state, input)?), - SequencerFocus::PhraseEditor => + AppFocus::Content(SequencerFocus::PhraseEditor) => Editor(PhraseCommand::input_to_command(state, input)?), _ => return None, - }) - } + } + }) } } @@ -100,22 +96,22 @@ impl InputToCommand for ArrangerCommand { key!(KeyCode::Esc) => Self::Focus(Exit), key!(KeyCode::Char(' ')) => Self::Clock(ClockCommand::Play(None)), _ => match state.focused() { - ArrangerFocus::Menu => { todo!() }, - ArrangerFocus::Transport => { + AppFocus::Menu => todo!(), + AppFocus::Content(ArrangerFocus::Transport(_)) => { use TransportCommand::{Clock, Focus}; match TransportCommand::input_to_command(state, input)? { Clock(command) => { todo!() }, Focus(command) => { todo!() } } }, - ArrangerFocus::PhraseEditor => Editor( + AppFocus::Content(ArrangerFocus::PhraseEditor) => Editor( PhraseCommand::input_to_command(state, input)? ), - ArrangerFocus::Phrases => match input.event() { + AppFocus::Content(ArrangerFocus::Phrases) => match input.event() { key!(KeyCode::Char('e')) => EditPhrase(state.phrase_editing().clone()), _ => Phrases(PhrasesCommand::input_to_command(state, input)?) }, - ArrangerFocus::Arranger => { + AppFocus::Content(ArrangerFocus::Arranger) => { use ArrangerSelection as Select; use ArrangerTrackCommand as Track; use ArrangerClipCommand as Clip; @@ -348,7 +344,7 @@ impl InputToCommand for PhraseRenameCommand { } } -impl InputToCommand for PhraseCommand { +impl InputToCommand for PhraseCommand { fn input_to_command (state: &T, from: &TuiInput) -> Option { use PhraseCommand::*; Some(match from.event() { diff --git a/crates/tek_tui/src/tui_model.rs b/crates/tek_tui/src/tui_model.rs index 5a7afb01..04b88e00 100644 --- a/crates/tek_tui/src/tui_model.rs +++ b/crates/tek_tui/src/tui_model.rs @@ -223,7 +223,7 @@ impl ArrangerTracksApi for ArrangerTui { width: name.len() + 2, name: Arc::new(name.into()), color: color.unwrap_or_else(||ItemColor::random()), - player: PhrasePlayerModel::from(&self.transport.clock), + player: PhrasePlayerModel::from(&self.clock), }; self.tracks_mut().push(track); let index = self.tracks().len() - 1; diff --git a/crates/tek_tui/src/tui_status.rs b/crates/tek_tui/src/tui_status.rs index 3a5036b8..459fb8e9 100644 --- a/crates/tek_tui/src/tui_status.rs +++ b/crates/tek_tui/src/tui_status.rs @@ -94,8 +94,8 @@ impl StatusBar for ArrangerStatus { } fn update (&mut self, (focused, selected, entered): &Self::State) { *self = match focused { - ArrangerFocus::Menu => { todo!() }, - ArrangerFocus::Transport => ArrangerStatus::Transport, + //ArrangerFocus::Menu => { todo!() }, + ArrangerFocus::Transport(_) => ArrangerStatus::Transport, ArrangerFocus::Arranger => match selected { ArrangerSelection::Mix => ArrangerStatus::ArrangerMix, ArrangerSelection::Track(_) => ArrangerStatus::ArrangerTrack, diff --git a/crates/tek_tui/src/tui_view.rs b/crates/tek_tui/src/tui_view.rs index 9a8c92fb..dcd0ee05 100644 --- a/crates/tek_tui/src/tui_view.rs +++ b/crates/tek_tui/src/tui_view.rs @@ -26,7 +26,7 @@ macro_rules! impl_transport_view_state { ($Struct:ident :: $field:ident) => { impl TransportViewState for $Struct { fn transport_selected (&self) -> TransportFocus { - self.$field.focus.inner() + self.focused().inner() } fn transport_focused (&self) -> bool { true @@ -34,16 +34,16 @@ macro_rules! impl_transport_view_state { } } } -impl_transport_view_state!(TransportTui::state); -impl_transport_view_state!(SequencerTui::transport); -impl_transport_view_state!(ArrangerTui::transport); +impl_transport_view_state!(TransportTui::clock); +impl_transport_view_state!(SequencerTui::clock); +impl_transport_view_state!(ArrangerTui::clock); pub trait ArrangerViewState { fn arranger_focused (&self) -> bool; } impl ArrangerViewState for ArrangerTui { fn arranger_focused (&self) -> bool { - self.focused() == ArrangerFocus::Arranger + self.focused() == AppFocus::Content(ArrangerFocus::Arranger) } }