Files
pages-tui/src/focus/manager.rs

137 lines
3.0 KiB
Rust

// 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<F: FocusId> {
targets: alloc::vec::Vec<F>,
index: usize,
overlay: Option<F>,
}
impl<F: FocusId> Default for FocusManager<F> {
fn default() -> Self {
Self::new()
}
}
impl<F: FocusId> FocusManager<F> {
pub fn new() -> Self {
Self {
targets: alloc::vec::Vec::new(),
index: 0,
overlay: None,
}
}
pub fn set_targets(&mut self, targets: alloc::vec::Vec<F>) {
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()
}
}