use crate::*; /// Handle top-level events in standalone sequencer. impl Handle for Sequencer { fn handle (&mut self, from: &TuiInput) -> Perhaps { 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 for PhrasePool { fn handle (&mut self, from: &TuiInput) -> Perhaps { 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 for PhraseEditor { fn handle (&mut self, from: &TuiInput) -> Perhaps { 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)) } }