cmdsys: HandleKey -> MatchInput

This commit is contained in:
🪞👃🪞 2024-11-08 19:10:24 +01:00
parent 1aaad23691
commit 2b163e9e27
7 changed files with 389 additions and 348 deletions

View file

@ -3,56 +3,18 @@ use crate::*;
pub trait Command<S>: Sized {
fn run (&self, state: &mut S) -> Perhaps<Self>;
}
pub trait HandleKey<C: Command<Self> + Clone + 'static>: Sized {
const HANDLE_KEY_MAP: &'static [(KeyEvent, C)] = &[]; // FIXME: needs to be method
#[inline] fn match_input_static (from: &TuiInput) -> Option<C> {
if let TuiEvent::Input(crossterm::event::Event::Key(key)) = from.event() {
return Self::match_key_static(&key)
}
None
}
#[inline] fn match_key_static (key: &KeyEvent) -> Option<C> {
for (binding, command) in Self::HANDLE_KEY_MAP.iter() {
if key == binding {
return Some(command.clone());
}
}
None
}
#[inline] fn match_key (&self, key: &KeyEvent) -> Option<C> {
Self::match_key_static(key)
}
#[inline] fn match_input (&self, input: &TuiInput) -> Option<C> {
Self::match_input_static(input)
}
#[inline] fn handle_input (&mut self, input: &TuiInput) -> Perhaps<C> {
if let Some(command) = self.match_input(input) {
command.run(self)
} else {
Ok(None)
}
}
#[inline] fn handle_key (&mut self, key: &KeyEvent) -> Perhaps<C> {
if let Some(command) = self.match_key(key) {
command.run(self)
} else {
Ok(None)
}
}
pub trait MatchInput<E: Engine, S>: Sized {
fn match_input (state: &S, input: &E::Input) -> Option<Self>;
}
pub struct Menu<E: Engine, S: Handle<E>, C: Command<S>> {
pub items: Vec<MenuItem<E, S, C>>,
pub index: usize,
}
impl<E: Engine, S: Handle<E>, C: Command<S>> Menu<E, S, C> {
pub const fn item (command: C, name: &'static str, key: &'static str) -> MenuItem<E, S, C> {
MenuItem::Command(command, name, key)
}
}
pub enum MenuItem<E: Engine, S: Handle<E>, C: Command<S>> {
/// Unused.
__(PhantomData<E>, PhantomData<S>),
@ -61,3 +23,11 @@ pub enum MenuItem<E: Engine, S: Handle<E>, C: Command<S>> {
/// A menu item with command, description and hotkey.
Command(C, &'static str, &'static str)
}
impl<E: Engine, S: Handle<E>, C: Command<S>> MenuItem<E, S, C> {
pub fn sep () -> Self {
Self::Separator
}
pub fn cmd (command: C, text: &'static str, hotkey: &'static str) -> Self {
Self::Command(command, text, hotkey)
}
}