// path_from_the_root: src/focus/manager.rs use super::error::FocusError; use super::id::FocusId; use super::query::FocusQuery; #[derive(Debug, Clone)] pub struct FocusManager { targets: alloc::vec::Vec, index: usize, overlay: Option, } impl Default for FocusManager { fn default() -> Self { Self::new() } } impl FocusManager { pub fn new() -> Self { Self { targets: alloc::vec::Vec::new(), index: 0, overlay: None, } } pub fn set_targets(&mut self, targets: alloc::vec::Vec) { self.targets = targets; self.index = 0; } pub fn add_target(&mut self, id: F) { if !self.targets.contains(&id) { self.targets.push(id); } } pub fn remove_target(&mut self, id: &F) { if let Some(pos) = self.targets.iter().position(|t| t == id) { self.targets.remove(pos); if self.index >= self.targets.len() && !self.targets.is_empty() { self.index = self.targets.len() - 1; } } } pub fn current(&self) -> Option<&F> { if let Some(overlay) = &self.overlay { return Some(overlay); } self.targets.get(self.index) } pub fn query(&self) -> FocusQuery<'_, F> { FocusQuery { current: self.current(), } } pub fn is_focused(&self, id: &F) -> bool { self.current() == Some(id) } pub fn has_overlay(&self) -> bool { self.overlay.is_some() } pub fn set_focus(&mut self, id: F) -> Result<(), FocusError> { if self.targets.is_empty() { return Err(FocusError::EmptyTargets); } if let Some(pos) = self.targets.iter().position(|t| t == &id) { self.index = pos; self.overlay = None; Ok(()) } else { Err(FocusError::TargetNotFound) } } pub fn set_overlay(&mut self, id: F) { self.overlay = Some(id); } pub fn clear_overlay(&mut self) { self.overlay = None; } pub fn next(&mut self) { if self.overlay.is_some() { return; } if !self.targets.is_empty() && self.index < self.targets.len() - 1 { self.index += 1; } } pub fn prev(&mut self) { if self.overlay.is_some() { return; } if !self.targets.is_empty() && self.index > 0 { self.index -= 1; } } pub fn first(&mut self) { self.index = 0; self.overlay = None; } pub fn last(&mut self) { if !self.targets.is_empty() { self.index = self.targets.len() - 1; } self.overlay = None; } pub fn targets(&self) -> &[F] { &self.targets } pub fn len(&self) -> usize { self.targets.len() } pub fn is_empty(&self) -> bool { self.targets.is_empty() } }