mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
wip: static KeyMap
This commit is contained in:
parent
49fe3322e1
commit
8df00dada6
2 changed files with 96 additions and 61 deletions
|
|
@ -30,51 +30,68 @@ pub enum PhraseCommand {
|
|||
ToggleDirection,
|
||||
}
|
||||
|
||||
impl InputToCommand<Tui, PhraseEditorModel> for PhraseCommand {
|
||||
fn input_to_command (state: &PhraseEditorModel, from: &TuiInput) -> Option<Self> {
|
||||
let length = ||state.phrase().as_ref().map(|p|p.read().unwrap().length).unwrap_or(1);
|
||||
|
||||
let note_lo = ||state.note_lo().get();
|
||||
let time_start = ||state.time_start().get();
|
||||
let time_zoom = ||state.time_zoom().get();
|
||||
let time_lock = ||state.time_lock().get();
|
||||
|
||||
let note_point = ||state.note_point();
|
||||
let time_point = ||state.time_point();
|
||||
let note_len = ||state.note_len();
|
||||
Some(match from.event() {
|
||||
key_pat!(Ctrl-Alt-Up) => SetNoteScroll(note_point() + 3),
|
||||
key_pat!(Ctrl-Alt-Down) => SetNoteScroll(note_point().saturating_sub(3)),
|
||||
key_pat!(Ctrl-Alt-Left) => SetTimeScroll(time_point().saturating_sub(time_zoom())),
|
||||
key_pat!(Ctrl-Alt-Right) => SetTimeScroll((time_point() + time_zoom()) % length()),
|
||||
key_pat!(Ctrl-Up) => SetNoteScroll(note_lo() + 1),
|
||||
key_pat!(Ctrl-Down) => SetNoteScroll(note_lo().saturating_sub(1)),
|
||||
key_pat!(Ctrl-Left) => SetTimeScroll(time_start().saturating_sub(note_len())),
|
||||
key_pat!(Ctrl-Right) => SetTimeScroll(time_start() + note_len()),
|
||||
key_pat!(Alt-Up) => SetNoteCursor(note_point() + 3),
|
||||
key_pat!(Alt-Down) => SetNoteCursor(note_point().saturating_sub(3)),
|
||||
key_pat!(Alt-Left) => SetTimeCursor(time_point().saturating_sub(time_zoom())),
|
||||
key_pat!(Alt-Right) => SetTimeCursor((time_point() + time_zoom()) % length()),
|
||||
key_pat!(Up) => SetNoteCursor(note_point() + 1),
|
||||
key_pat!(Down) => SetNoteCursor(note_point().saturating_sub(1)),
|
||||
key_pat!(Left) => SetTimeCursor(time_point().saturating_sub(note_len())),
|
||||
key_pat!(Right) => SetTimeCursor((time_point() + note_len()) % length()),
|
||||
key_pat!(Char('`')) => ToggleDirection,
|
||||
key_pat!(Char('z')) => SetTimeLock(!time_lock()),
|
||||
key_pat!(Char('-')) => SetTimeZoom(Note::next(time_zoom())),
|
||||
key_pat!(Char('_')) => SetTimeZoom(Note::next(time_zoom())),
|
||||
key_pat!(Char('=')) => SetTimeZoom(Note::prev(time_zoom())),
|
||||
key_pat!(Char('+')) => SetTimeZoom(Note::prev(time_zoom())),
|
||||
key_pat!(Enter) => PutNote,
|
||||
key_pat!(Ctrl-Enter) => AppendNote,
|
||||
key_pat!(Char(',')) => SetNoteLength(Note::prev(note_len())), // TODO: no 3plet
|
||||
key_pat!(Char('.')) => SetNoteLength(Note::next(note_len())),
|
||||
key_pat!(Char('<')) => SetNoteLength(Note::prev(note_len())), // TODO: 3plet
|
||||
key_pat!(Char('>')) => SetNoteLength(Note::next(note_len())),
|
||||
// TODO: key_pat!(Char('/')) => // toggle 3plet
|
||||
// TODO: key_pat!(Char('?')) => // toggle dotted
|
||||
_ => return None
|
||||
})
|
||||
impl PhraseEditorModel {
|
||||
fn to_editor_command (&self, from: &TuiInput) -> Option<PhraseCommand> {
|
||||
EventMap([
|
||||
(&key_expr!(Ctrl-Alt-Up),
|
||||
&|q: &Self|SetNoteScroll(q.note_point() + 3)),
|
||||
(&key_expr!(Ctrl-Alt-Down),
|
||||
&|q: &Self|SetNoteScroll(q.note_point().saturating_sub(3))),
|
||||
(&key_expr!(Ctrl-Alt-Left),
|
||||
&|q: &Self|SetTimeScroll(q.time_point().saturating_sub(q.time_zoom().get()))),
|
||||
(&key_expr!(Ctrl-Alt-Right),
|
||||
&|q: &Self|SetTimeScroll((q.time_point() + q.time_zoom()) % q.phrase_length().get())),
|
||||
(&key_expr!(Ctrl-Up),
|
||||
&|q: &Self|SetNoteScroll(q.note_lo().get() + 1)),
|
||||
(&key_expr!(Ctrl-Down),
|
||||
&|q: &Self|SetNoteScroll(q.note_lo().get().saturating_sub(1))),
|
||||
(&key_expr!(Ctrl-Left),
|
||||
&|q: &Self|SetTimeScroll(q.time_start().get().saturating_sub(q.note_len()))),
|
||||
(&key_expr!(Ctrl-Right),
|
||||
&|q: &Self|SetTimeScroll(q.time_start().get() + q.note_len())),
|
||||
(&key_expr!(Alt-Up),
|
||||
&|q: &Self|SetNoteCursor(q.note_point().get() + 3)),
|
||||
(&key_expr!(Alt-Down),
|
||||
&|q: &Self|SetNoteCursor(q.note_point().get().saturating_sub(3))),
|
||||
(&key_expr!(Alt-Left),
|
||||
&|q: &Self|SetTimeCursor(q.time_point().get().saturating_sub(q.time_zoom()))),
|
||||
(&key_expr!(Alt-Right),
|
||||
&|q: &Self|SetTimeCursor((q.time_point().get() + q.time_zoom().get()) % q.phrase_length().get())),
|
||||
(&key_expr!(Up),
|
||||
&|q: &Self|SetNoteCursor(q.note_point().get() + 1)),
|
||||
(&key_expr!(Down),
|
||||
&|q: &Self|SetNoteCursor(q.note_point().get().saturating_sub(1))),
|
||||
(&key_expr!(Left),
|
||||
&|q: &Self|SetTimeCursor(q.time_point().get().saturating_sub(q.note_len()))),
|
||||
(&key_expr!(Right),
|
||||
&|q: &Self|SetTimeCursor((q.time_point().get() + q.note_len().get()) % q.phrase_length().get())),
|
||||
(&key_pat!(Char('`')),
|
||||
&|q: &Self|ToggleDirection),
|
||||
(&key_pat!(Char('z')),
|
||||
&|q: &Self|SetTimeLock(!q.time_lock().get())),
|
||||
(&key_pat!(Char('-')),
|
||||
&|q: &Self|SetTimeZoom(Note::next(q.time_zoom().get()))),
|
||||
(&key_pat!(Char('_')),
|
||||
&|q: &Self|SetTimeZoom(Note::next(q.time_zoom().get()))),
|
||||
(&key_pat!(Char('=')),
|
||||
&|q: &Self|SetTimeZoom(Note::prev(q.time_zoom().get()))),
|
||||
(&key_pat!(Char('+')),
|
||||
&|q: &Self|SetTimeZoom(Note::prev(q.time_zoom().get()))),
|
||||
(&key_expr!(Enter),
|
||||
&|q: &Self|PutNote),
|
||||
(&key_expr!(Ctrl-Enter),
|
||||
&|q: &Self|AppendNote),
|
||||
(&key_pat!(Char(',')),
|
||||
&|q: &Self|SetNoteLength(Note::prev(q.note_len().get()))), // TODO: no 3plet
|
||||
(&key_pat!(Char('.')),
|
||||
&|q: &Self|SetNoteLength(Note::next(q.note_len().get()))),
|
||||
(&key_pat!(Char('<')),
|
||||
&|q: &Self|SetNoteLength(Note::prev(q.note_len().get()))), // TODO: 3plet
|
||||
(&key_pat!(Char('>')),
|
||||
&|q: &Self|SetNoteLength(Note::next(q.note_len().get()))),
|
||||
//// TODO: key_pat!(Char('/')) => // toggle 3plet
|
||||
//// TODO: key_pat!(Char('?')) => // toggle dotted
|
||||
]).handle(state, from.event())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,19 @@ impl Input<Tui> for TuiInput {
|
|||
}
|
||||
}
|
||||
|
||||
#[macro_export] macro_rules! key_pat {
|
||||
(Ctrl-Alt-$code:pat) => { key_event_pat!($code, KeyModifiers::CONTROL | KeyModifiers::ALT) };
|
||||
(Ctrl-$code:pat) => { key_event_pat!($code, KeyModifiers::CONTROL) };
|
||||
(Alt-$code:pat) => { key_event_pat!($code, KeyModifiers::ALT) };
|
||||
(Shift-$code:pat) => { key_event_pat!($code, KeyModifiers::SHIFT) };
|
||||
($code:pat) => { TuiEvent::Input(crossterm::event::Event::Key(KeyEvent {
|
||||
code: $code,
|
||||
modifiers: KeyModifiers::NONE,
|
||||
kind: KeyEventKind::Press,
|
||||
state: KeyEventState::NONE
|
||||
})) };
|
||||
}
|
||||
|
||||
#[macro_export] macro_rules! key_event_pat {
|
||||
($code:pat) => {
|
||||
TuiEvent::Input(crossterm::event::Event::Key(KeyEvent {
|
||||
|
|
@ -47,6 +60,14 @@ impl Input<Tui> for TuiInput {
|
|||
};
|
||||
}
|
||||
|
||||
#[macro_export] macro_rules! key_expr {
|
||||
(Ctrl-Alt-$code:ident) => { key_event_expr!($code, KeyModifiers::CONTROL | KeyModifiers::ALT) };
|
||||
(Ctrl-$code:ident) => { key_event_expr!($code, KeyModifiers::CONTROL) };
|
||||
(Alt-$code:ident) => { key_event_expr!($code, KeyModifiers::ALT) };
|
||||
(Shift-$code:ident) => { key_event_expr!($code, KeyModifiers::SHIFT) };
|
||||
($code:ident) => { key_event_expr!($code) };
|
||||
}
|
||||
|
||||
#[macro_export] macro_rules! key_event_expr {
|
||||
($code:ident, $modifiers: expr) => {
|
||||
TuiEvent::Input(crossterm::event::Event::Key(KeyEvent {
|
||||
|
|
@ -66,22 +87,6 @@ impl Input<Tui> for TuiInput {
|
|||
};
|
||||
}
|
||||
|
||||
#[macro_export] macro_rules! key_pat {
|
||||
(Ctrl-Alt-$code:pat) => { key_event_pat!($code, KeyModifiers::CONTROL | KeyModifiers::ALT) };
|
||||
(Ctrl-$code:pat) => { key_event_pat!($code, KeyModifiers::CONTROL) };
|
||||
(Alt-$code:pat) => { key_event_pat!($code, KeyModifiers::ALT) };
|
||||
(Shift-$code:pat) => { key_event_pat!($code, KeyModifiers::SHIFT) };
|
||||
($code:pat) => { key_event_pat!($code) };
|
||||
}
|
||||
|
||||
#[macro_export] macro_rules! key_expr {
|
||||
(Ctrl-Alt-$code:ident) => { key_event_expr!($code, KeyModifiers::CONTROL | KeyModifiers::ALT) };
|
||||
(Ctrl-$code:ident) => { key_event_expr!($code, KeyModifiers::CONTROL) };
|
||||
(Alt-$code:ident) => { key_event_expr!($code, KeyModifiers::ALT) };
|
||||
(Shift-$code:ident) => { key_event_expr!($code, KeyModifiers::SHIFT) };
|
||||
($code:ident) => { key_event_expr!($code) };
|
||||
}
|
||||
|
||||
/*
|
||||
/// Define a key
|
||||
pub const fn key (code: KeyCode) -> KeyEvent {
|
||||
|
|
@ -143,3 +148,16 @@ pub type KeyBinding<T> = (KeyCode, KeyModifiers, &'static str, &'static str, Key
|
|||
pub type KeyMap<T> = [KeyBinding<T>];
|
||||
|
||||
*/
|
||||
|
||||
pub struct EventMap<'a, const N: usize, E, T, U>(pub [(E, &'a dyn Fn(T) -> U); N]);
|
||||
|
||||
impl<'a, const N: usize, E, T, U> EventMap<'a, N, E, T, U> {
|
||||
pub fn handle (&self, context: T, event: E) -> Option<U> {
|
||||
for (binding, handler) in self.0.iter() {
|
||||
if event == binding {
|
||||
return Some(handler(context))
|
||||
}
|
||||
}
|
||||
return None
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue