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                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}