From 194dfcf0ec6b79fb0d272f0c8ff3cd598f4cfaa1 Mon Sep 17 00:00:00 2001 From: aiongg Date: Wed, 21 Oct 2026 01:57:07 +0000 Subject: [PATCH] Integration: Clear History resets the History Brush source and Undo brings it back, for #3534 and #3536 --- crates/ops/src/lib.rs | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/crates/ops/src/lib.rs b/crates/ops/src/lib.rs index a0e274f801..498c1deb8e 100644 --- a/crates/ops/src/lib.rs +++ b/crates/ops/src/lib.rs @@ -63,11 +63,13 @@ pub struct History { brush_source: Option, } -/// The undo and redo states [`History::clear_states`] removed. +/// The undo and redo states [`History::clear_states`] removed, and the History Brush source set +/// before it. #[derive(Clone, Debug)] struct Cleared { undo: VecDeque, redo: Vec, + brush_source: Option, } /// The undo label of the step [`History::clear_states`] adds (Edit › Undo Clear History). @@ -157,9 +159,10 @@ impl History { pub fn undo(&mut self, current: Arc) -> Option<(Arc, LayerTarget)> { // Undo Clear History: the cleared states come back; the document doesn't change. if let Some(cleared) = self.cleared.take() { - let Cleared { undo, redo } = *cleared; + let Cleared { undo, redo, brush_source } = *cleared; self.undo = undo; self.redo = redo; + self.brush_source = brush_source; self.tiles = None; return Some((current, self.current_layers.clone())); } @@ -307,6 +310,7 @@ impl History { /// History panel › Clear History: take every state but the current one off the list without /// changing the document. Unlike [`Self::clear`] (Edit › Purge › Histories) it is undoable: /// the next [`Self::undo`] puts the states back, and the next recorded step forgets them. + /// The History Brush's source goes back to the default until that undo, as in [`Self::clear`]. /// Returns false (and changes nothing) when the current state is the only one. pub fn clear_states(&mut self) -> bool { if self.undo.is_empty() && self.redo.is_empty() { @@ -314,7 +318,8 @@ impl History { } let undo = std::mem::take(&mut self.undo); let redo = std::mem::take(&mut self.redo); - self.cleared = Some(Box::new(Cleared { undo, redo })); + let brush_source = self.brush_source.take(); + self.cleared = Some(Box::new(Cleared { undo, redo, brush_source })); self.tiles = None; true } @@ -662,6 +667,22 @@ mod tests { assert_eq!(h.row_doc(0, &cur).unwrap().name, "b"); } + /// History panel › Clear History leaves a usable (default) source, and its undo restores the + /// source set on a past state. + #[test] + fn clear_states_resets_the_brush_source_until_undo() { + let mut h = History::new(50); + let mut cur = Arc::new(base()); + edit(&mut h, &mut cur, "A", |d| d.name = "a".into()); + edit(&mut h, &mut cur, "B", |d| d.name = "b".into()); + assert!(h.set_brush_source(1)); + assert!(h.clear_states()); + assert_eq!(h.brush_source(), Some(0)); + assert_eq!(h.row_doc(0, &cur).unwrap().name, "b"); + cur = h.undo(cur).unwrap().0; + assert_eq!((h.brush_source(), h.row_doc(1, &cur).unwrap().name.as_str()), (Some(1), "a")); + } + #[test] fn new_edit_clears_redo() { let mut h = History::default();