wip: refactor pt.6, fixed tek_api

This commit is contained in:
🪞👃🪞 2024-11-10 14:35:20 +01:00
parent 5df08409e5
commit 869d92110d
29 changed files with 1678 additions and 1679 deletions

View file

@ -0,0 +1,225 @@
use crate::*;
#[derive(Clone, PartialEq)]
pub enum PhrasePoolCommand {
Prev,
Next,
MoveUp,
MoveDown,
Delete,
Append,
Insert,
Duplicate,
RandomColor,
Edit,
Import,
Export,
Rename(PhraseRenameCommand),
Length(PhraseLengthCommand),
}
#[derive(Clone, PartialEq)]
pub enum PhraseRenameCommand {
Begin,
Backspace,
Append(char),
Set(String),
Confirm,
Cancel,
}
#[derive(Clone, PartialEq)]
pub enum PhraseLengthCommand {
Begin,
Next,
Prev,
Inc,
Dec,
Set(usize),
Confirm,
Cancel,
}
impl Handle<Tui> for PhrasePool<Tui> {
fn handle (&mut self, from: &TuiInput) -> Perhaps<bool> {
if let Some(command) = PhrasePoolCommand::input_to_command(self, from) {
let _undo = command.execute(self)?;
return Ok(Some(true))
}
Ok(None)
}
}
impl InputToCommand<Tui, PhrasePool<Tui>> for PhrasePoolCommand {
fn input_to_command (state: &PhrasePool<Tui>, input: &TuiInput) -> Option<Self> {
match input.event() {
key!(KeyCode::Up) => Some(Self::Prev),
key!(KeyCode::Down) => Some(Self::Next),
key!(KeyCode::Char(',')) => Some(Self::MoveUp),
key!(KeyCode::Char('.')) => Some(Self::MoveDown),
key!(KeyCode::Delete) => Some(Self::Delete),
key!(KeyCode::Char('a')) => Some(Self::Append),
key!(KeyCode::Char('i')) => Some(Self::Insert),
key!(KeyCode::Char('d')) => Some(Self::Duplicate),
key!(KeyCode::Char('c')) => Some(Self::RandomColor),
key!(KeyCode::Char('n')) => Some(Self::Rename(PhraseRenameCommand::Begin)),
key!(KeyCode::Char('t')) => Some(Self::Length(PhraseLengthCommand::Begin)),
_ => match state.mode {
Some(PhrasePoolMode::Rename(..)) => PhraseRenameCommand::input_to_command(state, input)
.map(Self::Rename),
Some(PhrasePoolMode::Length(..)) => PhraseLengthCommand::input_to_command(state, input)
.map(Self::Length),
_ => None
}
}
}
}
impl InputToCommand<Tui, PhrasePool<Tui>> for PhraseRenameCommand {
fn input_to_command (_: &PhrasePool<Tui>, from: &TuiInput) -> Option<Self> {
match from.event() {
key!(KeyCode::Backspace) => Some(Self::Backspace),
key!(KeyCode::Enter) => Some(Self::Confirm),
key!(KeyCode::Esc) => Some(Self::Cancel),
key!(KeyCode::Char(c)) => Some(Self::Append(*c)),
_ => None
}
}
}
impl InputToCommand<Tui, PhrasePool<Tui>> for PhraseLengthCommand {
fn input_to_command (_: &PhrasePool<Tui>, from: &TuiInput) -> Option<Self> {
match from.event() {
key!(KeyCode::Up) => Some(Self::Inc),
key!(KeyCode::Down) => Some(Self::Dec),
key!(KeyCode::Right) => Some(Self::Next),
key!(KeyCode::Left) => Some(Self::Prev),
key!(KeyCode::Enter) => Some(Self::Confirm),
key!(KeyCode::Esc) => Some(Self::Cancel),
_ => None
}
}
}
impl<E: Engine> Command<PhrasePool<E>> for PhrasePoolCommand {
fn execute (self, state: &mut PhrasePool<E>) -> Perhaps<Self> {
use PhrasePoolCommand::*;
use PhraseRenameCommand as Rename;
use PhraseLengthCommand as Length;
match self {
Rename(Rename::Begin) => { state.begin_rename() },
Length(Length::Begin) => { state.begin_length() },
Prev => { state.select_prev() },
Next => { state.select_next() },
Delete => { state.delete_selected() },
Append => { state.append_new(None, None) },
Insert => { state.insert_new(None, None) },
Duplicate => { state.insert_dup() },
RandomColor => { state.randomize_color() },
MoveUp => { state.move_up() },
MoveDown => { state.move_down() },
_ => unreachable!(),
}
Ok(None)
}
}
impl<E: Engine> Command<PhrasePool<E>> for PhraseRenameCommand {
fn translate (self, state: &PhrasePool<E>) -> Self {
use PhraseRenameCommand::*;
if let Some(PhrasePoolMode::Rename(_, ref old_name)) = state.mode {
match self {
Backspace => {
let mut new_name = old_name.clone();
new_name.pop();
return Self::Set(new_name)
},
Append(c) => {
let mut new_name = old_name.clone();
new_name.push(c);
return Self::Set(new_name)
},
_ => {}
}
} else if self != Begin {
unreachable!()
}
self
}
fn execute (self, state: &mut PhrasePool<E>) -> Perhaps<Self> {
use PhraseRenameCommand::*;
if let Some(PhrasePoolMode::Rename(phrase, ref mut old_name)) = state.mode {
match self {
Set(s) => {
state.phrases[phrase].write().unwrap().name = s.into();
return Ok(Some(Self::Set(old_name.clone())))
},
Confirm => {
let old_name = old_name.clone();
state.mode = None;
return Ok(Some(Self::Set(old_name)))
},
Cancel => {
let mut phrase = state.phrases[phrase].write().unwrap();
phrase.name = old_name.clone();
},
_ => unreachable!()
};
Ok(None)
} else if self == Begin {
todo!()
} else {
unreachable!()
}
}
}
impl<E: Engine> Command<PhrasePool<E>> for PhraseLengthCommand {
fn translate (self, state: &PhrasePool<E>) -> Self {
use PhraseLengthCommand::*;
if let Some(PhrasePoolMode::Length(_, length, _)) = state.mode {
match self {
Confirm => { return Self::Set(length) },
_ => self
}
} else if self == Begin {
todo!()
} else {
unreachable!()
}
}
fn execute (self, state: &mut PhrasePool<E>) -> Perhaps<Self> {
use PhraseLengthFocus::*;
use PhraseLengthCommand::*;
if let Some(PhrasePoolMode::Length(phrase, ref mut length, ref mut focus)) = state.mode {
match self {
Cancel => { state.mode = None; },
Prev => { focus.prev() },
Next => { focus.next() },
Inc => match focus {
Bar => { *length += 4 * PPQ },
Beat => { *length += PPQ },
Tick => { *length += 1 },
},
Dec => match focus {
Bar => { *length = length.saturating_sub(4 * PPQ) },
Beat => { *length = length.saturating_sub(PPQ) },
Tick => { *length = length.saturating_sub(1) },
},
Set(length) => {
let mut phrase = state.phrases[phrase].write().unwrap();
let old_length = phrase.length;
phrase.length = length;
state.mode = None;
return Ok(Some(Self::Set(old_length)))
},
_ => unreachable!()
}
Ok(None)
} else if self == Begin {
todo!()
} else {
unreachable!()
}
}
}