mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-08 20:56:43 +01:00
key pattern matching macro
This commit is contained in:
parent
e0c8a427f1
commit
92d747ba2a
7 changed files with 168 additions and 93 deletions
|
|
@ -1 +0,0 @@
|
||||||
use crate::*;
|
|
||||||
|
|
@ -33,8 +33,53 @@ pub fn handle_keymap <T> (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export] macro_rules! key {
|
#[macro_export] macro_rules! map_key {
|
||||||
($k:ident $(($char:literal))?, $m:ident, $n: literal, $d: literal, $f: expr) => {
|
($k:ident $(($char:literal))?, $m:ident, $n: literal, $d: literal, $f: expr) => {
|
||||||
(KeyCode::$k $(($char))?, KeyModifiers::$m, $n, $d, &$f as &dyn Fn()->Usually<bool>)
|
(KeyCode::$k $(($char))?, KeyModifiers::$m, $n, $d, &$f as &dyn Fn()->Usually<bool>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export] macro_rules! key {
|
||||||
|
($code:pat) => {
|
||||||
|
crossterm::event::Event::Key(crossterm::event::KeyEvent {
|
||||||
|
code: $code,
|
||||||
|
modifiers: crossterm::event::KeyModifiers::NONE,
|
||||||
|
kind: crossterm::event::KeyEventKind::Press,
|
||||||
|
state: crossterm::event::KeyEventState::NONE
|
||||||
|
})
|
||||||
|
};
|
||||||
|
(Ctrl-$code:pat) => {
|
||||||
|
crossterm::event::Event::Key(crossterm::event::KeyEvent {
|
||||||
|
code: $code,
|
||||||
|
modifiers: crossterm::event::KeyModifiers::CONTROL,
|
||||||
|
kind: crossterm::event::KeyEventKind::Press,
|
||||||
|
state: crossterm::event::KeyEventState::NONE
|
||||||
|
})
|
||||||
|
};
|
||||||
|
(Alt-$code:pat) => {
|
||||||
|
crossterm::event::Event::Key(crossterm::event::KeyEvent {
|
||||||
|
code: $code,
|
||||||
|
modifiers: crossterm::event::KeyModifiers::ALT,
|
||||||
|
kind: crossterm::event::KeyEventKind::Press,
|
||||||
|
state: crossterm::event::KeyEventState::NONE
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export] macro_rules! match_key {
|
||||||
|
($event:expr, {
|
||||||
|
$($key:pat=>$block:expr),* $(,)?
|
||||||
|
}) => {
|
||||||
|
match $event {
|
||||||
|
$(crossterm::event::Event::Key(crossterm::event::KeyEvent {
|
||||||
|
code: $key,
|
||||||
|
modifiers: crossterm::event::KeyModifiers::NONE,
|
||||||
|
kind: crossterm::event::KeyEventKind::Press,
|
||||||
|
state: crossterm::event::KeyEventState::NONE
|
||||||
|
}) => {
|
||||||
|
$block
|
||||||
|
})*
|
||||||
|
_ => Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ pub struct Plugin {
|
||||||
pub ports: JackPorts,
|
pub ports: JackPorts,
|
||||||
}
|
}
|
||||||
impl Handle<Tui> for Plugin {
|
impl Handle<Tui> for Plugin {
|
||||||
fn handle (&mut self, e: &Tui) -> Perhaps<bool> {
|
fn handle (&mut self, from: &Tui) -> Perhaps<bool> {
|
||||||
handle_keymap(self, event, KEYMAP_PLUGIN)
|
handle_keymap(self, &from.event(), KEYMAP_PLUGIN).map(|x|Some(x))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
process!(Plugin = Plugin::process);
|
process!(Plugin = Plugin::process);
|
||||||
|
|
|
||||||
|
|
@ -60,9 +60,9 @@ impl Render<Tui> for AddSampleModal {
|
||||||
impl Handle<Tui> for AddSampleModal {
|
impl Handle<Tui> for AddSampleModal {
|
||||||
fn handle (&mut self, from: &Tui) -> Perhaps<bool> {
|
fn handle (&mut self, from: &Tui) -> Perhaps<bool> {
|
||||||
if handle_keymap(self, &from.event(), KEYMAP_ADD_SAMPLE)? {
|
if handle_keymap(self, &from.event(), KEYMAP_ADD_SAMPLE)? {
|
||||||
return Ok(true)
|
return Ok(Some(true))
|
||||||
}
|
}
|
||||||
Ok(true)
|
Ok(Some(true))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,12 +49,13 @@ impl<E: Engine> Track<E> {
|
||||||
//None => ()
|
//None => ()
|
||||||
//})
|
//})
|
||||||
//}
|
//}
|
||||||
|
}
|
||||||
|
impl Track<Tui> {
|
||||||
pub fn from_edn <'a, 'e> (args: &[Edn<'e>]) -> Usually<Track<Tui>> {
|
pub fn from_edn <'a, 'e> (args: &[Edn<'e>]) -> Usually<Track<Tui>> {
|
||||||
let mut _gain = 0.0f64;
|
let mut _gain = 0.0f64;
|
||||||
let mut track = Self::new("")?;
|
let mut track = Self::new("")?;
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
let mut devices: Vec<JackDevice<E>> = vec![];
|
let mut devices: Vec<JackDevice<Tui>> = vec![];
|
||||||
edn!(edn in args {
|
edn!(edn in args {
|
||||||
Edn::Map(map) => {
|
Edn::Map(map) => {
|
||||||
if let Some(Edn::Str(n)) = map.get(&Edn::Key(SYM_NAME)) {
|
if let Some(Edn::Str(n)) = map.get(&Edn::Key(SYM_NAME)) {
|
||||||
|
|
@ -95,7 +96,7 @@ impl<E: Engine> Track<E> {
|
||||||
}
|
}
|
||||||
Ok(track)
|
Ok(track)
|
||||||
}
|
}
|
||||||
pub fn add_device (&mut self, device: JackDevice<E>) {
|
pub fn add_device (&mut self, device: JackDevice<Tui>) {
|
||||||
self.devices.push(device);
|
self.devices.push(device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,38 +3,37 @@ use crate::*;
|
||||||
impl Handle<Tui> for Track<Tui> {
|
impl Handle<Tui> for Track<Tui> {
|
||||||
fn handle (&mut self, from: &Tui) -> Perhaps<bool> {
|
fn handle (&mut self, from: &Tui) -> Perhaps<bool> {
|
||||||
match from.event() {
|
match from.event() {
|
||||||
TuiEvent::Input(crossterm::event::Event::Key(event)) => {
|
TuiEvent::Input(key) => match key {
|
||||||
for (code, modifiers, _, _, command) in [
|
//, NONE, "chain_cursor_up", "move cursor up", || {
|
||||||
key!(Up, NONE, "chain_cursor_up", "move cursor up", || {
|
key!(KeyCode::Up) => {
|
||||||
Ok(true)
|
Ok(Some(true))
|
||||||
}),
|
},
|
||||||
key!(Down, NONE, "chain_cursor_down", "move cursor down", || {
|
// , NONE, "chain_cursor_down", "move cursor down", || {
|
||||||
Ok(true)
|
key!(KeyCode::Down) => {
|
||||||
}),
|
Ok(Some(true))
|
||||||
key!(Left, NONE, "chain_cursor_left", "move cursor left", || {
|
},
|
||||||
//if let Some(track) = app.arranger.track_mut() {
|
// Left, NONE, "chain_cursor_left", "move cursor left", || {
|
||||||
//track.device = track.device.saturating_sub(1);
|
key!(KeyCode::Left) => {
|
||||||
//return Ok(true)
|
//if let Some(track) = app.arranger.track_mut() {
|
||||||
//}
|
//track.device = track.device.saturating_sub(1);
|
||||||
Ok(false)
|
//return Ok(true)
|
||||||
}),
|
//}
|
||||||
key!(Right, NONE, "chain_cursor_right", "move cursor right", || {
|
Ok(Some(true))
|
||||||
//if let Some(track) = app.arranger.track_mut() {
|
},
|
||||||
//track.device = (track.device + 1).min(track.devices.len().saturating_sub(1));
|
// , NONE, "chain_cursor_right", "move cursor right", || {
|
||||||
//return Ok(true)
|
key!(KeyCode::Right) => {
|
||||||
//}
|
//if let Some(track) = app.arranger.track_mut() {
|
||||||
Ok(false)
|
//track.device = (track.device + 1).min(track.devices.len().saturating_sub(1));
|
||||||
}),
|
//return Ok(true)
|
||||||
key!(Char('`'), NONE, "chain_mode_switch", "switch the display mode", || {
|
//}
|
||||||
//app.chain_mode = !app.chain_mode;
|
Ok(Some(true))
|
||||||
Ok(true)
|
},
|
||||||
}),
|
// , NONE, "chain_mode_switch", "switch the display mode", || {
|
||||||
].iter() {
|
key!(KeyCode::Char('`')) => {
|
||||||
if *code == event.code && modifiers.bits() == event.modifiers.bits() {
|
//app.chain_mode = !app.chain_mode;
|
||||||
return command()
|
Ok(Some(true))
|
||||||
}
|
},
|
||||||
}
|
_ => Ok(None)
|
||||||
return Ok(None)
|
|
||||||
},
|
},
|
||||||
_ => Ok(None)
|
_ => Ok(None)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,58 +10,89 @@ impl Handle<Tui> for Arranger<Tui> {
|
||||||
return Ok(result)
|
return Ok(result)
|
||||||
}
|
}
|
||||||
match from.event() {
|
match from.event() {
|
||||||
TuiEvent::Input(crossterm::event::Event::Key(event)) => {
|
TuiEvent::Input(key) => match key {
|
||||||
for (code, modifiers, _, _, command) in [
|
// mode_switch: switch the display mode
|
||||||
key!(Char('`'), NONE, "mode_switch", "switch the display mode", || {
|
key!(KeyCode::Char('`')) => {
|
||||||
self.mode.to_next();
|
self.mode.to_next();
|
||||||
Ok(true)
|
Ok(Some(true))
|
||||||
}),
|
},
|
||||||
key!(Up, NONE, "cursor_up", "move cursor up", || {
|
// cursor_up: move cursor up
|
||||||
match self.mode {
|
key!(KeyCode::Up) => {
|
||||||
ArrangerViewMode::Horizontal => self.track_prev(),
|
match self.mode {
|
||||||
_ => self.scene_prev(),
|
ArrangerViewMode::Horizontal => self.track_prev(),
|
||||||
};
|
_ => self.scene_prev(),
|
||||||
self.show_phrase()?;
|
};
|
||||||
Ok(true)
|
self.show_phrase()?;
|
||||||
}),
|
Ok(Some(true))
|
||||||
key!(Down, NONE, "cursor_down", "move cursor down", || {
|
},
|
||||||
match self.mode {
|
// cursor_down
|
||||||
ArrangerViewMode::Horizontal => self.track_next(),
|
key!(KeyCode::Down) => {
|
||||||
_ => self.scene_next(),
|
match self.mode {
|
||||||
};
|
ArrangerViewMode::Horizontal => self.track_next(),
|
||||||
self.show_phrase()?;
|
_ => self.scene_next(),
|
||||||
Ok(true)
|
};
|
||||||
}),
|
self.show_phrase()?;
|
||||||
key!(Left, NONE, "cursor_left", "move cursor left", || {
|
Ok(Some(true))
|
||||||
match self.mode {
|
},
|
||||||
ArrangerViewMode::Horizontal => self.scene_prev(),
|
// cursor left
|
||||||
_ => self.track_prev(),
|
key!(KeyCode::Left) => {
|
||||||
};
|
match self.mode {
|
||||||
self.show_phrase()?;
|
ArrangerViewMode::Horizontal => self.scene_prev(),
|
||||||
Ok(true)
|
_ => self.track_prev(),
|
||||||
}),
|
};
|
||||||
key!(Right, NONE, "cursor_right", "move cursor right", || {
|
self.show_phrase()?;
|
||||||
match self.mode {
|
Ok(Some(true))
|
||||||
ArrangerViewMode::Horizontal => self.scene_next(),
|
},
|
||||||
_ => self.track_next(),
|
// cursor right
|
||||||
};
|
key!(KeyCode::Right) => {
|
||||||
self.show_phrase()?;
|
match self.mode {
|
||||||
Ok(true)
|
ArrangerViewMode::Horizontal => self.scene_next(),
|
||||||
}),
|
_ => self.track_next(),
|
||||||
key!(Char('.'), NONE, "increment", "set next clip at cursor", || { self.phrase_next(); Ok(true) }),
|
};
|
||||||
key!(Char(','), NONE, "decrement", "set previous clip at cursor", || { self.phrase_prev(); Ok(true) }),
|
self.show_phrase()?;
|
||||||
key!(Enter, NONE, "activate", "activate item at cursor", || { self.activate(); Ok(true) }),
|
Ok(Some(true))
|
||||||
key!(Char('a'), CONTROL, "scene_add", "add a new scene", || { self.scene_add(None)?; Ok(true) }),
|
},
|
||||||
key!(Char('t'), CONTROL, "track_add", "add a new track", || { self.track_add(None)?; Ok(true) }),
|
// increment: use next clip here
|
||||||
key!(Char('n'), NONE, "rename", "rename item at cursor", || { self.rename_selected(); Ok(true) }),
|
key!(KeyCode::Char('.')) => {
|
||||||
key!(Char('l'), NONE, "length", "set length of item at cursor", || { todo!(); Ok(true) }),
|
self.phrase_next();
|
||||||
key!(Char('c'), NONE, "color", "set color of item at cursor", || { todo!(); Ok(true) })
|
Ok(Some(true))
|
||||||
].iter() {
|
},
|
||||||
if *code == event.code && modifiers.bits() == event.modifiers.bits() {
|
// increment: use next clip here
|
||||||
return command()
|
key!(KeyCode::Char(',')) => {
|
||||||
}
|
self.phrase_prev();
|
||||||
}
|
Ok(Some(true))
|
||||||
return Ok(None)
|
},
|
||||||
|
// decrement: use previous clip here
|
||||||
|
key!(KeyCode::Enter) => {
|
||||||
|
self.activate();
|
||||||
|
Ok(Some(true))
|
||||||
|
},
|
||||||
|
// scene_add: add a new scene
|
||||||
|
key!(Ctrl-KeyCode::Char('a')) => {
|
||||||
|
self.scene_add(None)?;
|
||||||
|
Ok(Some(true))
|
||||||
|
},
|
||||||
|
// track_add: add a new scene
|
||||||
|
key!(Ctrl-KeyCode::Char('t')) => {
|
||||||
|
self.track_add(None)?;
|
||||||
|
Ok(Some(true))
|
||||||
|
},
|
||||||
|
// rename: add a new scene
|
||||||
|
key!(KeyCode::Char('n')) => {
|
||||||
|
self.rename_selected();
|
||||||
|
Ok(Some(true))
|
||||||
|
},
|
||||||
|
// length: add a new scene
|
||||||
|
key!(KeyCode::Char('l')) => {
|
||||||
|
todo!();
|
||||||
|
Ok(Some(true))
|
||||||
|
},
|
||||||
|
// color: set color of item at cursor
|
||||||
|
key!(KeyCode::Char('c')) => {
|
||||||
|
todo!();
|
||||||
|
Ok(Some(true))
|
||||||
|
},
|
||||||
|
_ => Ok(None)
|
||||||
},
|
},
|
||||||
_ => Ok(None)
|
_ => Ok(None)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue