focus.rs

  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}