@@ -26,7 +26,9 @@ use crate::core::{
2626///
2727/// let is_toggled = true;
2828///
29- /// Toggler::new(Some("Toggle me!"), is_toggled, |b| Message::TogglerToggled(b));
29+ /// Toggler::new(is_toggled)
30+ /// .label("Toggle me!")
31+ /// .on_toggle(Message::TogglerToggled);
3032/// ```
3133#[ allow( missing_debug_implementations) ]
3234pub struct Toggler <
@@ -39,7 +41,7 @@ pub struct Toggler<
3941 Renderer : text:: Renderer ,
4042{
4143 is_toggled : bool ,
42- on_toggle : Box < dyn Fn ( bool ) -> Message + ' a > ,
44+ on_toggle : Option < Box < dyn Fn ( bool ) -> Message + ' a > > ,
4345 label : Option < text:: Fragment < ' a > > ,
4446 width : Length ,
4547 size : f32 ,
@@ -69,18 +71,11 @@ where
6971 /// * a function that will be called when the [`Toggler`] is toggled. It
7072 /// will receive the new state of the [`Toggler`] and must produce a
7173 /// `Message`.
72- pub fn new < F > (
73- label : Option < impl text:: IntoFragment < ' a > > ,
74- is_toggled : bool ,
75- f : F ,
76- ) -> Self
77- where
78- F : ' a + Fn ( bool ) -> Message ,
79- {
74+ pub fn new ( is_toggled : bool ) -> Self {
8075 Toggler {
8176 is_toggled,
82- on_toggle : Box :: new ( f ) ,
83- label : label . map ( text :: IntoFragment :: into_fragment ) ,
77+ on_toggle : None ,
78+ label : None ,
8479 width : Length :: Shrink ,
8580 size : Self :: DEFAULT_SIZE ,
8681 text_size : None ,
9489 }
9590 }
9691
92+ /// Sets the label of the [`Toggler`].
93+ pub fn label ( mut self , label : impl text:: IntoFragment < ' a > ) -> Self {
94+ self . label = Some ( label. into_fragment ( ) ) ;
95+ self
96+ }
97+
98+ /// Sets the message that should be produced when a user toggles
99+ /// the [`Toggler`].
100+ ///
101+ /// If this method is not called, the [`Toggler`] will be disabled.
102+ pub fn on_toggle (
103+ mut self ,
104+ on_toggle : impl Fn ( bool ) -> Message + ' a ,
105+ ) -> Self {
106+ self . on_toggle = Some ( Box :: new ( on_toggle) ) ;
107+ self
108+ }
109+
110+ /// Sets the message that should be produced when a user toggles
111+ /// the [`Toggler`], if `Some`.
112+ ///
113+ /// If `None`, the [`Toggler`] will be disabled.
114+ pub fn on_toggle_maybe (
115+ mut self ,
116+ on_toggle : Option < impl Fn ( bool ) -> Message + ' a > ,
117+ ) -> Self {
118+ self . on_toggle = on_toggle. map ( |on_toggle| Box :: new ( on_toggle) as _ ) ;
119+ self
120+ }
121+
97122 /// Sets the size of the [`Toggler`].
98123 pub fn size ( mut self , size : impl Into < Pixels > ) -> Self {
99124 self . size = size. into ( ) . 0 ;
@@ -244,13 +269,17 @@ where
244269 shell : & mut Shell < ' _ , Message > ,
245270 _viewport : & Rectangle ,
246271 ) -> event:: Status {
272+ let Some ( on_toggle) = & self . on_toggle else {
273+ return event:: Status :: Ignored ;
274+ } ;
275+
247276 match event {
248277 Event :: Mouse ( mouse:: Event :: ButtonPressed ( mouse:: Button :: Left ) )
249278 | Event :: Touch ( touch:: Event :: FingerPressed { .. } ) => {
250279 let mouse_over = cursor. is_over ( layout. bounds ( ) ) ;
251280
252281 if mouse_over {
253- shell. publish ( ( self . on_toggle ) ( !self . is_toggled ) ) ;
282+ shell. publish ( on_toggle ( !self . is_toggled ) ) ;
254283
255284 event:: Status :: Captured
256285 } else {
@@ -270,7 +299,11 @@ where
270299 _renderer : & Renderer ,
271300 ) -> mouse:: Interaction {
272301 if cursor. is_over ( layout. bounds ( ) ) {
273- mouse:: Interaction :: Pointer
302+ if self . on_toggle . is_some ( ) {
303+ mouse:: Interaction :: Pointer
304+ } else {
305+ mouse:: Interaction :: NotAllowed
306+ }
274307 } else {
275308 mouse:: Interaction :: default ( )
276309 }
@@ -314,7 +347,9 @@ where
314347 let bounds = toggler_layout. bounds ( ) ;
315348 let is_mouse_over = cursor. is_over ( layout. bounds ( ) ) ;
316349
317- let status = if is_mouse_over {
350+ let status = if self . on_toggle . is_none ( ) {
351+ Status :: Disabled
352+ } else if is_mouse_over {
318353 Status :: Hovered {
319354 is_toggled : self . is_toggled ,
320355 }
@@ -403,6 +438,8 @@ pub enum Status {
403438 /// Indicates whether the [`Toggler`] is toggled.
404439 is_toggled : bool ,
405440 } ,
441+ /// The [`Toggler`] is disabled.
442+ Disabled ,
406443}
407444
408445/// The appearance of a toggler.
@@ -463,6 +500,7 @@ pub fn default(theme: &Theme, status: Status) -> Style {
463500 palette. background . strong . color
464501 }
465502 }
503+ Status :: Disabled => palette. background . weak . color ,
466504 } ;
467505
468506 let foreground = match status {
@@ -483,6 +521,7 @@ pub fn default(theme: &Theme, status: Status) -> Style {
483521 palette. background . weak . color
484522 }
485523 }
524+ Status :: Disabled => palette. background . base . color ,
486525 } ;
487526
488527 Style {
0 commit comments