mathtex_editor_session/
undo.rs1use std::collections::VecDeque;
2
3use mathtex_editor_core::Snapshot;
4
5pub const DEFAULT_UNDO_LIMIT: usize = 200;
7
8#[derive(Debug, Clone)]
10pub struct UndoStack {
11 undo: VecDeque<Snapshot>,
12 redo: Vec<Snapshot>,
13 limit: usize,
14}
15
16impl Default for UndoStack {
17 fn default() -> Self {
18 Self::new(DEFAULT_UNDO_LIMIT)
19 }
20}
21
22impl UndoStack {
23 pub fn new(limit: usize) -> Self {
25 Self { undo: VecDeque::new(), redo: Vec::new(), limit }
26 }
27
28 pub fn limit(&self) -> usize {
30 self.limit
31 }
32
33 pub fn set_limit(&mut self, limit: usize) {
35 self.limit = limit;
36 self.trim();
37 }
38
39 pub fn record(&mut self, before: Snapshot) {
41 self.redo.clear();
42 self.undo.push_back(before);
43 self.trim();
44 }
45
46 pub fn undo(&mut self, current: Snapshot) -> Option<Snapshot> {
48 let target = self.undo.pop_back()?;
49 self.redo.push(current);
50 Some(target)
51 }
52
53 pub fn redo(&mut self, current: Snapshot) -> Option<Snapshot> {
55 let target = self.redo.pop()?;
56 self.undo.push_back(current);
57 self.trim();
58 Some(target)
59 }
60
61 pub fn can_undo(&self) -> bool {
63 !self.undo.is_empty()
64 }
65
66 pub fn can_redo(&self) -> bool {
68 !self.redo.is_empty()
69 }
70
71 pub fn clear(&mut self) {
73 self.undo.clear();
74 self.redo.clear();
75 }
76
77 pub fn snapshots(&self) -> impl Iterator<Item = &Snapshot> {
79 self.undo.iter().chain(&self.redo)
80 }
81
82 fn trim(&mut self) {
83 while self.undo.len() > self.limit {
84 self.undo.pop_front();
85 }
86 }
87}