use codegridfx::Module;
use theframework::prelude::*;
#[derive(Clone, Debug)]
pub enum VisualCodeUndoAtom {
ModuleEdit(Module, Module),
}
impl VisualCodeUndoAtom {
pub fn undo(&self, module: &mut Module, ui: &mut TheUI, ctx: &mut TheContext) {
match self {
VisualCodeUndoAtom::ModuleEdit(prev, _) => {
module.replace_preserving_runtime(prev);
module.redraw(ui, ctx);
module.show_settings(ui, ctx);
}
}
}
pub fn redo(&self, module: &mut Module, ui: &mut TheUI, ctx: &mut TheContext) {
match self {
VisualCodeUndoAtom::ModuleEdit(_, next) => {
module.replace_preserving_runtime(next);
module.redraw(ui, ctx);
module.show_settings(ui, ctx);
}
}
}
}
#[derive(Clone, Debug)]
pub struct VisualCodeUndo {
pub stack: Vec<VisualCodeUndoAtom>,
pub index: isize,
}
impl Default for VisualCodeUndo {
fn default() -> Self {
Self::new()
}
}
impl VisualCodeUndo {
pub fn new() -> Self {
Self {
stack: vec![],
index: -1,
}
}
pub fn is_empty(&self) -> bool {
self.stack.is_empty()
}
pub fn clear(&mut self) {
self.stack = vec![];
self.index = -1;
}
pub fn has_undo(&self) -> bool {
self.index >= 0
}
pub fn has_redo(&self) -> bool {
self.index >= -1 && self.index < self.stack.len() as isize - 1
}
pub fn has_changes(&self) -> bool {
self.index >= 0
}
pub fn add(&mut self, atom: VisualCodeUndoAtom) {
let to_remove = self.stack.len() as isize - self.index - 1;
for _i in 0..to_remove {
self.stack.pop();
}
self.stack.push(atom);
self.index += 1;
}
pub fn undo(&mut self, module: &mut Module, ui: &mut TheUI, ctx: &mut TheContext) {
if self.index >= 0 {
self.stack[self.index as usize].undo(module, ui, ctx);
self.index -= 1;
}
}
pub fn redo(&mut self, module: &mut Module, ui: &mut TheUI, ctx: &mut TheContext) {
if self.index < self.stack.len() as isize - 1 {
self.index += 1;
self.stack[self.index as usize].redo(module, ui, ctx);
}
}
pub fn truncate_to_limit(&mut self, limit: usize) {
if self.stack.len() > limit {
let excess = self.stack.len() - limit;
self.stack.drain(0..excess);
self.index -= excess as isize;
if self.index < -1 {
self.index = -1;
}
}
}
}