use crate::commands::AppCommand; use crate::state::undo::{UndoEntry, UndoScope}; use super::App; impl App { pub(super) fn undoable_scope(&self, cmd: &AppCommand) -> Option { 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 = self.project_state.project.pattern_at(bank, pattern).clone(); *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 = self.project_state.project.banks[bank].clone(); let pat_count = current.patterns.len(); self.project_state.project.banks[bank] = data; 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 } } }