interactive.rs

  1use crate::{
  2    DispatchPhase, Element, EventListeners, MouseButton, MouseClickEvent, MouseDownEvent,
  3    MouseMoveEvent, MouseUpEvent, ScrollWheelEvent, ViewContext,
  4};
  5use std::sync::Arc;
  6
  7pub trait Interactive: Element {
  8    fn listeners(&mut self) -> &mut EventListeners<Self::ViewState>;
  9
 10    fn on_mouse_down(
 11        mut self,
 12        button: MouseButton,
 13        handler: impl Fn(&mut Self::ViewState, &MouseDownEvent, &mut ViewContext<Self::ViewState>)
 14            + Send
 15            + Sync
 16            + 'static,
 17    ) -> Self
 18    where
 19        Self: Sized,
 20    {
 21        self.listeners()
 22            .mouse_down
 23            .push(Arc::new(move |view, event, bounds, phase, cx| {
 24                if phase == DispatchPhase::Bubble
 25                    && event.button == button
 26                    && bounds.contains_point(&event.position)
 27                {
 28                    handler(view, event, cx)
 29                }
 30            }));
 31        self
 32    }
 33
 34    fn on_mouse_up(
 35        mut self,
 36        button: MouseButton,
 37        handler: impl Fn(&mut Self::ViewState, &MouseUpEvent, &mut ViewContext<Self::ViewState>)
 38            + Send
 39            + Sync
 40            + 'static,
 41    ) -> Self
 42    where
 43        Self: Sized,
 44    {
 45        self.listeners()
 46            .mouse_up
 47            .push(Arc::new(move |view, event, bounds, phase, cx| {
 48                if phase == DispatchPhase::Bubble
 49                    && event.button == button
 50                    && bounds.contains_point(&event.position)
 51                {
 52                    handler(view, event, cx)
 53                }
 54            }));
 55        self
 56    }
 57
 58    fn on_mouse_down_out(
 59        mut self,
 60        button: MouseButton,
 61        handler: impl Fn(&mut Self::ViewState, &MouseDownEvent, &mut ViewContext<Self::ViewState>)
 62            + Send
 63            + Sync
 64            + 'static,
 65    ) -> Self
 66    where
 67        Self: Sized,
 68    {
 69        self.listeners()
 70            .mouse_down
 71            .push(Arc::new(move |view, event, bounds, phase, cx| {
 72                if phase == DispatchPhase::Capture
 73                    && event.button == button
 74                    && !bounds.contains_point(&event.position)
 75                {
 76                    handler(view, event, cx)
 77                }
 78            }));
 79        self
 80    }
 81
 82    fn on_mouse_up_out(
 83        mut self,
 84        button: MouseButton,
 85        handler: impl Fn(&mut Self::ViewState, &MouseUpEvent, &mut ViewContext<Self::ViewState>)
 86            + Send
 87            + Sync
 88            + 'static,
 89    ) -> Self
 90    where
 91        Self: Sized,
 92    {
 93        self.listeners()
 94            .mouse_up
 95            .push(Arc::new(move |view, event, bounds, phase, cx| {
 96                if phase == DispatchPhase::Capture
 97                    && event.button == button
 98                    && !bounds.contains_point(&event.position)
 99                {
100                    handler(view, event, cx);
101                }
102            }));
103        self
104    }
105
106    fn on_mouse_move(
107        mut self,
108        handler: impl Fn(&mut Self::ViewState, &MouseMoveEvent, &mut ViewContext<Self::ViewState>)
109            + Send
110            + Sync
111            + 'static,
112    ) -> Self
113    where
114        Self: Sized,
115    {
116        self.listeners()
117            .mouse_move
118            .push(Arc::new(move |view, event, bounds, phase, cx| {
119                if phase == DispatchPhase::Bubble && bounds.contains_point(&event.position) {
120                    handler(view, event, cx);
121                }
122            }));
123        self
124    }
125
126    fn on_scroll_wheel(
127        mut self,
128        handler: impl Fn(&mut Self::ViewState, &ScrollWheelEvent, &mut ViewContext<Self::ViewState>)
129            + Send
130            + Sync
131            + 'static,
132    ) -> Self
133    where
134        Self: Sized,
135    {
136        self.listeners()
137            .scroll_wheel
138            .push(Arc::new(move |view, event, bounds, phase, cx| {
139                if phase == DispatchPhase::Bubble && bounds.contains_point(&event.position) {
140                    handler(view, event, cx);
141                }
142            }));
143        self
144    }
145}
146
147pub trait Click: Interactive {
148    fn on_click(
149        mut self,
150        handler: impl Fn(&mut Self::ViewState, &MouseClickEvent, &mut ViewContext<Self::ViewState>)
151            + Send
152            + Sync
153            + 'static,
154    ) -> Self
155    where
156        Self: Sized,
157    {
158        self.listeners()
159            .mouse_click
160            .push(Arc::new(move |view, event, cx| handler(view, event, cx)));
161        self
162    }
163}