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 'widget')
-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 |