Files
gpx.studio/gpx-rs/src/stack.rs
T

103 lines
2.5 KiB
Rust
Raw Normal View History

2026-07-14 18:36:30 +02:00
use std::{collections::HashMap, rc::Rc};
2026-09-18 09:03:51 +02:00
use crate::gpx::GPXFile;
pub type GPXFileId = usize;
2026-07-14 18:36:30 +02:00
#[derive(Default)]
pub struct Stack {
entries: Vec<StackEntry>,
index: Option<usize>,
}
impl Stack {
pub fn current(&self) -> Option<&StackEntry> {
match self.index {
Some(i) => Some(&self.entries[i]),
None => None,
}
}
pub fn get_new_file_id(&self) -> GPXFileId {
if let Some(current) = self.current() {
for id in 0..current.len() {
if !current.contains_key(&id) {
return id;
}
}
current.len() as GPXFileId
} else {
0
}
}
2026-09-18 09:03:51 +02:00
pub fn update(&mut self, files: &[Rc<GPXFile>], ids: &[GPXFileId]) {
2026-07-14 18:36:30 +02:00
let mut next = match self.current() {
Some(current) => current.clone(),
None => StackEntry::default(),
};
2026-09-18 09:03:51 +02:00
for (file, id) in files.iter().zip(ids) {
next.insert(*id, file.clone());
2026-07-14 18:36:30 +02:00
}
self.push(next);
}
pub fn delete(&mut self, files: &[GPXFileId]) {
if let Some(current) = self.current() {
let mut next = current.clone();
for file in files {
next.remove(file);
}
self.push(next);
}
}
pub fn can_undo(&self) -> bool {
self.index.is_some()
}
pub fn can_redo(&self) -> bool {
match self.index {
Some(i) => i + 1 < self.entries.len(),
None => !self.entries.is_empty(),
}
}
pub fn undo(&mut self) {
if let Some(i) = self.index {
if i == 0 {
self.index = None;
} else {
self.index = Some(i - 1);
}
}
}
pub fn redo(&mut self) {
match self.index {
Some(i) => {
if i + 1 < self.entries.len() {
self.index = Some(i + 1);
}
}
None => {
if !self.entries.is_empty() {
self.index = Some(0);
}
}
}
}
fn push(&mut self, entry: StackEntry) {
if let Some(i) = self.index {
if i + 1 < self.entries.len() {
self.entries.truncate(i + 1);
}
}
self.entries.push(entry);
self.index = Some(self.entries.len() - 1);
}
}
pub type StackEntry = HashMap<GPXFileId, Rc<GPXFile>>;