use crate::persistence::AppStateSerde;
const DEFAULT_UNDO_LIMIT: usize = 100;
#[derive(Debug, Clone)]
pub struct LivePlotUndoEntry {
pub old_state: AppStateSerde,
pub new_state: AppStateSerde,
pub description: String,
}
pub struct LivePlotUndoStack {
undo: Vec<LivePlotUndoEntry>,
redo: Vec<LivePlotUndoEntry>,
pub limit: usize,
}
impl Default for LivePlotUndoStack {
fn default() -> Self {
Self {
undo: Vec::new(),
redo: Vec::new(),
limit: DEFAULT_UNDO_LIMIT,
}
}
}
impl LivePlotUndoStack {
pub fn new() -> Self {
Self::default()
}
pub fn push(&mut self, entry: LivePlotUndoEntry) {
self.undo.push(entry);
self.redo.clear();
self.enforce_limit();
}
pub fn can_undo(&self) -> bool {
!self.undo.is_empty()
}
pub fn can_redo(&self) -> bool {
!self.redo.is_empty()
}
pub fn undo_description(&self) -> Option<&str> {
self.undo.last().map(|e| e.description.as_str())
}
pub fn redo_description(&self) -> Option<&str> {
self.redo.last().map(|e| e.description.as_str())
}
pub fn pop_undo(&mut self) -> Option<LivePlotUndoEntry> {
self.undo.pop()
}
pub fn pop_redo(&mut self) -> Option<LivePlotUndoEntry> {
self.redo.pop()
}
pub fn push_redo(&mut self, entry: LivePlotUndoEntry) {
self.redo.push(entry);
}
pub fn push_undo(&mut self, entry: LivePlotUndoEntry) {
self.undo.push(entry);
self.enforce_limit();
}
pub fn clear(&mut self) {
self.undo.clear();
self.redo.clear();
}
pub fn undo_len(&self) -> usize {
self.undo.len()
}
pub fn redo_len(&self) -> usize {
self.redo.len()
}
fn enforce_limit(&mut self) {
while self.undo.len() > self.limit {
self.undo.remove(0);
}
}
}