Skip to main content

rustapi/undo/
project_undo.rs

1// use crate::editor::{SCENEMANAGER, SHADEGRIDFX};
2use crate::prelude::*;
3use crate::undo::project_atoms::ProjectUndoAtom;
4use theframework::prelude::*;
5
6#[derive(Clone, Debug)]
7pub struct ProjectUndo {
8    pub stack: Vec<ProjectUndoAtom>,
9    pub index: isize,
10    pub saved_index: isize,
11}
12
13impl Default for ProjectUndo {
14    fn default() -> Self {
15        Self::new()
16    }
17}
18
19impl ProjectUndo {
20    pub fn new() -> Self {
21        Self {
22            stack: vec![],
23            index: -1,
24            saved_index: -1,
25        }
26    }
27
28    pub fn is_empty(&self) -> bool {
29        self.stack.is_empty()
30    }
31
32    pub fn clear(&mut self) {
33        self.stack = vec![];
34        self.index = -1;
35        self.saved_index = -1;
36    }
37
38    pub fn mark_saved(&mut self) {
39        self.saved_index = self.index;
40    }
41
42    pub fn has_unsaved(&self) -> bool {
43        self.index != self.saved_index
44    }
45
46    pub fn has_undo(&self) -> bool {
47        self.index >= 0
48    }
49
50    pub fn has_redo(&self) -> bool {
51        if self.index >= -1 && self.index < self.stack.len() as isize - 1 {
52            return true;
53        }
54        false
55    }
56
57    pub fn add(&mut self, atom: ProjectUndoAtom) {
58        let to_remove = self.stack.len() as isize - self.index - 1;
59        for _i in 0..to_remove {
60            self.stack.pop();
61        }
62        self.stack.push(atom);
63        self.index += 1;
64    }
65
66    pub fn undo(
67        &mut self,
68        project: &mut Project,
69        ui: &mut TheUI,
70        ctx: &mut TheContext,
71        server_ctx: &mut ServerContext,
72    ) {
73        if self.index >= 0 {
74            self.stack[self.index as usize].undo(project, ui, ctx, server_ctx);
75            self.index -= 1;
76        }
77    }
78
79    pub fn redo(
80        &mut self,
81        region: &mut Project,
82        ui: &mut TheUI,
83        ctx: &mut TheContext,
84        server_ctx: &mut ServerContext,
85    ) {
86        if self.index < self.stack.len() as isize - 1 {
87            self.index += 1;
88            self.stack[self.index as usize].redo(region, ui, ctx, server_ctx);
89        }
90    }
91
92    pub fn truncate_to_limit(&mut self, limit: usize) {
93        if self.stack.len() > limit {
94            let excess = self.stack.len() - limit;
95
96            // Remove the oldest `excess` entries from the front
97            self.stack.drain(0..excess);
98
99            // Adjust the index accordingly
100            self.index -= excess as isize;
101            self.saved_index -= excess as isize;
102
103            // Clamp to -1 minimum in case we truncated everything
104            if self.index < -1 {
105                self.index = -1;
106            }
107            if self.saved_index < -1 {
108                self.saved_index = -1;
109            }
110        }
111    }
112}