cranpose_foundation/nodes/input/
focus.rs1use std::collections::HashMap;
8
9#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
11pub struct FocusId(pub(crate) usize);
12
13impl FocusId {
14 pub fn new(id: usize) -> Self {
15 Self(id)
16 }
17
18 pub fn as_usize(self) -> usize {
19 self.0
20 }
21}
22
23pub struct FocusManager {
28 active_focus_id: Option<FocusId>,
30 focus_states: HashMap<FocusId, crate::modifier::FocusState>,
32 next_id: usize,
34}
35
36impl Default for FocusManager {
37 fn default() -> Self {
38 Self::new()
39 }
40}
41
42impl FocusManager {
43 pub fn new() -> Self {
44 Self {
45 active_focus_id: None,
46 focus_states: HashMap::new(),
47 next_id: 1,
48 }
49 }
50
51 pub fn allocate_focus_id(&mut self) -> FocusId {
53 let id = FocusId(self.next_id);
54 self.next_id += 1;
55 id
56 }
57
58 pub fn active_focus_id(&self) -> Option<FocusId> {
60 self.active_focus_id
61 }
62
63 pub fn request_focus(&mut self, id: FocusId) -> bool {
68 if let Some(prev_id) = self.active_focus_id {
70 if prev_id != id {
71 self.focus_states
72 .insert(prev_id, crate::modifier::FocusState::Inactive);
73 }
74 }
75
76 self.active_focus_id = Some(id);
78 self.focus_states
79 .insert(id, crate::modifier::FocusState::Active);
80 true
81 }
82
83 pub fn clear_focus(&mut self) {
85 if let Some(id) = self.active_focus_id.take() {
86 self.focus_states
87 .insert(id, crate::modifier::FocusState::Inactive);
88 }
89 }
90
91 pub fn capture_focus(&mut self) -> bool {
93 if let Some(id) = self.active_focus_id {
94 self.focus_states
95 .insert(id, crate::modifier::FocusState::Captured);
96 true
97 } else {
98 false
99 }
100 }
101
102 pub fn free_focus(&mut self) -> bool {
104 if let Some(id) = self.active_focus_id {
105 let state = self.focus_states.get(&id);
106 if matches!(state, Some(crate::modifier::FocusState::Captured)) {
107 self.focus_states
108 .insert(id, crate::modifier::FocusState::Active);
109 return true;
110 }
111 }
112 false
113 }
114
115 pub fn focus_state(&self, id: FocusId) -> crate::modifier::FocusState {
117 self.focus_states
118 .get(&id)
119 .copied()
120 .unwrap_or(crate::modifier::FocusState::Inactive)
121 }
122
123 pub fn is_focused(&self, id: FocusId) -> bool {
125 self.active_focus_id == Some(id)
126 }
127}