Skip to content

Commit 97e35f7

Browse files
committed
Add on_press_with method for Button
This allows using a closure to produce the message only when the `Button` is actually pressed. Useful when generating the message may be expensive.
1 parent 1c1bee6 commit 97e35f7

1 file changed

Lines changed: 35 additions & 4 deletions

File tree

widget/src/button.rs

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,28 @@ where
5252
Theme: Catalog,
5353
{
5454
content: Element<'a, Message, Theme, Renderer>,
55-
on_press: Option<Message>,
55+
on_press: Option<OnPress<'a, Message>>,
5656
width: Length,
5757
height: Length,
5858
padding: Padding,
5959
clip: bool,
6060
class: Theme::Class<'a>,
6161
}
6262

63+
enum OnPress<'a, Message> {
64+
Direct(Message),
65+
Closure(Box<dyn Fn() -> Message + 'a>),
66+
}
67+
68+
impl<'a, Message: Clone> OnPress<'a, Message> {
69+
fn get(&self) -> Message {
70+
match self {
71+
OnPress::Direct(message) => message.clone(),
72+
OnPress::Closure(f) => f(),
73+
}
74+
}
75+
}
76+
6377
impl<'a, Message, Theme, Renderer> Button<'a, Message, Theme, Renderer>
6478
where
6579
Renderer: crate::core::Renderer,
@@ -105,7 +119,23 @@ where
105119
///
106120
/// Unless `on_press` is called, the [`Button`] will be disabled.
107121
pub fn on_press(mut self, on_press: Message) -> Self {
108-
self.on_press = Some(on_press);
122+
self.on_press = Some(OnPress::Direct(on_press));
123+
self
124+
}
125+
126+
/// Sets the message that will be produced when the [`Button`] is pressed.
127+
///
128+
/// This is analogous to [`Button::on_press`], but using a closure to produce
129+
/// the message.
130+
///
131+
/// This closure will only be called when the [`Button`] is actually pressed and,
132+
/// therefore, this method is useful to reduce overhead if creating the resulting
133+
/// message is slow.
134+
pub fn on_press_with(
135+
mut self,
136+
on_press: impl Fn() -> Message + 'a,
137+
) -> Self {
138+
self.on_press = Some(OnPress::Closure(Box::new(on_press)));
109139
self
110140
}
111141

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

@@ -258,7 +288,8 @@ where
258288
}
259289
Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left))
260290
| Event::Touch(touch::Event::FingerLifted { .. }) => {
261-
if let Some(on_press) = self.on_press.clone() {
291+
if let Some(on_press) = self.on_press.as_ref().map(OnPress::get)
292+
{
262293
let state = tree.state.downcast_mut::<State>();
263294

264295
if state.is_pressed {

0 commit comments

Comments
 (0)