Make label optional for checkbox widget

This commit is contained in:
Sebastiano Giordano 2025-04-03 17:29:13 +02:00 • committed by Héctor Ramón Jiménez
parent a2d052982b
commit 0d2aa41dee
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
15 changed files with 87 additions and 58 deletions

View file

@ -39,11 +39,13 @@ impl Example {
} }
fn view(&self) -> Element<'_, Message> { fn view(&self) -> Element<'_, Message> {
let default_checkbox = checkbox("Default", self.default) let default_checkbox = checkbox(self.default)
.label("Default")
.on_toggle(Message::DefaultToggled); .on_toggle(Message::DefaultToggled);
let styled_checkbox = |label| { let styled_checkbox = |label| {
checkbox(label, self.styled) checkbox(self.styled)
.label(label)
.on_toggle_maybe(self.default.then_some(Message::StyledToggled)) .on_toggle_maybe(self.default.then_some(Message::StyledToggled))
}; };
@ -55,7 +57,8 @@ impl Example {
] ]
.spacing(20); .spacing(20);
let custom_checkbox = checkbox("Custom", self.custom) let custom_checkbox = checkbox(self.custom)
.label("Custom")
.on_toggle(Message::CustomToggled) .on_toggle(Message::CustomToggled)
.icon(checkbox::Icon { .icon(checkbox::Icon {
font: ICON_FONT, font: ICON_FONT,

View file

@ -73,7 +73,8 @@ impl IcedCubes {
.step(0.01) .step(0.01)
.width(100), .width(100),
), ),
checkbox("Show Depth Buffer", self.scene.show_depth_buffer) checkbox(self.scene.show_depth_buffer)
.label("Show Depth Buffer")
.on_toggle(Message::ShowDepthBuffer), .on_toggle(Message::ShowDepthBuffer),
] ]
.spacing(40); .spacing(40);

View file

@ -63,7 +63,8 @@ impl Events {
.map(Element::from), .map(Element::from),
); );
let toggle = checkbox("Listen to runtime events", self.enabled) let toggle = checkbox(self.enabled)
.label("Listen to runtime events")
.on_toggle(Message::Toggled); .on_toggle(Message::Toggled);
let exit = button(text("Exit").width(Fill).align_x(Center)) let exit = button(text("Exit").width(Fill).align_x(Center))

View file

@ -153,7 +153,8 @@ impl Image {
self.rotation.degrees(), self.rotation.degrees(),
Message::RotationChanged Message::RotationChanged
), ),
checkbox("Spin!", self.spin) checkbox(self.spin)
.label("Spin!")
.text_size(12) .text_size(12)
.on_toggle(Message::SpinToggled) .on_toggle(Message::SpinToggled)
.size(12) .size(12)

View file

