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

@ -10,6 +10,42 @@ impl Content for Sequencer<Tui> {
})
}
}
impl Handle<Tui> for Sequencer<Tui> {
fn handle (&mut self, from: &TuiInput) -> Perhaps<bool> {
if let Some(command) = SequencerCommand::match_input(self, from) {
let _undo = command.run(self)?;
return Ok(Some(true))
}
Ok(None)
}
}
impl MatchInput<Tui, Sequencer<Tui>> for SequencerCommand {
fn match_input (state: &Sequencer<Tui>, input: &TuiInput) -> Option<Self> {
match input.event() {
key!(KeyCode::Tab) => Some(Self::FocusNext),
key!(Shift-KeyCode::Tab) => Some(Self::FocusPrev),
key!(KeyCode::BackTab) => Some(Self::FocusPrev),
key!(Shift-KeyCode::BackTab) => Some(Self::FocusPrev),
key!(KeyCode::Up) => Some(Self::FocusUp),
key!(KeyCode::Down) => Some(Self::FocusDown),
key!(KeyCode::Left) => Some(Self::FocusLeft),
key!(KeyCode::Right) => Some(Self::FocusRight),
key!(KeyCode::Char(' ')) => Some(Self::Transport(TransportCommand::TogglePlay)),
_ => match state.focused() {
SequencerFocus::Transport => state.transport.as_ref()
.map(|t|TransportCommand::match_input(&*t.read().unwrap(), input)
.map(Self::Transport))
.flatten(),
SequencerFocus::PhrasePool =>
PhrasePoolCommand::match_input(&*state.phrases.read().unwrap(), input)
.map(Self::Phrases),
SequencerFocus::PhraseEditor =>
PhraseEditorCommand::match_input(&state.editor, input)
.map(Self::Editor),
}
}
}
}
// TODO: Display phrases always in order of appearance
impl Content for PhrasePool<Tui> {
type Engine = Tui;
@ -45,6 +81,96 @@ impl Content for PhrasePool<Tui> {
Layers::new(move|add|{ add(&content)?; Ok(add(&title)?) })
}
}
impl Handle<Tui> for PhrasePool<Tui> {
fn handle (&mut self, from: &TuiInput) -> Perhaps<bool> {
if let Some(command) = PhrasePoolCommand::match_input(self, from) {
let _undo = command.run(self)?;
return Ok(Some(true))
}
Ok(None)
}
}
impl MatchInput<Tui, PhrasePool<Tui>> for PhrasePoolCommand {
fn match_input (state: &PhrasePool<Tui>, input: &TuiInput) -> Option<Self> {
match input.event() {
key!(KeyCode::Up) => Some(Self::Prev),
key!(KeyCode::Down) => Some(Self::Next),
key!(KeyCode::Char(',')) => Some(Self::MoveUp),
key!(KeyCode::Char('.')) => Some(Self::MoveDown),
key!(KeyCode::Delete) => Some(Self::Delete),
key!(KeyCode::Char('a')) => Some(Self::Append),
key!(KeyCode::Char('i')) => Some(Self::Insert),
key!(KeyCode::Char('d')) => Some(Self::Duplicate),
key!(KeyCode::Char('c')) => Some(Self::RandomColor),
key!(KeyCode::Char('n')) => Some(Self::Rename(PhraseRenameCommand::Begin)),
key!(KeyCode::Char('t')) => Some(Self::Length(PhraseLengthCommand::Begin)),
_ => match state.mode {
Some(PhrasePoolMode::Rename(..)) => PhraseRenameCommand::match_input(state, input)
.map(Self::Rename),
Some(PhrasePoolMode::Length(..)) => PhraseLengthCommand::match_input(state, input)
.map(Self::Length),
_ => None
}
}
}
}
impl MatchInput<Tui, PhrasePool<Tui>> for PhraseRenameCommand {
fn match_input (_: &PhrasePool<Tui>, from: &TuiInput) -> Option<Self> {
match from.event() {
key!(KeyCode::Backspace) => Some(Self::Backspace),
key!(KeyCode::Enter) => Some(Self::Confirm),
key!(KeyCode::Esc) => Some(Self::Cancel),
key!(KeyCode::Char(c)) => Some(Self::Append(*c)),
_ => None
}
}
}
impl MatchInput<Tui, PhrasePool<Tui>> for PhraseLengthCommand {
fn match_input (_: &PhrasePool<Tui>, from: &TuiInput) -> Option<Self> {
match from.event() {
key!(KeyCode::Up) => Some(Self::Inc),
key!(KeyCode::Down) => Some(Self::Dec),
key!(KeyCode::Right) => Some(Self::Next),
key!(KeyCode::Left) => Some(Self::Prev),
key!(KeyCode::Enter) => Some(Self::Confirm),
key!(KeyCode::Esc) => Some(Self::Cancel),
_ => None
}
}
}
impl Content for PhraseLength<Tui> {
type Engine = Tui;
fn content (&self) -> impl Widget<Engine = Tui> {
Layers::new(move|add|{
match self.focus {
None => add(&row!(
" ", self.bars_string(),
".", self.beats_string(),
".", self.ticks_string(),
" "
)),
Some(PhraseLengthFocus::Bar) => add(&row!(
"[", self.bars_string(),
"]", self.beats_string(),
".", self.ticks_string(),
" "
)),
Some(PhraseLengthFocus::Beat) => add(&row!(
" ", self.bars_string(),
"[", self.beats_string(),
"]", self.ticks_string(),
" "
)),
Some(PhraseLengthFocus::Tick) => add(&row!(
" ", self.bars_string(),
".", self.beats_string(),
"[", self.ticks_string(),
"]"
)),
}
})
}
}
impl Content for PhraseEditor<Tui> {
type Engine = Tui;
fn content (&self) -> impl Widget<Engine = Tui> {
@ -307,36 +433,36 @@ pub(crate) fn keys_vert () -> Buffer {
});
buffer
}
impl Content for PhraseLength<Tui> {
type Engine = Tui;
fn content (&self) -> impl Widget<Engine = Tui> {
Layers::new(move|add|{
match self.focus {
None => add(&row!(
" ", self.bars_string(),
".", self.beats_string(),
".", self.ticks_string(),
" "
)),
Some(PhraseLengthFocus::Bar) => add(&row!(
"[", self.bars_string(),
"]", self.beats_string(),
".", self.ticks_string(),
" "
)),
Some(PhraseLengthFocus::Beat) => add(&row!(
" ", self.bars_string(),
"[", self.beats_string(),
"]", self.ticks_string(),
" "
)),
Some(PhraseLengthFocus::Tick) => add(&row!(
" ", self.bars_string(),
".", self.beats_string(),
"[", self.ticks_string(),
"]"
)),
}
})
impl Handle<Tui> for PhraseEditor<Tui> {
fn handle (&mut self, from: &TuiInput) -> Perhaps<bool> {
if let Some(command) = PhraseEditorCommand::match_input(self, from) {
let _undo = command.run(self)?;
return Ok(Some(true))
}
Ok(None)
}
}
impl MatchInput<Tui, PhraseEditor<Tui>> for PhraseEditorCommand {
fn match_input (_: &PhraseEditor<Tui>, from: &TuiInput) -> Option<Self> {
match from.event() {
key!(KeyCode::Char('`')) => Some(Self::ToggleDirection),
key!(KeyCode::Enter) => Some(Self::EnterEditMode),
key!(KeyCode::Esc) => Some(Self::ExitEditMode),
key!(KeyCode::Char('[')) => Some(Self::NoteLengthDec),
key!(KeyCode::Char(']')) => Some(Self::NoteLengthInc),
key!(KeyCode::Char('a')) => Some(Self::NoteAppend),
key!(KeyCode::Char('s')) => Some(Self::NoteSet),
key!(KeyCode::Char('-')) => Some(Self::TimeZoomOut),
key!(KeyCode::Char('_')) => Some(Self::TimeZoomOut),
key!(KeyCode::Char('=')) => Some(Self::TimeZoomIn),
key!(KeyCode::Char('+')) => Some(Self::TimeZoomIn),
key!(KeyCode::PageUp) => Some(Self::NotePageUp),
key!(KeyCode::PageDown) => Some(Self::NotePageDown),
key!(KeyCode::Up) => Some(Self::GoUp),
key!(KeyCode::Down) => Some(Self::GoDown),
key!(KeyCode::Left) => Some(Self::GoLeft),
key!(KeyCode::Right) => Some(Self::GoRight),
_ => None
}
}
}