tek/crates/tek_app/src/arranger_tui_cmd.rs

161 lines
7.1 KiB
Rust

use crate::*;
/// Handle top-level events in standalone arranger.
impl Handle<Tui> for Arranger<Tui> {
fn handle (&mut self, i: &TuiInput) -> Perhaps<bool> {
if let Some(entered) = self.entered() {
use ArrangerFocus::*;
if let Some(true) = match entered {
Transport => self.transport.as_mut().map(|t|t.handle(i)).transpose()?.flatten(),
Arrangement => self.arrangement.handle(i)?,
PhrasePool => self.phrases.write().unwrap().handle(i)?,
PhraseEditor => self.editor.handle(i)?,
} {
return Ok(Some(true))
}
}
Ok(if let Some(command) = ArrangerCommand::input_to_command(self, i) {
let _undo = command.execute(self)?;
Some(true)
} else {
None
})
}
}
impl InputToCommand<Tui, Arranger<Tui>> for ArrangerCommand {
fn input_to_command (state: &Arranger<Tui>, input: &TuiInput) -> Option<Self> {
use FocusCommand::*;
use ArrangerCommand::*;
match input.event() {
key!(KeyCode::Tab) => Some(Focus(Next)),
key!(Shift-KeyCode::Tab) => Some(Focus(Prev)),
key!(KeyCode::BackTab) => Some(Focus(Prev)),
key!(Shift-KeyCode::BackTab) => Some(Focus(Prev)),
key!(KeyCode::Up) => Some(Focus(Up)),
key!(KeyCode::Down) => Some(Focus(Down)),
key!(KeyCode::Left) => Some(Focus(Left)),
key!(KeyCode::Right) => Some(Focus(Right)),
key!(KeyCode::Enter) => Some(Focus(Enter)),
key!(KeyCode::Esc) => Some(Focus(Exit)),
key!(KeyCode::Char(' ')) => Some(Transport(TransportCommand::PlayToggle)),
_ => match state.focused() {
ArrangerFocus::Transport => state.transport.as_ref()
.map(|t|TransportCommand::input_to_command(&*t.read().unwrap(), input)
.map(Transport))
.flatten(),
ArrangerFocus::PhrasePool => {
let phrases = state.phrases.read().unwrap();
match input.event() {
key!(KeyCode::Char('e')) => Some(EditPhrase(Some(phrases.phrase().clone()))),
_ => PhrasePoolCommand::input_to_command(&*phrases, input)
.map(Phrases)
}
},
ArrangerFocus::PhraseEditor =>
PhraseEditorCommand::input_to_command(&state.editor, input)
.map(Editor),
ArrangerFocus::Arrangement => match input.event() {
key!(KeyCode::Char('e')) => Some(EditPhrase(state.arrangement.phrase())),
_ => ArrangementCommand::input_to_command(&state.arrangement, &input)
.map(Arrangement)
}
}
}
}
}
/// Handle events for arrangement.
impl Handle<Tui> for Arrangement<Tui> {
fn handle (&mut self, from: &TuiInput) -> Perhaps<bool> {
Ok(if let Some(command) = ArrangementCommand::input_to_command(self, from) {
let _undo = command.execute(self)?;
Some(true)
} else {
None
})
}
}
impl InputToCommand<Tui, Arrangement<Tui>> for ArrangementCommand {
fn input_to_command (state: &Arrangement<Tui>, input: &TuiInput) -> Option<Self> {
use ArrangementCommand::*;
match input.event() {
key!(KeyCode::Char('`')) => Some(ToggleViewMode),
key!(KeyCode::Delete) => Some(Delete),
key!(KeyCode::Enter) => Some(Activate),
key!(KeyCode::Char('.')) => Some(Increment),
key!(KeyCode::Char(',')) => Some(Decrement),
key!(KeyCode::Char('+')) => Some(ZoomIn),
key!(KeyCode::Char('=')) => Some(ZoomOut),
key!(KeyCode::Char('_')) => Some(ZoomOut),
key!(KeyCode::Char('-')) => Some(ZoomOut),
key!(KeyCode::Char('<')) => Some(MoveBack),
key!(KeyCode::Char('>')) => Some(MoveForward),
key!(KeyCode::Char('c')) => Some(RandomColor),
key!(KeyCode::Char('s')) => Some(Put),
key!(KeyCode::Char('g')) => Some(Get),
key!(KeyCode::Char('e')) => Some(Edit(state.phrase())),
key!(Ctrl-KeyCode::Char('a')) => Some(AddScene),
key!(Ctrl-KeyCode::Char('t')) => Some(AddTrack),
key!(KeyCode::Char('l')) => Some(ToggleLoop),
key!(KeyCode::Up) => Some(GoUp),
key!(KeyCode::Down) => Some(GoDown),
key!(KeyCode::Left) => Some(GoLeft),
key!(KeyCode::Right) => Some(GoRight),
_ => None
}
}
}
//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))
//}
//}