use crate::*; #[derive(Clone)] pub enum ArrangerViewCommand { Focus(FocusCommand), Arrangement(ArrangementEditorCommand), Transport(TransportCommand), Phrases(PhrasePoolCommand), Editor(PhraseEditorCommand), EditPhrase(Option>>), } /// Handle top-level events in standalone arranger. impl Handle for ArrangerView { fn handle (&mut self, i: &TuiInput) -> Perhaps { ArrangerViewCommand::execute_with_state(self, i) } } impl InputToCommand> for ArrangerViewCommand { fn input_to_command (state: &ArrangerView, input: &TuiInput) -> Option { use FocusCommand::*; use ArrangerViewCommand::*; 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() { ArrangerViewFocus::Transport => state.transport.as_ref() .map(|t|TransportCommand::input_to_command(&*t.read().unwrap(), input) .map(Transport)) .flatten(), ArrangerViewFocus::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) } }, ArrangerViewFocus::PhraseEditor => PhraseEditorCommand::input_to_command(&state.editor, input) .map(Editor), ArrangerViewFocus::Arrangement => match input.event() { key!(KeyCode::Char('e')) => Some(EditPhrase(state.arrangement.phrase())), _ => ArrangementCommand::input_to_command(&state.arrangement, &input) .map(Arrangement) } } } } } impl Command> for ArrangerViewCommand { fn execute (self, view: &mut ArrangerView) -> Perhaps { let undo = match self { Self::Focus(cmd) => delegate(cmd, Self::Focus, view), Self::Phrases(cmd) => delegate(cmd, Self::Phrases, &mut view.sequencer.phrases), Self::Editor(cmd) => delegate(cmd, Self::Editor, &mut view.sequencer.editor), Self::Transport(cmd) => delegate(cmd, Self::Transport, &mut view.sequencer.transport.state), Self::Arrangement(cmd) => delegate(cmd, Self::Arrangement, &mut view.arrangement), Self::EditPhrase(phrase) => { view.sequencer.editor.phrase = phrase.clone(); view.focus(ArrangerViewFocus::PhraseEditor); view.focus_enter(); Ok(None) } }?; view.sequencer.show_phrase(); view.sequencer.update_status(); return Ok(undo); } }