137 lines
3.0 KiB
Rust
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()
|
|
}
|
|
}
|