tek/crates/tek_sequencer/src/arranger_cmd.rs

143 lines
5.6 KiB
Rust

use crate::*;
#[derive(Clone, PartialEq)]
enum ArrangerCommand {
FocusNext,
FocusPrev,
FocusUp,
FocusDown,
FocusLeft,
FocusRight,
Transport(TransportCommand),
Phrase(PhrasePoolCommand),
Editor(PhraseEditorCommand),
Arrangement(ArrangementCommand),
}
#[derive(Clone, PartialEq)]
enum ArrangementCommand {
ToggleViewMode,
Delete,
Activate,
Increment,
Decrement,
ZoomIn,
ZoomOut,
MoveBack,
MoveForward,
RandomColor,
Put,
Get,
AddScene,
AddTrack,
ToggleLoop,
GoUp,
GoDown,
GoLeft,
GoRight,
}
/// Handle top-level events in standalone arranger.
impl Handle<Tui> for Arranger<Tui> {
fn handle (&mut self, from: &TuiInput) -> Perhaps<bool> {
if !self.handle_focused(from)?.unwrap_or(false) {
match from.event() {
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(); },
key!(KeyCode::Up) => { self.focus_up(); },
key!(KeyCode::Down) => { self.focus_down(); },
key!(KeyCode::Left) => { self.focus_left(); },
key!(KeyCode::Right) => { self.focus_right(); },
key!(KeyCode::Char('e')) => { self.edit_phrase(); },
key!(KeyCode::Char(' ')) => { self.toggle_play()?; },
key!(KeyCode::Char('n')) => { self.rename_selected(); },
_ => return Ok(None)
}
};
self.update_status();
Ok(Some(true))
}
}
impl Arranger<Tui> {
/// Helper for event passthru to focused component
fn handle_focused (&mut self, from: &TuiInput) -> Perhaps<bool> {
match self.focused() {
ArrangerFocus::Transport => self.transport.handle(from),
ArrangerFocus::PhrasePool => self.handle_pool(from),
ArrangerFocus::PhraseEditor => self.editor.handle(from),
ArrangerFocus::Arrangement => self.handle_arrangement(from)
.and_then(|result|{self.show_phrase();Ok(result)}),
}
}
/// Helper for phrase event passthru when phrase pool is focused
fn handle_pool (&mut self, from: &TuiInput) -> Perhaps<bool> {
match from.event() {
key!(KeyCode::Char('<')) => {
self.phrases_split = self.phrases_split.saturating_sub(1).max(12);
},
key!(KeyCode::Char('>')) => {
self.phrases_split = self.phrases_split + 1;
},
_ => return self.phrases.handle(from)
}
Ok(Some(true))
}
/// Helper for phrase event passthru when arrangement is focused
fn handle_arrangement (&mut self, from: &TuiInput) -> Perhaps<bool> {
let mut handle_phrase = ||{
let result = self.phrases.handle(from);
self.arrangement.phrase_put();
result
};
match from.event() {
key!(KeyCode::Char('a')) => return handle_phrase(),
key!(KeyCode::Char('i')) => return handle_phrase(),
key!(KeyCode::Char('d')) => return handle_phrase(),
key!(KeyCode::Char('<')) => if self.arrangement.selected == ArrangementFocus::Mix {
self.arrangement_split = self.arrangement_split.saturating_sub(1).max(12);
} else {
return self.arrangement.handle(from)
},
key!(KeyCode::Char('>')) => if self.arrangement.selected == ArrangementFocus::Mix {
self.arrangement_split = self.arrangement_split + 1;
} else {
return self.arrangement.handle(from)
},
_ => return self.arrangement.handle(from)
}
self.show_phrase();
Ok(Some(true))
}
}
/// Handle events for arrangement.
impl Handle<Tui> for Arrangement<Tui> {
fn handle (&mut self, from: &TuiInput) -> Perhaps<bool> {
match from.event() {
key!(KeyCode::Char('`')) => { self.mode.to_next(); },
key!(KeyCode::Delete) => { self.delete(); },
key!(KeyCode::Enter) => { self.activate(); },
key!(KeyCode::Char('.')) => { self.increment(); },
key!(KeyCode::Char(',')) => { self.decrement(); },
key!(KeyCode::Char('+')) => { self.zoom_in(); },
key!(KeyCode::Char('=')) => { self.zoom_in(); },
key!(KeyCode::Char('_')) => { self.zoom_out(); },
key!(KeyCode::Char('-')) => { self.zoom_out(); },
key!(KeyCode::Char('<')) => { self.move_back(); },
key!(KeyCode::Char('>')) => { self.move_forward(); },
key!(KeyCode::Char('c')) => { self.randomize_color(); },
key!(KeyCode::Char('s')) => { self.phrase_put(); },
key!(KeyCode::Char('g')) => { self.phrase_get(); },
key!(Ctrl-KeyCode::Char('a')) => { self.scene_add(None, None)?; },
key!(Ctrl-KeyCode::Char('t')) => { self.track_add(None, None)?; },
key!(KeyCode::Char('l')) => { self.toggle_loop() },
key!(KeyCode::Up) => { self.go_up() },
key!(KeyCode::Down) => { self.go_down() },
key!(KeyCode::Left) => { self.go_left() },
key!(KeyCode::Right) => { self.go_right() },
_ => return Ok(None)
}
Ok(Some(true))
}
}