Files
Cagire/src/app/undo.rs
2026-02-22 13:28:03 +01:00

93 lines
4.2 KiB
Rust

use crate::commands::AppCommand;
use crate::state::undo::{UndoEntry, UndoScope};
use super::App;
impl App {
pub(super) fn undoable_scope(&self, cmd: &AppCommand) -> Option<UndoScope> {
match cmd {
AppCommand::ToggleSteps
| AppCommand::LengthIncrease
| AppCommand::LengthDecrease
| AppCommand::SpeedIncrease
| AppCommand::SpeedDecrease
| AppCommand::SaveEditorToStep
| AppCommand::CompileCurrentStep
| AppCommand::HardenSteps
| AppCommand::PasteSteps
| AppCommand::LinkPasteSteps
| AppCommand::DuplicateSteps
| AppCommand::CopySteps => {
let (bank, pattern) = self.current_bank_pattern();
let data = self.project_state.project.pattern_at(bank, pattern).clone();
Some(UndoScope::Pattern { bank, pattern, data })
}
AppCommand::SetLength { bank, pattern, .. }
| AppCommand::SetSpeed { bank, pattern, .. }
| AppCommand::DeleteStep { bank, pattern, .. }
| AppCommand::DeleteSteps { bank, pattern, .. }
| AppCommand::ResetPattern { bank, pattern }
| AppCommand::PastePattern { bank, pattern }
| AppCommand::RenamePattern { bank, pattern, .. } => {
let data = self.project_state.project.pattern_at(*bank, *pattern).clone();
Some(UndoScope::Pattern { bank: *bank, pattern: *pattern, data })
}
AppCommand::RenameStep { bank, pattern, .. } => {
let data = self.project_state.project.pattern_at(*bank, *pattern).clone();
Some(UndoScope::Pattern { bank: *bank, pattern: *pattern, data })
}
AppCommand::ApplyEuclideanDistribution { bank, pattern, .. } => {
let data = self.project_state.project.pattern_at(*bank, *pattern).clone();
Some(UndoScope::Pattern { bank: *bank, pattern: *pattern, data })
}
AppCommand::ResetBank { bank } | AppCommand::PasteBank { bank } => {
let data = self.project_state.project.banks[*bank].clone();
Some(UndoScope::Bank { bank: *bank, data })
}
AppCommand::ShiftPatternsUp | AppCommand::ShiftPatternsDown => {
let bank = self.patterns_nav.bank_cursor;
let data = self.project_state.project.banks[bank].clone();
Some(UndoScope::Bank { bank, data })
}
AppCommand::PastePatterns { bank, .. }
| AppCommand::ResetPatterns { bank, .. }
| AppCommand::RenameBank { bank, .. } => {
let data = self.project_state.project.banks[*bank].clone();
Some(UndoScope::Bank { bank: *bank, data })
}
AppCommand::PasteBanks { .. } | AppCommand::ResetBanks { .. } => None,
_ => None,
}
}
pub(super) fn apply_undo_entry(&mut self, entry: UndoEntry) -> UndoEntry {
let cursor = (self.editor_ctx.bank, self.editor_ctx.pattern, self.editor_ctx.step);
let reverse_scope = match entry.scope {
UndoScope::Pattern { bank, pattern, data } => {
let current = std::mem::replace(
self.project_state.project.pattern_at_mut(bank, pattern),
data,
);
self.project_state.mark_dirty(bank, pattern);
UndoScope::Pattern { bank, pattern, data: current }
}
UndoScope::Bank { bank, data } => {
let current = std::mem::replace(
&mut self.project_state.project.banks[bank],
data,
);
let pat_count = current.patterns.len();
for p in 0..pat_count {
self.project_state.mark_dirty(bank, p);
}
UndoScope::Bank { bank, data: current }
}
};
self.editor_ctx.bank = entry.cursor.0;
self.editor_ctx.pattern = entry.cursor.1;
self.editor_ctx.step = entry.cursor.2;
self.load_step_to_editor();
UndoEntry { scope: reverse_scope, cursor }
}
}