focus.rs

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