tek/crates/tek/src/tui/ctrl_file_browser.rs
2024-12-09 17:31:31 +01:00

116 lines
4.2 KiB
Rust

use crate::*;
/// Commands supported by [FileBrowser]
#[derive(Debug, Clone, PartialEq)]
pub enum FileBrowserCommand {
Begin,
Cancel,
Confirm,
Select(usize),
Chdir(PathBuf),
Filter(String),
}
impl Command<PhraseListModel> for FileBrowserCommand {
fn execute (self, state: &mut PhraseListModel) -> Perhaps<Self> {
use FileBrowserCommand::*;
use PhrasesMode::{Import, Export};
let mode = state.phrases_mode_mut();
match mode {
Some(Import(index, ref mut browser)) => match self {
Cancel => {
*mode = None;
},
Chdir(cwd) => {
*mode = Some(Import(*index, FileBrowser::new(Some(cwd))?));
},
Select(index) => {
browser.index = index;
},
Confirm => {
if browser.is_file() {
let index = *index;
let path = browser.path();
*mode = None;
PhrasePoolCommand::Import(index, path).execute(state)?;
} else if browser.is_dir() {
*mode = Some(Import(*index, browser.chdir()?));
}
},
_ => todo!(),
_ => unreachable!()
},
Some(PhrasesMode::Export(index, ref mut browser)) => match self {
Cancel => {
*mode = None;
},
Chdir(cwd) => {
*mode = Some(PhrasesMode::Export(*index, FileBrowser::new(Some(cwd))?));
},
Select(index) => {
browser.index = index;
},
_ => unreachable!()
},
_ => unreachable!(),
};
Ok(None)
}
}
impl InputToCommand<Tui, PhraseListModel> for FileBrowserCommand {
fn input_to_command (state: &PhraseListModel, from: &TuiInput) -> Option<Self> {
use KeyCode::{Up, Down, Right, Left, Enter, Esc, Char, Backspace};
use FileBrowserCommand::*;
if let Some(PhrasesMode::Import(index, browser)) = state.phrases_mode() {
Some(match from.event() {
key!(Up) => Select(
browser.index.overflowing_sub(1).0.min(browser.len().saturating_sub(1))
),
key!(Down) => Select(
browser.index.saturating_add(1) % browser.len()
),
key!(Right) => Chdir(browser.cwd.clone()),
key!(Left) => Chdir(browser.cwd.clone()),
key!(Enter) => Confirm,
key!(Char(c)) => { todo!() },
key!(Backspace) => { todo!() },
key!(Esc) => Self::Cancel,
_ => return None
})
} else if let Some(PhrasesMode::Export(index, browser)) = state.phrases_mode() {
Some(match from.event() {
key!(Up) => Select(browser.index.overflowing_sub(1).0.min(browser.len())),
key!(Down) => Select(browser.index.saturating_add(1) % browser.len()),
key!(Right) => Chdir(browser.cwd.clone()),
key!(Left) => Chdir(browser.cwd.clone()),
key!(Enter) => Confirm,
key!(Char(c)) => { todo!() },
key!(Backspace) => { todo!() },
key!(Esc) => Self::Cancel,
_ => return None
})
} else {
unreachable!()
}
}
}
impl InputToCommand<Tui, PhraseListModel> for PhraseLengthCommand {
fn input_to_command (state: &PhraseListModel, from: &TuiInput) -> Option<Self> {
use KeyCode::{Up, Down, Right, Left, Enter, Esc};
if let Some(PhrasesMode::Length(_, length, _)) = state.phrases_mode() {
Some(match from.event() {
key!(Up) => Self::Inc,
key!(Down) => Self::Dec,
key!(Right) => Self::Next,
key!(Left) => Self::Prev,
key!(Enter) => Self::Set(*length),
key!(Esc) => Self::Cancel,
_ => return None
})
} else {
unreachable!()
}
}
}