@@ -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+
6377impl < ' a , Message , Theme , Renderer > Button < ' a , Message , Theme , Renderer >
6478where
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