diff options
| author | 2024-10-25 19:28:18 +0200 | |
|---|---|---|
| committer | 2024-11-05 23:52:58 +0100 | |
| commit | dcc184b01b753dbecb500205391f6eaaa21c8683 (patch) | |
| tree | 9f1854261c3b3805e28f524df65487c09c9729f7 | |
| parent | 752403d70c851ece620c4007710062b158e8dec3 (diff) | |
| download | iced-dcc184b01b753dbecb500205391f6eaaa21c8683.tar.gz iced-dcc184b01b753dbecb500205391f6eaaa21c8683.tar.bz2 iced-dcc184b01b753dbecb500205391f6eaaa21c8683.zip  | |
Replace `event::Status` in `Widget::on_event` with `Shell::capture_event`
44 files changed, 556 insertions, 705 deletions
diff --git a/core/src/element.rs b/core/src/element.rs index 6ebb8a15..8276b70c 100644 --- a/core/src/element.rs +++ b/core/src/element.rs @@ -1,4 +1,3 @@ -use crate::event::{self, Event};  use crate::layout;  use crate::mouse;  use crate::overlay; @@ -6,8 +5,8 @@ use crate::renderer;  use crate::widget;  use crate::widget::tree::{self, Tree};  use crate::{ -    Border, Clipboard, Color, Layout, Length, Rectangle, Shell, Size, Vector, -    Widget, +    Border, Clipboard, Color, Event, Layout, Length, Rectangle, Shell, Size, +    Vector, Widget,  };  use std::borrow::Borrow; @@ -319,11 +318,11 @@ where          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, B>,          viewport: &Rectangle, -    ) -> event::Status { +    ) {          let mut local_messages = Vec::new();          let mut local_shell = Shell::new(&mut local_messages); -        let status = self.widget.on_event( +        self.widget.on_event(              tree,              event,              layout, @@ -335,8 +334,6 @@ where          );          shell.merge(local_shell, &self.mapper); - -        status      }      fn draw( @@ -457,10 +454,10 @@ where          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          viewport: &Rectangle, -    ) -> event::Status { +    ) {          self.element.widget.on_event(              state, event, layout, cursor, renderer, clipboard, shell, viewport, -        ) +        );      }      fn draw( diff --git a/core/src/overlay.rs b/core/src/overlay.rs index f09de831..e063bb94 100644 --- a/core/src/overlay.rs +++ b/core/src/overlay.rs @@ -5,13 +5,12 @@ mod group;  pub use element::Element;  pub use group::Group; -use crate::event::{self, Event};  use crate::layout;  use crate::mouse;  use crate::renderer;  use crate::widget;  use crate::widget::Tree; -use crate::{Clipboard, Layout, Point, Rectangle, Shell, Size, Vector}; +use crate::{Clipboard, Event, Layout, Point, Rectangle, Shell, Size, Vector};  /// An interactive component that can be displayed on top of other widgets.  pub trait Overlay<Message, Theme, Renderer> @@ -65,8 +64,7 @@ where          _renderer: &Renderer,          _clipboard: &mut dyn Clipboard,          _shell: &mut Shell<'_, Message>, -    ) -> event::Status { -        event::Status::Ignored +    ) {      }      /// Returns the current [`mouse::Interaction`] of the [`Overlay`]. diff --git a/core/src/overlay/element.rs b/core/src/overlay/element.rs index 32e987a3..4a242213 100644 --- a/core/src/overlay/element.rs +++ b/core/src/overlay/element.rs @@ -1,11 +1,10 @@  pub use crate::Overlay; -use crate::event::{self, Event};  use crate::layout;  use crate::mouse;  use crate::renderer;  use crate::widget; -use crate::{Clipboard, Layout, Point, Rectangle, Shell, Size}; +use crate::{Clipboard, Event, Layout, Point, Rectangle, Shell, Size};  /// A generic [`Overlay`].  #[allow(missing_debug_implementations)] @@ -58,9 +57,9 @@ where          renderer: &Renderer,          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>, -    ) -> event::Status { +    ) {          self.overlay -            .on_event(event, layout, cursor, renderer, clipboard, shell) +            .on_event(event, layout, cursor, renderer, clipboard, shell);      }      /// Returns the current [`mouse::Interaction`] of the [`Element`]. @@ -157,11 +156,11 @@ where          renderer: &Renderer,          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, B>, -    ) -> event::Status { +    ) {          let mut local_messages = Vec::new();          let mut local_shell = Shell::new(&mut local_messages); -        let event_status = self.content.on_event( +        self.content.on_event(              event,              layout,              cursor, @@ -171,8 +170,6 @@ where          );          shell.merge(local_shell, self.mapper); - -        event_status      }      fn mouse_interaction( diff --git a/core/src/overlay/group.rs b/core/src/overlay/group.rs index 6541d311..11ebd579 100644 --- a/core/src/overlay/group.rs +++ b/core/src/overlay/group.rs @@ -1,4 +1,3 @@ -use crate::event;  use crate::layout;  use crate::mouse;  use crate::overlay; @@ -81,21 +80,17 @@ where          renderer: &Renderer,          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>, -    ) -> event::Status { -        self.children -            .iter_mut() -            .zip(layout.children()) -            .map(|(child, layout)| { -                child.on_event( -                    event.clone(), -                    layout, -                    cursor, -                    renderer, -                    clipboard, -                    shell, -                ) -            }) -            .fold(event::Status::Ignored, event::Status::merge) +    ) { +        for (child, layout) in self.children.iter_mut().zip(layout.children()) { +            child.on_event( +                event.clone(), +                layout, +                cursor, +                renderer, +                clipboard, +                shell, +            ); +        }      }      fn draw( diff --git a/core/src/shell.rs b/core/src/shell.rs index 7a92a2be..12ebbaa8 100644 --- a/core/src/shell.rs +++ b/core/src/shell.rs @@ -1,3 +1,4 @@ +use crate::event;  use crate::time::Instant;  use crate::window; @@ -10,6 +11,7 @@ use crate::window;  #[derive(Debug)]  pub struct Shell<'a, Message> {      messages: &'a mut Vec<Message>, +    event_status: event::Status,      redraw_request: Option<window::RedrawRequest>,      is_layout_invalid: bool,      are_widgets_invalid: bool, @@ -20,6 +22,7 @@ impl<'a, Message> Shell<'a, Message> {      pub fn new(messages: &'a mut Vec<Message>) -> Self {          Self {              messages, +            event_status: event::Status::Ignored,              redraw_request: None,              is_layout_invalid: false,              are_widgets_invalid: false, @@ -36,6 +39,24 @@ impl<'a, Message> Shell<'a, Message> {          self.messages.push(message);      } +    /// Marks the current event as captured. Prevents "event bubbling". +    /// +    /// A widget should capture an event when no ancestor should +    /// handle it. +    pub fn capture_event(&mut self) { +        self.event_status = event::Status::Captured; +    } + +    /// Returns the current [`event::Status`] of the [`Shell`]. +    pub fn event_status(&self) -> event::Status { +        self.event_status +    } + +    /// Returns whether the current event has been captured. +    pub fn is_event_captured(&self) -> bool { +        self.event_status == event::Status::Captured +    } +      /// Requests a new frame to be drawn as soon as possible.      pub fn request_redraw(&mut self) {          self.redraw_request = Some(window::RedrawRequest::NextFrame); @@ -114,5 +135,7 @@ impl<'a, Message> Shell<'a, Message> {          self.are_widgets_invalid =              self.are_widgets_invalid || other.are_widgets_invalid; + +        self.event_status = self.event_status.merge(other.event_status);      }  } diff --git a/core/src/widget.rs b/core/src/widget.rs index 9cfff83d..bddf99cc 100644 --- a/core/src/widget.rs +++ b/core/src/widget.rs @@ -10,12 +10,11 @@ pub use operation::Operation;  pub use text::Text;  pub use tree::Tree; -use crate::event::{self, Event};  use crate::layout::{self, Layout};  use crate::mouse;  use crate::overlay;  use crate::renderer; -use crate::{Clipboard, Length, Rectangle, Shell, Size, Vector}; +use crate::{Clipboard, Event, Length, Rectangle, Shell, Size, Vector};  /// A component that displays information and allows interaction.  /// @@ -122,8 +121,7 @@ where          _clipboard: &mut dyn Clipboard,          _shell: &mut Shell<'_, Message>,          _viewport: &Rectangle, -    ) -> event::Status { -        event::Status::Ignored +    ) {      }      /// Returns the current [`mouse::Interaction`] of the [`Widget`]. diff --git a/examples/loading_spinners/src/circular.rs b/examples/loading_spinners/src/circular.rs index 954a777e..e6b59cae 100644 --- a/examples/loading_spinners/src/circular.rs +++ b/examples/loading_spinners/src/circular.rs @@ -3,7 +3,6 @@ use iced::advanced::layout;  use iced::advanced::renderer;  use iced::advanced::widget::tree::{self, Tree};  use iced::advanced::{self, Clipboard, Layout, Shell, Widget}; -use iced::event;  use iced::mouse;  use iced::time::Instant;  use iced::widget::canvas; @@ -272,7 +271,7 @@ where          _clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          _viewport: &Rectangle, -    ) -> event::Status { +    ) {          let state = tree.state.downcast_mut::<State>();          if let Event::Window(window::Event::RedrawRequested(now)) = event { @@ -285,8 +284,6 @@ where              state.cache.clear();              shell.request_redraw();          } - -        event::Status::Ignored      }      fn draw( diff --git a/examples/loading_spinners/src/linear.rs b/examples/loading_spinners/src/linear.rs index 81edde75..34576261 100644 --- a/examples/loading_spinners/src/linear.rs +++ b/examples/loading_spinners/src/linear.rs @@ -3,7 +3,6 @@ use iced::advanced::layout;  use iced::advanced::renderer::{self, Quad};  use iced::advanced::widget::tree::{self, Tree};  use iced::advanced::{self, Clipboard, Layout, Shell, Widget}; -use iced::event;  use iced::mouse;  use iced::time::Instant;  use iced::window; @@ -186,7 +185,7 @@ where          _clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          _viewport: &Rectangle, -    ) -> event::Status { +    ) {          let state = tree.state.downcast_mut::<State>();          if let Event::Window(window::Event::RedrawRequested(now)) = event { @@ -194,8 +193,6 @@ where              shell.request_redraw();          } - -        event::Status::Ignored      }      fn draw( diff --git a/examples/toast/src/main.rs b/examples/toast/src/main.rs index 0b46c74e..079b96b4 100644 --- a/examples/toast/src/main.rs +++ b/examples/toast/src/main.rs @@ -169,7 +169,6 @@ mod toast {      use iced::advanced::renderer;      use iced::advanced::widget::{self, Operation, Tree};      use iced::advanced::{Clipboard, Shell, Widget}; -    use iced::event::{self, Event};      use iced::mouse;      use iced::theme;      use iced::widget::{ @@ -177,8 +176,8 @@ mod toast {      };      use iced::window;      use iced::{ -        Alignment, Center, Element, Fill, Length, Point, Rectangle, Renderer, -        Size, Theme, Vector, +        Alignment, Center, Element, Event, Fill, Length, Point, Rectangle, +        Renderer, Size, Theme, Vector,      };      pub const DEFAULT_TIMEOUT: u64 = 5; @@ -369,7 +368,7 @@ mod toast {              clipboard: &mut dyn Clipboard,              shell: &mut Shell<'_, Message>,              viewport: &Rectangle, -        ) -> event::Status { +        ) {              self.content.as_widget_mut().on_event(                  &mut state.children[0],                  event, @@ -379,7 +378,7 @@ mod toast {                  clipboard,                  shell,                  viewport, -            ) +            );          }          fn draw( @@ -498,7 +497,7 @@ mod toast {              renderer: &Renderer,              clipboard: &mut dyn Clipboard,              shell: &mut Shell<'_, Message>, -        ) -> event::Status { +        ) {              if let Event::Window(window::Event::RedrawRequested(now)) = &event {                  self.instants.iter_mut().enumerate().for_each(                      |(index, maybe_instant)| { @@ -520,35 +519,33 @@ mod toast {              let viewport = layout.bounds(); -            self.toasts +            for (((child, state), layout), instant) in self +                .toasts                  .iter_mut()                  .zip(self.state.iter_mut())                  .zip(layout.children())                  .zip(self.instants.iter_mut()) -                .map(|(((child, state), layout), instant)| { -                    let mut local_messages = vec![]; -                    let mut local_shell = Shell::new(&mut local_messages); - -                    let status = child.as_widget_mut().on_event( -                        state, -                        event.clone(), -                        layout, -                        cursor, -                        renderer, -                        clipboard, -                        &mut local_shell, -                        &viewport, -                    ); +            { +                let mut local_messages = vec![]; +                let mut local_shell = Shell::new(&mut local_messages); -                    if !local_shell.is_empty() { -                        instant.take(); -                    } +                child.as_widget_mut().on_event( +                    state, +                    event.clone(), +                    layout, +                    cursor, +                    renderer, +                    clipboard, +                    &mut local_shell, +                    &viewport, +                ); -                    shell.merge(local_shell, std::convert::identity); +                if !local_shell.is_empty() { +                    instant.take(); +                } -                    status -                }) -                .fold(event::Status::Ignored, event::Status::merge) +                shell.merge(local_shell, std::convert::identity); +            }          }          fn draw( diff --git a/runtime/src/overlay/nested.rs b/runtime/src/overlay/nested.rs index da3e6929..45f6b220 100644 --- a/runtime/src/overlay/nested.rs +++ b/runtime/src/overlay/nested.rs @@ -166,7 +166,7 @@ where          renderer: &Renderer,          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>, -    ) -> event::Status { +    ) {          fn recurse<Message, Theme, Renderer>(              element: &mut overlay::Element<'_, Message, Theme, Renderer>,              layout: Layout<'_>, @@ -175,31 +175,30 @@ where              renderer: &Renderer,              clipboard: &mut dyn Clipboard,              shell: &mut Shell<'_, Message>, -        ) -> (event::Status, bool) +        ) -> bool          where              Renderer: renderer::Renderer,          {              let mut layouts = layout.children();              if let Some(layout) = layouts.next() { -                let (nested_status, nested_is_over) = -                    if let Some((mut nested, nested_layout)) = -                        element.overlay(layout, renderer).zip(layouts.next()) -                    { -                        recurse( -                            &mut nested, -                            nested_layout, -                            event.clone(), -                            cursor, -                            renderer, -                            clipboard, -                            shell, -                        ) -                    } else { -                        (event::Status::Ignored, false) -                    }; +                let nested_is_over = if let Some((mut nested, nested_layout)) = +                    element.overlay(layout, renderer).zip(layouts.next()) +                { +                    recurse( +                        &mut nested, +                        nested_layout, +                        event.clone(), +                        cursor, +                        renderer, +                        clipboard, +                        shell, +                    ) +                } else { +                    false +                }; -                if matches!(nested_status, event::Status::Ignored) { +                if shell.event_status() == event::Status::Ignored {                      let is_over = nested_is_over                          || cursor                              .position() @@ -212,30 +211,29 @@ where                              })                              .unwrap_or_default(); -                    ( -                        element.on_event( -                            event, -                            layout, -                            if nested_is_over { -                                mouse::Cursor::Unavailable -                            } else { -                                cursor -                            }, -                            renderer, -                            clipboard, -                            shell, -                        ), -                        is_over, -                    ) +                    element.on_event( +                        event, +                        layout, +                        if nested_is_over { +                            mouse::Cursor::Unavailable +                        } else { +                            cursor +                        }, +                        renderer, +                        clipboard, +                        shell, +                    ); + +                    is_over                  } else { -                    (nested_status, nested_is_over) +                    nested_is_over                  }              } else { -                (event::Status::Ignored, false) +                false              }          } -        let (status, _) = recurse( +        let _ = recurse(              &mut self.overlay,              layout,              event, @@ -244,8 +242,6 @@ where              clipboard,              shell,          ); - -        status      }      /// Returns the current [`mouse::Interaction`] of the [`Nested`] overlay. diff --git a/runtime/src/user_interface.rs b/runtime/src/user_interface.rs index 8dfc97a7..cae17bcc 100644 --- a/runtime/src/user_interface.rs +++ b/runtime/src/user_interface.rs @@ -210,7 +210,7 @@ where              for event in events.iter().cloned() {                  let mut shell = Shell::new(messages); -                let event_status = overlay.on_event( +                overlay.on_event(                      event,                      Layout::new(&layout),                      cursor, @@ -219,7 +219,7 @@ where                      &mut shell,                  ); -                event_statuses.push(event_status); +                event_statuses.push(shell.event_status());                  match (redraw_request, shell.redraw_request()) {                      (None, Some(at)) => { @@ -308,7 +308,7 @@ where                  let mut shell = Shell::new(messages); -                let event_status = self.root.as_widget_mut().on_event( +                self.root.as_widget_mut().on_event(                      &mut self.state,                      event,                      Layout::new(&self.base), @@ -319,7 +319,7 @@ where                      &viewport,                  ); -                if matches!(event_status, event::Status::Captured) { +                if shell.event_status() == event::Status::Captured {                      self.overlay = None;                  } @@ -347,7 +347,7 @@ where                      outdated = true;                  } -                event_status.merge(overlay_status) +                shell.event_status().merge(overlay_status)              })              .collect(); diff --git a/widget/src/button.rs b/widget/src/button.rs index 46fd0e17..6be17f59 100644 --- a/widget/src/button.rs +++ b/widget/src/button.rs @@ -283,8 +283,8 @@ where          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          viewport: &Rectangle, -    ) -> event::Status { -        if let event::Status::Captured = self.content.as_widget_mut().on_event( +    ) { +        self.content.as_widget_mut().on_event(              &mut tree.children[0],              event.clone(),              layout.children().next().unwrap(), @@ -293,62 +293,53 @@ where              clipboard,              shell,              viewport, -        ) { -            return event::Status::Captured; +        ); + +        if shell.event_status() == event::Status::Captured { +            return;          } -        let mut update = || { -            match event { -                Event::Mouse(mouse::Event::ButtonPressed( -                    mouse::Button::Left, -                )) -                | Event::Touch(touch::Event::FingerPressed { .. }) => { -                    if self.on_press.is_some() { -                        let bounds = layout.bounds(); +        match event { +            Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) +            | Event::Touch(touch::Event::FingerPressed { .. }) => { +                if self.on_press.is_some() { +                    let bounds = layout.bounds(); -                        if cursor.is_over(bounds) { -                            let state = tree.state.downcast_mut::<State>(); +                    if cursor.is_over(bounds) { +                        let state = tree.state.downcast_mut::<State>(); -                            state.is_pressed = true; +                        state.is_pressed = true; -                            return event::Status::Captured; -                        } +                        shell.capture_event();                      }                  } -                Event::Mouse(mouse::Event::ButtonReleased( -                    mouse::Button::Left, -                )) -                | Event::Touch(touch::Event::FingerLifted { .. }) => { -                    if let Some(on_press) = -                        self.on_press.as_ref().map(OnPress::get) -                    { -                        let state = tree.state.downcast_mut::<State>(); - -                        if state.is_pressed { -                            state.is_pressed = false; +            } +            Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) +            | Event::Touch(touch::Event::FingerLifted { .. }) => { +                if let Some(on_press) = self.on_press.as_ref().map(OnPress::get) +                { +                    let state = tree.state.downcast_mut::<State>(); -                            let bounds = layout.bounds(); +                    if state.is_pressed { +                        state.is_pressed = false; -                            if cursor.is_over(bounds) { -                                shell.publish(on_press); -                            } +                        let bounds = layout.bounds(); -                            return event::Status::Captured; +                        if cursor.is_over(bounds) { +                            shell.publish(on_press);                          } -                    } -                } -                Event::Touch(touch::Event::FingerLost { .. }) => { -                    let state = tree.state.downcast_mut::<State>(); -                    state.is_pressed = false; +                        shell.capture_event(); +                    }                  } -                _ => {}              } +            Event::Touch(touch::Event::FingerLost { .. }) => { +                let state = tree.state.downcast_mut::<State>(); -            event::Status::Ignored -        }; - -        let update_status = update(); +                state.is_pressed = false; +            } +            _ => {} +        }          let current_status = if self.on_press.is_none() {              Status::Disabled @@ -369,8 +360,6 @@ where          } else if self.status.is_some_and(|status| status != current_status) {              shell.request_redraw();          } - -        update_status      }      fn draw( diff --git a/widget/src/canvas.rs b/widget/src/canvas.rs index 9fbccf82..a9c65bb6 100644 --- a/widget/src/canvas.rs +++ b/widget/src/canvas.rs @@ -223,7 +223,7 @@ where          _clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          _viewport: &Rectangle, -    ) -> event::Status { +    ) {          let bounds = layout.bounds();          let canvas_event = match event { @@ -245,10 +245,10 @@ where                  shell.publish(message);              } -            return event_status; +            if event_status == event::Status::Captured { +                shell.capture_event(); +            }          } - -        event::Status::Ignored      }      fn mouse_interaction( diff --git a/widget/src/checkbox.rs b/widget/src/checkbox.rs index 6c5d7d6b..9b5f3602 100644 --- a/widget/src/checkbox.rs +++ b/widget/src/checkbox.rs @@ -31,7 +31,6 @@  //! ```  //!   use crate::core::alignment; -use crate::core::event::{self, Event};  use crate::core::layout;  use crate::core::mouse;  use crate::core::renderer; @@ -42,8 +41,8 @@ use crate::core::widget;  use crate::core::widget::tree::{self, Tree};  use crate::core::window;  use crate::core::{ -    Background, Border, Clipboard, Color, Element, Layout, Length, Pixels, -    Rectangle, Shell, Size, Theme, Widget, +    Background, Border, Clipboard, Color, Element, Event, Layout, Length, +    Pixels, Rectangle, Shell, Size, Theme, Widget,  };  /// A box that can be checked. @@ -313,7 +312,7 @@ where          _clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          _viewport: &Rectangle, -    ) -> event::Status { +    ) {          match event {              Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))              | Event::Touch(touch::Event::FingerPressed { .. }) => { @@ -322,7 +321,7 @@ where                  if mouse_over {                      if let Some(on_toggle) = &self.on_toggle {                          shell.publish((on_toggle)(!self.is_checked)); -                        return event::Status::Captured; +                        shell.capture_event();                      }                  }              } @@ -351,8 +350,6 @@ where          {              shell.request_redraw();          } - -        event::Status::Ignored      }      fn mouse_interaction( diff --git a/widget/src/column.rs b/widget/src/column.rs index 213f68fc..3fdc17f8 100644 --- a/widget/src/column.rs +++ b/widget/src/column.rs @@ -1,14 +1,13 @@  //! Distribute content vertically.  use crate::core::alignment::{self, Alignment}; -use crate::core::event::{self, Event};  use crate::core::layout;  use crate::core::mouse;  use crate::core::overlay;  use crate::core::renderer;  use crate::core::widget::{Operation, Tree};  use crate::core::{ -    Clipboard, Element, Layout, Length, Padding, Pixels, Rectangle, Shell, -    Size, Vector, Widget, +    Clipboard, Element, Event, Layout, Length, Padding, Pixels, Rectangle, +    Shell, Size, Vector, Widget,  };  /// A container that distributes its contents vertically. @@ -268,24 +267,24 @@ where          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          viewport: &Rectangle, -    ) -> event::Status { -        self.children +    ) { +        for ((child, state), layout) in self +            .children              .iter_mut()              .zip(&mut tree.children)              .zip(layout.children()) -            .map(|((child, state), layout)| { -                child.as_widget_mut().on_event( -                    state, -                    event.clone(), -                    layout, -                    cursor, -                    renderer, -                    clipboard, -                    shell, -                    viewport, -                ) -            }) -            .fold(event::Status::Ignored, event::Status::merge) +        { +            child.as_widget_mut().on_event( +                state, +                event.clone(), +                layout, +                cursor, +                renderer, +                clipboard, +                shell, +                viewport, +            ); +        }      }      fn mouse_interaction( diff --git a/widget/src/combo_box.rs b/widget/src/combo_box.rs index e300f1d0..1122861f 100644 --- a/widget/src/combo_box.rs +++ b/widget/src/combo_box.rs @@ -54,7 +54,7 @@  //!     }  //! }  //! ``` -use crate::core::event::{self, Event}; +use crate::core::event;  use crate::core::keyboard;  use crate::core::keyboard::key;  use crate::core::layout::{self, Layout}; @@ -65,7 +65,8 @@ use crate::core::text;  use crate::core::time::Instant;  use crate::core::widget::{self, Widget};  use crate::core::{ -    Clipboard, Element, Length, Padding, Rectangle, Shell, Size, Theme, Vector, +    Clipboard, Element, Event, Length, Padding, Rectangle, Shell, Size, Theme, +    Vector,  };  use crate::overlay::menu;  use crate::text::LineHeight; @@ -519,7 +520,7 @@ where          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          viewport: &Rectangle, -    ) -> event::Status { +    ) {          let menu = tree.state.downcast_mut::<Menu<T>>();          let started_focused = { @@ -538,7 +539,7 @@ where          let mut local_shell = Shell::new(&mut local_messages);          // Provide it to the widget -        let mut event_status = self.text_input.on_event( +        self.text_input.on_event(              &mut tree.children[0],              event.clone(),              layout, @@ -549,13 +550,16 @@ where              viewport,          ); +        if local_shell.event_status() == event::Status::Captured { +            shell.capture_event(); +        } +          // Then finally react to them here          for message in local_messages {              let TextInputEvent::TextChanged(new_value) = message;              if let Some(on_input) = &self.on_input {                  shell.publish((on_input)(new_value.clone())); -                published_message_to_shell = true;              }              // Couple the filtered options with the `ComboBox` @@ -619,7 +623,7 @@ where                                  }                              } -                            event_status = event::Status::Captured; +                            shell.capture_event();                          }                          (key::Named::ArrowUp, _) | (key::Named::Tab, true) => { @@ -656,7 +660,7 @@ where                                  }                              } -                            event_status = event::Status::Captured; +                            shell.capture_event();                          }                          (key::Named::ArrowDown, _)                          | (key::Named::Tab, false) @@ -703,7 +707,7 @@ where                                  }                              } -                            event_status = event::Status::Captured; +                            shell.capture_event();                          }                          _ => {}                      } @@ -724,7 +728,7 @@ where                  published_message_to_shell = true;                  // Unfocus the input -                let _ = self.text_input.on_event( +                self.text_input.on_event(                      &mut tree.children[0],                      Event::Mouse(mouse::Event::ButtonPressed(                          mouse::Button::Left, @@ -761,8 +765,6 @@ where                  }              }          } - -        event_status      }      fn mouse_interaction( diff --git a/widget/src/container.rs b/widget/src/container.rs index f4993ac9..f96c495c 100644 --- a/widget/src/container.rs +++ b/widget/src/container.rs @@ -21,7 +21,6 @@  //! ```  use crate::core::alignment::{self, Alignment};  use crate::core::border::{self, Border}; -use crate::core::event::{self, Event};  use crate::core::gradient::{self, Gradient};  use crate::core::layout;  use crate::core::mouse; @@ -30,7 +29,7 @@ use crate::core::renderer;  use crate::core::widget::tree::{self, Tree};  use crate::core::widget::{self, Operation};  use crate::core::{ -    self, color, Background, Clipboard, Color, Element, Layout, Length, +    self, color, Background, Clipboard, Color, Element, Event, Layout, Length,      Padding, Pixels, Point, Rectangle, Shadow, Shell, Size, Theme, Vector,      Widget,  }; @@ -308,7 +307,7 @@ where          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          viewport: &Rectangle, -    ) -> event::Status { +    ) {          self.content.as_widget_mut().on_event(              tree,              event, @@ -318,7 +317,7 @@ where              clipboard,              shell,              viewport, -        ) +        );      }      fn mouse_interaction( diff --git a/widget/src/helpers.rs b/widget/src/helpers.rs index 52290a54..13d69e1f 100644 --- a/widget/src/helpers.rs +++ b/widget/src/helpers.rs @@ -363,12 +363,11 @@ where      Theme: 'a,      Renderer: core::Renderer + 'a,  { -    use crate::core::event::{self, Event};      use crate::core::layout::{self, Layout};      use crate::core::mouse;      use crate::core::renderer;      use crate::core::widget::tree::{self, Tree}; -    use crate::core::{Rectangle, Shell, Size}; +    use crate::core::{Event, Rectangle, Shell, Size};      struct Opaque<'a, Message, Theme, Renderer> {          content: Element<'a, Message, Theme, Renderer>, @@ -449,25 +448,19 @@ where              clipboard: &mut dyn core::Clipboard,              shell: &mut Shell<'_, Message>,              viewport: &Rectangle, -        ) -> event::Status { +        ) {              let is_mouse_press = matches!(                  event,                  core::Event::Mouse(mouse::Event::ButtonPressed(_))              ); -            if let core::event::Status::Captured = -                self.content.as_widget_mut().on_event( -                    state, event, layout, cursor, renderer, clipboard, shell, -                    viewport, -                ) -            { -                return event::Status::Captured; -            } +            self.content.as_widget_mut().on_event( +                state, event, layout, cursor, renderer, clipboard, shell, +                viewport, +            );              if is_mouse_press && cursor.is_over(layout.bounds()) { -                event::Status::Captured -            } else { -                event::Status::Ignored +                shell.capture_event();              }          } @@ -530,12 +523,11 @@ where      Theme: 'a,      Renderer: core::Renderer + 'a,  { -    use crate::core::event::{self, Event};      use crate::core::layout::{self, Layout};      use crate::core::mouse;      use crate::core::renderer;      use crate::core::widget::tree::{self, Tree}; -    use crate::core::{Rectangle, Shell, Size}; +    use crate::core::{Event, Rectangle, Shell, Size};      struct Hover<'a, Message, Theme, Renderer> {          base: Element<'a, Message, Theme, Renderer>, @@ -658,7 +650,7 @@ where              clipboard: &mut dyn core::Clipboard,              shell: &mut Shell<'_, Message>,              viewport: &Rectangle, -        ) -> event::Status { +        ) {              let mut children = layout.children().zip(&mut tree.children);              let (base_layout, base_tree) = children.next().unwrap();              let (top_layout, top_tree) = children.next().unwrap(); @@ -680,7 +672,7 @@ where                  };              } -            let top_status = if matches!( +            if matches!(                  event,                  Event::Mouse(                      mouse::Event::CursorMoved { .. } @@ -699,13 +691,11 @@ where                      clipboard,                      shell,                      viewport, -                ) -            } else { -                event::Status::Ignored +                );              }; -            if top_status == event::Status::Captured { -                return top_status; +            if shell.is_event_captured() { +                return;              }              self.base.as_widget_mut().on_event( @@ -717,7 +707,7 @@ where                  clipboard,                  shell,                  viewport, -            ) +            );          }          fn mouse_interaction( diff --git a/widget/src/image/viewer.rs b/widget/src/image/viewer.rs index b1aad22c..5787200b 100644 --- a/widget/src/image/viewer.rs +++ b/widget/src/image/viewer.rs @@ -1,13 +1,12 @@  //! Zoom and pan on an image. -use crate::core::event::{self, Event};  use crate::core::image::{self, FilterMethod};  use crate::core::layout;  use crate::core::mouse;  use crate::core::renderer;  use crate::core::widget::tree::{self, Tree};  use crate::core::{ -    Clipboard, ContentFit, Element, Image, Layout, Length, Pixels, Point, -    Radians, Rectangle, Shell, Size, Vector, Widget, +    Clipboard, ContentFit, Element, Event, Image, Layout, Length, Pixels, +    Point, Radians, Rectangle, Shell, Size, Vector, Widget,  };  /// A frame that displays an image with the ability to zoom in/out and pan. @@ -157,15 +156,15 @@ where          cursor: mouse::Cursor,          renderer: &Renderer,          _clipboard: &mut dyn Clipboard, -        _shell: &mut Shell<'_, Message>, +        shell: &mut Shell<'_, Message>,          _viewport: &Rectangle, -    ) -> event::Status { +    ) {          let bounds = layout.bounds();          match event {              Event::Mouse(mouse::Event::WheelScrolled { delta }) => {                  let Some(cursor_position) = cursor.position_over(bounds) else { -                    return event::Status::Ignored; +                    return;                  };                  match delta { @@ -216,29 +215,25 @@ where                      }                  } -                event::Status::Captured +                shell.capture_event();              }              Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => {                  let Some(cursor_position) = cursor.position_over(bounds) else { -                    return event::Status::Ignored; +                    return;                  };                  let state = tree.state.downcast_mut::<State>();                  state.cursor_grabbed_at = Some(cursor_position);                  state.starting_offset = state.current_offset; - -                event::Status::Captured +                shell.capture_event();              }              Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) => {                  let state = tree.state.downcast_mut::<State>();                  if state.cursor_grabbed_at.is_some() {                      state.cursor_grabbed_at = None; - -                    event::Status::Captured -                } else { -                    event::Status::Ignored +                    shell.capture_event();                  }              }              Event::Mouse(mouse::Event::CursorMoved { position }) => { @@ -278,13 +273,10 @@ where                      };                      state.current_offset = Vector::new(x, y); - -                    event::Status::Captured -                } else { -                    event::Status::Ignored +                    shell.capture_event();                  }              } -            _ => event::Status::Ignored, +            _ => {}          }      } diff --git a/widget/src/keyed/column.rs b/widget/src/keyed/column.rs index 5852ede1..1172785a 100644 --- a/widget/src/keyed/column.rs +++ b/widget/src/keyed/column.rs @@ -1,5 +1,4 @@  //! Keyed columns distribute content vertically while keeping continuity. -use crate::core::event::{self, Event};  use crate::core::layout;  use crate::core::mouse;  use crate::core::overlay; @@ -7,8 +6,8 @@ use crate::core::renderer;  use crate::core::widget::tree::{self, Tree};  use crate::core::widget::Operation;  use crate::core::{ -    Alignment, Clipboard, Element, Layout, Length, Padding, Pixels, Rectangle, -    Shell, Size, Vector, Widget, +    Alignment, Clipboard, Element, Event, Layout, Length, Padding, Pixels, +    Rectangle, Shell, Size, Vector, Widget,  };  /// A container that distributes its contents vertically while keeping continuity. @@ -308,24 +307,24 @@ where          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          viewport: &Rectangle, -    ) -> event::Status { -        self.children +    ) { +        for ((child, state), layout) in self +            .children              .iter_mut()              .zip(&mut tree.children)              .zip(layout.children()) -            .map(|((child, state), layout)| { -                child.as_widget_mut().on_event( -                    state, -                    event.clone(), -                    layout, -                    cursor, -                    renderer, -                    clipboard, -                    shell, -                    viewport, -                ) -            }) -            .fold(event::Status::Ignored, event::Status::merge) +        { +            child.as_widget_mut().on_event( +                state, +                event.clone(), +                layout, +                cursor, +                renderer, +                clipboard, +                shell, +                viewport, +            ); +        }      }      fn mouse_interaction( diff --git a/widget/src/lazy.rs b/widget/src/lazy.rs index 232f254c..4a9a6154 100644 --- a/widget/src/lazy.rs +++ b/widget/src/lazy.rs @@ -10,7 +10,6 @@ pub use responsive::Responsive;  mod cache; -use crate::core::event::{self, Event};  use crate::core::layout::{self, Layout};  use crate::core::mouse;  use crate::core::overlay; @@ -19,7 +18,7 @@ use crate::core::widget::tree::{self, Tree};  use crate::core::widget::{self, Widget};  use crate::core::Element;  use crate::core::{ -    self, Clipboard, Length, Point, Rectangle, Shell, Size, Vector, +    self, Clipboard, Event, Length, Point, Rectangle, Shell, Size, Vector,  };  use crate::runtime::overlay::Nested; @@ -206,7 +205,7 @@ where          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          viewport: &Rectangle, -    ) -> event::Status { +    ) {          self.with_element_mut(|element| {              element.as_widget_mut().on_event(                  &mut tree.children[0], @@ -217,8 +216,8 @@ where                  clipboard,                  shell,                  viewport, -            ) -        }) +            ); +        });      }      fn mouse_interaction( @@ -395,11 +394,10 @@ where          renderer: &Renderer,          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>, -    ) -> event::Status { -        self.with_overlay_mut_maybe(|overlay| { -            overlay.on_event(event, layout, cursor, renderer, clipboard, shell) -        }) -        .unwrap_or(event::Status::Ignored) +    ) { +        let _ = self.with_overlay_mut_maybe(|overlay| { +            overlay.on_event(event, layout, cursor, renderer, clipboard, shell); +        });      }      fn is_over( diff --git a/widget/src/lazy/component.rs b/widget/src/lazy/component.rs index e45c24ac..062e6f35 100644 --- a/widget/src/lazy/component.rs +++ b/widget/src/lazy/component.rs @@ -1,6 +1,5 @@  //! Build and reuse custom widgets using The Elm Architecture.  #![allow(deprecated)] -use crate::core::event;  use crate::core::layout::{self, Layout};  use crate::core::mouse;  use crate::core::overlay; @@ -322,12 +321,12 @@ where          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          viewport: &Rectangle, -    ) -> event::Status { +    ) {          let mut local_messages = Vec::new();          let mut local_shell = Shell::new(&mut local_messages);          let t = tree.state.downcast_mut::<Rc<RefCell<Option<Tree>>>>(); -        let event_status = self.with_element_mut(|element| { +        self.with_element_mut(|element| {              element.as_widget_mut().on_event(                  &mut t.borrow_mut().as_mut().unwrap().children[0],                  event, @@ -337,9 +336,13 @@ where                  clipboard,                  &mut local_shell,                  viewport, -            ) +            );          }); +        if local_shell.is_event_captured() { +            shell.capture_event(); +        } +          local_shell.revalidate_layout(|| shell.invalidate_layout());          if let Some(redraw_request) = local_shell.redraw_request() { @@ -377,8 +380,6 @@ where              shell.invalidate_layout();          } - -        event_status      }      fn operate( @@ -608,22 +609,24 @@ where          renderer: &Renderer,          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>, -    ) -> event::Status { +    ) {          let mut local_messages = Vec::new();          let mut local_shell = Shell::new(&mut local_messages); -        let event_status = self -            .with_overlay_mut_maybe(|overlay| { -                overlay.on_event( -                    event, -                    layout, -                    cursor, -                    renderer, -                    clipboard, -                    &mut local_shell, -                ) -            }) -            .unwrap_or(event::Status::Ignored); +        let _ = self.with_overlay_mut_maybe(|overlay| { +            overlay.on_event( +                event, +                layout, +                cursor, +                renderer, +                clipboard, +                &mut local_shell, +            ); +        }); + +        if local_shell.is_event_captured() { +            shell.capture_event(); +        }          local_shell.revalidate_layout(|| shell.invalidate_layout()); @@ -673,8 +676,6 @@ where              shell.invalidate_layout();          } - -        event_status      }      fn is_over( diff --git a/widget/src/lazy/responsive.rs b/widget/src/lazy/responsive.rs index a6c40ab0..c17798a6 100644 --- a/widget/src/lazy/responsive.rs +++ b/widget/src/lazy/responsive.rs @@ -1,4 +1,3 @@ -use crate::core::event::{self, Event};  use crate::core::layout::{self, Layout};  use crate::core::mouse;  use crate::core::overlay; @@ -6,8 +5,8 @@ use crate::core::renderer;  use crate::core::widget;  use crate::core::widget::tree::{self, Tree};  use crate::core::{ -    self, Clipboard, Element, Length, Point, Rectangle, Shell, Size, Vector, -    Widget, +    self, Clipboard, Element, Event, Length, Point, Rectangle, Shell, Size, +    Vector, Widget,  };  use crate::horizontal_space;  use crate::runtime::overlay::Nested; @@ -193,14 +192,14 @@ where          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          viewport: &Rectangle, -    ) -> event::Status { +    ) {          let state = tree.state.downcast_mut::<State>();          let mut content = self.content.borrow_mut();          let mut local_messages = vec![];          let mut local_shell = Shell::new(&mut local_messages); -        let status = content.resolve( +        content.resolve(              &mut state.tree.borrow_mut(),              renderer,              layout, @@ -215,7 +214,7 @@ where                      clipboard,                      &mut local_shell,                      viewport, -                ) +                );              },          ); @@ -224,8 +223,6 @@ where          }          shell.merge(local_shell, std::convert::identity); - -        status      }      fn draw( @@ -425,28 +422,20 @@ where          renderer: &Renderer,          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>, -    ) -> event::Status { +    ) {          let mut is_layout_invalid = false; -        let event_status = self -            .with_overlay_mut_maybe(|overlay| { -                let event_status = overlay.on_event( -                    event, layout, cursor, renderer, clipboard, shell, -                ); - -                is_layout_invalid = shell.is_layout_invalid(); +        let _ = self.with_overlay_mut_maybe(|overlay| { +            overlay.on_event(event, layout, cursor, renderer, clipboard, shell); -                event_status -            }) -            .unwrap_or(event::Status::Ignored); +            is_layout_invalid = shell.is_layout_invalid(); +        });          if is_layout_invalid {              self.with_overlay_mut(|(_overlay, layout)| {                  **layout = None;              });          } - -        event_status      }      fn is_over( diff --git a/widget/src/mouse_area.rs b/widget/src/mouse_area.rs index c5a37ae3..50188abd 100644 --- a/widget/src/mouse_area.rs +++ b/widget/src/mouse_area.rs @@ -1,5 +1,4 @@  //! A container for capturing mouse events. -use crate::core::event::{self, Event};  use crate::core::layout;  use crate::core::mouse;  use crate::core::overlay; @@ -7,8 +6,8 @@ use crate::core::renderer;  use crate::core::touch;  use crate::core::widget::{tree, Operation, Tree};  use crate::core::{ -    Clipboard, Element, Layout, Length, Point, Rectangle, Shell, Size, Vector, -    Widget, +    Clipboard, Element, Event, Layout, Length, Point, Rectangle, Shell, Size, +    Vector, Widget,  };  /// Emit messages on mouse events. @@ -226,8 +225,8 @@ where          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          viewport: &Rectangle, -    ) -> event::Status { -        if let event::Status::Captured = self.content.as_widget_mut().on_event( +    ) { +        self.content.as_widget_mut().on_event(              &mut tree.children[0],              event.clone(),              layout, @@ -236,11 +235,13 @@ where              clipboard,              shell,              viewport, -        ) { -            return event::Status::Captured; +        ); + +        if shell.is_event_captured() { +            return;          } -        update(self, tree, event, layout, cursor, shell) +        update(self, tree, event, layout, cursor, shell);      }      fn mouse_interaction( @@ -329,7 +330,7 @@ fn update<Message: Clone, Theme, Renderer>(      layout: Layout<'_>,      cursor: mouse::Cursor,      shell: &mut Shell<'_, Message>, -) -> event::Status { +) {      let state: &mut State = tree.state.downcast_mut();      let cursor_position = cursor.position(); @@ -363,104 +364,71 @@ fn update<Message: Clone, Theme, Renderer>(      }      if !cursor.is_over(layout.bounds()) { -        return event::Status::Ignored; +        return;      } -    if let Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) -    | Event::Touch(touch::Event::FingerPressed { .. }) = event -    { -        let mut captured = false; - -        if let Some(message) = widget.on_press.as_ref() { -            captured = true; -            shell.publish(message.clone()); -        } +    match event { +        Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) +        | Event::Touch(touch::Event::FingerPressed { .. }) => { +            if let Some(message) = widget.on_press.as_ref() { +                shell.publish(message.clone()); +                shell.capture_event(); +            } -        if let Some(position) = cursor_position { -            if let Some(message) = widget.on_double_click.as_ref() { -                let new_click = mouse::Click::new( -                    position, -                    mouse::Button::Left, -                    state.previous_click, -                ); +            if let Some(position) = cursor_position { +                if let Some(message) = widget.on_double_click.as_ref() { +                    let new_click = mouse::Click::new( +                        position, +                        mouse::Button::Left, +                        state.previous_click, +                    ); -                if matches!(new_click.kind(), mouse::click::Kind::Double) { -                    shell.publish(message.clone()); -                } +                    if matches!(new_click.kind(), mouse::click::Kind::Double) { +                        shell.publish(message.clone()); +                    } -                state.previous_click = Some(new_click); +                    state.previous_click = Some(new_click); -                // Even if this is not a double click, but the press is nevertheless -                // processed by us and should not be popup to parent widgets. -                captured = true; +                    // Even if this is not a double click, but the press is nevertheless +                    // processed by us and should not be popup to parent widgets. +                    shell.capture_event(); +                }              }          } - -        if captured { -            return event::Status::Captured; -        } -    } - -    if let Some(message) = widget.on_release.as_ref() { -        if let Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) -        | Event::Touch(touch::Event::FingerLifted { .. }) = event -        { -            shell.publish(message.clone()); - -            return event::Status::Captured; +        Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) +        | Event::Touch(touch::Event::FingerLifted { .. }) => { +            if let Some(message) = widget.on_release.as_ref() { +                shell.publish(message.clone()); +            }          } -    } - -    if let Some(message) = widget.on_right_press.as_ref() { -        if let Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Right)) = -            event -        { -            shell.publish(message.clone()); - -            return event::Status::Captured; +        Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Right)) => { +            if let Some(message) = widget.on_right_press.as_ref() { +                shell.publish(message.clone()); +                shell.capture_event(); +            }          } -    } - -    if let Some(message) = widget.on_right_release.as_ref() { -        if let Event::Mouse(mouse::Event::ButtonReleased( -            mouse::Button::Right, -        )) = event -        { -            shell.publish(message.clone()); - -            return event::Status::Captured; +        Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Right)) => { +            if let Some(message) = widget.on_right_release.as_ref() { +                shell.publish(message.clone()); +            }          } -    } - -    if let Some(message) = widget.on_middle_press.as_ref() { -        if let Event::Mouse(mouse::Event::ButtonPressed( -            mouse::Button::Middle, -        )) = event -        { -            shell.publish(message.clone()); - -            return event::Status::Captured; +        Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Middle)) => { +            if let Some(message) = widget.on_middle_press.as_ref() { +                shell.publish(message.clone()); +                shell.capture_event(); +            }          } -    } - -    if let Some(message) = widget.on_middle_release.as_ref() { -        if let Event::Mouse(mouse::Event::ButtonReleased( -            mouse::Button::Middle, -        )) = event -        { -            shell.publish(message.clone()); - -            return event::Status::Captured; +        Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Middle)) => { +            if let Some(message) = widget.on_middle_release.as_ref() { +                shell.publish(message.clone()); +            }          } -    } - -    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::Mouse(mouse::Event::WheelScrolled { delta }) => { +            if let Some(on_scroll) = widget.on_scroll.as_ref() { +                shell.publish(on_scroll(delta)); +                shell.capture_event(); +            }          } +        _ => {}      } - -    event::Status::Ignored  } diff --git a/widget/src/overlay/menu.rs b/widget/src/overlay/menu.rs index c1a0a5d8..78ee3da6 100644 --- a/widget/src/overlay/menu.rs +++ b/widget/src/overlay/menu.rs @@ -1,7 +1,6 @@  //! Build and show dropdown menus.  use crate::core::alignment;  use crate::core::border::{self, Border}; -use crate::core::event::{self, Event};  use crate::core::layout::{self, Layout};  use crate::core::mouse;  use crate::core::overlay; @@ -11,8 +10,8 @@ use crate::core::touch;  use crate::core::widget::tree::{self, Tree};  use crate::core::window;  use crate::core::{ -    Background, Clipboard, Color, Length, Padding, Pixels, Point, Rectangle, -    Size, Theme, Vector, +    Background, Clipboard, Color, Event, Length, Padding, Pixels, Point, +    Rectangle, Size, Theme, Vector,  };  use crate::core::{Element, Shell, Widget};  use crate::scrollable::{self, Scrollable}; @@ -271,13 +270,13 @@ where          renderer: &Renderer,          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>, -    ) -> event::Status { +    ) {          let bounds = layout.bounds();          self.list.on_event(              self.state, event, layout, cursor, renderer, clipboard, shell,              &bounds, -        ) +        );      }      fn mouse_interaction( @@ -397,14 +396,14 @@ where          _clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          _viewport: &Rectangle, -    ) -> event::Status { +    ) {          match event {              Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => {                  if cursor.is_over(layout.bounds()) {                      if let Some(index) = *self.hovered_option {                          if let Some(option) = self.options.get(index) {                              shell.publish((self.on_selected)(option.clone())); -                            return event::Status::Captured; +                            shell.capture_event();                          }                      }                  } @@ -460,7 +459,7 @@ where                      if let Some(index) = *self.hovered_option {                          if let Some(option) = self.options.get(index) {                              shell.publish((self.on_selected)(option.clone())); -                            return event::Status::Captured; +                            shell.capture_event();                          }                      }                  } @@ -477,8 +476,6 @@ where          }) {              shell.request_redraw();          } - -        event::Status::Ignored      }      fn mouse_interaction( diff --git a/widget/src/pane_grid.rs b/widget/src/pane_grid.rs index b4ed4b64..29b7ac87 100644 --- a/widget/src/pane_grid.rs +++ b/widget/src/pane_grid.rs @@ -79,7 +79,6 @@ pub use state::State;  pub use title_bar::TitleBar;  use crate::container; -use crate::core::event::{self, Event};  use crate::core::layout;  use crate::core::mouse;  use crate::core::overlay::{self, Group}; @@ -88,7 +87,7 @@ use crate::core::touch;  use crate::core::widget;  use crate::core::widget::tree::{self, Tree};  use crate::core::{ -    self, Background, Border, Clipboard, Color, Element, Layout, Length, +    self, Background, Border, Clipboard, Color, Element, Event, Layout, Length,      Pixels, Point, Rectangle, Shell, Size, Theme, Vector, Widget,  }; @@ -433,9 +432,7 @@ where          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          viewport: &Rectangle, -    ) -> event::Status { -        let mut event_status = event::Status::Ignored; - +    ) {          let Memory { action, .. } = tree.state.downcast_mut();          let node = self.internal.layout(); @@ -451,7 +448,7 @@ where                  let bounds = layout.bounds();                  if let Some(cursor_position) = cursor.position_over(bounds) { -                    event_status = event::Status::Captured; +                    shell.capture_event();                      match &self.on_resize {                          Some((leeway, _)) => { @@ -556,9 +553,9 @@ where                          }                      } -                    event_status = event::Status::Captured; +                    shell.capture_event();                  } else if action.picked_split().is_some() { -                    event_status = event::Status::Captured; +                    shell.capture_event();                  }                  *action = state::Action::Idle; @@ -600,7 +597,7 @@ where                                      ratio,                                  })); -                                event_status = event::Status::Captured; +                                shell.capture_event();                              }                          }                      } @@ -611,7 +608,8 @@ where          let picked_pane = action.picked_pane().map(|(pane, _)| pane); -        self.panes +        for (((pane, content), tree), layout) in self +            .panes              .iter()              .copied()              .zip(&mut self.contents) @@ -622,22 +620,21 @@ where                      .maximized()                      .map_or(true, |maximized| *pane == maximized)              }) -            .map(|(((pane, content), tree), layout)| { -                let is_picked = picked_pane == Some(pane); - -                content.on_event( -                    tree, -                    event.clone(), -                    layout, -                    cursor, -                    renderer, -                    clipboard, -                    shell, -                    viewport, -                    is_picked, -                ) -            }) -            .fold(event_status, event::Status::merge) +        { +            let is_picked = picked_pane == Some(pane); + +            content.on_event( +                tree, +                event.clone(), +                layout, +                cursor, +                renderer, +                clipboard, +                shell, +                viewport, +                is_picked, +            ); +        }      }      fn mouse_interaction( diff --git a/widget/src/pane_grid/content.rs b/widget/src/pane_grid/content.rs index ec0676b1..81a5cc1e 100644 --- a/widget/src/pane_grid/content.rs +++ b/widget/src/pane_grid/content.rs @@ -1,12 +1,12 @@  use crate::container; -use crate::core::event::{self, Event};  use crate::core::layout;  use crate::core::mouse;  use crate::core::overlay;  use crate::core::renderer;  use crate::core::widget::{self, Tree};  use crate::core::{ -    self, Clipboard, Element, Layout, Point, Rectangle, Shell, Size, Vector, +    self, Clipboard, Element, Event, Layout, Point, Rectangle, Shell, Size, +    Vector,  };  use crate::pane_grid::{Draggable, TitleBar}; @@ -250,13 +250,11 @@ where          shell: &mut Shell<'_, Message>,          viewport: &Rectangle,          is_picked: bool, -    ) -> event::Status { -        let mut event_status = event::Status::Ignored; - +    ) {          let body_layout = if let Some(title_bar) = &mut self.title_bar {              let mut children = layout.children(); -            event_status = title_bar.on_event( +            title_bar.on_event(                  &mut tree.children[1],                  event.clone(),                  children.next().unwrap(), @@ -272,9 +270,7 @@ where              layout          }; -        let body_status = if is_picked { -            event::Status::Ignored -        } else { +        if !is_picked {              self.body.as_widget_mut().on_event(                  &mut tree.children[0],                  event, @@ -284,10 +280,8 @@ where                  clipboard,                  shell,                  viewport, -            ) -        }; - -        event_status.merge(body_status) +            ); +        }      }      pub(crate) fn mouse_interaction( diff --git a/widget/src/pane_grid/title_bar.rs b/widget/src/pane_grid/title_bar.rs index 5002b4f7..ec1dc302 100644 --- a/widget/src/pane_grid/title_bar.rs +++ b/widget/src/pane_grid/title_bar.rs @@ -1,13 +1,12 @@  use crate::container; -use crate::core::event::{self, Event};  use crate::core::layout;  use crate::core::mouse;  use crate::core::overlay;  use crate::core::renderer;  use crate::core::widget::{self, Tree};  use crate::core::{ -    self, Clipboard, Element, Layout, Padding, Point, Rectangle, Shell, Size, -    Vector, +    self, Clipboard, Element, Event, Layout, Padding, Point, Rectangle, Shell, +    Size, Vector,  };  use crate::pane_grid::controls::Controls; @@ -438,7 +437,7 @@ where          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          viewport: &Rectangle, -    ) -> event::Status { +    ) {          let mut children = layout.children();          let padded = children.next().unwrap(); @@ -446,8 +445,9 @@ where          let title_layout = children.next().unwrap();          let mut show_title = true; -        let control_status = if let Some(controls) = &mut self.controls { +        if let Some(controls) = &mut self.controls {              let controls_layout = children.next().unwrap(); +              if title_layout.bounds().width + controls_layout.bounds().width                  > padded.bounds().width              { @@ -463,7 +463,7 @@ where                          clipboard,                          shell,                          viewport, -                    ) +                    );                  } else {                      show_title = false; @@ -476,7 +476,7 @@ where                          clipboard,                          shell,                          viewport, -                    ) +                    );                  }              } else {                  controls.full.as_widget_mut().on_event( @@ -488,13 +488,11 @@ where                      clipboard,                      shell,                      viewport, -                ) +                );              } -        } else { -            event::Status::Ignored -        }; +        } -        let title_status = if show_title { +        if show_title {              self.content.as_widget_mut().on_event(                  &mut tree.children[0],                  event, @@ -504,12 +502,8 @@ where                  clipboard,                  shell,                  viewport, -            ) -        } else { -            event::Status::Ignored -        }; - -        control_status.merge(title_status) +            ); +        }      }      pub(crate) fn mouse_interaction( diff --git a/widget/src/pick_list.rs b/widget/src/pick_list.rs index 9c9ba9e9..9eb43e72 100644 --- a/widget/src/pick_list.rs +++ b/widget/src/pick_list.rs @@ -61,7 +61,6 @@  //! }  //! ```  use crate::core::alignment; -use crate::core::event::{self, Event};  use crate::core::keyboard;  use crate::core::layout;  use crate::core::mouse; @@ -73,8 +72,8 @@ use crate::core::touch;  use crate::core::widget::tree::{self, Tree};  use crate::core::window;  use crate::core::{ -    Background, Border, Clipboard, Color, Element, Layout, Length, Padding, -    Pixels, Point, Rectangle, Shell, Size, Theme, Vector, Widget, +    Background, Border, Clipboard, Color, Element, Event, Layout, Length, +    Padding, Pixels, Point, Rectangle, Shell, Size, Theme, Vector, Widget,  };  use crate::overlay::menu::{self, Menu}; @@ -438,10 +437,10 @@ where          _clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          _viewport: &Rectangle, -    ) -> event::Status { +    ) {          let state = tree.state.downcast_mut::<State<Renderer::Paragraph>>(); -        let event_status = match event { +        match event {              Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))              | Event::Touch(touch::Event::FingerPressed { .. }) => {                  if state.is_open { @@ -453,7 +452,7 @@ where                          shell.publish(on_close.clone());                      } -                    event::Status::Captured +                    shell.capture_event();                  } else if cursor.is_over(layout.bounds()) {                      let selected = self.selected.as_ref().map(Borrow::borrow); @@ -468,9 +467,7 @@ where                          shell.publish(on_open.clone());                      } -                    event::Status::Captured -                } else { -                    event::Status::Ignored +                    shell.capture_event();                  }              }              Event::Mouse(mouse::Event::WheelScrolled { @@ -512,17 +509,13 @@ where                          shell.publish((self.on_select)(next_option.clone()));                      } -                    event::Status::Captured -                } else { -                    event::Status::Ignored +                    shell.capture_event();                  }              }              Event::Keyboard(keyboard::Event::ModifiersChanged(modifiers)) => {                  state.keyboard_modifiers = modifiers; - -                event::Status::Ignored              } -            _ => event::Status::Ignored, +            _ => {}          };          let status = if state.is_open { @@ -541,8 +534,6 @@ where          {              shell.request_redraw();          } - -        event_status      }      fn mouse_interaction( diff --git a/widget/src/radio.rs b/widget/src/radio.rs index ed821532..70e1c423 100644 --- a/widget/src/radio.rs +++ b/widget/src/radio.rs @@ -58,7 +58,6 @@  //! ```  use crate::core::alignment;  use crate::core::border::{self, Border}; -use crate::core::event::{self, Event};  use crate::core::layout;  use crate::core::mouse;  use crate::core::renderer; @@ -68,8 +67,8 @@ use crate::core::widget;  use crate::core::widget::tree::{self, Tree};  use crate::core::window;  use crate::core::{ -    Background, Clipboard, Color, Element, Layout, Length, Pixels, Rectangle, -    Shell, Size, Theme, Widget, +    Background, Clipboard, Color, Element, Event, Layout, Length, Pixels, +    Rectangle, Shell, Size, Theme, Widget,  };  /// A circular button representing a choice. @@ -334,14 +333,13 @@ where          _clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          _viewport: &Rectangle, -    ) -> event::Status { +    ) {          match event {              Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))              | Event::Touch(touch::Event::FingerPressed { .. }) => {                  if cursor.is_over(layout.bounds()) {                      shell.publish(self.on_click.clone()); - -                    return event::Status::Captured; +                    shell.capture_event();                  }              }              _ => {} @@ -366,8 +364,6 @@ where          {              shell.request_redraw();          } - -        event::Status::Ignored      }      fn mouse_interaction( diff --git a/widget/src/row.rs b/widget/src/row.rs index 9c0fa97e..a4b6aa2a 100644 --- a/widget/src/row.rs +++ b/widget/src/row.rs @@ -1,13 +1,12 @@  //! Distribute content horizontally.  use crate::core::alignment::{self, Alignment}; -use crate::core::event::{self, Event};  use crate::core::layout::{self, Layout};  use crate::core::mouse;  use crate::core::overlay;  use crate::core::renderer;  use crate::core::widget::{Operation, Tree};  use crate::core::{ -    Clipboard, Element, Length, Padding, Pixels, Rectangle, Shell, Size, +    Clipboard, Element, Event, Length, Padding, Pixels, Rectangle, Shell, Size,      Vector, Widget,  }; @@ -264,24 +263,24 @@ where          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          viewport: &Rectangle, -    ) -> event::Status { -        self.children +    ) { +        for ((child, state), layout) in self +            .children              .iter_mut()              .zip(&mut tree.children)              .zip(layout.children()) -            .map(|((child, state), layout)| { -                child.as_widget_mut().on_event( -                    state, -                    event.clone(), -                    layout, -                    cursor, -                    renderer, -                    clipboard, -                    shell, -                    viewport, -                ) -            }) -            .fold(event::Status::Ignored, event::Status::merge) +        { +            child.as_widget_mut().on_event( +                state, +                event.clone(), +                layout, +                cursor, +                renderer, +                clipboard, +                shell, +                viewport, +            ); +        }      }      fn mouse_interaction( @@ -503,10 +502,10 @@ where          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          viewport: &Rectangle, -    ) -> event::Status { +    ) {          self.row.on_event(              tree, event, layout, cursor, renderer, clipboard, shell, viewport, -        ) +        );      }      fn mouse_interaction( diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index abad6ea6..33d4f545 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -21,7 +21,6 @@  //! ```  use crate::container;  use crate::core::border::{self, Border}; -use crate::core::event::{self, Event};  use crate::core::keyboard;  use crate::core::layout;  use crate::core::mouse; @@ -34,8 +33,8 @@ use crate::core::widget::operation::{self, Operation};  use crate::core::widget::tree::{self, Tree};  use crate::core::window;  use crate::core::{ -    self, Background, Clipboard, Color, Element, Layout, Length, Padding, -    Pixels, Point, Rectangle, Shell, Size, Theme, Vector, Widget, +    self, Background, Clipboard, Color, Element, Event, Layout, Length, +    Padding, Pixels, Point, Rectangle, Shell, Size, Theme, Vector, Widget,  };  use crate::runtime::task::{self, Task};  use crate::runtime::Action; @@ -519,7 +518,7 @@ where          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          _viewport: &Rectangle, -    ) -> event::Status { +    ) {          let state = tree.state.downcast_mut::<State>();          let bounds = layout.bounds();          let cursor_over_scrollable = cursor.position_over(bounds); @@ -561,7 +560,7 @@ where                          if let Some(scrollbar) = scrollbars.y {                              let Some(cursor_position) = cursor.position()                              else { -                                return event::Status::Ignored; +                                return;                              };                              state.scroll_y_to( @@ -581,7 +580,7 @@ where                                  shell,                              ); -                            return event::Status::Captured; +                            shell.capture_event();                          }                      }                      _ => {} @@ -593,7 +592,7 @@ where                      ))                      | Event::Touch(touch::Event::FingerPressed { .. }) => {                          let Some(cursor_position) = cursor.position() else { -                            return event::Status::Ignored; +                            return;                          };                          if let (Some(scroller_grabbed_at), Some(scrollbar)) = ( @@ -621,7 +620,7 @@ where                              );                          } -                        return event::Status::Captured; +                        shell.capture_event();                      }                      _ => {}                  } @@ -632,7 +631,7 @@ where                      Event::Mouse(mouse::Event::CursorMoved { .. })                      | Event::Touch(touch::Event::FingerMoved { .. }) => {                          let Some(cursor_position) = cursor.position() else { -                            return event::Status::Ignored; +                            return;                          };                          if let Some(scrollbar) = scrollbars.x { @@ -654,7 +653,7 @@ where                              );                          } -                        return event::Status::Captured; +                        shell.capture_event();                      }                      _ => {}                  } @@ -665,7 +664,7 @@ where                      ))                      | Event::Touch(touch::Event::FingerPressed { .. }) => {                          let Some(cursor_position) = cursor.position() else { -                            return event::Status::Ignored; +                            return;                          };                          if let (Some(scroller_grabbed_at), Some(scrollbar)) = ( @@ -692,20 +691,19 @@ where                                  shell,                              ); -                            return event::Status::Captured; +                            shell.capture_event();                          }                      }                      _ => {}                  }              } -            let content_status = if state.last_scrolled.is_some() -                && matches!( +            if state.last_scrolled.is_none() +                || !matches!(                      event,                      Event::Mouse(mouse::Event::WheelScrolled { .. }) -                ) { -                event::Status::Ignored -            } else { +                ) +            {                  let cursor = match cursor_over_scrollable {                      Some(cursor_position)                          if !(mouse_over_x_scrollbar @@ -739,7 +737,7 @@ where                          x: bounds.x + translation.x,                          ..bounds                      }, -                ) +                );              };              if matches!( @@ -754,11 +752,11 @@ where                  state.x_scroller_grabbed_at = None;                  state.y_scroller_grabbed_at = None; -                return content_status; +                return;              } -            if let event::Status::Captured = content_status { -                return event::Status::Captured; +            if shell.is_event_captured() { +                return;              }              if let Event::Keyboard(keyboard::Event::ModifiersChanged( @@ -767,13 +765,13 @@ where              {                  state.keyboard_modifiers = modifiers; -                return event::Status::Ignored; +                return;              }              match event {                  Event::Mouse(mouse::Event::WheelScrolled { delta }) => {                      if cursor_over_scrollable.is_none() { -                        return event::Status::Ignored; +                        return;                      }                      let delta = match delta { @@ -827,9 +825,7 @@ where                      let in_transaction = state.last_scrolled.is_some();                      if has_scrolled || in_transaction { -                        event::Status::Captured -                    } else { -                        event::Status::Ignored +                        shell.capture_event();                      }                  }                  Event::Touch(event) @@ -841,7 +837,7 @@ where                          touch::Event::FingerPressed { .. } => {                              let Some(cursor_position) = cursor.position()                              else { -                                return event::Status::Ignored; +                                return;                              };                              state.scroll_area_touched_at = @@ -853,7 +849,7 @@ where                              {                                  let Some(cursor_position) = cursor.position()                                  else { -                                    return event::Status::Ignored; +                                    return;                                  };                                  let delta = Vector::new( @@ -883,7 +879,7 @@ where                          _ => {}                      } -                    event::Status::Captured +                    shell.capture_event();                  }                  Event::Window(window::Event::RedrawRequested(_)) => {                      let _ = notify_viewport( @@ -893,14 +889,12 @@ where                          content_bounds,                          shell,                      ); - -                    event::Status::Ignored                  } -                _ => event::Status::Ignored, +                _ => {}              }          }; -        let event_status = update(); +        update();          let status = if state.y_scroller_grabbed_at.is_some()              || state.x_scroller_grabbed_at.is_some() @@ -933,8 +927,6 @@ where          {              shell.request_redraw();          } - -        event_status      }      fn draw( diff --git a/widget/src/shader.rs b/widget/src/shader.rs index fa692336..5e4d3915 100644 --- a/widget/src/shader.rs +++ b/widget/src/shader.rs @@ -97,7 +97,7 @@ where          _clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          _viewport: &Rectangle, -    ) -> event::Status { +    ) {          let bounds = layout.bounds();          let custom_shader_event = match event { @@ -115,22 +115,14 @@ where          if let Some(custom_shader_event) = custom_shader_event {              let state = tree.state.downcast_mut::<P::State>(); -            let (event_status, message) = self.program.update( +            self.program.update(                  state,                  custom_shader_event,                  bounds,                  cursor,                  shell,              ); - -            if let Some(message) = message { -                shell.publish(message); -            } - -            return event_status;          } - -        event::Status::Ignored      }      fn mouse_interaction( @@ -195,8 +187,8 @@ where          bounds: Rectangle,          cursor: mouse::Cursor,          shell: &mut Shell<'_, Message>, -    ) -> (event::Status, Option<Message>) { -        T::update(self, state, event, bounds, cursor, shell) +    ) { +        T::update(self, state, event, bounds, cursor, shell);      }      fn draw( diff --git a/widget/src/shader/event.rs b/widget/src/shader/event.rs index 005c8725..2d7c79bb 100644 --- a/widget/src/shader/event.rs +++ b/widget/src/shader/event.rs @@ -4,8 +4,6 @@ use crate::core::mouse;  use crate::core::time::Instant;  use crate::core::touch; -pub use crate::core::event::Status; -  /// A [`Shader`] event.  ///  /// [`Shader`]: crate::Shader diff --git a/widget/src/shader/program.rs b/widget/src/shader/program.rs index 902c7c3b..5124a1cc 100644 --- a/widget/src/shader/program.rs +++ b/widget/src/shader/program.rs @@ -1,4 +1,3 @@ -use crate::core::event;  use crate::core::mouse;  use crate::core::{Rectangle, Shell};  use crate::renderer::wgpu::Primitive; @@ -31,8 +30,7 @@ pub trait Program<Message> {          _bounds: Rectangle,          _cursor: mouse::Cursor,          _shell: &mut Shell<'_, Message>, -    ) -> (event::Status, Option<Message>) { -        (event::Status::Ignored, None) +    ) {      }      /// Draws the [`Primitive`]. diff --git a/widget/src/slider.rs b/widget/src/slider.rs index dbdb5f07..4a424bd9 100644 --- a/widget/src/slider.rs +++ b/widget/src/slider.rs @@ -29,7 +29,6 @@  //! }  //! ```  use crate::core::border::{self, Border}; -use crate::core::event::{self, Event};  use crate::core::keyboard;  use crate::core::keyboard::key::{self, Key};  use crate::core::layout; @@ -39,8 +38,8 @@ use crate::core::touch;  use crate::core::widget::tree::{self, Tree};  use crate::core::window;  use crate::core::{ -    self, Background, Clipboard, Color, Element, Layout, Length, Pixels, Point, -    Rectangle, Shell, Size, Theme, Widget, +    self, Background, Clipboard, Color, Element, Event, Layout, Length, Pixels, +    Point, Rectangle, Shell, Size, Theme, Widget,  };  use std::ops::RangeInclusive; @@ -253,7 +252,7 @@ where          _clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          _viewport: &Rectangle, -    ) -> event::Status { +    ) {          let state = tree.state.downcast_mut::<State>();          let mut update = || { @@ -349,7 +348,7 @@ where                              state.is_dragging = true;                          } -                        return event::Status::Captured; +                        shell.capture_event();                      }                  }                  Event::Mouse(mouse::Event::ButtonReleased( @@ -363,7 +362,7 @@ where                          }                          state.is_dragging = false; -                        return event::Status::Captured; +                        shell.capture_event();                      }                  }                  Event::Mouse(mouse::Event::CursorMoved { .. }) @@ -371,7 +370,7 @@ where                      if state.is_dragging {                          let _ = cursor.position().and_then(locate).map(change); -                        return event::Status::Captured; +                        shell.capture_event();                      }                  }                  Event::Mouse(mouse::Event::WheelScrolled { delta }) @@ -389,7 +388,7 @@ where                              let _ = increment(current_value).map(change);                          } -                        return event::Status::Captured; +                        shell.capture_event();                      }                  }                  Event::Keyboard(keyboard::Event::KeyPressed { @@ -406,7 +405,7 @@ where                              _ => (),                          } -                        return event::Status::Captured; +                        shell.capture_event();                      }                  }                  Event::Keyboard(keyboard::Event::ModifiersChanged( @@ -416,11 +415,9 @@ where                  }                  _ => {}              } - -            event::Status::Ignored          }; -        let update_status = update(); +        update();          let current_status = if state.is_dragging {              Status::Dragged @@ -435,8 +432,6 @@ where          } else if self.status.is_some_and(|status| status != current_status) {              shell.request_redraw();          } - -        update_status      }      fn draw( diff --git a/widget/src/stack.rs b/widget/src/stack.rs index 6a44c328..2cb628ab 100644 --- a/widget/src/stack.rs +++ b/widget/src/stack.rs @@ -1,12 +1,12 @@  //! Display content on top of other content. -use crate::core::event::{self, Event};  use crate::core::layout;  use crate::core::mouse;  use crate::core::overlay;  use crate::core::renderer;  use crate::core::widget::{Operation, Tree};  use crate::core::{ -    Clipboard, Element, Layout, Length, Rectangle, Shell, Size, Vector, Widget, +    Clipboard, Element, Event, Layout, Length, Rectangle, Shell, Size, Vector, +    Widget,  };  /// A container that displays children on top of each other. @@ -214,40 +214,41 @@ where          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          viewport: &Rectangle, -    ) -> event::Status { +    ) {          let is_over = cursor.is_over(layout.bounds()); -        self.children +        for ((child, state), layout) in self +            .children              .iter_mut()              .rev()              .zip(tree.children.iter_mut().rev())              .zip(layout.children().rev()) -            .map(|((child, state), layout)| { -                let status = child.as_widget_mut().on_event( -                    state, -                    event.clone(), -                    layout, -                    cursor, -                    renderer, -                    clipboard, -                    shell, -                    viewport, +        { +            child.as_widget_mut().on_event( +                state, +                event.clone(), +                layout, +                cursor, +                renderer, +                clipboard, +                shell, +                viewport, +            ); + +            if is_over && cursor != mouse::Cursor::Unavailable { +                let interaction = child.as_widget().mouse_interaction( +                    state, layout, cursor, viewport, renderer,                  ); -                if is_over && cursor != mouse::Cursor::Unavailable { -                    let interaction = child.as_widget().mouse_interaction( -                        state, layout, cursor, viewport, renderer, -                    ); - -                    if interaction != mouse::Interaction::None { -                        cursor = mouse::Cursor::Unavailable; -                    } +                if interaction != mouse::Interaction::None { +                    cursor = mouse::Cursor::Unavailable;                  } +            } -                status -            }) -            .find(|&status| status == event::Status::Captured) -            .unwrap_or(event::Status::Ignored) +            if shell.is_event_captured() { +                return; +            } +        }      }      fn mouse_interaction( diff --git a/widget/src/text/rich.rs b/widget/src/text/rich.rs index 3d241375..f778b029 100644 --- a/widget/src/text/rich.rs +++ b/widget/src/text/rich.rs @@ -1,5 +1,4 @@  use crate::core::alignment; -use crate::core::event;  use crate::core::layout;  use crate::core::mouse;  use crate::core::renderer; @@ -365,7 +364,7 @@ where          _clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Link>,          _viewport: &Rectangle, -    ) -> event::Status { +    ) {          match event {              Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => {                  if let Some(position) = cursor.position_in(layout.bounds()) { @@ -374,9 +373,16 @@ where                          .downcast_mut::<State<Link, Renderer::Paragraph>>();                      if let Some(span) = state.paragraph.hit_span(position) { -                        state.span_pressed = Some(span); - -                        return event::Status::Captured; +                        if self +                            .spans +                            .as_ref() +                            .as_ref() +                            .get(span) +                            .is_some_and(|span| span.link.is_some()) +                        { +                            state.span_pressed = Some(span); +                            shell.capture_event(); +                        }                      }                  }              } @@ -409,8 +415,6 @@ where              }              _ => {}          } - -        event::Status::Ignored      }      fn mouse_interaction( diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index 3bb45494..292e584e 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -33,7 +33,6 @@  //! ```  use crate::core::alignment;  use crate::core::clipboard::{self, Clipboard}; -use crate::core::event::{self, Event};  use crate::core::keyboard;  use crate::core::keyboard::key;  use crate::core::layout::{self, Layout}; @@ -47,7 +46,7 @@ use crate::core::widget::operation;  use crate::core::widget::{self, Widget};  use crate::core::window;  use crate::core::{ -    Background, Border, Color, Element, Length, Padding, Pixels, Point, +    Background, Border, Color, Element, Event, Length, Padding, Pixels, Point,      Rectangle, Shell, Size, SmolStr, Theme, Vector,  }; @@ -606,9 +605,9 @@ where          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          _viewport: &Rectangle, -    ) -> event::Status { +    ) {          let Some(on_edit) = self.on_edit.as_ref() else { -            return event::Status::Ignored; +            return;          };          let state = tree.state.downcast_mut::<State<Highlighter>>(); @@ -656,7 +655,7 @@ where              cursor,              self.key_binding.as_deref(),          ) else { -            return event::Status::Ignored; +            return;          };          match update { @@ -685,7 +684,7 @@ where                  let bounds = self.content.0.borrow().editor.bounds();                  if bounds.height >= i32::MAX as f32 { -                    return event::Status::Ignored; +                    return;                  }                  let lines = lines + state.partial_scroll; @@ -798,7 +797,7 @@ where              }          } -        event::Status::Captured +        shell.capture_event();      }      fn draw( diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index 8fa7889f..87dffb98 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -42,7 +42,6 @@ use editor::Editor;  use crate::core::alignment;  use crate::core::clipboard::{self, Clipboard}; -use crate::core::event::{self, Event};  use crate::core::keyboard;  use crate::core::keyboard::key;  use crate::core::layout; @@ -57,8 +56,8 @@ use crate::core::widget::operation::{self, Operation};  use crate::core::widget::tree::{self, Tree};  use crate::core::window;  use crate::core::{ -    Background, Border, Color, Element, Layout, Length, Padding, Pixels, Point, -    Rectangle, Shell, Size, Theme, Vector, Widget, +    Background, Border, Color, Element, Event, Layout, Length, Padding, Pixels, +    Point, Rectangle, Shell, Size, Theme, Vector, Widget,  };  use crate::runtime::task::{self, Task};  use crate::runtime::Action; @@ -638,7 +637,7 @@ where          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          _viewport: &Rectangle, -    ) -> event::Status { +    ) {          let update_cache = |state, value| {              replace_paragraph(                  renderer, @@ -754,7 +753,7 @@ where                          shell.request_redraw();                      } -                    return event::Status::Captured; +                    shell.capture_event();                  }              }              Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) @@ -809,7 +808,7 @@ where                          shell.request_redraw();                      } -                    return event::Status::Captured; +                    shell.capture_event();                  }              }              Event::Keyboard(keyboard::Event::KeyPressed { @@ -834,14 +833,15 @@ where                                  );                              } -                            return event::Status::Captured; +                            shell.capture_event(); +                            return;                          }                          keyboard::Key::Character("x")                              if state.keyboard_modifiers.command()                                  && !self.is_secure =>                          {                              let Some(on_input) = &self.on_input else { -                                return event::Status::Ignored; +                                return;                              };                              if let Some((start, end)) = @@ -859,18 +859,18 @@ where                              let message = (on_input)(editor.contents());                              shell.publish(message); +                            shell.capture_event();                              focus.updated_at = Instant::now();                              update_cache(state, &self.value); - -                            return event::Status::Captured; +                            return;                          }                          keyboard::Key::Character("v")                              if state.keyboard_modifiers.command()                                  && !state.keyboard_modifiers.alt() =>                          {                              let Some(on_input) = &self.on_input else { -                                return event::Status::Ignored; +                                return;                              };                              let content = match state.is_pasting.take() { @@ -897,12 +897,12 @@ where                                  (on_input)(editor.contents())                              };                              shell.publish(message); +                            shell.capture_event();                              state.is_pasting = Some(content);                              focus.updated_at = Instant::now();                              update_cache(state, &self.value); - -                            return event::Status::Captured; +                            return;                          }                          keyboard::Key::Character("a")                              if state.keyboard_modifiers.command() => @@ -917,14 +917,15 @@ where                                  shell.request_redraw();                              } -                            return event::Status::Captured; +                            shell.capture_event(); +                            return;                          }                          _ => {}                      }                      if let Some(text) = text {                          let Some(on_input) = &self.on_input else { -                            return event::Status::Ignored; +                            return;                          };                          state.is_pasting = None; @@ -939,11 +940,11 @@ where                              let message = (on_input)(editor.contents());                              shell.publish(message); +                            shell.capture_event();                              focus.updated_at = Instant::now();                              update_cache(state, &self.value); - -                            return event::Status::Captured; +                            return;                          }                      } @@ -951,13 +952,12 @@ where                          keyboard::Key::Named(key::Named::Enter) => {                              if let Some(on_submit) = self.on_submit.clone() {                                  shell.publish(on_submit); - -                                return event::Status::Captured; +                                shell.capture_event();                              }                          }                          keyboard::Key::Named(key::Named::Backspace) => {                              let Some(on_input) = &self.on_input else { -                                return event::Status::Ignored; +                                return;                              };                              if modifiers.jump() @@ -980,15 +980,14 @@ where                              let message = (on_input)(editor.contents());                              shell.publish(message); +                            shell.capture_event();                              focus.updated_at = Instant::now();                              update_cache(state, &self.value); - -                            return event::Status::Captured;                          }                          keyboard::Key::Named(key::Named::Delete) => {                              let Some(on_input) = &self.on_input else { -                                return event::Status::Ignored; +                                return;                              };                              if modifiers.jump() @@ -1014,11 +1013,10 @@ where                              let message = (on_input)(editor.contents());                              shell.publish(message); +                            shell.capture_event();                              focus.updated_at = Instant::now();                              update_cache(state, &self.value); - -                            return event::Status::Captured;                          }                          keyboard::Key::Named(key::Named::Home) => {                              let cursor_before = state.cursor; @@ -1038,7 +1036,7 @@ where                                  shell.request_redraw();                              } -                            return event::Status::Captured; +                            shell.capture_event();                          }                          keyboard::Key::Named(key::Named::End) => {                              let cursor_before = state.cursor; @@ -1058,7 +1056,7 @@ where                                  shell.request_redraw();                              } -                            return event::Status::Captured; +                            shell.capture_event();                          }                          keyboard::Key::Named(key::Named::ArrowLeft)                              if modifiers.macos_command() => @@ -1080,7 +1078,7 @@ where                                  shell.request_redraw();                              } -                            return event::Status::Captured; +                            shell.capture_event();                          }                          keyboard::Key::Named(key::Named::ArrowRight)                              if modifiers.macos_command() => @@ -1102,7 +1100,7 @@ where                                  shell.request_redraw();                              } -                            return event::Status::Captured; +                            shell.capture_event();                          }                          keyboard::Key::Named(key::Named::ArrowLeft) => {                              let cursor_before = state.cursor; @@ -1129,7 +1127,7 @@ where                                  shell.request_redraw();                              } -                            return event::Status::Captured; +                            shell.capture_event();                          }                          keyboard::Key::Named(key::Named::ArrowRight) => {                              let cursor_before = state.cursor; @@ -1156,7 +1154,7 @@ where                                  shell.request_redraw();                              } -                            return event::Status::Captured; +                            shell.capture_event();                          }                          keyboard::Key::Named(key::Named::Escape) => {                              state.is_focused = None; @@ -1166,7 +1164,7 @@ where                              state.keyboard_modifiers =                                  keyboard::Modifiers::default(); -                            return event::Status::Captured; +                            shell.capture_event();                          }                          _ => {}                      } @@ -1179,7 +1177,7 @@ where                      if let keyboard::Key::Character("v") = key.as_ref() {                          state.is_pasting = None; -                        return event::Status::Captured; +                        shell.capture_event();                      }                  } @@ -1257,8 +1255,6 @@ where          {              shell.request_redraw();          } - -        event::Status::Ignored      }      fn draw( diff --git a/widget/src/themer.rs b/widget/src/themer.rs index 499a9fe8..649cfbdd 100644 --- a/widget/src/themer.rs +++ b/widget/src/themer.rs @@ -1,5 +1,4 @@  use crate::container; -use crate::core::event::{self, Event};  use crate::core::layout;  use crate::core::mouse;  use crate::core::overlay; @@ -7,8 +6,8 @@ use crate::core::renderer;  use crate::core::widget::tree::{self, Tree};  use crate::core::widget::Operation;  use crate::core::{ -    Background, Clipboard, Color, Element, Layout, Length, Point, Rectangle, -    Shell, Size, Vector, Widget, +    Background, Clipboard, Color, Element, Event, Layout, Length, Point, +    Rectangle, Shell, Size, Vector, Widget,  };  use std::marker::PhantomData; @@ -121,10 +120,10 @@ where          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          viewport: &Rectangle, -    ) -> event::Status { +    ) {          self.content.as_widget_mut().on_event(              tree, event, layout, cursor, renderer, clipboard, shell, viewport, -        ) +        );      }      fn mouse_interaction( @@ -227,9 +226,10 @@ where                  renderer: &Renderer,                  clipboard: &mut dyn Clipboard,                  shell: &mut Shell<'_, Message>, -            ) -> event::Status { -                self.content -                    .on_event(event, layout, cursor, renderer, clipboard, shell) +            ) { +                self.content.on_event( +                    event, layout, cursor, renderer, clipboard, shell, +                );              }              fn operate( diff --git a/widget/src/toggler.rs b/widget/src/toggler.rs index 2553a7e4..8461fbb2 100644 --- a/widget/src/toggler.rs +++ b/widget/src/toggler.rs @@ -31,7 +31,6 @@  //! }  //! ```  use crate::core::alignment; -use crate::core::event;  use crate::core::layout;  use crate::core::mouse;  use crate::core::renderer; @@ -317,26 +316,23 @@ where          _clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          _viewport: &Rectangle, -    ) -> event::Status { +    ) {          let Some(on_toggle) = &self.on_toggle else { -            return event::Status::Ignored; +            return;          }; -        let event_status = match event { +        match event {              Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))              | Event::Touch(touch::Event::FingerPressed { .. }) => {                  let mouse_over = cursor.is_over(layout.bounds());                  if mouse_over {                      shell.publish(on_toggle(!self.is_toggled)); - -                    event::Status::Captured -                } else { -                    event::Status::Ignored +                    shell.capture_event();                  }              } -            _ => event::Status::Ignored, -        }; +            _ => {} +        }          let current_status = if self.on_toggle.is_none() {              Status::Disabled @@ -358,8 +354,6 @@ where          {              shell.request_redraw();          } - -        event_status      }      fn mouse_interaction( diff --git a/widget/src/tooltip.rs b/widget/src/tooltip.rs index e98f4da7..91151acc 100644 --- a/widget/src/tooltip.rs +++ b/widget/src/tooltip.rs @@ -22,7 +22,6 @@  //! }  //! ```  use crate::container; -use crate::core::event::{self, Event};  use crate::core::layout::{self, Layout};  use crate::core::mouse;  use crate::core::overlay; @@ -30,8 +29,8 @@ use crate::core::renderer;  use crate::core::text;  use crate::core::widget::{self, Widget};  use crate::core::{ -    Clipboard, Element, Length, Padding, Pixels, Point, Rectangle, Shell, Size, -    Vector, +    Clipboard, Element, Event, Length, Padding, Pixels, Point, Rectangle, +    Shell, Size, Vector,  };  /// An element to display a widget over another. @@ -200,7 +199,7 @@ where          clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          viewport: &Rectangle, -    ) -> event::Status { +    ) {          let state = tree.state.downcast_mut::<State>();          let was_idle = *state == State::Idle; @@ -225,7 +224,7 @@ where              clipboard,              shell,              viewport, -        ) +        );      }      fn mouse_interaction( diff --git a/widget/src/vertical_slider.rs b/widget/src/vertical_slider.rs index 18633474..e7e36d2a 100644 --- a/widget/src/vertical_slider.rs +++ b/widget/src/vertical_slider.rs @@ -35,7 +35,6 @@ pub use crate::slider::{  };  use crate::core::border::Border; -use crate::core::event::{self, Event};  use crate::core::keyboard;  use crate::core::keyboard::key::{self, Key};  use crate::core::layout::{self, Layout}; @@ -44,8 +43,8 @@ use crate::core::renderer;  use crate::core::touch;  use crate::core::widget::tree::{self, Tree};  use crate::core::{ -    self, Clipboard, Element, Length, Pixels, Point, Rectangle, Shell, Size, -    Widget, +    self, Clipboard, Element, Event, Length, Pixels, Point, Rectangle, Shell, +    Size, Widget,  };  /// An vertical bar and a handle that selects a single value from a range of @@ -254,7 +253,7 @@ where          _clipboard: &mut dyn Clipboard,          shell: &mut Shell<'_, Message>,          _viewport: &Rectangle, -    ) -> event::Status { +    ) {          let state = tree.state.downcast_mut::<State>();          let is_dragging = state.is_dragging;          let current_value = self.value; @@ -350,7 +349,7 @@ where                          state.is_dragging = true;                      } -                    return event::Status::Captured; +                    shell.capture_event();                  }              }              Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) @@ -362,7 +361,7 @@ where                      }                      state.is_dragging = false; -                    return event::Status::Captured; +                    shell.capture_event();                  }              }              Event::Mouse(mouse::Event::CursorMoved { .. }) @@ -370,7 +369,7 @@ where                  if is_dragging {                      let _ = cursor.position().and_then(locate).map(change); -                    return event::Status::Captured; +                    shell.capture_event();                  }              }              Event::Mouse(mouse::Event::WheelScrolled { delta }) @@ -388,7 +387,7 @@ where                          let _ = increment(current_value).map(change);                      } -                    return event::Status::Captured; +                    shell.capture_event();                  }              }              Event::Keyboard(keyboard::Event::KeyPressed { key, .. }) => { @@ -403,7 +402,7 @@ where                          _ => (),                      } -                    return event::Status::Captured; +                    shell.capture_event();                  }              }              Event::Keyboard(keyboard::Event::ModifiersChanged(modifiers)) => { @@ -411,8 +410,6 @@ where              }              _ => {}          } - -        event::Status::Ignored      }      fn draw(  | 
