1use crate::{
2 DispatchPhase, FocusEvent, FocusHandle, Interactive, KeyDownEvent, KeyUpEvent, StyleRefinement,
3 ViewContext,
4};
5
6pub trait Focus: Interactive {
7 fn set_focus_style(&mut self, style: StyleRefinement);
8 fn set_focus_in_style(&mut self, style: StyleRefinement);
9 fn set_in_focus_style(&mut self, style: StyleRefinement);
10 fn handle(&self) -> &FocusHandle;
11
12 fn focus(mut self, f: impl FnOnce(StyleRefinement) -> StyleRefinement) -> Self
13 where
14 Self: Sized,
15 {
16 self.set_focus_style(f(StyleRefinement::default()));
17 self
18 }
19
20 fn focus_in(mut self, f: impl FnOnce(StyleRefinement) -> StyleRefinement) -> Self
21 where
22 Self: Sized,
23 {
24 self.set_focus_in_style(f(StyleRefinement::default()));
25 self
26 }
27
28 fn in_focus(mut self, f: impl FnOnce(StyleRefinement) -> StyleRefinement) -> Self
29 where
30 Self: Sized,
31 {
32 self.set_in_focus_style(f(StyleRefinement::default()));
33 self
34 }
35
36 fn on_focus(
37 mut self,
38 listener: impl Fn(&mut Self::ViewState, &FocusEvent, &mut ViewContext<Self::ViewState>)
39 + Send
40 + Sync
41 + 'static,
42 ) -> Self
43 where
44 Self: Sized,
45 {
46 let handle = self.handle().clone();
47 self.listeners()
48 .focus
49 .push(Box::new(move |view, event, cx| {
50 if event.focused.as_ref() == Some(&handle) {
51 listener(view, event, cx)
52 }
53 }));
54 self
55 }
56
57 fn on_blur(
58 mut self,
59 listener: impl Fn(&mut Self::ViewState, &FocusEvent, &mut ViewContext<Self::ViewState>)
60 + Send
61 + Sync
62 + 'static,
63 ) -> Self
64 where
65 Self: Sized,
66 {
67 let handle = self.handle().clone();
68 self.listeners()
69 .focus
70 .push(Box::new(move |view, event, cx| {
71 if event.blurred.as_ref() == Some(&handle) {
72 listener(view, event, cx)
73 }
74 }));
75 self
76 }
77
78 fn on_focus_in(
79 mut self,
80 listener: impl Fn(&mut Self::ViewState, &FocusEvent, &mut ViewContext<Self::ViewState>)
81 + Send
82 + Sync
83 + 'static,
84 ) -> Self
85 where
86 Self: Sized,
87 {
88 let handle = self.handle().clone();
89 self.listeners()
90 .focus
91 .push(Box::new(move |view, event, cx| {
92 let descendant_blurred = event
93 .blurred
94 .as_ref()
95 .map_or(false, |blurred| handle.contains(blurred, cx));
96 let descendant_focused = event
97 .focused
98 .as_ref()
99 .map_or(false, |focused| handle.contains(focused, cx));
100
101 if !descendant_blurred && descendant_focused {
102 listener(view, event, cx)
103 }
104 }));
105 self
106 }
107
108 fn on_focus_out(
109 mut self,
110 listener: impl Fn(&mut Self::ViewState, &FocusEvent, &mut ViewContext<Self::ViewState>)
111 + Send
112 + Sync
113 + 'static,
114 ) -> Self
115 where
116 Self: Sized,
117 {
118 let handle = self.handle().clone();
119 self.listeners()
120 .focus
121 .push(Box::new(move |view, event, cx| {
122 let descendant_blurred = event
123 .blurred
124 .as_ref()
125 .map_or(false, |blurred| handle.contains(blurred, cx));
126 let descendant_focused = event
127 .focused
128 .as_ref()
129 .map_or(false, |focused| handle.contains(focused, cx));
130 if descendant_blurred && !descendant_focused {
131 listener(view, event, cx)
132 }
133 }));
134 self
135 }
136
137 fn on_key_down(
138 mut self,
139 listener: impl Fn(
140 &mut Self::ViewState,
141 &KeyDownEvent,
142 DispatchPhase,
143 &mut ViewContext<Self::ViewState>,
144 ) + Send
145 + Sync
146 + 'static,
147 ) -> Self
148 where
149 Self: Sized,
150 {
151 self.listeners().key_down.push(Box::new(listener));
152 self
153 }
154
155 fn on_key_up(
156 mut self,
157 listener: impl Fn(&mut Self::ViewState, &KeyUpEvent, DispatchPhase, &mut ViewContext<Self::ViewState>)
158 + Send
159 + Sync
160 + 'static,
161 ) -> Self
162 where
163 Self: Sized,
164 {
165 self.listeners().key_up.push(Box::new(listener));
166 self
167 }
168}