mirror of
https://codeberg.org/unspeaker/perch.git
synced 2025-12-06 09:36:42 +01:00
factor input handling into modes
This commit is contained in:
parent
648c37e9d4
commit
48f651fc0f
5 changed files with 115 additions and 74 deletions
93
src/keys.rs
93
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<TuiIn> for Taggart {
|
impl Handle<TuiIn> for Taggart {
|
||||||
fn handle (&mut self, input: &TuiIn) -> Perhaps<bool> {
|
fn handle (&mut self, input: &TuiIn) -> Perhaps<bool> {
|
||||||
let x_min = self.offset;
|
let min = self.offset;
|
||||||
let x_max = self.offset + self.display.h().saturating_sub(1);
|
let max = self.offset + self.display.h().saturating_sub(1);
|
||||||
let event = &*input.event();
|
let event = &*input.event();
|
||||||
match &self.mode {
|
match &self.mode {
|
||||||
Some(Mode::Edit { .. }) => match event {
|
Some(Mode::Edit { .. }) => self.mode_edit(event),
|
||||||
press!(Char(c)) => self.edit_insert(*c),
|
Some(Mode::Save { .. }) => self.mode_save(event),
|
||||||
press!(Shift-Char(c)) => self.edit_insert(c.to_uppercase().next().unwrap()),
|
Some(Mode::Quit { .. }) => self.mode_quit(event),
|
||||||
press!(Backspace) => self.edit_backspace(),
|
|
||||||
press!(Delete) => self.edit_delete(),
|
|
||||||
press!(Enter) => self.edit_confirm(),
|
|
||||||
press!(Esc) => self.edit_cancel(),
|
|
||||||
_ => {}
|
|
||||||
},
|
|
||||||
None => match 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!(Up) => { self.cursor = self.cursor.saturating_sub(1); },
|
||||||
press!(Down) => { self.cursor = self.cursor + 1; },
|
press!(Down) => { self.cursor = self.cursor + 1; },
|
||||||
press!(PageUp) => { self.cursor = self.cursor.saturating_sub(PAGE_SIZE); },
|
press!(PageUp) => { self.cursor = self.cursor.saturating_sub(PAGE_SIZE); },
|
||||||
press!(PageDown) => { self.cursor += PAGE_SIZE; },
|
press!(PageDown) => { self.cursor += PAGE_SIZE; },
|
||||||
press!(Left) => { self.column = self.column.saturating_sub(1); },
|
press!(Left) => { self.column = self.column.saturating_sub(1); },
|
||||||
press!(Right) => { self.column = self.column + 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(' ')) => { 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 += 1; }
|
||||||
press!(Char('[')) => { self.columns.0[self.column].width =
|
press!(Char('[')) => { self.columns.0[self.column].width =
|
||||||
|
|
@ -52,11 +51,18 @@ impl Handle<TuiIn> for Taggart {
|
||||||
}
|
}
|
||||||
_ => todo!("{:?}", self.mode)
|
_ => 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;
|
self.offset = self.cursor;
|
||||||
}
|
}
|
||||||
if self.cursor > x_max {
|
if self.cursor > max {
|
||||||
self.offset += self.cursor - x_max;
|
self.offset += self.cursor - max;
|
||||||
}
|
}
|
||||||
if self.offset > self.entries.len().saturating_sub(self.display.h()) {
|
if self.offset > self.entries.len().saturating_sub(self.display.h()) {
|
||||||
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<TuiIn> for Taggart {
|
||||||
if self.column + 1 > self.columns.0.len() {
|
if self.column + 1 > self.columns.0.len() {
|
||||||
self.column = self.columns.0.len().saturating_sub(1)
|
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!()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
66
src/keys/edit.rs
Normal file
66
src/keys/edit.rs
Normal file
|
|
@ -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!()
|
||||||
|
}
|
||||||
|
}
|
||||||
14
src/keys/quit.rs
Normal file
14
src/keys/quit.rs
Normal file
|
|
@ -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 })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/keys/save.rs
Normal file
10
src/keys/save.rs
Normal file
|
|
@ -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 })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -25,11 +25,11 @@ pub enum Mode {
|
||||||
value: Arc<str>,
|
value: Arc<str>,
|
||||||
index: usize,
|
index: usize,
|
||||||
},
|
},
|
||||||
Apply {
|
Save {
|
||||||
value: bool,
|
value: bool,
|
||||||
},
|
},
|
||||||
Unsaved {
|
Quit {
|
||||||
value: u8
|
value: bool,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue