From b3ae4ad3db93c70fe350f9eb9acb745ea378a1c3 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Wed, 21 Aug 2024 22:07:37 +0300 Subject: [PATCH] arranger: text input in rename modal --- crates/tek_sequencer/src/arranger_main.rs | 17 +++++-- crates/tek_sequencer/src/arranger_modal.rs | 58 +++++++++++++++------- 2 files changed, 55 insertions(+), 20 deletions(-) diff --git a/crates/tek_sequencer/src/arranger_main.rs b/crates/tek_sequencer/src/arranger_main.rs index 22eda53c..50a86ed9 100644 --- a/crates/tek_sequencer/src/arranger_main.rs +++ b/crates/tek_sequencer/src/arranger_main.rs @@ -43,10 +43,15 @@ impl ArrangerStandalone { app.arranger.name = name.clone(); } for _ in 0..args.tracks { - app.arranger.track_add(None)?; + let track = app.arranger.track_add(None)?; + for _ in 0..args.scenes { + track.phrases.push( + Arc::new(RwLock::new(Phrase::new("", 96 * 4, None))) + ); + } } for _ in 0..args.scenes { - app.arranger.scene_add(None)?; + let scene = app.arranger.scene_add(None)?; } Ok(app) } @@ -65,7 +70,13 @@ render!(ArrangerStandalone |self, buf, area| { } else { layout = layout.add_ref(&self.arranger) } - layout.render(buf, area) + let result = layout.render(buf, area)?; + if let Some(ref modal) = self.arranger.modal { + fill_bg(buf, area, Nord::bg_lo(false, false)); + fill_fg(buf, area, Nord::bg_hi(false, false)); + modal.render(buf, area)?; + } + Ok(result) }); handle!(ArrangerStandalone |self, e| { diff --git a/crates/tek_sequencer/src/arranger_modal.rs b/crates/tek_sequencer/src/arranger_modal.rs index fce11b5d..8aa60276 100644 --- a/crates/tek_sequencer/src/arranger_modal.rs +++ b/crates/tek_sequencer/src/arranger_modal.rs @@ -1,11 +1,21 @@ use crate::*; /// Appears on first run (i.e. if state dir is missing). -pub struct ArrangerRenameModal(bool, ArrangerFocus, String); +pub struct ArrangerRenameModal { + done: bool, + target: ArrangerFocus, + value: String, + cursor: usize +} impl ArrangerRenameModal { - pub fn new (focus: ArrangerFocus, name: String) -> Self { - Self(false, focus, name) + pub fn new (target: ArrangerFocus, value: String) -> Self { + Self { + done: false, + target, + value: value.to_string(), + cursor: value.len() + } } } @@ -19,29 +29,43 @@ render!(ArrangerRenameModal |self, buf, area| { }; fill_bg(buf, bg_area, Nord::BG0); Lozenge(Style::default().bold().white().dim()).draw(buf, bg_area)?; - let label = match self.1 { + let label = match self.target { ArrangerFocus::Mix => "Rename project:", ArrangerFocus::Track(_) => "Rename track:", ArrangerFocus::Scene(_) => "Rename scene:", ArrangerFocus::Clip(_, _) => "Rename clip:", }; - label.blit( - buf, area.x + 3, y, Some(Style::default().not_bold().white().not_dim()) - )?; - self.2.blit( - buf, area.x + 3 + label.len() as u16 + 1, y, Some(Style::default().bold().white().not_dim()) - )?; + let style = Some(Style::default().not_bold().white().not_dim()); + label.blit(buf, area.x + 3, y, style)?; + let style = Some(Style::default().bold().white().not_dim()); + self.value.blit(buf, area.x + 3 + label.len() as u16 + 1, y, style)?; + let style = Some(Style::default().bold().white().not_dim().reversed()); + "▂".blit(buf, area.x + 3 + label.len() as u16 + 1 + self.cursor as u16, y, style)?; Ok(area) }); handle!(ArrangerRenameModal |self, e| { match e { AppEvent::Input(Event::Key(k)) => { - if k.code == KeyCode::Esc { - self.exit(); - } else { - todo!(); - }; + match k.code { + KeyCode::Esc => { + self.exit(); + }, + KeyCode::Enter => { + todo!(); + }, + KeyCode::Left => { + self.cursor = self.cursor.saturating_sub(1); + }, + KeyCode::Right => { + self.cursor = self.value.len().min(self.cursor + 1) + }, + KeyCode::Char(c) => { + self.value.insert(self.cursor, c); + self.cursor = self.value.len().min(self.cursor + 1) + }, + _ => {} + } Ok(true) }, _ => Ok(false), @@ -50,9 +74,9 @@ handle!(ArrangerRenameModal |self, e| { impl Exit for ArrangerRenameModal { fn exited (&self) -> bool { - self.0 + self.done } fn exit (&mut self) { - self.0 = true + self.done = true } }