history: Add unique mode to keep unique item in History. (#529)
This commit is contained in:
parent
99e51288e0
commit
e012eb6d07
3 changed files with 65 additions and 3 deletions
|
|
@ -28,7 +28,7 @@ const MINIMUM_SIZE: Size<Pixels> = size(px(100.), px(100.));
|
|||
const DRAG_BAR_HEIGHT: Pixels = px(30.);
|
||||
const HANDLE_SIZE: Pixels = px(20.0);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
struct TileChange {
|
||||
tile_id: EntityId,
|
||||
old_bounds: Option<Bounds<Pixels>>,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::{
|
|||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
pub trait HistoryItem: Clone {
|
||||
pub trait HistoryItem: Clone + PartialEq {
|
||||
fn version(&self) -> usize;
|
||||
fn set_version(&mut self, version: usize);
|
||||
}
|
||||
|
|
@ -22,6 +22,7 @@ pub struct History<I: HistoryItem> {
|
|||
pub(crate) ignore: bool,
|
||||
max_undo: usize,
|
||||
group_interval: Option<Duration>,
|
||||
unique: bool,
|
||||
}
|
||||
|
||||
impl<I> History<I>
|
||||
|
|
@ -37,6 +38,7 @@ where
|
|||
version: 0,
|
||||
max_undo: 1000,
|
||||
group_interval: None,
|
||||
unique: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -46,6 +48,13 @@ where
|
|||
self
|
||||
}
|
||||
|
||||
/// Set the history to be unique, defaults to false.
|
||||
/// If set to true, the history will only keep unique changes.
|
||||
pub fn unique(mut self) -> Self {
|
||||
self.unique = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the interval in milliseconds to group changes, defaults to None.
|
||||
pub fn group_interval(mut self, group_interval: Duration) -> Self {
|
||||
self.group_interval = Some(group_interval);
|
||||
|
|
@ -75,6 +84,10 @@ where
|
|||
self.undos.remove(0);
|
||||
}
|
||||
|
||||
if self.unique {
|
||||
self.undos.retain(|c| *c != item);
|
||||
}
|
||||
|
||||
let mut item = item;
|
||||
item.set_version(version);
|
||||
self.undos.push(item);
|
||||
|
|
@ -150,6 +163,12 @@ mod tests {
|
|||
version: usize,
|
||||
}
|
||||
|
||||
impl PartialEq for TabIndex {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.tab_index == other.tab_index
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for TabIndex {
|
||||
fn from(value: usize) -> Self {
|
||||
TabIndex {
|
||||
|
|
@ -210,4 +229,47 @@ mod tests {
|
|||
|
||||
assert_eq!(history.undo().is_none(), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unique_history() {
|
||||
let mut history: History<TabIndex> = History::new().max_undo(100).unique();
|
||||
|
||||
// Push some items
|
||||
history.push(0.into());
|
||||
history.push(1.into());
|
||||
history.push(1.into()); // Duplicate, should be ignored
|
||||
history.push(2.into());
|
||||
history.push(1.into()); // Duplicate, should be remove old, and add new
|
||||
|
||||
// Check the version and undo stack
|
||||
assert_eq!(history.version(), 5);
|
||||
assert_eq!(history.undos().len(), 3);
|
||||
assert_eq!(history.undos().last().unwrap().tab_index, 1);
|
||||
|
||||
// Undo the last change
|
||||
let changes = history.undo().unwrap();
|
||||
assert_eq!(changes.len(), 1);
|
||||
assert_eq!(changes[0].tab_index, 1);
|
||||
|
||||
// Redo the last undone change
|
||||
let changes = history.redo().unwrap();
|
||||
assert_eq!(changes.len(), 1);
|
||||
assert_eq!(changes[0].tab_index, 1);
|
||||
|
||||
// Push another item
|
||||
history.push(3.into());
|
||||
|
||||
// Check the version and undo stack
|
||||
assert_eq!(history.version(), 6);
|
||||
assert_eq!(history.undos().len(), 4);
|
||||
|
||||
// Undo all changes
|
||||
for _ in 0..4 {
|
||||
history.undo();
|
||||
}
|
||||
|
||||
// Check the undo stack is empty and redo stack has all changes
|
||||
assert_eq!(history.undos().len(), 0);
|
||||
assert_eq!(history.redos().len(), 4);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::{fmt::Debug, ops::Range};
|
|||
|
||||
use crate::history::HistoryItem;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct Change {
|
||||
pub(crate) old_range: Range<usize>,
|
||||
pub(crate) old_text: String,
|
||||
|
|
|
|||
Loading…
Reference in a new issue