dioxus_html/events/
scroll.rs

1use dioxus_core::Event;
2
3pub type ScrollEvent = Event<ScrollData>;
4
5pub struct ScrollData {
6    inner: Box<dyn HasScrollData>,
7}
8
9impl<E: HasScrollData> From<E> for ScrollData {
10    fn from(e: E) -> Self {
11        Self { inner: Box::new(e) }
12    }
13}
14
15impl ScrollData {
16    /// Create a new ScrollData
17    pub fn new(inner: impl HasScrollData + 'static) -> Self {
18        Self {
19            inner: Box::new(inner),
20        }
21    }
22
23    /// Downcast this event to a concrete event type
24    #[inline(always)]
25    pub fn downcast<T: 'static>(&self) -> Option<&T> {
26        self.inner.as_any().downcast_ref::<T>()
27    }
28
29    pub fn scroll_top(&self) -> f64 {
30        self.inner.scroll_top()
31    }
32
33    pub fn scroll_left(&self) -> f64 {
34        self.inner.scroll_left()
35    }
36
37    pub fn scroll_width(&self) -> i32 {
38        self.inner.scroll_width()
39    }
40
41    pub fn scroll_height(&self) -> i32 {
42        self.inner.scroll_height()
43    }
44
45    pub fn client_width(&self) -> i32 {
46        self.inner.client_width()
47    }
48
49    pub fn client_height(&self) -> i32 {
50        self.inner.client_height()
51    }
52}
53
54impl std::fmt::Debug for ScrollData {
55    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56        f.debug_struct("ScrollData")
57            .field("scroll_top", &self.scroll_top())
58            .field("scroll_left", &self.scroll_left())
59            .field("scroll_width", &self.scroll_width())
60            .field("scroll_height", &self.scroll_height())
61            .field("client_width", &self.client_width())
62            .field("client_height", &self.client_height())
63            .finish()
64    }
65}
66
67impl PartialEq for ScrollData {
68    fn eq(&self, other: &Self) -> bool {
69        self.scroll_top() == other.scroll_top()
70            && self.scroll_left() == other.scroll_left()
71            && self.scroll_width() == other.scroll_width()
72            && self.scroll_height() == other.scroll_height()
73            && self.client_width() == other.client_width()
74            && self.client_height() == other.client_height()
75    }
76}
77
78#[cfg(feature = "serialize")]
79/// A serialized version of ScrollData
80#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)]
81pub struct SerializedScrollData {
82    pub scroll_top: f64,
83    pub scroll_left: f64,
84    pub scroll_width: i32,
85    pub scroll_height: i32,
86    pub client_width: i32,
87    pub client_height: i32,
88}
89
90#[cfg(feature = "serialize")]
91impl From<&ScrollData> for SerializedScrollData {
92    fn from(data: &ScrollData) -> Self {
93        Self {
94            scroll_top: data.inner.scroll_top(),
95            scroll_left: data.inner.scroll_left(),
96            scroll_width: data.inner.scroll_width(),
97            scroll_height: data.inner.scroll_height(),
98            client_width: data.inner.client_width(),
99            client_height: data.inner.client_height(),
100        }
101    }
102}
103
104#[cfg(feature = "serialize")]
105impl HasScrollData for SerializedScrollData {
106    fn as_any(&self) -> &dyn std::any::Any {
107        self
108    }
109
110    fn scroll_top(&self) -> f64 {
111        self.scroll_top
112    }
113
114    fn scroll_left(&self) -> f64 {
115        self.scroll_left
116    }
117
118    fn scroll_width(&self) -> i32 {
119        self.scroll_width
120    }
121
122    fn scroll_height(&self) -> i32 {
123        self.scroll_height
124    }
125
126    fn client_width(&self) -> i32 {
127        self.client_width
128    }
129
130    fn client_height(&self) -> i32 {
131        self.client_height
132    }
133}
134
135#[cfg(feature = "serialize")]
136impl serde::Serialize for ScrollData {
137    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
138        SerializedScrollData::from(self).serialize(serializer)
139    }
140}
141
142#[cfg(feature = "serialize")]
143impl<'de> serde::Deserialize<'de> for ScrollData {
144    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
145        let data = SerializedScrollData::deserialize(deserializer)?;
146        Ok(Self {
147            inner: Box::new(data),
148        })
149    }
150}
151
152pub trait HasScrollData: std::any::Any {
153    /// Return self as Any
154    fn as_any(&self) -> &dyn std::any::Any;
155
156    /// Get the vertical scroll position
157    fn scroll_top(&self) -> f64;
158
159    /// Get the horizontal scroll position
160    fn scroll_left(&self) -> f64;
161
162    /// Get the total scrollable width
163    fn scroll_width(&self) -> i32;
164
165    /// Get the total scrollable height
166    fn scroll_height(&self) -> i32;
167
168    /// Get the viewport width
169    fn client_width(&self) -> i32;
170
171    /// Get the viewport height
172    fn client_height(&self) -> i32;
173}
174
175impl_event! {
176    ScrollData;
177
178    /// onscroll
179    onscroll
180}