use std::collections::HashMap;
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct FocusId(pub(crate) usize);
impl FocusId {
pub fn new(id: usize) -> Self {
Self(id)
}
pub fn as_usize(self) -> usize {
self.0
}
}
pub struct FocusManager {
active_focus_id: Option<FocusId>,
focus_states: HashMap<FocusId, crate::modifier::FocusState>,
next_id: usize,
}
impl Default for FocusManager {
fn default() -> Self {
Self::new()
}
}
impl FocusManager {
pub fn new() -> Self {
Self {
active_focus_id: None,
focus_states: HashMap::new(),
next_id: 1,
}
}
pub fn allocate_focus_id(&mut self) -> FocusId {
let id = FocusId(self.next_id);
self.next_id += 1;
id
}
pub fn active_focus_id(&self) -> Option<FocusId> {
self.active_focus_id
}
pub fn request_focus(&mut self, id: FocusId) -> bool {
if let Some(prev_id) = self.active_focus_id {
if prev_id != id {
self.focus_states
.insert(prev_id, crate::modifier::FocusState::Inactive);
}
}
self.active_focus_id = Some(id);
self.focus_states
.insert(id, crate::modifier::FocusState::Active);
true
}
pub fn clear_focus(&mut self) {
if let Some(id) = self.active_focus_id.take() {
self.focus_states
.insert(id, crate::modifier::FocusState::Inactive);
}
}
pub fn capture_focus(&mut self) -> bool {
if let Some(id) = self.active_focus_id {
self.focus_states
.insert(id, crate::modifier::FocusState::Captured);
true
} else {
false
}
}
pub fn free_focus(&mut self) -> bool {
if let Some(id) = self.active_focus_id {
let state = self.focus_states.get(&id);
if matches!(state, Some(crate::modifier::FocusState::Captured)) {
self.focus_states
.insert(id, crate::modifier::FocusState::Active);
return true;
}
}
false
}
pub fn focus_state(&self, id: FocusId) -> crate::modifier::FocusState {
self.focus_states
.get(&id)
.copied()
.unwrap_or(crate::modifier::FocusState::Inactive)
}
pub fn is_focused(&self, id: FocusId) -> bool {
self.active_focus_id == Some(id)
}
}