Skip to content

Commit

Permalink
Add disabled state and on_toggle handler to Toggler
Browse files Browse the repository at this point in the history
Co-authored-by: Your Name here only <[email protected]>
  • Loading branch information
hecrj and sundaram123krishnan committed Sep 10, 2024
1 parent 770176a commit 9f72b74
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 29 deletions.
7 changes: 2 additions & 5 deletions examples/editor/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,8 @@ impl Editor {
self.is_dirty.then_some(Message::SaveFile)
),
horizontal_space(),
toggler(
Some("Word Wrap"),
self.word_wrap,
Message::WordWrapToggled
),
toggler(Some("Word Wrap"), self.word_wrap)
.on_toggle(Message::WordWrapToggled),
pick_list(
highlighter::Theme::ALL,
Some(self.theme),
Expand Down
9 changes: 3 additions & 6 deletions examples/styling/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,9 @@ impl Styling {
let checkbox = checkbox("Check me!", self.checkbox_value)
.on_toggle(Message::CheckboxToggled);

let toggler = toggler(
Some("Toggle me!"),
self.toggler_value,
Message::TogglerToggled,
)
.spacing(10);
let toggler = toggler(Some("Toggle me!"), self.toggler_value)
.on_toggle(Message::TogglerToggled)
.spacing(10);

let content = column![
choose_theme,
Expand Down
9 changes: 4 additions & 5 deletions examples/tour/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,11 +357,10 @@ impl Tour {
Self::container("Toggler")
.push("A toggler is mostly used to enable or disable something.")
.push(
Container::new(toggler(
Some("Toggle me to continue..."),
self.toggler,
Message::TogglerChanged,
))
Container::new(
toggler(Some("Toggle me to continue..."), self.toggler)
.on_toggle(Message::TogglerChanged),
)
.padding([0, 40]),
)
}
Expand Down
3 changes: 1 addition & 2 deletions widget/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -769,13 +769,12 @@ where
pub fn toggler<'a, Message, Theme, Renderer>(
label: Option<impl text::IntoFragment<'a>>,
is_checked: bool,
f: impl Fn(bool) -> Message + 'a,
) -> Toggler<'a, Message, Theme, Renderer>
where
Theme: toggler::Catalog + 'a,
Renderer: core::text::Renderer,
{
Toggler::new(label, is_checked, f)
Toggler::new(label, is_checked)
}

/// Creates a new [`TextInput`].
Expand Down
56 changes: 45 additions & 11 deletions widget/src/toggler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub struct Toggler<
Renderer: text::Renderer,
{
is_toggled: bool,
on_toggle: Box<dyn Fn(bool) -> Message + 'a>,
on_toggle: Option<Box<dyn Fn(bool) -> Message + 'a>>,
label: Option<text::Fragment<'a>>,
width: Length,
size: f32,
Expand Down Expand Up @@ -69,17 +69,13 @@ where
/// * a function that will be called when the [`Toggler`] is toggled. It
/// will receive the new state of the [`Toggler`] and must produce a
/// `Message`.
pub fn new<F>(
pub fn new(
label: Option<impl text::IntoFragment<'a>>,
is_toggled: bool,
f: F,
) -> Self
where
F: 'a + Fn(bool) -> Message,
{
) -> Self {
Toggler {
is_toggled,
on_toggle: Box::new(f),
on_toggle: None,
label: label.map(text::IntoFragment::into_fragment),
width: Length::Shrink,
size: Self::DEFAULT_SIZE,
Expand All @@ -94,6 +90,30 @@ where
}
}

/// Sets the message that should be produced when a user toggles
/// the [`Toggler`].
///
/// If this method is not called, the [`Toggler`] will be disabled.
pub fn on_toggle(
mut self,
on_toggle: impl Fn(bool) -> Message + 'a,
) -> Self {
self.on_toggle = Some(Box::new(on_toggle));
self
}

/// Sets the message that should be produced when a user toggles
/// the [`Toggler`], if `Some`.
///
/// If `None`, the [`Toggler`] will be disabled.
pub fn on_toggle_maybe(
mut self,
on_toggle: Option<impl Fn(bool) -> Message + 'a>,
) -> Self {
self.on_toggle = on_toggle.map(|on_toggle| Box::new(on_toggle) as _);
self
}

/// Sets the size of the [`Toggler`].
pub fn size(mut self, size: impl Into<Pixels>) -> Self {
self.size = size.into().0;
Expand Down Expand Up @@ -244,13 +264,17 @@ where
shell: &mut Shell<'_, Message>,
_viewport: &Rectangle,
) -> event::Status {
let Some(on_toggle) = &self.on_toggle else {
return event::Status::Ignored;
};

match event {
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
| Event::Touch(touch::Event::FingerPressed { .. }) => {
let mouse_over = cursor.is_over(layout.bounds());

if mouse_over {
shell.publish((self.on_toggle)(!self.is_toggled));
shell.publish(on_toggle(!self.is_toggled));

event::Status::Captured
} else {
Expand All @@ -270,7 +294,11 @@ where
_renderer: &Renderer,
) -> mouse::Interaction {
if cursor.is_over(layout.bounds()) {
mouse::Interaction::Pointer
if self.on_toggle.is_some() {
mouse::Interaction::Pointer
} else {
mouse::Interaction::NotAllowed
}
} else {
mouse::Interaction::default()
}
Expand Down Expand Up @@ -314,7 +342,9 @@ where
let bounds = toggler_layout.bounds();
let is_mouse_over = cursor.is_over(layout.bounds());

let status = if is_mouse_over {
let status = if self.on_toggle.is_none() {
Status::Disabled
} else if is_mouse_over {
Status::Hovered {
is_toggled: self.is_toggled,
}
Expand Down Expand Up @@ -403,6 +433,8 @@ pub enum Status {
/// Indicates whether the [`Toggler`] is toggled.
is_toggled: bool,
},
/// The [`Toggler`] is disabled.
Disabled,
}

/// The appearance of a toggler.
Expand Down Expand Up @@ -463,6 +495,7 @@ pub fn default(theme: &Theme, status: Status) -> Style {
palette.background.strong.color
}
}
Status::Disabled => palette.background.weak.color,
};

let foreground = match status {
Expand All @@ -483,6 +516,7 @@ pub fn default(theme: &Theme, status: Status) -> Style {
palette.background.weak.color
}
}
Status::Disabled => palette.background.base.color,
};

Style {
Expand Down

0 comments on commit 9f72b74

Please sign in to comment.