@ -162,7 +162,9 @@ fn view_controls<'a>(
row![ row![
playback_controls, playback_controls,
speed_controls, speed_controls,
checkbox("Grid", is_grid_enabled).on_toggle(Message::ToggleGrid), checkbox(is_grid_enabled)
.label("Grid")
.on_toggle(Message::ToggleGrid),
row![ row![
pick_list(preset::ALL, Some(preset), Message::PresetPicked), pick_list(preset::ALL, Some(preset), Message::PresetPicked),
button("Clear") button("Clear")

View file

@ -78,7 +78,8 @@ impl Gradient {
.align_y(Center); .align_y(Center);
let transparency_toggle = iced::widget::Container::new( let transparency_toggle = iced::widget::Container::new(
checkbox("Transparent window", transparent) checkbox(transparent)
.label("Transparent window")
.on_toggle(Message::TransparentToggled), .on_toggle(Message::TransparentToggled),
) )
.padding(8); .padding(8);

View file

@ -71,7 +71,8 @@ impl Layout {
let header = row![ let header = row![
text(self.example.title).size(20).font(Font::MONOSPACE), text(self.example.title).size(20).font(Font::MONOSPACE),
space::horizontal(), space::horizontal(),
checkbox("Explain", self.explain) checkbox(self.explain)
.label("Explain")
.on_toggle(Message::ExplainToggled), .on_toggle(Message::ExplainToggled),
pick_list(Theme::ALL, self.theme.as_ref(), Message::ThemeSelected) pick_list(Theme::ALL, self.theme.as_ref(), Message::ThemeSelected)
.placeholder("Theme"), .placeholder("Theme"),

View file

@ -58,7 +58,8 @@ impl Progress {
) )
}, },
center_x( center_x(
checkbox("Vertical", self.is_vertical) checkbox(self.is_vertical)
.label("Vertical")
.on_toggle(Message::ToggleVertical) .on_toggle(Message::ToggleVertical)
), ),
] ]

View file

@ -133,10 +133,11 @@ impl Styling {
.width(Fill) .width(Fill)
.height(Fill); .height(Fill);
let check = checkbox("Check me!", self.checkbox_value) let check = checkbox(self.checkbox_value)
.label("Check me!")
.on_toggle(Message::CheckboxToggled); .on_toggle(Message::CheckboxToggled);
let check_disabled = checkbox("Disabled", self.checkbox_value); let check_disabled = checkbox(self.checkbox_value).label("Disabled");
let toggle = toggler(self.toggler_value) let toggle = toggler(self.toggler_value)
.label("Toggle me!") .label("Toggle me!")

View file

@ -37,9 +37,9 @@ impl Tiger {
}, },
}); });
let apply_color_filter = let apply_color_filter = checkbox(self.apply_color_filter)
checkbox("Apply a color filter", self.apply_color_filter) .label("Apply a color filter")
.on_toggle(Message::ToggleColorFilter); .on_toggle(Message::ToggleColorFilter);
center(column![svg, center_x(apply_color_filter)].spacing(20)) center(column![svg, center_x(apply_color_filter)].spacing(20))
.padding(20) .padding(20)

View file

