Skip to content

Commit

Permalink
Add on_press_with method for Button
Browse files Browse the repository at this point in the history
This allows using a closure to produce the message
onyl when the `Button` is actually pressed. Useful
when generating the message may be expensive.
  • Loading branch information
hecrj committed Jul 12, 2024
1 parent 1c1bee6 commit 3a772e7
Showing 1 changed file with 35 additions and 4 deletions.
39 changes: 35 additions & 4 deletions widget/src/button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,28 @@ where
Theme: Catalog,
{
content: Element<'a, Message, Theme, Renderer>,
on_press: Option<Message>,
on_press: Option<OnPress<'a, Message>>,
width: Length,
height: Length,
padding: Padding,
clip: bool,
class: Theme::Class<'a>,
}

enum OnPress<'a, Message> {
Direct(Message),
Closure(Box<dyn Fn() -> Message + 'a>),
}

impl<'a, Message: Clone> OnPress<'a, Message> {
fn get(&self) -> Message {
match self {
OnPress::Direct(message) => message.clone(),
OnPress::Closure(f) => f(),
}
}
}

impl<'a, Message, Theme, Renderer> Button<'a, Message, Theme, Renderer>
where
Renderer: crate::core::Renderer,
Expand Down Expand Up @@ -105,7 +119,23 @@ where
///
/// Unless `on_press` is called, the [`Button`] will be disabled.
pub fn on_press(mut self, on_press: Message) -> Self {
self.on_press = Some(on_press);
self.on_press = Some(OnPress::Direct(on_press));
self
}

/// Sets the message that will be produced when the [`Button`] is pressed.
///
/// This is analogous to [`Button::on_press`], but using a closure to produce
/// the message.
///
/// This closure will only be called when the [`Button`] is actually pressed and,
/// therefore, this method is useful to reduce overhead if creating the resulting
/// message is slow.
pub fn on_press_with(
mut self,
on_press: impl Fn() -> Message + 'a,
) -> Self {
self.on_press = Some(OnPress::Closure(Box::new(on_press)));
self
}

Expand All @@ -114,7 +144,7 @@ where
///
/// If `None`, the [`Button`] will be disabled.
pub fn on_press_maybe(mut self, on_press: Option<Message>) -> Self {
self.on_press = on_press;
self.on_press = on_press.map(OnPress::Direct);
self
}

Expand Down Expand Up @@ -258,7 +288,8 @@ where
}
Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left))
| Event::Touch(touch::Event::FingerLifted { .. }) => {
if let Some(on_press) = self.on_press.clone() {
if let Some(on_press) = self.on_press.as_ref().map(OnPress::get)
{
let state = tree.state.downcast_mut::<State>();

if state.is_pressed {
Expand Down

0 comments on commit 3a772e7

Please sign in to comment.