Feat: entretien de la codebase

This commit is contained in:
2026-02-09 21:12:49 +01:00
parent a5f17687f1
commit 869d3af244
25 changed files with 847 additions and 878 deletions

View File

@@ -11,8 +11,9 @@ use crate::engine::{AudioCommand, LinkState, SeqCommand, SequencerSnapshot};
use crate::model::PatternSpeed;
use crate::page::Page;
use crate::state::{
CyclicEnum, DeviceKind, EditorTarget, EngineSection, EuclideanField, Modal, OptionsFocus,
PanelFocus, PatternField, PatternPropsField, SampleBrowserState, SettingKind, SidePanel,
ConfirmAction, CyclicEnum, DeviceKind, EditorTarget, EngineSection, EuclideanField, Modal,
OptionsFocus, PanelFocus, PatternField, PatternPropsField, RenameTarget, SampleBrowserState,
SettingKind, SidePanel,
};
pub enum InputResult {
@@ -79,169 +80,61 @@ fn handle_live_keys(ctx: &mut InputContext, key: &KeyEvent) -> bool {
}
}
fn execute_confirm(ctx: &mut InputContext, action: &ConfirmAction) -> InputResult {
match action {
ConfirmAction::Quit => return InputResult::Quit,
ConfirmAction::DeleteStep { bank, pattern, step } => {
ctx.dispatch(AppCommand::DeleteStep { bank: *bank, pattern: *pattern, step: *step });
}
ConfirmAction::DeleteSteps { bank, pattern, steps } => {
ctx.dispatch(AppCommand::DeleteSteps { bank: *bank, pattern: *pattern, steps: steps.clone() });
}
ConfirmAction::ResetPattern { bank, pattern } => {
ctx.dispatch(AppCommand::ResetPattern { bank: *bank, pattern: *pattern });
}
ConfirmAction::ResetBank { bank } => {
ctx.dispatch(AppCommand::ResetBank { bank: *bank });
}
ConfirmAction::ResetPatterns { bank, patterns } => {
ctx.dispatch(AppCommand::ResetPatterns { bank: *bank, patterns: patterns.clone() });
}
ConfirmAction::ResetBanks { banks } => {
ctx.dispatch(AppCommand::ResetBanks { banks: banks.clone() });
}
}
ctx.dispatch(AppCommand::CloseModal);
InputResult::Continue
}
fn rename_command(target: &RenameTarget, name: Option<String>) -> AppCommand {
match target {
RenameTarget::Bank { bank } => AppCommand::RenameBank { bank: *bank, name },
RenameTarget::Pattern { bank, pattern } => AppCommand::RenamePattern {
bank: *bank, pattern: *pattern, name,
},
RenameTarget::Step { bank, pattern, step } => AppCommand::RenameStep {
bank: *bank, pattern: *pattern, step: *step, name,
},
}
}
fn handle_modal_input(ctx: &mut InputContext, key: KeyEvent) -> InputResult {
match &mut ctx.app.ui.modal {
Modal::ConfirmQuit { selected } => match key.code {
KeyCode::Char('y') | KeyCode::Char('Y') => return InputResult::Quit,
KeyCode::Char('n') | KeyCode::Char('N') | KeyCode::Esc => {
ctx.dispatch(AppCommand::CloseModal);
}
KeyCode::Left | KeyCode::Right => {
*selected = !*selected;
}
KeyCode::Enter => {
if *selected {
return InputResult::Quit;
} else {
ctx.dispatch(AppCommand::CloseModal);
}
}
_ => {}
},
Modal::ConfirmDeleteStep {
bank,
pattern,
step,
selected: _,
} => {
let (bank, pattern, step) = (*bank, *pattern, *step);
Modal::Confirm { action, selected } => {
let (action, confirmed) = (action.clone(), *selected);
match key.code {
KeyCode::Char('y') | KeyCode::Char('Y') => {
ctx.dispatch(AppCommand::DeleteStep {
bank,
pattern,
step,
});
ctx.dispatch(AppCommand::CloseModal);
}
KeyCode::Char('y') | KeyCode::Char('Y') => return execute_confirm(ctx, &action),
KeyCode::Char('n') | KeyCode::Char('N') | KeyCode::Esc => {
ctx.dispatch(AppCommand::CloseModal);
}
KeyCode::Left | KeyCode::Right => {
if let Modal::ConfirmDeleteStep { selected, .. } = &mut ctx.app.ui.modal {
if let Modal::Confirm { selected, .. } = &mut ctx.app.ui.modal {
*selected = !*selected;
}
}
KeyCode::Enter => {
let do_delete =
if let Modal::ConfirmDeleteStep { selected, .. } = &ctx.app.ui.modal {
*selected
} else {
false
};
if do_delete {
ctx.dispatch(AppCommand::DeleteStep {
bank,
pattern,
step,
});
}
ctx.dispatch(AppCommand::CloseModal);
}
_ => {}
}
}
Modal::ConfirmDeleteSteps {
bank,
pattern,
steps,
selected: _,
} => {
let (bank, pattern, steps) = (*bank, *pattern, steps.clone());
match key.code {
KeyCode::Char('y') | KeyCode::Char('Y') => {
ctx.dispatch(AppCommand::DeleteSteps {
bank,
pattern,
steps,
});
ctx.dispatch(AppCommand::CloseModal);
}
KeyCode::Char('n') | KeyCode::Char('N') | KeyCode::Esc => {
ctx.dispatch(AppCommand::CloseModal);
}
KeyCode::Left | KeyCode::Right => {
if let Modal::ConfirmDeleteSteps { selected, .. } = &mut ctx.app.ui.modal {
*selected = !*selected;
}
}
KeyCode::Enter => {
let do_delete =
if let Modal::ConfirmDeleteSteps { selected, .. } = &ctx.app.ui.modal {
*selected
} else {
false
};
if do_delete {
ctx.dispatch(AppCommand::DeleteSteps {
bank,
pattern,
steps,
});
}
ctx.dispatch(AppCommand::CloseModal);
}
_ => {}
}
}
Modal::ConfirmResetPattern {
bank,
pattern,
selected: _,
} => {
let (bank, pattern) = (*bank, *pattern);
match key.code {
KeyCode::Char('y') | KeyCode::Char('Y') => {
ctx.dispatch(AppCommand::ResetPattern { bank, pattern });
ctx.dispatch(AppCommand::CloseModal);
}
KeyCode::Char('n') | KeyCode::Char('N') | KeyCode::Esc => {
ctx.dispatch(AppCommand::CloseModal);
}
KeyCode::Left | KeyCode::Right => {
if let Modal::ConfirmResetPattern { selected, .. } = &mut ctx.app.ui.modal {
*selected = !*selected;
}
}
KeyCode::Enter => {
let do_reset =
if let Modal::ConfirmResetPattern { selected, .. } = &ctx.app.ui.modal {
*selected
} else {
false
};
if do_reset {
ctx.dispatch(AppCommand::ResetPattern { bank, pattern });
}
ctx.dispatch(AppCommand::CloseModal);
}
_ => {}
}
}
Modal::ConfirmResetBank { bank, selected: _ } => {
let bank = *bank;
match key.code {
KeyCode::Char('y') | KeyCode::Char('Y') => {
ctx.dispatch(AppCommand::ResetBank { bank });
ctx.dispatch(AppCommand::CloseModal);
}
KeyCode::Char('n') | KeyCode::Char('N') | KeyCode::Esc => {
ctx.dispatch(AppCommand::CloseModal);
}
KeyCode::Left | KeyCode::Right => {
if let Modal::ConfirmResetBank { selected, .. } = &mut ctx.app.ui.modal {
*selected = !*selected;
}
}
KeyCode::Enter => {
let do_reset =
if let Modal::ConfirmResetBank { selected, .. } = &ctx.app.ui.modal {
*selected
} else {
false
};
if do_reset {
ctx.dispatch(AppCommand::ResetBank { bank });
if confirmed {
return execute_confirm(ctx, &action);
}
ctx.dispatch(AppCommand::CloseModal);
}
@@ -278,81 +171,32 @@ fn handle_modal_input(ctx: &mut InputContext, key: KeyEvent) -> InputResult {
}
_ => {}
},
Modal::RenameBank { bank, name } => match key.code {
KeyCode::Enter => {
let bank_idx = *bank;
let new_name = if name.trim().is_empty() {
None
} else {
Some(name.clone())
};
ctx.dispatch(AppCommand::RenameBank {
bank: bank_idx,
name: new_name,
});
ctx.dispatch(AppCommand::CloseModal);
Modal::Rename { target, name } => {
let target = target.clone();
match key.code {
KeyCode::Enter => {
let new_name = if name.trim().is_empty() {
None
} else {
Some(name.clone())
};
ctx.dispatch(rename_command(&target, new_name));
ctx.dispatch(AppCommand::CloseModal);
}
KeyCode::Esc => ctx.dispatch(AppCommand::CloseModal),
KeyCode::Backspace => {
if let Modal::Rename { name, .. } = &mut ctx.app.ui.modal {
name.pop();
}
}
KeyCode::Char(c) => {
if let Modal::Rename { name, .. } = &mut ctx.app.ui.modal {
name.push(c);
}
}
_ => {}
}
KeyCode::Esc => ctx.dispatch(AppCommand::CloseModal),
KeyCode::Backspace => {
name.pop();
}
KeyCode::Char(c) => name.push(c),
_ => {}
},
Modal::RenamePattern {
bank,
pattern,
name,
} => match key.code {
KeyCode::Enter => {
let (bank_idx, pattern_idx) = (*bank, *pattern);
let new_name = if name.trim().is_empty() {
None
} else {
Some(name.clone())
};
ctx.dispatch(AppCommand::RenamePattern {
bank: bank_idx,
pattern: pattern_idx,
name: new_name,
});
ctx.dispatch(AppCommand::CloseModal);
}
KeyCode::Esc => ctx.dispatch(AppCommand::CloseModal),
KeyCode::Backspace => {
name.pop();
}
KeyCode::Char(c) => name.push(c),
_ => {}
},
Modal::RenameStep {
bank,
pattern,
step,
name,
} => match key.code {
KeyCode::Enter => {
let (bank_idx, pattern_idx, step_idx) = (*bank, *pattern, *step);
let new_name = if name.trim().is_empty() {
None
} else {
Some(name.clone())
};
ctx.dispatch(AppCommand::RenameStep {
bank: bank_idx,
pattern: pattern_idx,
step: step_idx,
name: new_name,
});
ctx.dispatch(AppCommand::CloseModal);
}
KeyCode::Esc => ctx.dispatch(AppCommand::CloseModal),
KeyCode::Backspace => {
name.pop();
}
KeyCode::Char(c) => name.push(c),
_ => {}
},
}
Modal::SetPattern { field, input } => match key.code {
KeyCode::Enter => {
let field = *field;
@@ -774,70 +618,6 @@ fn handle_modal_input(ctx: &mut InputContext, key: KeyEvent) -> InputResult {
_ => {}
}
}
Modal::ConfirmResetPatterns {
bank,
patterns,
selected: _,
} => {
let (bank, patterns) = (*bank, patterns.clone());
match key.code {
KeyCode::Char('y') | KeyCode::Char('Y') => {
ctx.dispatch(AppCommand::ResetPatterns { bank, patterns });
ctx.dispatch(AppCommand::CloseModal);
}
KeyCode::Char('n') | KeyCode::Char('N') | KeyCode::Esc => {
ctx.dispatch(AppCommand::CloseModal);
}
KeyCode::Left | KeyCode::Right => {
if let Modal::ConfirmResetPatterns { selected, .. } = &mut ctx.app.ui.modal {
*selected = !*selected;
}
}
KeyCode::Enter => {
let do_reset =
if let Modal::ConfirmResetPatterns { selected, .. } = &ctx.app.ui.modal {
*selected
} else {
false
};
if do_reset {
ctx.dispatch(AppCommand::ResetPatterns { bank, patterns });
}
ctx.dispatch(AppCommand::CloseModal);
}
_ => {}
}
}
Modal::ConfirmResetBanks { banks, selected: _ } => {
let banks = banks.clone();
match key.code {
KeyCode::Char('y') | KeyCode::Char('Y') => {
ctx.dispatch(AppCommand::ResetBanks { banks });
ctx.dispatch(AppCommand::CloseModal);
}
KeyCode::Char('n') | KeyCode::Char('N') | KeyCode::Esc => {
ctx.dispatch(AppCommand::CloseModal);
}
KeyCode::Left | KeyCode::Right => {
if let Modal::ConfirmResetBanks { selected, .. } = &mut ctx.app.ui.modal {
*selected = !*selected;
}
}
KeyCode::Enter => {
let do_reset =
if let Modal::ConfirmResetBanks { selected, .. } = &ctx.app.ui.modal {
*selected
} else {
false
};
if do_reset {
ctx.dispatch(AppCommand::ResetBanks { banks });
}
ctx.dispatch(AppCommand::CloseModal);
}
_ => {}
}
}
Modal::None => unreachable!(),
}
InputResult::Continue
@@ -996,7 +776,8 @@ fn handle_main_page(ctx: &mut InputContext, key: KeyEvent, ctrl: bool) -> InputR
}
}
KeyCode::Char('q') => {
ctx.dispatch(AppCommand::OpenModal(Modal::ConfirmQuit {
ctx.dispatch(AppCommand::OpenModal(Modal::Confirm {
action: ConfirmAction::Quit,
selected: false,
}));
}
@@ -1114,18 +895,14 @@ fn handle_main_page(ctx: &mut InputContext, key: KeyEvent, ctrl: bool) -> InputR
let (bank, pattern) = (ctx.app.editor_ctx.bank, ctx.app.editor_ctx.pattern);
if let Some(range) = ctx.app.editor_ctx.selection_range() {
let steps: Vec<usize> = range.collect();
ctx.dispatch(AppCommand::OpenModal(Modal::ConfirmDeleteSteps {
bank,
pattern,
steps,
ctx.dispatch(AppCommand::OpenModal(Modal::Confirm {
action: ConfirmAction::DeleteSteps { bank, pattern, steps },
selected: false,
}));
} else {
let step = ctx.app.editor_ctx.step;
ctx.dispatch(AppCommand::OpenModal(Modal::ConfirmDeleteStep {
bank,
pattern,
step,
ctx.dispatch(AppCommand::OpenModal(Modal::Confirm {
action: ConfirmAction::DeleteStep { bank, pattern, step },
selected: false,
}));
}
@@ -1163,10 +940,8 @@ fn handle_main_page(ctx: &mut InputContext, key: KeyEvent, ctrl: bool) -> InputR
.step(step)
.and_then(|s| s.name.clone())
.unwrap_or_default();
ctx.dispatch(AppCommand::OpenModal(Modal::RenameStep {
bank,
pattern,
step,
ctx.dispatch(AppCommand::OpenModal(Modal::Rename {
target: RenameTarget::Step { bank, pattern, step },
name: current_name,
}));
}
@@ -1308,7 +1083,8 @@ fn handle_patterns_page(ctx: &mut InputContext, key: KeyEvent) -> InputResult {
}
}
KeyCode::Char('q') => {
ctx.dispatch(AppCommand::OpenModal(Modal::ConfirmQuit {
ctx.dispatch(AppCommand::OpenModal(Modal::Confirm {
action: ConfirmAction::Quit,
selected: false,
}));
}
@@ -1368,13 +1144,13 @@ fn handle_patterns_page(ctx: &mut InputContext, key: KeyEvent) -> InputResult {
PatternsColumn::Banks => {
let banks = ctx.app.patterns_nav.selected_banks();
if banks.len() > 1 {
ctx.dispatch(AppCommand::OpenModal(Modal::ConfirmResetBanks {
banks,
ctx.dispatch(AppCommand::OpenModal(Modal::Confirm {
action: ConfirmAction::ResetBanks { banks },
selected: false,
}));
} else {
ctx.dispatch(AppCommand::OpenModal(Modal::ConfirmResetBank {
bank,
ctx.dispatch(AppCommand::OpenModal(Modal::Confirm {
action: ConfirmAction::ResetBank { bank },
selected: false,
}));
}
@@ -1382,16 +1158,14 @@ fn handle_patterns_page(ctx: &mut InputContext, key: KeyEvent) -> InputResult {
PatternsColumn::Patterns => {
let patterns = ctx.app.patterns_nav.selected_patterns();
if patterns.len() > 1 {
ctx.dispatch(AppCommand::OpenModal(Modal::ConfirmResetPatterns {
bank,
patterns,
ctx.dispatch(AppCommand::OpenModal(Modal::Confirm {
action: ConfirmAction::ResetPatterns { bank, patterns },
selected: false,
}));
} else {
let pattern = ctx.app.patterns_nav.pattern_cursor;
ctx.dispatch(AppCommand::OpenModal(Modal::ConfirmResetPattern {
bank,
pattern,
ctx.dispatch(AppCommand::OpenModal(Modal::Confirm {
action: ConfirmAction::ResetPattern { bank, pattern },
selected: false,
}));
}
@@ -1407,8 +1181,8 @@ fn handle_patterns_page(ctx: &mut InputContext, key: KeyEvent) -> InputResult {
.name
.clone()
.unwrap_or_default();
ctx.dispatch(AppCommand::OpenModal(Modal::RenameBank {
bank,
ctx.dispatch(AppCommand::OpenModal(Modal::Rename {
target: RenameTarget::Bank { bank },
name: current_name,
}));
}
@@ -1419,9 +1193,8 @@ fn handle_patterns_page(ctx: &mut InputContext, key: KeyEvent) -> InputResult {
.name
.clone()
.unwrap_or_default();
ctx.dispatch(AppCommand::OpenModal(Modal::RenamePattern {
bank,
pattern,
ctx.dispatch(AppCommand::OpenModal(Modal::Rename {
target: RenameTarget::Pattern { bank, pattern },
name: current_name,
}));
}
@@ -1468,7 +1241,8 @@ fn handle_patterns_page(ctx: &mut InputContext, key: KeyEvent) -> InputResult {
fn handle_engine_page(ctx: &mut InputContext, key: KeyEvent) -> InputResult {
match key.code {
KeyCode::Char('q') => {
ctx.dispatch(AppCommand::OpenModal(Modal::ConfirmQuit {
ctx.dispatch(AppCommand::OpenModal(Modal::Confirm {
action: ConfirmAction::Quit,
selected: false,
}));
}
@@ -1649,7 +1423,8 @@ fn handle_engine_page(ctx: &mut InputContext, key: KeyEvent) -> InputResult {
fn handle_options_page(ctx: &mut InputContext, key: KeyEvent) -> InputResult {
match key.code {
KeyCode::Char('q') => {
ctx.dispatch(AppCommand::OpenModal(Modal::ConfirmQuit {
ctx.dispatch(AppCommand::OpenModal(Modal::Confirm {
action: ConfirmAction::Quit,
selected: false,
}));
}
@@ -1858,7 +1633,8 @@ fn handle_help_page(ctx: &mut InputContext, key: KeyEvent) -> InputResult {
KeyCode::PageDown => ctx.dispatch(AppCommand::HelpScrollDown(10)),
KeyCode::PageUp => ctx.dispatch(AppCommand::HelpScrollUp(10)),
KeyCode::Char('q') => {
ctx.dispatch(AppCommand::OpenModal(Modal::ConfirmQuit {
ctx.dispatch(AppCommand::OpenModal(Modal::Confirm {
action: ConfirmAction::Quit,
selected: false,
}));
}
@@ -1911,7 +1687,8 @@ fn handle_dict_page(ctx: &mut InputContext, key: KeyEvent) -> InputResult {
KeyCode::PageDown => ctx.dispatch(AppCommand::DictScrollDown(10)),
KeyCode::PageUp => ctx.dispatch(AppCommand::DictScrollUp(10)),
KeyCode::Char('q') => {
ctx.dispatch(AppCommand::OpenModal(Modal::ConfirmQuit {
ctx.dispatch(AppCommand::OpenModal(Modal::Confirm {
action: ConfirmAction::Quit,
selected: false,
}));
}