cmdsys: separate match_key_static

This commit is contained in:
🪞👃🪞 2024-11-07 01:18:53 +01:00
parent 1f375219db
commit a4925082ca
2 changed files with 66 additions and 30 deletions

View file

@ -1,5 +1,9 @@
use crate::*;
pub trait Command<T>: Sized {
fn run (&self, state: &mut T) -> Perhaps<Self>;
}
pub const fn key (code: KeyCode) -> KeyEvent {
KeyEvent {
code,
@ -21,13 +25,15 @@ pub const fn shift (key: KeyEvent) -> KeyEvent {
KeyEvent { modifiers: key.modifiers.union(KeyModifiers::SHIFT), ..key }
}
pub trait Command<T>: Sized {
fn run (&self, state: &mut T) -> Perhaps<Self>;
}
pub trait HandleKey<C: Command<Self> + 'static>: Sized {
const HANDLE_KEY_MAP: &'static [(KeyEvent, C)]; // FIXME: needs to be method
fn match_key (key: &KeyEvent) -> Option<&'static C> {
const HANDLE_KEY_MAP: &'static [(KeyEvent, C)] = &[]; // FIXME: needs to be method
#[inline] fn match_input (from: &TuiInput) -> Option<&'static 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<&'static C> {
for (binding, command) in Self::HANDLE_KEY_MAP.iter() {
if key == binding {
return Some(command);
@ -35,8 +41,11 @@ pub trait HandleKey<C: Command<Self> + 'static>: Sized {
}
None
}
fn handle_key (&mut self, key: &KeyEvent) -> Perhaps<C> {
if let Some(command) = Self::match_key(key) {
#[inline] fn match_key (&self, key: &KeyEvent) -> Option<&'static C> {
Self::match_key_static(key)
}
#[inline] fn handle_key (&mut self, key: &KeyEvent) -> Perhaps<C> {
if let Some(command) = self.match_key(key) {
command.run(self)
} else {
Ok(None)

View file

@ -155,7 +155,7 @@ impl Handle<Tui> for PhrasePool<Tui> {
if let TuiEvent::Input(crossterm::event::Event::Key(key)) = from.event() {
match self.mode {
Some(PhrasePoolMode::Rename(..)) => {
if HandleKey::<PhraseNameCommand>::match_key(key).is_some() {
if HandleKey::<PhraseNameCommand>::match_key_static(key).is_some() {
let _undo = HandleKey::<PhraseNameCommand>::handle_key(self, key)?;
return Ok(Some(true))
} else if let KeyEvent { code: KeyCode::Char(c), .. } = key {
@ -332,14 +332,26 @@ impl<E: Engine> Command<PhrasePool<E>> for PhraseLengthCommand {
focus.next()
},
Self::Increment => match focus {
PhraseLengthFocus::Bar => { *length += 4 * PPQ },
PhraseLengthFocus::Beat => { *length += PPQ },
PhraseLengthFocus::Tick => { *length += 1 },
PhraseLengthFocus::Bar => {
*length += 4 * PPQ
},
PhraseLengthFocus::Beat => {
*length += PPQ
},
PhraseLengthFocus::Tick => {
*length += 1
},
},
Self::Decrement => match focus {
PhraseLengthFocus::Bar => { *length = length.saturating_sub(4 * PPQ) },
PhraseLengthFocus::Beat => { *length = length.saturating_sub(PPQ) },
PhraseLengthFocus::Tick => { *length = length.saturating_sub(1) },
PhraseLengthFocus::Bar => {
*length = length.saturating_sub(4 * PPQ)
},
PhraseLengthFocus::Beat => {
*length = length.saturating_sub(PPQ)
},
PhraseLengthFocus::Tick => {
*length = length.saturating_sub(1)
},
},
Self::Cancel => {
state.mode = None;
@ -366,17 +378,33 @@ impl<E: Engine> Command<PhrasePool<E>> for PhraseLengthCommand {
impl<E: Engine> Command<PhraseEditor<E>> for PhraseEditorCommand {
fn run (&self, state: &mut PhraseEditor<E>) -> Perhaps<Self> {
match self {
Self::ToggleDirection => { state.mode = !state.mode; },
Self::EnterEditMode => { state.entered = true; },
Self::ExitEditMode => { state.entered = false; },
Self::TimeZoomOut => { state.time_zoom_out() },
Self::TimeZoomIn => { state.time_zoom_in() },
Self::NoteLengthDecrement => { state.note_length_dec() },
Self::NoteLengthIncrement => { state.note_length_inc() },
Self::NotePageUp => { state.note_page_up() },
Self::NotePageDown => { state.note_page_down() },
Self::ToggleDirection => {
state.mode = !state.mode;
},
Self::EnterEditMode => {
state.entered = true;
},
Self::ExitEditMode => {
state.entered = false;
},
Self::TimeZoomOut => {
state.time_zoom_out()
},
Self::TimeZoomIn => {
state.time_zoom_in()
},
Self::NoteLengthDecrement => {
state.note_length_dec()
},
Self::NoteLengthIncrement => {
state.note_length_inc()
},
Self::NotePageUp => {
state.note_page_up()
},
Self::NotePageDown => {
state.note_page_down()
},
Self::NoteAppend => if state.entered {
state.put();
state.time_cursor_advance();
@ -384,7 +412,6 @@ impl<E: Engine> Command<PhraseEditor<E>> for PhraseEditorCommand {
Self::NoteSet => if state.entered {
state.put();
},
Self::GoUp => match state.entered {
true => state.note_cursor_inc(),
false => state.note_scroll_inc(),