interactive.rs

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