From 0964ad3be405b954388831d8db1a2b3c5a190740 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Mon, 18 Nov 2024 22:17:22 +0100 Subject: [PATCH] wip: p.56, e=86 --- crates/tek_tui/src/tui_control.rs | 1 - crates/tek_tui/src/tui_init.rs | 104 +++++++++++++++++++----------- crates/tek_tui/src/tui_input.rs | 69 +++++++++++--------- crates/tek_tui/src/tui_model.rs | 6 +- 4 files changed, 108 insertions(+), 72 deletions(-) diff --git a/crates/tek_tui/src/tui_control.rs b/crates/tek_tui/src/tui_control.rs index c286930a..1c641491 100644 --- a/crates/tek_tui/src/tui_control.rs +++ b/crates/tek_tui/src/tui_control.rs @@ -67,7 +67,6 @@ impl PhrasesControl for PhrasesTui { } } - pub trait PhraseControl { fn phrase_entered (&self) -> bool; fn time_axis (&self) -> &RwLock>; diff --git a/crates/tek_tui/src/tui_init.rs b/crates/tek_tui/src/tui_init.rs index fb9ee41e..6f3e91c2 100644 --- a/crates/tek_tui/src/tui_init.rs +++ b/crates/tek_tui/src/tui_init.rs @@ -5,12 +5,18 @@ impl TryFrom<&Arc>> for TransportTui { type Error = Box; fn try_from (jack: &Arc>) -> Usually { Ok(Self { - metronome: false, - transport: jack.read().unwrap().transport(), - jack: jack.clone(), - focused: false, + current: Instant::default(), + cursor: (0, 0), focus: TransportFocus::PlayPause, + focused: false, + jack: jack.clone(), + metronome: false, + playing: RwLock::new(None), + quant: Quantize::default(), size: Measure::new(), + started: RwLock::new(None), + sync: LaunchSync::default(), + transport: jack.read().unwrap().transport(), }) } } @@ -18,14 +24,35 @@ impl TryFrom<&Arc>> for TransportTui { impl TryFrom<&Arc>> for SequencerTui { type Error = Box; fn try_from (jack: &Arc>) -> Usually { - Ok(Self::new(SequencerTui { - phrases: vec![], - metronome: false, - transport: jack.read().unwrap().transport(), - jack: jack.clone(), - focused: false, - size: Measure::new(), - }.into(), None, None)) + Ok(Self { + current: Instant::default(), + cursor: (0, 0), + entered: false, + jack: jack.clone(), + metronome: false, + midi_buf: vec![], + midi_inputs: vec![], + midi_outputs: vec![], + monitoring: true, + next_phrase: None, + note_buf: vec![], + notes_in: RwLock::new([false;128]).into(), + notes_out: RwLock::new([false;128]).into(), + overdub: true, + phrases: vec![], + phrases_mode: None, + play_phrase: None, + playing: RwLock::new(None), + quant: Quantize::default(), + recording: true, + reset: false, + size: Measure::new(), + split: 20, + started: RwLock::new(None), + sync: LaunchSync::default(), + transport: jack.read().unwrap().transport(), + view_phrase: 0, + }) } } @@ -33,33 +60,32 @@ impl TryFrom<&Arc>> for ArrangerTui { type Error = Box; fn try_from (jack: &Arc>) -> Usually { Ok(Self { - name: Arc::new(RwLock::new(String::new())), - phrases: vec![], - phrase: 0, - scenes: vec![], - tracks: vec![], - metronome: false, - playing: None.into(), - started: None.into(), - transport: jack.read().unwrap().transport(), - current: Instant::default(), - jack: jack.clone(), - selected: ArrangerSelection::Clip(0, 0), - mode: ArrangerMode::Vertical(2), - color: Color::Rgb(28, 35, 25).into(), - size: Measure::new(), - entered: false, - quant: Default::default(), - sync: Default::default(), - splits: [20, 20], - note_buf: vec![], - midi_buf: vec![], - cursor: (0, 0), - entered: false, - history: vec![], - size: Measure::new(), - menu_bar: None, - status_bar: None, + color: Color::Rgb(28, 35, 25).into(), + current: Instant::default(), + cursor: (0, 0), + entered: false, + history: vec![], + jack: jack.clone(), + menu_bar: None, + metronome: false, + midi_buf: vec![], + mode: ArrangerMode::Vertical(2), + name: Arc::new(RwLock::new(String::new())), + note_buf: vec![], + phrase: 0, + phrases: vec![], + phrases_mode: None, + playing: None.into(), + quant: Default::default(), + scenes: vec![], + selected: ArrangerSelection::Clip(0, 0), + size: Measure::new(), + splits: [20, 20], + started: None.into(), + status_bar: None, + sync: Default::default(), + tracks: vec![], + transport: jack.read().unwrap().transport(), }) } } diff --git a/crates/tek_tui/src/tui_input.rs b/crates/tek_tui/src/tui_input.rs index b69a1235..8fd4d2d3 100644 --- a/crates/tek_tui/src/tui_input.rs +++ b/crates/tek_tui/src/tui_input.rs @@ -1,12 +1,15 @@ use crate::*; -impl InputToCommand for TransportCommand { +impl InputToCommand for TransportCommand +where + T: TransportControl + HasFocus +{ fn input_to_command (state: &T, input: &TuiInput) -> Option { use KeyCode::Char; use ClockCommand::{SetBpm, SetQuant, SetSync}; use TransportFocus as Focused; use TransportCommand::{Focus, Clock, Playhead}; - let focused = state.focused(); + let focused = state.focused(); Some(match input.event() { key!(Left) => Focus(FocusCommand::Prev), key!(Right) => Focus(FocusCommand::Next), @@ -18,7 +21,7 @@ impl InputToCommand for TransportCommand { Focused::Clock => Playhead(todo!()), _ => {todo!()} }, - key!(KeyCode::Char(',')) => match focused { + key!(Char(',')) => match focused { Focused::Bpm => Clock(SetBpm(state.bpm().get() - 1.0)), Focused::Quant => Clock(SetQuant(state.prev_quant())), Focused::Sync => Clock(SetSync(state.prev_sync())), @@ -26,7 +29,7 @@ impl InputToCommand for TransportCommand { Focused::Clock => Playhead(todo!()), _ => {todo!()} }, - key!(KeyCode::Char('>')) => match focused { + key!(Char('>')) => match focused { Focused::Bpm => Clock(SetBpm(state.bpm().get() + 0.001)), Focused::Quant => Clock(SetQuant(state.next_quant())), Focused::Sync => Clock(SetSync(state.next_sync())), @@ -34,7 +37,7 @@ impl InputToCommand for TransportCommand { Focused::Clock => Playhead(todo!()), _ => {todo!()} }, - key!(KeyCode::Char('<')) => match focused { + key!(Char('<')) => match focused { Focused::Bpm => Clock(SetBpm(state.bpm().get() - 0.001)), Focused::Quant => Clock(SetQuant(state.prev_quant())), Focused::Sync => Clock(SetSync(state.prev_sync())), @@ -47,8 +50,11 @@ impl InputToCommand for TransportCommand { } } -impl InputToCommand for SequencerCommand { - fn input_to_command (state: &SequencerTui, input: &TuiInput) -> Option { +impl InputToCommand for SequencerCommand +where + T: SequencerControl + TransportControl + PhrasesControl + PhraseControl + HasFocus +{ + fn input_to_command (state: &T, input: &TuiInput) -> Option { use FocusCommand::*; use SequencerCommand::*; match input.event() { @@ -84,7 +90,10 @@ impl InputToCommand for SequencerCommand { } } -impl InputToCommand for ArrangerCommand { +impl InputToCommand for ArrangerCommand +where + T: ArrangerControl + TransportControl + PhrasesControl + PhraseControl + HasFocus +{ fn input_to_command (state: &T, input: &TuiInput) -> Option { use FocusCommand::*; use ArrangerCommand::*; @@ -242,28 +251,27 @@ impl InputToCommand for ArrangerCommand { impl InputToCommand for PhrasesCommand { fn input_to_command (state: &T, input: &TuiInput) -> Option { - use PhrasesCommand as Cmd; use PhrasePoolCommand as Edit; use PhraseRenameCommand as Rename; use PhraseLengthCommand as Length; match input.event() { - key!(KeyCode::Up) => Some(Cmd::Select(0)), - key!(KeyCode::Down) => Some(Cmd::Select(0)), - key!(KeyCode::Char(',')) => Some(Cmd::Edit(Edit::Swap(0, 0))), - key!(KeyCode::Char('.')) => Some(Cmd::Edit(Edit::Swap(0, 0))), - key!(KeyCode::Delete) => Some(Cmd::Edit(Edit::Delete(0))), - key!(KeyCode::Char('a')) => Some(Cmd::Edit(Edit::Add(0))), - key!(KeyCode::Char('i')) => Some(Cmd::Edit(Edit::Add(0))), - key!(KeyCode::Char('d')) => Some(Cmd::Edit(Edit::Duplicate(0))), - key!(KeyCode::Char('c')) => Some(Cmd::Edit(Edit::RandomColor(0))), - key!(KeyCode::Char('n')) => Some(Cmd::Rename(Rename::Begin)), - key!(KeyCode::Char('t')) => Some(Cmd::Length(Length::Begin)), + key!(KeyCode::Up) => Some(Self::Select(0)), + key!(KeyCode::Down) => Some(Self::Select(0)), + key!(KeyCode::Char(',')) => Some(Self::Edit(Edit::Swap(0, 0))), + key!(KeyCode::Char('.')) => Some(Self::Edit(Edit::Swap(0, 0))), + key!(KeyCode::Delete) => Some(Self::Edit(Edit::Delete(0))), + key!(KeyCode::Char('a')) => Some(Self::Edit(Edit::Add(0))), + key!(KeyCode::Char('i')) => Some(Self::Edit(Edit::Add(0))), + key!(KeyCode::Char('d')) => Some(Self::Edit(Edit::Duplicate(0))), + key!(KeyCode::Char('c')) => Some(Self::Edit(Edit::RandomColor(0))), + key!(KeyCode::Char('n')) => Some(Self::Rename(Rename::Begin)), + key!(KeyCode::Char('t')) => Some(Self::Length(Length::Begin)), _ => match state.phrases_mode() { Some(PhrasesMode::Rename(..)) => { - Rename::input_to_command(state, input).map(Cmd::Rename) + Rename::input_to_command(state, input).map(Self::Rename) }, Some(PhrasesMode::Length(..)) => { - Length::input_to_command(state, input).map(Cmd::Length) + Length::input_to_command(state, input).map(Self::Length) }, _ => None } @@ -279,7 +287,7 @@ impl InputToCommand for PhraseLengthCommand { key!(KeyCode::Down) => Self::Dec, key!(KeyCode::Right) => Self::Next, key!(KeyCode::Left) => Self::Prev, - key!(KeyCode::Enter) => Self::Set(length), + key!(KeyCode::Enter) => Self::Set(*length), key!(KeyCode::Esc) => Self::Cancel, _ => return None }) @@ -293,7 +301,7 @@ impl InputToCommand for PhraseRenameCommand { fn input_to_command (state: &T, from: &TuiInput) -> Option { if let Some(PhrasesMode::Rename(_, ref old_name)) = state.phrases_mode() { Some(match from.event() { - key!(KeyCode::Char(c)) => { + key!(KeyCode::Char(c)) => { let mut new_name = old_name.clone(); new_name.push(*c); Self::Set(new_name) @@ -303,8 +311,8 @@ impl InputToCommand for PhraseRenameCommand { new_name.pop(); Self::Set(new_name) }, - key!(KeyCode::Enter) => Self::Confirm, - key!(KeyCode::Esc) => Self::Cancel, + key!(KeyCode::Enter) => Self::Confirm, + key!(KeyCode::Esc) => Self::Cancel, _ => return None }) } else { @@ -330,19 +338,20 @@ impl InputToCommand for PhraseCommand { key!(KeyCode::Char('+')) => TimeZoomSet(0), key!(KeyCode::PageUp) => NoteScrollSet(0), key!(KeyCode::PageDown) => NoteScrollSet(0), - key!(KeyCode::Up) => match state.phrase_entered() { + + key!(KeyCode::Up) => match state.phrase_entered() { true => NoteCursorSet(0), false => NoteScrollSet(0), }, - key!(KeyCode::Down) => match state.phrase_entered() { + key!(KeyCode::Down) => match state.phrase_entered() { true => NoteCursorSet(0), false => NoteScrollSet(0), }, - key!(KeyCode::Left) => match state.phrase_entered() { + key!(KeyCode::Left) => match state.phrase_entered() { true => TimeCursorSet(0), false => TimeScrollSet(0), }, - key!(KeyCode::Right) => match state.phrase_entered() { + key!(KeyCode::Right) => match state.phrase_entered() { true => TimeCursorSet(0), false => TimeScrollSet(0), }, diff --git a/crates/tek_tui/src/tui_model.rs b/crates/tek_tui/src/tui_model.rs index 1beb0ef7..1f83754a 100644 --- a/crates/tek_tui/src/tui_model.rs +++ b/crates/tek_tui/src/tui_model.rs @@ -74,8 +74,8 @@ pub struct SequencerTui { pub(crate) cursor: (usize, usize), pub(crate) size: Measure, - /// Mode switch - pub(crate) phrases_mode: Option, + /// Mode switch for phrase pool + pub(crate) phrases_mode: Option, } /// Root view for standalone `tek_arranger` @@ -105,6 +105,8 @@ pub struct ArrangerTui { pub(crate) menu_bar: Option>, pub(crate) status_bar: Option, pub(crate) history: Vec, + /// Mode switch for phrase pool + pub(crate) phrases_mode: Option, } #[derive(Default, Debug, Clone)]