use crate::*; /// Handle top-level events in standalone arranger. impl Handle for Arranger { fn handle (&mut self, i: &TuiInput) -> Perhaps { 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> for ArrangerCommand { fn input_to_command (state: &Arranger, input: &TuiInput) -> Option { 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 for Arrangement { fn handle (&mut self, from: &TuiInput) -> Perhaps { Ok(if let Some(command) = ArrangementCommand::input_to_command(self, from) { let _undo = command.execute(self)?; Some(true) } else { None }) } } impl InputToCommand> for ArrangementCommand { fn input_to_command (state: &Arrangement, input: &TuiInput) -> Option { 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 { ///// Helper for event passthru to focused component //fn handle_focused (&mut self, from: &TuiInput) -> Perhaps { //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 { //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 { //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)) //} //}