From d5a37229b932f166c119bf80a4c96a8e7a1e3c19 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sun, 24 Nov 2024 00:11:57 +0100 Subject: [PATCH] reenable adding phrases with new command system --- crates/tek_api/src/api_phrase.rs | 16 ++- crates/tek_tui/src/tui_input.rs | 162 ++++++++++++++++++------------- 2 files changed, 107 insertions(+), 71 deletions(-) diff --git a/crates/tek_api/src/api_phrase.rs b/crates/tek_api/src/api_phrase.rs index e93eaa2c..eaf48c6f 100644 --- a/crates/tek_api/src/api_phrase.rs +++ b/crates/tek_api/src/api_phrase.rs @@ -7,7 +7,7 @@ pub trait HasPhrases { #[derive(Clone, Debug, PartialEq)] pub enum PhrasePoolCommand { - Add(usize), + Add(usize, Phrase), Delete(usize), Duplicate(usize), Swap(usize, usize), @@ -21,9 +21,16 @@ pub enum PhrasePoolCommand { impl Command for PhrasePoolCommand { fn execute (self, model: &mut T) -> Perhaps { match self { - Self::Add(index) => { - //Self::Append => { view.append_new(None, None) }, - //Self::Insert => { view.insert_new(None, None) }, + Self::Add(mut index, phrase) => { + let phrase = Arc::new(RwLock::new(phrase)); + let phrases = model.phrases_mut(); + if index >= phrases.len() { + index = phrases.len(); + phrases.push(phrase) + } else { + phrases.insert(index, phrase); + } + return Ok(Some(Self::Delete(index))) }, Self::Delete(index) => { //if view.phrase > 0 { @@ -125,6 +132,7 @@ impl Phrase { return false } } + impl Default for Phrase { fn default () -> Self { Self::new("(empty)", false, 0, None, Some(ItemColor::from(Color::Rgb(0, 0, 0)).into())) diff --git a/crates/tek_tui/src/tui_input.rs b/crates/tek_tui/src/tui_input.rs index f27f26e9..e88b6583 100644 --- a/crates/tek_tui/src/tui_input.rs +++ b/crates/tek_tui/src/tui_input.rs @@ -138,82 +138,110 @@ fn to_arranger_command (state: &ArrangerTui, input: &TuiInput) -> Option { - use ArrangerSelection as Select; - use ArrangerTrackCommand as Track; - use ArrangerClipCommand as Clip; - use ArrangerSceneCommand as Scene; - use KeyCode::{Char, Up, Down, Left, Right, Enter, Delete}; + use ArrangerSelection::*; + use KeyCode::Char; match input.event() { key!(Char('e')) => Cmd::EditPhrase(state.phrase_editing().clone()), - key!(Char('l')) => Cmd::Clip(Clip::SetLoop(false)), + key!(Char('l')) => Cmd::Clip(ArrangerClipCommand::SetLoop(false)), key!(Char('+')) => Cmd::Zoom(0), // TODO key!(Char('=')) => Cmd::Zoom(0), // TODO key!(Char('_')) => Cmd::Zoom(0), // TODO key!(Char('-')) => Cmd::Zoom(0), // TODO key!(Char('`')) => { todo!("toggle state mode") }, - key!(Ctrl-Char('a')) => Cmd::Scene(Scene::Add), - key!(Ctrl-Char('t')) => Cmd::Track(Track::Add), + key!(Ctrl-Char('a')) => Cmd::Scene(ArrangerSceneCommand::Add), + key!(Ctrl-Char('t')) => Cmd::Track(ArrangerTrackCommand::Add), _ => match state.selected() { - Select::Mix => match input.event() { - key!(Down) => Cmd::Select(Select::Scene(0)), - key!(Right) => Cmd::Select(Select::Track(0)), - key!(Char(',')) => Cmd::Zoom(0), - key!(Char('.')) => Cmd::Zoom(0), - key!(Char('<')) => Cmd::Zoom(0), - key!(Char('>')) => Cmd::Zoom(0), - key!(Delete) => Cmd::Clear, - key!(Char('c')) => Cmd::Color(ItemColor::random()), - _ => return None - }, - Select::Track(t) => match input.event() { - key!(Down) => Cmd::Select(Select::Clip(t, 0)), - key!(Left) => Cmd::Select(if t > 0 { Select::Track(t - 1) } else { Select::Mix }), - key!(Right) => Cmd::Select(Select::Track(t + 1)), - key!(Char(',')) => Cmd::Track(Track::Swap(t, t - 1)), - key!(Char('.')) => Cmd::Track(Track::Swap(t, t + 1)), - key!(Char('<')) => Cmd::Track(Track::Swap(t, t - 1)), - key!(Char('>')) => Cmd::Track(Track::Swap(t, t + 1)), - key!(Delete) => Cmd::Track(Track::Delete(t)), - //key!(Char('c')) => Cmd::Track(Track::Color(t, ItemColor::random())), - _ => return None - }, - Select::Scene(s) => match input.event() { - key!(Up) => Cmd::Select(if s > 0 { Select::Scene(s - 1) } else { Select::Mix }), - key!(Down) => Cmd::Select(Select::Scene(s + 1)), - key!(Right) => Cmd::Select(Select::Clip(0, s)), - key!(Char(',')) => Cmd::Scene(Scene::Swap(s, s - 1)), - key!(Char('.')) => Cmd::Scene(Scene::Swap(s, s + 1)), - key!(Char('<')) => Cmd::Scene(Scene::Swap(s, s - 1)), - key!(Char('>')) => Cmd::Scene(Scene::Swap(s, s + 1)), - key!(Enter) => Cmd::Scene(Scene::Play(s)), - key!(Delete) => Cmd::Scene(Scene::Delete(s)), - //key!(Char('c')) => Cmd::Track(Scene::Color(s, ItemColor::random())), - _ => return None - }, - Select::Clip(t, s) => match input.event() { - key!(Up) => Cmd::Select(if s > 0 { Select::Clip(t, s - 1) } else { Select::Track(t) }), - key!(Down) => Cmd::Select(Select::Clip(t, s + 1)), - key!(Left) => Cmd::Select(if t > 0 { Select::Clip(t - 1, s) } else { Select::Scene(s) }), - key!(Right) => Cmd::Select(Select::Clip(t + 1, s)), - key!(Char(',')) => Cmd::Clip(Clip::Set(t, s, None)), - key!(Char('.')) => Cmd::Clip(Clip::Set(t, s, None)), - key!(Char('<')) => Cmd::Clip(Clip::Set(t, s, None)), - key!(Char('>')) => Cmd::Clip(Clip::Set(t, s, None)), - key!(Delete) => Cmd::Clip(Clip::Set(t, s, None)), - //key!(Char('c')) => Cmd::Clip(Clip::Color(t, s, ItemColor::random())), - //key!(Char('g')) => Cmd::Clip(Clip(Clip::Get(t, s))), - //key!(Char('s')) => Cmd::Clip(Clip(Clip::Set(t, s))), - _ => return None - }, + Mix => to_arranger_mix_command(input)?, + Track(t) => to_arranger_track_command(input, t)?, + Scene(s) => to_arranger_scene_command(input, s)?, + Clip(t, s) => to_arranger_clip_command(input, t, s)?, } } } }) } +fn to_arranger_mix_command (input: &TuiInput) -> Option { + use KeyCode::{Char, Down, Right, Delete}; + use ArrangerCommand as Cmd; + use ArrangerSelection as Select; + Some(match input.event() { + key!(Down) => Cmd::Select(Select::Scene(0)), + key!(Right) => Cmd::Select(Select::Track(0)), + key!(Char(',')) => Cmd::Zoom(0), + key!(Char('.')) => Cmd::Zoom(0), + key!(Char('<')) => Cmd::Zoom(0), + key!(Char('>')) => Cmd::Zoom(0), + key!(Delete) => Cmd::Clear, + key!(Char('c')) => Cmd::Color(ItemColor::random()), + _ => return None + }) +} + +fn to_arranger_track_command (input: &TuiInput, t: usize) -> Option { + use KeyCode::{Char, Down, Left, Right, Delete}; + use ArrangerCommand as Cmd; + use ArrangerSelection as Select; + use ArrangerTrackCommand as Track; + Some(match input.event() { + key!(Down) => Cmd::Select(Select::Clip(t, 0)), + key!(Left) => Cmd::Select(if t > 0 { Select::Track(t - 1) } else { Select::Mix }), + key!(Right) => Cmd::Select(Select::Track(t + 1)), + key!(Char(',')) => Cmd::Track(Track::Swap(t, t - 1)), + key!(Char('.')) => Cmd::Track(Track::Swap(t, t + 1)), + key!(Char('<')) => Cmd::Track(Track::Swap(t, t - 1)), + key!(Char('>')) => Cmd::Track(Track::Swap(t, t + 1)), + key!(Delete) => Cmd::Track(Track::Delete(t)), + //key!(Char('c')) => Cmd::Track(Track::Color(t, ItemColor::random())), + _ => return None + }) +} + +fn to_arranger_scene_command (input: &TuiInput, s: usize) -> Option { + use KeyCode::{Char, Up, Down, Right, Enter, Delete}; + use ArrangerCommand as Cmd; + use ArrangerSelection as Select; + use ArrangerSceneCommand as Scene; + Some(match input.event() { + key!(Up) => Cmd::Select(if s > 0 { Select::Scene(s - 1) } else { Select::Mix }), + key!(Down) => Cmd::Select(Select::Scene(s + 1)), + key!(Right) => Cmd::Select(Select::Clip(0, s)), + key!(Char(',')) => Cmd::Scene(Scene::Swap(s, s - 1)), + key!(Char('.')) => Cmd::Scene(Scene::Swap(s, s + 1)), + key!(Char('<')) => Cmd::Scene(Scene::Swap(s, s - 1)), + key!(Char('>')) => Cmd::Scene(Scene::Swap(s, s + 1)), + key!(Enter) => Cmd::Scene(Scene::Play(s)), + key!(Delete) => Cmd::Scene(Scene::Delete(s)), + //key!(Char('c')) => Cmd::Track(Scene::Color(s, ItemColor::random())), + _ => return None + }) +} + +fn to_arranger_clip_command (input: &TuiInput, t: usize, s: usize) -> Option { + use KeyCode::{Char, Up, Down, Left, Right, Delete}; + use ArrangerCommand as Cmd; + use ArrangerSelection as Select; + use ArrangerClipCommand as Clip; + Some(match input.event() { + key!(Up) => Cmd::Select(if s > 0 { Select::Clip(t, s - 1) } else { Select::Track(t) }), + key!(Down) => Cmd::Select(Select::Clip(t, s + 1)), + key!(Left) => Cmd::Select(if t > 0 { Select::Clip(t - 1, s) } else { Select::Scene(s) }), + key!(Right) => Cmd::Select(Select::Clip(t + 1, s)), + key!(Char(',')) => Cmd::Clip(Clip::Set(t, s, None)), + key!(Char('.')) => Cmd::Clip(Clip::Set(t, s, None)), + key!(Char('<')) => Cmd::Clip(Clip::Set(t, s, None)), + key!(Char('>')) => Cmd::Clip(Clip::Set(t, s, None)), + key!(Delete) => Cmd::Clip(Clip::Set(t, s, None)), + //key!(Char('c')) => Cmd::Clip(Clip::Color(t, s, ItemColor::random())), + //key!(Char('g')) => Cmd::Clip(Clip(Clip::Get(t, s))), + //key!(Char('s')) => Cmd::Clip(Clip(Clip::Set(t, s))), + _ => return None + }) +} + impl InputToCommand for PhrasesCommand { fn input_to_command (state: &T, input: &TuiInput) -> Option { - use PhrasePoolCommand as Phrase; + use PhrasePoolCommand as Pool; use PhraseRenameCommand as Rename; use PhraseLengthCommand as Length; use KeyCode::{Up, Down, Delete, Char}; @@ -224,26 +252,26 @@ impl InputToCommand for PhrasesCommand { key!(Down) => Self::Select(0), key!(Char(',')) => if index > 1 { state.set_phrase_index(state.phrase_index().saturating_sub(1)); - Self::Phrase(Phrase::Swap(index - 1, index)) + Self::Phrase(Pool::Swap(index - 1, index)) } else { return None }, key!(Char('.')) => if index < count.saturating_sub(1) { state.set_phrase_index(state.phrase_index() + 1); - Self::Phrase(Phrase::Swap(index + 1, index)) + Self::Phrase(Pool::Swap(index + 1, index)) } else { return None }, key!(Delete) => if index > 0 { state.set_phrase_index(index.min(count.saturating_sub(1))); - Self::Phrase(Phrase::Delete(index)) + Self::Phrase(Pool::Delete(index)) } else { return None }, - key!(Char('a')) => Self::Phrase(Phrase::Add(count)), - key!(Char('i')) => Self::Phrase(Phrase::Add(index + 1)), - key!(Char('d')) => Self::Phrase(Phrase::Duplicate(index)), - key!(Char('c')) => Self::Phrase(Phrase::Color(index, ItemColor::random())), + key!(Char('a')) => Self::Phrase(Pool::Add(count, Phrase::default())), + key!(Char('i')) => Self::Phrase(Pool::Add(index + 1, Phrase::default())), + key!(Char('d')) => Self::Phrase(Pool::Duplicate(index)), + key!(Char('c')) => Self::Phrase(Pool::Color(index, ItemColor::random())), key!(Char('n')) => Self::Rename(Rename::Begin), key!(Char('t')) => Self::Length(Length::Begin), _ => match state.phrases_mode() {