tilo_app/framework/views/
stack.rs1#[derive(Clone, Debug, Default, PartialEq)]
7pub struct ViewPlace {
8 pub scroll: f64,
10 pub selection: Vec<String>,
12 pub focus: Option<String>,
14}
15
16#[derive(Clone, Debug, PartialEq)]
18pub struct ViewEntry<V> {
19 pub view: V,
20 pub place: ViewPlace,
21}
22
23#[derive(Clone, Debug)]
30pub struct ViewStack<V> {
31 back: Vec<ViewEntry<V>>,
32 current: ViewEntry<V>,
33 forward: Vec<ViewEntry<V>>,
34}
35
36impl<V: Clone + PartialEq> ViewStack<V> {
37 #[must_use]
39 pub fn new(root: V) -> Self {
40 Self {
41 back: Vec::new(),
42 current: ViewEntry {
43 view: root,
44 place: ViewPlace::default(),
45 },
46 forward: Vec::new(),
47 }
48 }
49
50 #[must_use]
52 pub fn current(&self) -> &V {
53 &self.current.view
54 }
55
56 #[must_use]
58 pub fn place(&self) -> &ViewPlace {
59 &self.current.place
60 }
61
62 #[must_use]
63 pub fn can_go_back(&self) -> bool {
64 !self.back.is_empty()
65 }
66
67 #[must_use]
68 pub fn can_go_forward(&self) -> bool {
69 !self.forward.is_empty()
70 }
71
72 #[must_use]
73 pub fn previous(&self) -> Option<&V> {
74 self.back.last().map(|entry| &entry.view)
75 }
76
77 pub fn open(&mut self, view: V, left: ViewPlace) -> bool {
81 if view == self.current.view {
82 return false;
83 }
84 self.forward.clear();
85 let entry = ViewEntry {
86 view,
87 place: ViewPlace::default(),
88 };
89 let mut leaving = std::mem::replace(&mut self.current, entry);
90 leaving.place = left;
91 self.back.push(leaving);
92 true
93 }
94
95 pub fn replace(&mut self, view: V) {
99 self.current.view = view;
100 }
101
102 pub fn back(&mut self, left: ViewPlace) -> Option<&ViewEntry<V>> {
105 let entry = self.back.pop()?;
106 let mut leaving = std::mem::replace(&mut self.current, entry);
107 leaving.place = left;
108 self.forward.push(leaving);
109 Some(&self.current)
110 }
111
112 pub fn forward(&mut self, left: ViewPlace) -> Option<&ViewEntry<V>> {
114 let entry = self.forward.pop()?;
115 let mut leaving = std::mem::replace(&mut self.current, entry);
116 leaving.place = left;
117 self.back.push(leaving);
118 Some(&self.current)
119 }
120
121 pub fn note_place(&mut self, place: ViewPlace) {
123 self.current.place = place;
124 }
125
126 pub fn forget(&mut self, mut gone: impl FnMut(&V) -> bool) {
129 self.back.retain(|entry| !gone(&entry.view));
130 self.forward.retain(|entry| !gone(&entry.view));
131 }
132}