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