use crate::*; #[derive(Clone, PartialEq)] pub enum PhraseEditorCommand { // TODO: 1-9 seek markers that by default start every 8th of the phrase ToggleDirection, EnterEditMode, ExitEditMode, NoteAppend, NoteSet, NoteCursorSet(usize), NoteLengthSet(usize), NoteScrollSet(usize), TimeCursorSet(usize), TimeScrollSet(usize), TimeZoomSet(usize), } impl Handle for PhraseEditor { fn handle (&mut self, from: &TuiInput) -> Perhaps { PhraseEditorCommand::execute_with_state(self, from) } } impl InputToCommand> for PhraseEditorCommand { fn input_to_command (state: &PhraseEditor, from: &TuiInput) -> Option { use PhraseEditorCommand::*; Some(match from.event() { key!(KeyCode::Char('`')) => ToggleDirection, key!(KeyCode::Enter) => EnterEditMode, key!(KeyCode::Esc) => ExitEditMode, key!(KeyCode::Char('[')) => NoteLengthSet(0), key!(KeyCode::Char(']')) => NoteLengthSet(0), key!(KeyCode::Char('a')) => NoteAppend, key!(KeyCode::Char('s')) => NoteSet, key!(KeyCode::Char('-')) => TimeZoomSet(0), key!(KeyCode::Char('_')) => TimeZoomSet(0), key!(KeyCode::Char('=')) => TimeZoomSet(0), key!(KeyCode::Char('+')) => TimeZoomSet(0), key!(KeyCode::PageUp) => NoteScrollSet(0), key!(KeyCode::PageDown) => NoteScrollSet(0), key!(KeyCode::Up) => match state.entered { true => NoteCursorSet(0), false => NoteScrollSet(0), }, key!(KeyCode::Down) => match state.entered { true => NoteCursorSet(0), false => NoteScrollSet(0), }, key!(KeyCode::Left) => match state.entered { true => TimeCursorSet(0), false => TimeScrollSet(0), }, key!(KeyCode::Right) => match state.entered { true => TimeCursorSet(0), false => TimeScrollSet(0), }, _ => return None }) } } impl Command> for PhraseEditorCommand { //fn translate (self, state: &PhraseEditor) -> Self { //use PhraseEditorCommand::*; //match self { //GoUp => match state.entered { true => NoteCursorInc, false => NoteScrollInc, }, //GoDown => match state.entered { true => NoteCursorDec, false => NoteScrollDec, }, //GoLeft => match state.entered { true => TimeCursorDec, false => TimeScrollDec, }, //GoRight => match state.entered { true => TimeCursorInc, false => TimeScrollInc, }, //_ => self //} //} fn execute (self, state: &mut PhraseEditor) -> Perhaps { use PhraseEditorCommand::*; match self.translate(state) { ToggleDirection => { state.mode = !state.mode; }, EnterEditMode => { state.entered = true; }, ExitEditMode => { state.entered = false; }, TimeZoomOut => { let scale = state.time_axis.read().unwrap().scale; state.time_axis.write().unwrap().scale = next_note_length(scale) }, TimeZoomIn => { let scale = state.time_axis.read().unwrap().scale; state.time_axis.write().unwrap().scale = prev_note_length(scale) }, TimeCursorDec => { let scale = state.time_axis.read().unwrap().scale; state.time_axis.write().unwrap().point_dec(scale); }, TimeCursorInc => { let scale = state.time_axis.read().unwrap().scale; state.time_axis.write().unwrap().point_inc(scale); }, TimeScrollDec => { let scale = state.time_axis.read().unwrap().scale; state.time_axis.write().unwrap().start_dec(scale); }, TimeScrollInc => { let scale = state.time_axis.read().unwrap().scale; state.time_axis.write().unwrap().start_inc(scale); }, NoteCursorDec => { let mut axis = state.note_axis.write().unwrap(); axis.point_inc(1); if let Some(point) = axis.point { if point > 73 { axis.point = Some(73); } } }, NoteCursorInc => { let mut axis = state.note_axis.write().unwrap(); axis.point_dec(1); if let Some(point) = axis.point { if point < axis.start { axis.start = (point / 2) * 2; } } }, NoteScrollDec => { state.note_axis.write().unwrap().start_inc(1); }, NoteScrollInc => { state.note_axis.write().unwrap().start_dec(1); }, NoteLengthDec => { state.note_len = prev_note_length(state.note_len) }, NoteLengthInc => { state.note_len = next_note_length(state.note_len) }, NotePageUp => { let mut axis = state.note_axis.write().unwrap(); axis.start_dec(3); axis.point_dec(3); }, NotePageDown => { let mut axis = state.note_axis.write().unwrap(); axis.start_inc(3); axis.point_inc(3); }, NoteAppend => { if state.entered { state.put(); state.time_cursor_advance(); } }, NoteSet => { if state.entered { state.put(); } }, _ => unreachable!() } Ok(None) } }