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 if event
93 .focused
94 .as_ref()
95 .map_or(false, |focused| focused.contains(&handle, cx))
96 {
97 listener(view, event, cx)
98 }
99 }));
100 self
101 }
102
103 fn on_focus_out(
104 mut self,
105 listener: impl Fn(&mut Self::ViewState, &FocusEvent, &mut ViewContext<Self::ViewState>)
106 + Send
107 + Sync
108 + 'static,
109 ) -> Self
110 where
111 Self: Sized,
112 {
113 let handle = self.handle().clone();
114 self.listeners()
115 .focus
116 .push(Box::new(move |view, event, cx| {
117 if event
118 .blurred
119 .as_ref()
120 .map_or(false, |blurred| handle.contains(&blurred, cx))
121 {
122 listener(view, event, cx)
123 }
124 }));
125 self
126 }
127
128 fn on_key_down(
129 mut self,
130 listener: impl Fn(
131 &mut Self::ViewState,
132 &KeyDownEvent,
133 DispatchPhase,
134 &mut ViewContext<Self::ViewState>,
135 ) + Send
136 + Sync
137 + 'static,
138 ) -> Self
139 where
140 Self: Sized,
141 {
142 self.listeners().key_down.push(Box::new(listener));
143 self
144 }
145
146 fn on_key_up(
147 mut self,
148 listener: impl Fn(&mut Self::ViewState, &KeyUpEvent, DispatchPhase, &mut ViewContext<Self::ViewState>)
149 + Send
150 + Sync
151 + 'static,
152 ) -> Self
153 where
154 Self: Sized,
155 {
156 self.listeners().key_up.push(Box::new(listener));
157 self
158 }
159}