Skip to main content

dioxus_html/events/
mod.rs

1#![doc = include_str!("../../docs/event_handlers.md")]
2
3use std::any::Any;
4use std::sync::RwLock;
5
6static EVENT_CONVERTER: RwLock<Option<Box<dyn HtmlEventConverter>>> = RwLock::new(None);
7
8#[inline]
9pub fn set_event_converter(converter: Box<dyn HtmlEventConverter>) {
10    *EVENT_CONVERTER.write().unwrap() = Some(converter);
11}
12
13#[inline]
14pub(crate) fn with_event_converter<F, R>(f: F) -> R
15where
16    F: FnOnce(&dyn HtmlEventConverter) -> R,
17{
18    let converter = EVENT_CONVERTER.read().unwrap();
19    f(converter.as_ref().unwrap().as_ref())
20}
21
22/// A platform specific event.
23pub struct PlatformEventData {
24    event: Box<dyn Any>,
25}
26
27impl PlatformEventData {
28    pub fn new(event: Box<dyn Any>) -> Self {
29        Self { event }
30    }
31
32    pub fn inner(&self) -> &Box<dyn Any> {
33        &self.event
34    }
35
36    pub fn downcast<T: 'static>(&self) -> Option<&T> {
37        self.event.downcast_ref::<T>()
38    }
39
40    pub fn downcast_mut<T: 'static>(&mut self) -> Option<&mut T> {
41        self.event.downcast_mut::<T>()
42    }
43
44    pub fn into_inner<T: 'static>(self) -> Option<T> {
45        self.event.downcast::<T>().ok().map(|e| *e)
46    }
47}
48
49/// Marker for event handlers provided as closures.
50pub struct EventClosureMarker<Marker>(std::marker::PhantomData<Marker>);
51
52/// Marker for event handlers provided as listener callbacks.
53#[doc(hidden)]
54pub struct EventListenerMarker;
55
56/// Marker for event handlers provided as callbacks.
57#[doc(hidden)]
58pub struct EventCallbackMarker;
59
60/// A value that can be converted into a platform event listener.
61pub trait EventHandlerValue<Data, Marker>
62where
63    Data: for<'a> From<&'a PlatformEventData> + 'static,
64{
65    /// Convert this handler into a platform event listener.
66    fn into_platform_listener(self) -> ::dioxus_core::ListenerCallback<PlatformEventData>;
67}
68
69impl<Data, Function, Spawn, Marker> EventHandlerValue<Data, EventClosureMarker<Marker>> for Function
70where
71    Data: for<'a> From<&'a PlatformEventData> + 'static,
72    Function: FnMut(::dioxus_core::Event<Data>) -> Spawn + 'static,
73    Spawn: ::dioxus_core::SpawnIfAsync<Marker> + 'static,
74{
75    fn into_platform_listener(mut self) -> ::dioxus_core::ListenerCallback<PlatformEventData> {
76        ::dioxus_core::ListenerCallback::new(
77            move |event: ::dioxus_core::Event<PlatformEventData>| {
78                self(event.map(|data| Data::from(data)))
79            },
80        )
81    }
82}
83
84impl<Data> EventHandlerValue<Data, EventListenerMarker> for ::dioxus_core::ListenerCallback<Data>
85where
86    Data: for<'a> From<&'a PlatformEventData> + 'static,
87{
88    fn into_platform_listener(self) -> ::dioxus_core::ListenerCallback<PlatformEventData> {
89        ::dioxus_core::ListenerCallback::new(
90            move |event: ::dioxus_core::Event<PlatformEventData>| {
91                self.call(event.map(|data| Data::from(data)).into_any());
92            },
93        )
94    }
95}
96
97impl<Data> EventHandlerValue<Data, EventCallbackMarker>
98    for ::dioxus_core::Callback<::dioxus_core::Event<Data>>
99where
100    Data: for<'a> From<&'a PlatformEventData> + 'static,
101{
102    fn into_platform_listener(self) -> ::dioxus_core::ListenerCallback<PlatformEventData> {
103        ::dioxus_core::ListenerCallback::new(
104            move |event: ::dioxus_core::Event<PlatformEventData>| {
105                self.call(event.map(|data| Data::from(data)));
106            },
107        )
108    }
109}
110
111pub(crate) fn event_attribute<Data, Marker>(
112    name: &'static str,
113    event_handler: impl EventHandlerValue<Data, Marker>,
114) -> ::dioxus_core::Attribute
115where
116    Data: for<'a> From<&'a PlatformEventData> + 'static,
117{
118    ::dioxus_core::Attribute::new(
119        name,
120        ::dioxus_core::AttributeValue::Listener(event_handler.into_platform_listener().erase()),
121        None,
122        false,
123    )
124}
125
126mod generated;
127
128mod animation;
129mod before_input;
130mod cancel;
131mod clipboard;
132mod composition;
133mod drag;
134mod focus;
135mod form;
136mod image;
137mod keyboard;
138mod media;
139mod mounted;
140mod mouse;
141mod pointer;
142mod resize;
143mod scroll;
144mod selection;
145mod toggle;
146mod touch;
147mod transition;
148mod visible;
149mod wheel;
150
151pub use animation::*;
152pub use before_input::*;
153pub use cancel::*;
154pub use clipboard::*;
155pub use composition::*;
156pub use drag::*;
157pub use focus::*;
158pub use form::*;
159pub use generated::*;
160pub use image::*;
161pub use keyboard::*;
162pub use media::*;
163pub use mounted::*;
164pub use mouse::*;
165pub use pointer::*;
166pub use resize::*;
167pub use scroll::*;
168pub use selection::*;
169pub use toggle::*;
170pub use touch::*;
171pub use transition::*;
172pub use visible::*;
173pub use wheel::*;