diff options
| author | 2024-10-22 00:13:42 +0200 | |
|---|---|---|
| committer | 2024-11-05 23:52:56 +0100 | |
| commit | 5c33ce18ed8b12db9a6ba138112804761d26fddb (patch) | |
| tree | cb51c63fb14c4c84e20fd6f201ffaaaf86dc7b0c /widget | |
| parent | 42a2cb6d4f78343f43d6a68a28e5502d9426ed2c (diff) | |
| download | iced-5c33ce18ed8b12db9a6ba138112804761d26fddb.tar.gz iced-5c33ce18ed8b12db9a6ba138112804761d26fddb.tar.bz2 iced-5c33ce18ed8b12db9a6ba138112804761d26fddb.zip | |
Draft `reactive-rendering` feature for `button`
Diffstat (limited to '')
| -rw-r--r-- | widget/src/button.rs | 112 | 
1 files changed, 68 insertions, 44 deletions
| diff --git a/widget/src/button.rs b/widget/src/button.rs index a3394a01..5850cea0 100644 --- a/widget/src/button.rs +++ b/widget/src/button.rs @@ -26,6 +26,7 @@ use crate::core::theme::palette;  use crate::core::touch;  use crate::core::widget::tree::{self, Tree};  use crate::core::widget::Operation; +use crate::core::window;  use crate::core::{      Background, Clipboard, Color, Element, Layout, Length, Padding, Rectangle,      Shadow, Shell, Size, Theme, Vector, Widget, @@ -81,6 +82,7 @@ where      padding: Padding,      clip: bool,      class: Theme::Class<'a>, +    status: Option<Status>,  }  enum OnPress<'a, Message> { @@ -117,6 +119,7 @@ where              padding: DEFAULT_PADDING,              clip: false,              class: Theme::default(), +            status: None,          }      } @@ -294,49 +297,85 @@ where              return event::Status::Captured;          } -        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(); +        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(); -                    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; +                            return event::Status::Captured; +                        }                      }                  } -            } -            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>(); +                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; +                        if state.is_pressed { +                            state.is_pressed = false; -                        let bounds = layout.bounds(); +                            let bounds = layout.bounds(); -                        if cursor.is_over(bounds) { -                            shell.publish(on_press); -                        } +                            if cursor.is_over(bounds) { +                                shell.publish(on_press); +                            } -                        return event::Status::Captured; +                            return event::Status::Captured; +                        }                      }                  } +                Event::Touch(touch::Event::FingerLost { .. }) => { +                    let state = tree.state.downcast_mut::<State>(); + +                    state.is_pressed = false; +                } +                _ => {} +            } + +            event::Status::Ignored +        }; + +        let update_status = update(); + +        let current_status = if self.on_press.is_none() { +            Status::Disabled +        } else if cursor.is_over(layout.bounds()) { +            let state = tree.state.downcast_ref::<State>(); + +            if state.is_pressed { +                Status::Pressed +            } else { +                Status::Hovered              } -            Event::Touch(touch::Event::FingerLost { .. }) => { -                let state = tree.state.downcast_mut::<State>(); +        } else { +            Status::Active +        }; -                state.is_pressed = false; +        if let Event::Window(window::Event::RedrawRequested(_now)) = event { +            self.status = Some(current_status); +        } else { +            match self.status { +                Some(status) if status != current_status => { +                    shell.request_redraw(window::RedrawRequest::NextFrame); +                } +                _ => {}              } -            _ => {}          } -        event::Status::Ignored +        update_status      }      fn draw( @@ -351,23 +390,8 @@ where      ) {          let bounds = layout.bounds();          let content_layout = layout.children().next().unwrap(); -        let is_mouse_over = cursor.is_over(bounds); - -        let status = if self.on_press.is_none() { -            Status::Disabled -        } else if is_mouse_over { -            let state = tree.state.downcast_ref::<State>(); - -            if state.is_pressed { -                Status::Pressed -            } else { -                Status::Hovered -            } -        } else { -            Status::Active -        }; - -        let style = theme.style(&self.class, status); +        let style = +            theme.style(&self.class, self.status.unwrap_or(Status::Disabled));          if style.background.is_some()              || style.border.width > 0.0 | 