@ -339,7 +339,8 @@ impl Task {
fn view(&self, i: usize) -> Element<'_, TaskMessage> { fn view(&self, i: usize) -> Element<'_, TaskMessage> {
match &self.state { match &self.state {
TaskState::Idle => { TaskState::Idle => {
let checkbox = checkbox(&self.description, self.completed) let checkbox = checkbox(self.completed)
.label(&self.description)
.on_toggle(TaskMessage::Completed) .on_toggle(TaskMessage::Completed)
.width(Fill) .width(Fill)
.size(17) .size(17)

View file

@ -386,11 +386,9 @@ impl Tour {
.push(slider(100..=500, width, Message::ImageWidthChanged)) .push(slider(100..=500, width, Message::ImageWidthChanged))
.push(text!("Width: {width} px").width(Fill).align_x(Center)) .push(text!("Width: {width} px").width(Fill).align_x(Center))
.push( .push(
checkbox( checkbox(filter_method == image::FilterMethod::Nearest)
"Use nearest interpolation", .label("Use nearest interpolation")
filter_method == image::FilterMethod::Nearest, .on_toggle(Message::ImageUseNearestToggled),
)
.on_toggle(Message::ImageUseNearestToggled),
) )
.align_x(Center) .align_x(Center)
} }
@ -441,11 +439,13 @@ impl Tour {
.push("Use a text input to ask for different kinds of information.") .push("Use a text input to ask for different kinds of information.")
.push(text_input.secure(is_secure)) .push(text_input.secure(is_secure))
.push( .push(
checkbox("Enable password mode", is_secure) checkbox(is_secure)
.label("Enable password mode")
.on_toggle(Message::ToggleSecureInput), .on_toggle(Message::ToggleSecureInput),
) )
.push( .push(
checkbox("Show icon", is_showing_icon) checkbox(is_showing_icon)
.label("Show icon")
.on_toggle(Message::ToggleTextInputIcon), .on_toggle(Message::ToggleTextInputIcon),
) )
.push( .push(
@ -474,7 +474,8 @@ impl Tour {
see element boundaries.", see element boundaries.",
) )
.push( .push(
checkbox("Explain layout", self.debug) checkbox(self.debug)
.label("Explain layout")
.on_toggle(Message::DebugToggled), .on_toggle(Message::DebugToggled),
) )
.push("Feel free to go back and take a look.") .push("Feel free to go back and take a look.")

View file

@ -58,7 +58,8 @@ impl VectorialText {
column![ column![
canvas(&self.state).width(Fill).height(Fill), canvas(&self.state).width(Fill).height(Fill),
column![ column![
checkbox("Use Japanese", self.state.use_japanese,) checkbox(self.state.use_japanese,)
.label("Use Japanese")
.on_toggle(Message::ToggleJapanese), .on_toggle(Message::ToggleJapanese),
row![ row![
slider_with_label( slider_with_label(

View file

@ -16,7 +16,8 @@
//! } //! }
//! //!
//! fn view(state: &State) -> Element<'_, Message> { //! fn view(state: &State) -> Element<'_, Message> {
//! checkbox("Toggle me!", state.is_checked) //! checkbox(state.is_checked)
//! .label("Toggle me!")
//! .on_toggle(Message::CheckboxToggled) //! .on_toggle(Message::CheckboxToggled)
//! .into() //! .into()
//! } //! }
@ -63,7 +64,8 @@ use crate::core::{
/// } /// }
/// ///
/// fn view(state: &State) -> Element<'_, Message> { /// fn view(state: &State) -> Element<'_, Message> {
/// checkbox("Toggle me!", state.is_checked) /// checkbox(state.is_checked)
/// .label("Toggle me!")
/// .on_toggle(Message::CheckboxToggled) /// .on_toggle(Message::CheckboxToggled)
/// .into() /// .into()
/// } /// }
@ -88,7 +90,7 @@ pub struct Checkbox<
{ {
is_checked: bool, is_checked: bool,
on_toggle: Option<Box<dyn Fn(bool) -> Message + 'a>>, on_toggle: Option<Box<dyn Fn(bool) -> Message + 'a>>,
label: String, label: Option<text::Fragment<'a>>,
width: Length, width: Length,
size: f32, size: f32,
spacing: f32, spacing: f32,
@ -110,22 +112,18 @@ where
/// The default size of a [`Checkbox`]. /// The default size of a [`Checkbox`].
const DEFAULT_SIZE: f32 = 16.0; const DEFAULT_SIZE: f32 = 16.0;
/// The default spacing of a [`Checkbox`].
const DEFAULT_SPACING: f32 = 8.0;
/// Creates a new [`Checkbox`]. /// Creates a new [`Checkbox`].
/// ///
/// It expects: /// It expects:
/// * the label of the [`Checkbox`]
/// * a boolean describing whether the [`Checkbox`] is checked or not /// * a boolean describing whether the [`Checkbox`] is checked or not
pub fn new(label: impl Into<String>, is_checked: bool) -> Self { pub fn new(is_checked: bool) -> Self {
Checkbox { Checkbox {
is_checked, is_checked,
on_toggle: None, on_toggle: None,
label: label.into(), label: None,
width: Length::Shrink, width: Length::Shrink,
size: Self::DEFAULT_SIZE, size: Self::DEFAULT_SIZE,
spacing: Self::DEFAULT_SPACING, spacing: Self::DEFAULT_SIZE / 2.0,
text_size: None, text_size: None,
text_line_height: text::LineHeight::default(), text_line_height: text::LineHeight::default(),
text_shaping: text::Shaping::default(), text_shaping: text::Shaping::default(),
@ -143,6 +141,12 @@ where
} }
} }
/// Sets the label of the [`Checkbox`].
pub fn label(mut self, label: impl text::IntoFragment<'a>) -> Self {
self.label = Some(label.into_fragment());
self
}
/// Sets the function that will be called when the [`Checkbox`] is toggled. /// Sets the function that will be called when the [`Checkbox`] is toggled.
/// It will receive the new state of the [`Checkbox`] and must produce a /// It will receive the new state of the [`Checkbox`] and must produce a
/// `Message`. /// `Message`.
@ -275,30 +279,38 @@ where
) -> layout::Node { ) -> layout::Node {
layout::next_to_each_other( layout::next_to_each_other(
&limits.width(self.width), &limits.width(self.width),
self.spacing, if self.label.is_some() {
self.spacing
} else {
0.0
},
|_| layout::Node::new(Size::new(self.size, self.size)), |_| layout::Node::new(Size::new(self.size, self.size)),
|limits| { |limits| {
let state = tree if let Some(label) = self.label.as_deref() {
let state = tree
.state .state
.downcast_mut::<widget::text::State<Renderer::Paragraph>>(); .downcast_mut::<widget::text::State<Renderer::Paragraph>>();
widget::text::layout( widget::text::layout(
state, state,
renderer, renderer,
limits, limits,
&self.label, label,
widget::text::Format { widget::text::Format {
width: self.width, width: self.width,
height: Length::Shrink, height: Length::Shrink,
line_height: self.text_line_height, line_height: self.text_line_height,
size: self.text_size, size: self.text_size,
font: self.font, font: self.font,
align_x: text::Alignment::Default, align_x: text::Alignment::Default,
align_y: alignment::Vertical::Top, align_y: alignment::Vertical::Top,
shaping: self.text_shaping, shaping: self.text_shaping,
wrapping: self.text_wrapping, wrapping: self.text_wrapping,
}, },
) )
} else {
layout::Node::new(Size::ZERO)
}
}, },
) )
} }
@ -452,7 +464,9 @@ where
_renderer: &Renderer, _renderer: &Renderer,
operation: &mut dyn widget::Operation, operation: &mut dyn widget::Operation,
) { ) {
operation.text(None, layout.bounds(), &self.label); if let Some(label) = self.label.as_deref() {
operation.text(None, layout.bounds(), label);
}
} }
} }

View file

@ -1250,7 +1250,8 @@ pub use crate::markdown::view as markdown;
/// } /// }
/// ///
/// fn view(state: &State) -> Element<'_, Message> { /// fn view(state: &State) -> Element<'_, Message> {
/// checkbox("Toggle me!", state.is_checked) /// checkbox(state.is_checked)
/// .label("Toggle me!")
/// .on_toggle(Message::CheckboxToggled) /// .on_toggle(Message::CheckboxToggled)
/// .into() /// .into()
/// } /// }
@ -1265,14 +1266,13 @@ pub use crate::markdown::view as markdown;
/// ``` /// ```
/// ![Checkbox drawn by `iced_wgpu`](https://github.com/iced-rs/iced/blob/7760618fb112074bc40b148944521f312152012a/docs/images/checkbox.png?raw=true) /// ![Checkbox drawn by `iced_wgpu`](https://github.com/iced-rs/iced/blob/7760618fb112074bc40b148944521f312152012a/docs/images/checkbox.png?raw=true)
pub fn checkbox<'a, Message, Theme, Renderer>( pub fn checkbox<'a, Message, Theme, Renderer>(
label: impl Into<String>,
is_checked: bool, is_checked: bool,
) -> Checkbox<'a, Message, Theme, Renderer> ) -> Checkbox<'a, Message, Theme, Renderer>
where where
Theme: checkbox::Catalog + 'a, Theme: checkbox::Catalog + 'a,
Renderer: core::text::Renderer, Renderer: core::text::Renderer,
{ {
Checkbox::new(label, is_checked) Checkbox::new(is_checked)
} }
/// Creates a new [`Radio`]. /// Creates a new [`Radio`].