From bf4796bbeb7a8274bf8eb32cfac51ad26de51681 Mon Sep 17 00:00:00 2001
From: Siliwolf <reynardbrendan@gmail.com>
Date: Sat, 25 May 2024 18:13:34 -0300
Subject: Add `on_scroll` handler to `mouse_area` widget

---
 widget/src/mouse_area.rs | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/widget/src/mouse_area.rs b/widget/src/mouse_area.rs
index 366335f4..d206322e 100644
--- a/widget/src/mouse_area.rs
+++ b/widget/src/mouse_area.rs
@@ -1,7 +1,5 @@
 //! A container for capturing mouse events.
 
-use iced_renderer::core::Point;
-
 use crate::core::event::{self, Event};
 use crate::core::layout;
 use crate::core::mouse;
@@ -10,7 +8,8 @@ use crate::core::renderer;
 use crate::core::touch;
 use crate::core::widget::{tree, Operation, Tree};
 use crate::core::{
-    Clipboard, Element, Layout, Length, Rectangle, Shell, Size, Vector, Widget,
+    Clipboard, Element, Layout, Length, Point, Rectangle, Shell, Size, Vector,
+    Widget,
 };
 
 /// Emit messages on mouse events.
@@ -28,6 +27,7 @@ pub struct MouseArea<
     on_right_release: Option<Message>,
     on_middle_press: Option<Message>,
     on_middle_release: Option<Message>,
+    on_scroll: Option<Box<dyn Fn(mouse::ScrollDelta) -> Message + 'a>>,
     on_enter: Option<Message>,
     on_move: Option<Box<dyn Fn(Point) -> Message>>,
     on_exit: Option<Message>,
@@ -77,6 +77,16 @@ impl<'a, Message, Theme, Renderer> MouseArea<'a, Message, Theme, Renderer> {
         self
     }
 
+    /// The message to emit when scroll wheel is used
+    #[must_use]
+    pub fn on_scroll<F>(mut self, on_scroll: F) -> Self
+    where
+        F: Fn(mouse::ScrollDelta) -> Message + 'static,
+    {
+        self.on_scroll = Some(Box::new(on_scroll));
+        self
+    }
+
     /// The message to emit when the mouse enters the area.
     #[must_use]
     pub fn on_enter(mut self, message: Message) -> Self {
@@ -128,6 +138,7 @@ impl<'a, Message, Theme, Renderer> MouseArea<'a, Message, Theme, Renderer> {
             on_right_release: None,
             on_middle_press: None,
             on_middle_release: None,
+            on_scroll: None,
             on_enter: None,
             on_move: None,
             on_exit: None,
@@ -397,5 +408,13 @@ fn update<Message: Clone, Theme, Renderer>(
         }
     }
 
+    if let Some(on_scroll) = widget.on_scroll.as_ref() {
+        if let Event::Mouse(mouse::Event::WheelScrolled { delta }) = event {
+            shell.publish(on_scroll(delta));
+
+            return event::Status::Captured;
+        }
+    }
+
     event::Status::Ignored
 }
-- 
cgit