Skip to content

Commit 07c9a2a

Browse files
authored
Merge pull request #2478 from sundaram123krishnan/master
Add Disable Feature to Toggler Widget
2 parents 770176a + 6e4970c commit 07c9a2a

File tree

5 files changed

+67
-34
lines changed

5 files changed

+67
-34
lines changed

examples/editor/src/main.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,11 +150,9 @@ impl Editor {
150150
self.is_dirty.then_some(Message::SaveFile)
151151
),
152152
horizontal_space(),
153-
toggler(
154-
Some("Word Wrap"),
155-
self.word_wrap,
156-
Message::WordWrapToggled
157-
),
153+
toggler(self.word_wrap)
154+
.label("Word Wrap")
155+
.on_toggle(Message::WordWrapToggled),
158156
pick_list(
159157
highlighter::Theme::ALL,
160158
Some(self.theme),

examples/styling/src/main.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,10 @@ impl Styling {
7777
let checkbox = checkbox("Check me!", self.checkbox_value)
7878
.on_toggle(Message::CheckboxToggled);
7979

80-
let toggler = toggler(
81-
Some("Toggle me!"),
82-
self.toggler_value,
83-
Message::TogglerToggled,
84-
)
85-
.spacing(10);
80+
let toggler = toggler(self.toggler_value)
81+
.label("Toggle me!")
82+
.on_toggle(Message::TogglerToggled)
83+
.spacing(10);
8684

8785
let content = column![
8886
choose_theme,

examples/tour/src/main.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -357,11 +357,11 @@ impl Tour {
357357
Self::container("Toggler")
358358
.push("A toggler is mostly used to enable or disable something.")
359359
.push(
360-
Container::new(toggler(
361-
Some("Toggle me to continue..."),
362-
self.toggler,
363-
Message::TogglerChanged,
364-
))
360+
Container::new(
361+
toggler(self.toggler)
362+
.label("Toggle me to continue...")
363+
.on_toggle(Message::TogglerChanged),
364+
)
365365
.padding([0, 40]),
366366
)
367367
}

widget/src/helpers.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -767,15 +767,13 @@ where
767767
///
768768
/// [`Toggler`]: crate::Toggler
769769
pub fn toggler<'a, Message, Theme, Renderer>(
770-
label: Option<impl text::IntoFragment<'a>>,
771770
is_checked: bool,
772-
f: impl Fn(bool) -> Message + 'a,
773771
) -> Toggler<'a, Message, Theme, Renderer>
774772
where
775773
Theme: toggler::Catalog + 'a,
776774
Renderer: core::text::Renderer,
777775
{
778-
Toggler::new(label, is_checked, f)
776+
Toggler::new(is_checked)
779777
}
780778

781779
/// Creates a new [`TextInput`].

widget/src/toggler.rs

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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)]
3234
pub 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,
@@ -94,6 +89,36 @@ where
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

Comments
 (0)