From 26d75340f681399656fac71a17b32ca29a1c438d Mon Sep 17 00:00:00 2001 From: unspeaker Date: Wed, 16 Oct 2024 11:14:13 +0300 Subject: [PATCH] enter phrase length set mode --- crates/tek_sequencer/src/sequencer.rs | 28 +++++++++++++++-------- crates/tek_sequencer/src/sequencer_cmd.rs | 13 +++++++++++ crates/tek_sequencer/src/sequencer_tui.rs | 19 ++++++++------- 3 files changed, 43 insertions(+), 17 deletions(-) diff --git a/crates/tek_sequencer/src/sequencer.rs b/crates/tek_sequencer/src/sequencer.rs index ffdcdc22..c8ac670b 100644 --- a/crates/tek_sequencer/src/sequencer.rs +++ b/crates/tek_sequencer/src/sequencer.rs @@ -34,7 +34,10 @@ pub struct PhrasePool { pub mode: Option, } /// Modes for phrase pool -pub enum PhrasePoolMode { Rename(usize, String) } +pub enum PhrasePoolMode { + Rename(usize, String), + Length(usize, usize, PhraseLengthFocus), +} /// A MIDI sequence. #[derive(Debug, Clone)] pub struct Phrase { @@ -188,8 +191,17 @@ impl PhrasePool { phrase.color = random_color(); } pub fn begin_rename (&mut self) { - let phrase = self.phrases[self.phrase].read().unwrap(); - self.mode = Some(PhrasePoolMode::Rename(self.phrase, phrase.name.clone())); + self.mode = Some(PhrasePoolMode::Rename( + self.phrase, + self.phrases[self.phrase].read().unwrap().name.clone() + )); + } + pub fn begin_length (&mut self) { + self.mode = Some(PhrasePoolMode::Length( + self.phrase, + self.phrases[self.phrase].read().unwrap().length, + PhraseLengthFocus::Bar + )); } pub fn move_up (&mut self) { if self.phrase > 1 { @@ -314,18 +326,16 @@ pub struct PhraseLength { pub ppq: usize, pub bpb: usize, pub pulses: usize, - pub focused: bool, - pub focus: PhraseLengthFocus + pub focus: Option, } impl PhraseLength { - fn new (pulses: usize) -> Self { + pub fn new (pulses: usize, focus: Option) -> Self { Self { _engine: Default::default(), ppq: PPQ, bpb: 4, pulses, - focused: false, - focus: PhraseLengthFocus::Bar + focus } } pub fn bars (&self) -> usize { @@ -344,7 +354,7 @@ impl PhraseLength { format!("{}", self.beats()) } pub fn ticks_string (&self) -> String { - format!("{}", self.ticks()) + format!("{:>02}", self.ticks()) } } #[derive(Copy,Clone)] diff --git a/crates/tek_sequencer/src/sequencer_cmd.rs b/crates/tek_sequencer/src/sequencer_cmd.rs index 6f137359..e8a19b4d 100644 --- a/crates/tek_sequencer/src/sequencer_cmd.rs +++ b/crates/tek_sequencer/src/sequencer_cmd.rs @@ -43,6 +43,18 @@ impl Handle for PhrasePool { _ => return Ok(None) } }, + Some(PhrasePoolMode::Length(phrase, length, focus)) => { + todo!("edit phrase length"); + let mut phrase = self.phrases[phrase].write().unwrap(); + match from.event() { + key!(KeyCode::Backspace) => { phrase.name.pop(); }, + key!(KeyCode::Char(c)) => { phrase.name.push(*c); }, + key!(Shift-KeyCode::Char(c)) => { phrase.name.push(*c); }, + //key!(KeyCode::Esc) => { phrase.name = old_name.clone(); self.mode = None; }, + key!(KeyCode::Enter) => { self.mode = None; }, + _ => return Ok(None) + } + }, None => match from.event() { key!(KeyCode::Up) => { self.select_prev() }, key!(KeyCode::Down) => { self.select_next() }, @@ -51,6 +63,7 @@ impl Handle for PhrasePool { key!(KeyCode::Char('d')) => { self.insert_dup() }, key!(KeyCode::Char('c')) => { self.randomize_color() }, key!(KeyCode::Char('n')) => { self.begin_rename() }, + key!(KeyCode::Char('t')) => { self.begin_length() }, key!(KeyCode::Char(',')) => { self.move_up() }, key!(KeyCode::Char('.')) => { self.move_down() }, _ => return Ok(None), diff --git a/crates/tek_sequencer/src/sequencer_tui.rs b/crates/tek_sequencer/src/sequencer_tui.rs index e95bf5cd..23b2b7bf 100644 --- a/crates/tek_sequencer/src/sequencer_tui.rs +++ b/crates/tek_sequencer/src/sequencer_tui.rs @@ -20,9 +20,12 @@ impl Content for PhrasePool { let ticks = length % PPQ; let beats = length % (4 * PPQ); let bars = length / (4 * PPQ); - let row1 = lay!( - format!(" {i}").align_w().fill_x(), - format!("{bars}.{beats}.{ticks:>02} ").align_e().fill_x(), + let row1 = lay!(format!(" {i}").align_w().fill_x(), + if let Some(PhrasePoolMode::Length(phrase, length, focus)) = self.mode { + PhraseLength::new(length, Some(focus)) + } else { + PhraseLength::new(length, None) + }.align_e().fill_x() ).fill_x(); let row2 = if let Some(PhrasePoolMode::Rename(phrase, _)) = self.mode { if self.focused && i == phrase { @@ -327,26 +330,26 @@ impl Content for PhraseLength { type Engine = Tui; fn content (&self) -> impl Widget { Layers::new(move|add|{ - match (self.focused, &self.focus) { - (false, _) => add(&row!( + match self.focus { + None => add(&row!( " ", self.bars_string(), ".", self.beats_string(), ".", self.ticks_string(), " " )), - (true, PhraseLengthFocus::Bar) => add(&row!( + Some(PhraseLengthFocus::Bar) => add(&row!( "[", self.bars_string(), "]", self.beats_string(), ".", self.ticks_string(), " " )), - (true, PhraseLengthFocus::Beat) => add(&row!( + Some(PhraseLengthFocus::Beat) => add(&row!( " ", self.bars_string(), "[", self.beats_string(), "]", self.ticks_string(), " " )), - (true, PhraseLengthFocus::Tick) => add(&row!( + Some(PhraseLengthFocus::Tick) => add(&row!( " ", self.bars_string(), ".", self.beats_string(), "[", self.ticks_string(),