#[derive(Debug, Clone)]
pub struct FocusManager<T> {
elements: Vec<T>,
current: usize,
}
impl<T> Default for FocusManager<T> {
fn default() -> Self {
Self {
elements: Vec::new(),
current: 0,
}
}
}
impl<T: Copy + Eq> FocusManager<T> {
pub fn new(elements: Vec<T>) -> Self {
Self {
elements,
current: 0,
}
}
pub fn current(&self) -> Option<T> {
self.elements.get(self.current).copied()
}
pub fn current_index(&self) -> usize {
self.current
}
pub fn focus_next(&mut self) -> Option<T> {
if self.elements.is_empty() {
return None;
}
self.current = (self.current + 1) % self.elements.len();
self.current()
}
pub fn focus_prev(&mut self) -> Option<T> {
if self.elements.is_empty() {
return None;
}
self.current = (self.current + self.elements.len() - 1) % self.elements.len();
self.current()
}
pub fn set(&mut self, element: T) -> bool {
if let Some(idx) = self.elements.iter().position(|&e| e == element) {
self.current = idx;
true
} else {
false
}
}
pub fn set_index(&mut self, index: usize) -> bool {
if index < self.elements.len() {
self.current = index;
true
} else {
false
}
}
pub fn is_current(&self, element: T) -> bool {
self.current() == Some(element)
}
pub fn len(&self) -> usize {
self.elements.len()
}
pub fn is_empty(&self) -> bool {
self.elements.is_empty()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum TestPanel {
A,
B,
C,
}
#[test]
fn test_new_starts_at_first() {
let focus = FocusManager::new(vec![TestPanel::A, TestPanel::B, TestPanel::C]);
assert_eq!(focus.current(), Some(TestPanel::A));
assert_eq!(focus.current_index(), 0);
}
#[test]
fn test_focus_next_cycles() {
let mut focus = FocusManager::new(vec![TestPanel::A, TestPanel::B, TestPanel::C]);
assert_eq!(focus.focus_next(), Some(TestPanel::B));
assert_eq!(focus.focus_next(), Some(TestPanel::C));
assert_eq!(focus.focus_next(), Some(TestPanel::A)); }
#[test]
fn test_focus_prev_cycles() {
let mut focus = FocusManager::new(vec![TestPanel::A, TestPanel::B, TestPanel::C]);
assert_eq!(focus.focus_prev(), Some(TestPanel::C)); assert_eq!(focus.focus_prev(), Some(TestPanel::B));
assert_eq!(focus.focus_prev(), Some(TestPanel::A));
}
#[test]
fn test_set_element() {
let mut focus = FocusManager::new(vec![TestPanel::A, TestPanel::B, TestPanel::C]);
assert!(focus.set(TestPanel::C));
assert_eq!(focus.current(), Some(TestPanel::C));
assert_eq!(focus.current_index(), 2);
}
#[test]
fn test_set_index() {
let mut focus = FocusManager::new(vec![TestPanel::A, TestPanel::B, TestPanel::C]);
assert!(focus.set_index(1));
assert_eq!(focus.current(), Some(TestPanel::B));
assert!(!focus.set_index(10)); assert_eq!(focus.current(), Some(TestPanel::B)); }
#[test]
fn test_is_current() {
let focus = FocusManager::new(vec![TestPanel::A, TestPanel::B, TestPanel::C]);
assert!(focus.is_current(TestPanel::A));
assert!(!focus.is_current(TestPanel::B));
}
#[test]
fn test_empty_manager() {
let mut focus: FocusManager<TestPanel> = FocusManager::new(vec![]);
assert_eq!(focus.current(), None);
assert_eq!(focus.focus_next(), None);
assert_eq!(focus.focus_prev(), None);
assert!(focus.is_empty());
}
#[test]
fn test_single_element() {
let mut focus = FocusManager::new(vec![TestPanel::A]);
assert_eq!(focus.current(), Some(TestPanel::A));
assert_eq!(focus.focus_next(), Some(TestPanel::A)); assert_eq!(focus.focus_prev(), Some(TestPanel::A)); }
}