summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2024-09-11 00:17:16 +0200
committerLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2024-09-11 00:22:13 +0200
commitc741688b4c52dd2397880ca05b5f9a997d762246 (patch)
treee8f07997ddaa22ba58e202fdc60ba76afdff5b1d
parent770176a4e19ef3db257daa311860b54a4ec14bc1 (diff)
downloadiced-c741688b4c52dd2397880ca05b5f9a997d762246.tar.gz
iced-c741688b4c52dd2397880ca05b5f9a997d762246.tar.bz2
iced-c741688b4c52dd2397880ca05b5f9a997d762246.zip
Add disabled state and `on_toggle` handler to `Toggler`
Co-authored-by: Your Name here only <krishnsundaram@gmail.com>
-rw-r--r--examples/editor/src/main.rs7
-rw-r--r--examples/styling/src/main.rs9
-rw-r--r--examples/tour/src/main.rs9
-rw-r--r--widget/src/helpers.rs3
-rw-r--r--widget/src/toggler.rs59
5 files changed, 57 insertions, 30 deletions
diff --git a/examples/editor/src/main.rs b/examples/editor/src/main.rs
index 068782ba..c7d7eb26 100644
--- a/examples/editor/src/main.rs
+++ b/examples/editor/src/main.rs
@@ -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),
diff --git a/examples/styling/src/main.rs b/examples/styling/src/main.rs
index e19d5cf7..222ab79d 100644
--- a/examples/styling/src/main.rs
+++ b/examples/styling/src/main.rs
@@ -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,
diff --git a/examples/tour/src/main.rs b/examples/tour/src/main.rs
index 0dd588fe..fad5f0b1 100644
--- a/examples/tour/src/main.rs
+++ b/examples/tour/src/main.rs
@@ -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]),
)
}
diff --git a/widget/src/helpers.rs b/widget/src/helpers.rs
index 349f02a6..e48ba328 100644
--- a/widget/src/helpers.rs
+++ b/widget/src/helpers.rs
@@ -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`].
diff --git a/widget/src/toggler.rs b/widget/src/toggler.rs
index 57e142e8..a6b2ae92 100644
--- a/widget/src/toggler.rs
+++ b/widget/src/toggler.rs
@@ -26,7 +26,8 @@ use crate::core::{
///
/// let is_toggled = true;
///
-/// Toggler::new(Some("Toggle me!"), is_toggled, |b| Message::TogglerToggled(b));
+/// Toggler::new(Some("Toggle me!"), is_toggled)
+/// .on_toggle(Message::TogglerToggled);
/// ```
#[allow(missing_debug_implementations)]
pub struct Toggler<
@@ -39,7 +40,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,
@@ -69,17 +70,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,
@@ -94,6 +91,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;
@@ -244,13 +265,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 {
@@ -270,7 +295,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()
}
@@ -314,7 +343,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,
}
@@ -403,6 +434,8 @@ pub enum Status {
/// Indicates whether the [`Toggler`] is toggled.
is_toggled: bool,
},
+ /// The [`Toggler`] is disabled.
+ Disabled,
}
/// The appearance of a toggler.
@@ -463,6 +496,7 @@ pub fn default(theme: &Theme, status: Status) -> Style {
palette.background.strong.color
}
}
+ Status::Disabled => palette.background.weak.color,
};
let foreground = match status {
@@ -483,6 +517,7 @@ pub fn default(theme: &Theme, status: Status) -> Style {
palette.background.weak.color
}
}
+ Status::Disabled => palette.background.base.color,
};
Style {