From 48f651fc0f3e99b40535cccaee7b3d6bbe169cd3 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Thu, 3 Apr 2025 23:29:35 +0300 Subject: [PATCH] factor input handling into modes --- src/keys.rs | 93 ++++++++++++------------------------------------ src/keys/edit.rs | 66 ++++++++++++++++++++++++++++++++++ src/keys/quit.rs | 14 ++++++++ src/keys/save.rs | 10 ++++++ src/model.rs | 6 ++-- 5 files changed, 115 insertions(+), 74 deletions(-) create mode 100644 src/keys/edit.rs create mode 100644 src/keys/quit.rs create mode 100644 src/keys/save.rs diff --git a/src/keys.rs b/src/keys.rs index 1acca39..4d0349b 100644 --- a/src/keys.rs +++ b/src/keys.rs @@ -20,30 +20,29 @@ macro_rules! press { }; } +mod edit; pub use self::edit::*; +mod save; pub use self::save::*; +mod quit; pub use self::quit::*; + impl Handle for Taggart { fn handle (&mut self, input: &TuiIn) -> Perhaps { - let x_min = self.offset; - let x_max = self.offset + self.display.h().saturating_sub(1); + let min = self.offset; + let max = self.offset + self.display.h().saturating_sub(1); let event = &*input.event(); match &self.mode { - Some(Mode::Edit { .. }) => match event { - press!(Char(c)) => self.edit_insert(*c), - press!(Shift-Char(c)) => self.edit_insert(c.to_uppercase().next().unwrap()), - press!(Backspace) => self.edit_backspace(), - press!(Delete) => self.edit_delete(), - press!(Enter) => self.edit_confirm(), - press!(Esc) => self.edit_cancel(), - _ => {} - }, + Some(Mode::Edit { .. }) => self.mode_edit(event), + Some(Mode::Save { .. }) => self.mode_save(event), + Some(Mode::Quit { .. }) => self.mode_quit(event), None => match event { - press!(Char('q')) => { input.done() }, + press!(Char('q')) => { self.quit_begin(&input) }, + press!(Char('w')) => { self.save_begin() }, + press!(Enter) => { self.edit_begin() }, press!(Up) => { self.cursor = self.cursor.saturating_sub(1); }, press!(Down) => { self.cursor = self.cursor + 1; }, press!(PageUp) => { self.cursor = self.cursor.saturating_sub(PAGE_SIZE); }, press!(PageDown) => { self.cursor += PAGE_SIZE; }, press!(Left) => { self.column = self.column.saturating_sub(1); }, press!(Right) => { self.column = self.column + 1; }, - press!(Enter) => { self.edit_begin() }, press!(Char(' ')) => { open(self.entries[self.cursor].path.as_ref())?; } press!(Char(']')) => { self.columns.0[self.column].width += 1; } press!(Char('[')) => { self.columns.0[self.column].width = @@ -52,11 +51,18 @@ impl Handle for Taggart { } _ => todo!("{:?}", self.mode) } - if self.cursor < x_min { + self.clamp(min, max); + Ok(None) + } +} + +impl Taggart { + fn clamp (&mut self, min: usize, max: usize) { + if self.cursor < min { self.offset = self.cursor; } - if self.cursor > x_max { - self.offset += self.cursor - x_max; + if self.cursor > max { + self.offset += self.cursor - max; } if self.offset > self.entries.len().saturating_sub(self.display.h()) { self.offset = self.entries.len().saturating_sub(self.display.h()) @@ -67,60 +73,5 @@ impl Handle for Taggart { if self.column + 1 > self.columns.0.len() { self.column = self.columns.0.len().saturating_sub(1) } - Ok(None) - } -} - -impl Taggart { - pub fn edit_begin (&mut self) { - if let Some(column) = self.columns.0.get(self.column) - && column.setter.is_some() - { - let value = (column.getter)(&self.entries[self.cursor]); - let value = format!("{}", value.unwrap_or_default()); - self.mode = Some(Mode::Edit { - index: value.len(), - value: value.into(), - }); - } - } - pub fn edit_cancel (&mut self) { - self.mode = None; - } - pub fn edit_confirm (&mut self) { - let value = if let Some(Mode::Edit { value, .. }) = &self.mode { - Some(value.clone()) - } else { - None - }; - if let Some(value) = value - && let Some(column) = self.columns.0.get(self.column) - && let Some(setter) = &column.setter - && self.entries.get_mut(self.cursor).is_some() - { - setter(self, self.cursor, value.as_ref()); - self.mode = None; - } - } - pub fn edit_insert (&mut self, c: char) { - if let Some(Mode::Edit { value, index }) = &self.mode { - self.mode = Some(Mode::Edit { - index: *index + 1, - value: format!("{value}{c}").into() - }); - } - } - pub fn edit_backspace (&mut self) { - if let Some(Mode::Edit { value, index }) = &self.mode { - let mut chars = value.chars(); - chars.next_back(); - self.mode = Some(Mode::Edit { - index: index.saturating_sub(1), - value: chars.as_str().into() - }); - } - } - pub fn edit_delete (&mut self) { - todo!() } } diff --git a/src/keys/edit.rs b/src/keys/edit.rs new file mode 100644 index 0000000..17eaa2e --- /dev/null +++ b/src/keys/edit.rs @@ -0,0 +1,66 @@ +use crate::*; + +impl Taggart { + pub fn mode_edit (&mut self, event: &Event) { + match event { + press!(Char(c)) => self.edit_insert(*c), + press!(Shift-Char(c)) => self.edit_insert(c.to_uppercase().next().unwrap()), + press!(Backspace) => self.edit_backspace(), + press!(Delete) => self.edit_delete(), + press!(Enter) => self.edit_confirm(), + press!(Esc) => self.edit_cancel(), + _ => {} + } + } + pub fn edit_begin (&mut self) { + if let Some(column) = self.columns.0.get(self.column) + && column.setter.is_some() + { + let value = (column.getter)(&self.entries[self.cursor]); + let value = format!("{}", value.unwrap_or_default()); + self.mode = Some(Mode::Edit { + index: value.len(), + value: value.into(), + }); + } + } + pub fn edit_cancel (&mut self) { + self.mode = None; + } + pub fn edit_confirm (&mut self) { + let value = if let Some(Mode::Edit { value, .. }) = &self.mode { + Some(value.clone()) + } else { + None + }; + if let Some(value) = value + && let Some(column) = self.columns.0.get(self.column) + && let Some(setter) = &column.setter + && self.entries.get_mut(self.cursor).is_some() + { + setter(self, self.cursor, value.as_ref()); + self.mode = None; + } + } + pub fn edit_insert (&mut self, c: char) { + if let Some(Mode::Edit { value, index }) = &self.mode { + self.mode = Some(Mode::Edit { + index: *index + 1, + value: format!("{value}{c}").into() + }); + } + } + pub fn edit_backspace (&mut self) { + if let Some(Mode::Edit { value, index }) = &self.mode { + let mut chars = value.chars(); + chars.next_back(); + self.mode = Some(Mode::Edit { + index: index.saturating_sub(1), + value: chars.as_str().into() + }); + } + } + pub fn edit_delete (&mut self) { + todo!() + } +} diff --git a/src/keys/quit.rs b/src/keys/quit.rs new file mode 100644 index 0000000..17c802d --- /dev/null +++ b/src/keys/quit.rs @@ -0,0 +1,14 @@ +use crate::*; + +impl Taggart { + pub fn mode_quit (&mut self, event: &Event) { + todo!() + } + pub fn quit_begin (&mut self, input: &TuiIn) { + if self.tasks.len() == 0 { + input.done() + } else { + self.mode = Some(Mode::Quit { value: false }) + } + } +} diff --git a/src/keys/save.rs b/src/keys/save.rs new file mode 100644 index 0000000..e042159 --- /dev/null +++ b/src/keys/save.rs @@ -0,0 +1,10 @@ +use crate::*; + +impl Taggart { + pub fn mode_save (&mut self, event: &Event) { + todo!() + } + pub fn save_begin (&mut self) { + self.mode = Some(Mode::Save { value: false }) + } +} diff --git a/src/model.rs b/src/model.rs index 643ec76..1b115f6 100644 --- a/src/model.rs +++ b/src/model.rs @@ -25,11 +25,11 @@ pub enum Mode { value: Arc, index: usize, }, - Apply { + Save { value: bool, }, - Unsaved { - value: u8 + Quit { + value: bool, }, }