mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 04:06:45 +01:00
104 lines
4.8 KiB
Rust
104 lines
4.8 KiB
Rust
use crate::*;
|
|
/// Handle top-level events in standalone sequencer.
|
|
impl Handle<Tui> for Sequencer<Tui> {
|
|
fn handle (&mut self, from: &TuiInput) -> Perhaps<bool> {
|
|
if !match self.focused() {
|
|
SequencerFocus::Transport => self.transport.handle(from)?,
|
|
SequencerFocus::PhrasePool => self.phrases.handle(from)?,
|
|
SequencerFocus::PhraseEditor => self.editor.handle(from)?
|
|
}.unwrap_or(false) {
|
|
match from.event() {
|
|
// Tab navigation
|
|
key!(KeyCode::Tab) => { self.focus_next(); },
|
|
key!(Shift-KeyCode::Tab) => { self.focus_prev(); },
|
|
key!(KeyCode::BackTab) => { self.focus_prev(); },
|
|
key!(Shift-KeyCode::BackTab) => { self.focus_prev(); },
|
|
// Directional navigation
|
|
key!(KeyCode::Up) => { self.focus_up(); },
|
|
key!(KeyCode::Down) => { self.focus_down(); },
|
|
key!(KeyCode::Left) => { self.focus_left(); },
|
|
key!(KeyCode::Right) => { self.focus_right(); },
|
|
// Global play/pause binding
|
|
key!(KeyCode::Char(' ')) => match self.transport {
|
|
Some(ref mut transport) => { transport.write().unwrap().toggle_play()?; },
|
|
None => { return Ok(None) }
|
|
},
|
|
_ => {}
|
|
}
|
|
};
|
|
Ok(Some(true))
|
|
}
|
|
}
|
|
impl Handle<Tui> for PhrasePool<Tui> {
|
|
fn handle (&mut self, from: &TuiInput) -> Perhaps<bool> {
|
|
match self.mode {
|
|
Some(PhrasePoolMode::Rename(phrase, ref mut old_name)) => {
|
|
let mut phrase = self.phrases[phrase].write().unwrap();
|
|
match from.event() {
|
|
key!(KeyCode::Backspace) => { phrase.name.pop(); },
|
|
key!(KeyCode::Char(c)) => { phrase.name.push(*c); },
|
|
key!(Shift-KeyCode::Char(c)) => { phrase.name.push(*c); },
|
|
key!(KeyCode::Esc) => { phrase.name = old_name.clone(); self.mode = None; },
|
|
key!(KeyCode::Enter) => { self.mode = None; },
|
|
_ => return Ok(None)
|
|
}
|
|
},
|
|
Some(PhrasePoolMode::Length(phrase, length, focus)) => {
|
|
todo!("edit phrase length");
|
|
let mut phrase = self.phrases[phrase].write().unwrap();
|
|
match from.event() {
|
|
key!(KeyCode::Backspace) => { phrase.name.pop(); },
|
|
key!(KeyCode::Char(c)) => { phrase.name.push(*c); },
|
|
key!(Shift-KeyCode::Char(c)) => { phrase.name.push(*c); },
|
|
//key!(KeyCode::Esc) => { phrase.name = old_name.clone(); self.mode = None; },
|
|
key!(KeyCode::Enter) => { self.mode = None; },
|
|
_ => return Ok(None)
|
|
}
|
|
},
|
|
None => match from.event() {
|
|
key!(KeyCode::Up) => { self.select_prev() },
|
|
key!(KeyCode::Down) => { self.select_next() },
|
|
key!(KeyCode::Char('a')) => { self.append_new(None, None) },
|
|
key!(KeyCode::Char('i')) => { self.insert_new(None, None) },
|
|
key!(KeyCode::Char('d')) => { self.insert_dup() },
|
|
key!(KeyCode::Char('c')) => { self.randomize_color() },
|
|
key!(KeyCode::Char('n')) => { self.begin_rename() },
|
|
key!(KeyCode::Char('t')) => { self.begin_length() },
|
|
key!(KeyCode::Char(',')) => { self.move_up() },
|
|
key!(KeyCode::Char('.')) => { self.move_down() },
|
|
_ => return Ok(None),
|
|
}
|
|
}
|
|
|
|
return Ok(Some(true))
|
|
}
|
|
}
|
|
impl Handle<Tui> for PhraseEditor<Tui> {
|
|
fn handle (&mut self, from: &TuiInput) -> Perhaps<bool> {
|
|
match from.event() {
|
|
key!(KeyCode::Char('`')) => {
|
|
self.mode = !self.mode;
|
|
},
|
|
key!(KeyCode::Up) => match self.entered {
|
|
true => { self.note_axis.point_dec(); },
|
|
false => { self.note_axis.start_dec(); },
|
|
},
|
|
key!(KeyCode::Down) => match self.entered {
|
|
true => { self.note_axis.point_inc(); },
|
|
false => { self.note_axis.start_inc(); },
|
|
},
|
|
key!(KeyCode::Left) => match self.entered {
|
|
true => { self.time_axis.point_dec(); },
|
|
false => { self.time_axis.start_dec(); },
|
|
},
|
|
key!(KeyCode::Right) => match self.entered {
|
|
true => { self.time_axis.point_inc(); },
|
|
false => { self.time_axis.start_inc(); },
|
|
},
|
|
_ => {
|
|
return Ok(None)
|
|
}
|
|
}
|
|
return Ok(Some(true))
|
|
}
|
|
}
|