1#[derive(Debug, Clone)]
31pub struct FocusManager<T> {
32 elements: Vec<T>,
33 current: usize,
34}
35
36impl<T> Default for FocusManager<T> {
37 fn default() -> Self {
38 Self {
39 elements: Vec::new(),
40 current: 0,
41 }
42 }
43}
44
45impl<T: Copy + Eq> FocusManager<T> {
46 pub fn new(elements: Vec<T>) -> Self {
50 Self {
51 elements,
52 current: 0,
53 }
54 }
55
56 pub fn current(&self) -> Option<T> {
58 self.elements.get(self.current).copied()
59 }
60
61 pub fn current_index(&self) -> usize {
63 self.current
64 }
65
66 pub fn focus_next(&mut self) -> Option<T> {
70 if self.elements.is_empty() {
71 return None;
72 }
73 self.current = (self.current + 1) % self.elements.len();
74 self.current()
75 }
76
77 pub fn focus_prev(&mut self) -> Option<T> {
81 if self.elements.is_empty() {
82 return None;
83 }
84 self.current = (self.current + self.elements.len() - 1) % self.elements.len();
85 self.current()
86 }
87
88 pub fn set(&mut self, element: T) -> bool {
92 if let Some(idx) = self.elements.iter().position(|&e| e == element) {
93 self.current = idx;
94 true
95 } else {
96 false
97 }
98 }
99
100 pub fn set_index(&mut self, index: usize) -> bool {
104 if index < self.elements.len() {
105 self.current = index;
106 true
107 } else {
108 false
109 }
110 }
111
112 pub fn is_current(&self, element: T) -> bool {
114 self.current() == Some(element)
115 }
116
117 pub fn len(&self) -> usize {
119 self.elements.len()
120 }
121
122 pub fn is_empty(&self) -> bool {
124 self.elements.is_empty()
125 }
126}
127
128#[cfg(test)]
129mod tests {
130 use super::*;
131
132 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
133 enum TestPanel {
134 A,
135 B,
136 C,
137 }
138
139 #[test]
140 fn test_new_starts_at_first() {
141 let focus = FocusManager::new(vec![TestPanel::A, TestPanel::B, TestPanel::C]);
142 assert_eq!(focus.current(), Some(TestPanel::A));
143 assert_eq!(focus.current_index(), 0);
144 }
145
146 #[test]
147 fn test_focus_next_cycles() {
148 let mut focus = FocusManager::new(vec![TestPanel::A, TestPanel::B, TestPanel::C]);
149
150 assert_eq!(focus.focus_next(), Some(TestPanel::B));
151 assert_eq!(focus.focus_next(), Some(TestPanel::C));
152 assert_eq!(focus.focus_next(), Some(TestPanel::A)); }
154
155 #[test]
156 fn test_focus_prev_cycles() {
157 let mut focus = FocusManager::new(vec![TestPanel::A, TestPanel::B, TestPanel::C]);
158
159 assert_eq!(focus.focus_prev(), Some(TestPanel::C)); assert_eq!(focus.focus_prev(), Some(TestPanel::B));
161 assert_eq!(focus.focus_prev(), Some(TestPanel::A));
162 }
163
164 #[test]
165 fn test_set_element() {
166 let mut focus = FocusManager::new(vec![TestPanel::A, TestPanel::B, TestPanel::C]);
167
168 assert!(focus.set(TestPanel::C));
169 assert_eq!(focus.current(), Some(TestPanel::C));
170 assert_eq!(focus.current_index(), 2);
171 }
172
173 #[test]
174 fn test_set_index() {
175 let mut focus = FocusManager::new(vec![TestPanel::A, TestPanel::B, TestPanel::C]);
176
177 assert!(focus.set_index(1));
178 assert_eq!(focus.current(), Some(TestPanel::B));
179
180 assert!(!focus.set_index(10)); assert_eq!(focus.current(), Some(TestPanel::B)); }
183
184 #[test]
185 fn test_is_current() {
186 let focus = FocusManager::new(vec![TestPanel::A, TestPanel::B, TestPanel::C]);
187
188 assert!(focus.is_current(TestPanel::A));
189 assert!(!focus.is_current(TestPanel::B));
190 }
191
192 #[test]
193 fn test_empty_manager() {
194 let mut focus: FocusManager<TestPanel> = FocusManager::new(vec![]);
195
196 assert_eq!(focus.current(), None);
197 assert_eq!(focus.focus_next(), None);
198 assert_eq!(focus.focus_prev(), None);
199 assert!(focus.is_empty());
200 }
201
202 #[test]
203 fn test_single_element() {
204 let mut focus = FocusManager::new(vec![TestPanel::A]);
205
206 assert_eq!(focus.current(), Some(TestPanel::A));
207 assert_eq!(focus.focus_next(), Some(TestPanel::A)); assert_eq!(focus.focus_prev(), Some(TestPanel::A)); }
210}