1use crate::field::{Field, NodeId};
2
3#[derive(Clone, Copy, Debug, PartialEq, Eq)]
6pub struct Focus {
7 focused: Option<NodeId>,
8}
9
10impl Focus {
11 pub fn new() -> Self {
12 Self { focused: None }
13 }
14
15 pub fn current(&self) -> Option<NodeId> {
16 self.focused
17 }
18
19 pub fn is_focused(&self, id: NodeId) -> bool {
20 self.focused == Some(id)
21 }
22
23 pub fn set(&mut self, field: &Field, id: NodeId) -> bool {
25 if !field.is_visible(id) {
26 return false;
27 }
28 self.focused = Some(id);
29 true
30 }
31
32 pub fn clear(&mut self) {
33 self.focused = None;
34 }
35
36 pub fn on_removed(&mut self, removed: NodeId) {
38 if self.focused == Some(removed) {
39 self.focused = None;
40 }
41 }
42
43 pub fn on_hidden(&mut self, field: &Field, id: NodeId) {
45 if self.focused == Some(id) && !field.is_visible(id) {
46 self.focused = None;
47 }
48 }
49}
50
51impl Default for Focus {
52 fn default() -> Self {
53 Self::new()
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60 use crate::field::Vec2;
61
62 #[test]
63 fn starts_empty() {
64 let f = Focus::new();
65 assert_eq!(f.current(), None);
66 }
67
68 #[test]
69 fn can_focus_existing_node() {
70 let mut field = Field::new();
71 let id = field.spawn_surface("A", Vec2 { x: 0.0, y: 0.0 }, Vec2 { x: 10.0, y: 10.0 });
72
73 let mut focus = Focus::new();
74 assert!(focus.set(&field, id));
75 assert_eq!(focus.current(), Some(id));
76 assert!(focus.is_focused(id));
77 }
78
79 #[test]
80 fn cannot_focus_missing_node() {
81 let field = Field::new();
82 let mut focus = Focus::new();
83 assert!(!focus.set(&field, NodeId::new(999)));
84 assert_eq!(focus.current(), None);
85 }
86
87 #[test]
88 fn cannot_focus_hidden_node() {
89 let mut field = Field::new();
90 let id = field.spawn_surface("A", Vec2 { x: 0.0, y: 0.0 }, Vec2 { x: 10.0, y: 10.0 });
91
92 assert!(field.set_hidden(id, true));
93
94 let mut focus = Focus::new();
95 assert!(!focus.set(&field, id));
96 assert_eq!(focus.current(), None);
97 }
98
99 #[test]
100 fn clears_when_focused_node_removed() {
101 let mut field = Field::new();
102 let id = field.spawn_surface("A", Vec2 { x: 0.0, y: 0.0 }, Vec2 { x: 10.0, y: 10.0 });
103
104 let mut focus = Focus::new();
105 assert!(focus.set(&field, id));
106
107 field.remove(id);
108 focus.on_removed(id);
109
110 assert_eq!(focus.current(), None);
111 }
112
113 #[test]
114 fn clears_when_focused_node_becomes_hidden() {
115 let mut field = Field::new();
116 let id = field.spawn_surface("A", Vec2 { x: 0.0, y: 0.0 }, Vec2 { x: 10.0, y: 10.0 });
117
118 let mut focus = Focus::new();
119 assert!(focus.set(&field, id));
120
121 assert!(field.set_hidden(id, true));
122 focus.on_hidden(&field, id);
123
124 assert_eq!(focus.current(), None);
125 }
126}