use super::types::UndoHistory;
#[derive(Clone, Debug)]
pub struct UndoGroup<T> {
pub operations: Vec<T>,
}
impl<T> Default for UndoGroup<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> UndoGroup<T> {
pub fn new() -> Self {
Self {
operations: Vec::new(),
}
}
pub fn push(&mut self, op: T) {
self.operations.push(op);
}
pub fn is_empty(&self) -> bool {
self.operations.is_empty()
}
pub fn len(&self) -> usize {
self.operations.len()
}
pub fn into_operations(self) -> Vec<T> {
self.operations
}
pub fn operations(&self) -> &[T] {
&self.operations
}
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.operations.iter()
}
pub fn iter_rev(&self) -> impl Iterator<Item = &T> {
self.operations.iter().rev()
}
}
impl<T: Clone> UndoGroup<T> {
pub fn reversed(&self) -> Vec<T> {
self.operations.iter().rev().cloned().collect()
}
}
#[derive(Clone, Debug)]
pub struct GroupedUndoHistory<T> {
pub history: UndoHistory<UndoGroup<T>>,
pub current_group: Option<UndoGroup<T>>,
}
impl<T> Default for GroupedUndoHistory<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> GroupedUndoHistory<T> {
pub fn new() -> Self {
Self {
history: UndoHistory::new(),
current_group: None,
}
}
pub fn with_max_size(max_size: usize) -> Self {
Self {
history: UndoHistory::with_max_size(max_size),
current_group: None,
}
}
pub fn begin_group(&mut self) {
if self.current_group.is_none() {
self.current_group = Some(UndoGroup::new());
}
}
pub fn end_group(&mut self) {
if let Some(group) = self.current_group.take() {
if !group.is_empty() {
self.history.push(group);
}
}
}
pub fn in_group(&self) -> bool {
self.current_group.is_some()
}
pub fn push(&mut self, op: T) {
if let Some(ref mut group) = self.current_group {
group.push(op);
} else {
let mut group = UndoGroup::new();
group.push(op);
self.history.push(group);
}
}
#[inline]
pub fn can_undo(&self) -> bool {
self.history.can_undo()
}
#[inline]
pub fn can_redo(&self) -> bool {
self.history.can_redo()
}
pub fn clear(&mut self) {
self.history.clear();
self.current_group = None;
}
}
impl<T: Clone> GroupedUndoHistory<T> {
pub fn undo(&mut self) -> Option<UndoGroup<T>> {
self.history.undo()
}
pub fn redo(&mut self) -> Option<UndoGroup<T>> {
self.history.redo()
}
}