From 9dd20ead085ff3b9b4bd441b5e4938cf8e813f35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 15 Feb 2024 02:01:56 +0100 Subject: [PATCH 1/5] Rename `password` method in `TextInput` to `secure` --- examples/modal/src/main.rs | 2 +- examples/tour/src/main.rs | 6 +----- widget/src/text_input.rs | 8 ++++---- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/examples/modal/src/main.rs b/examples/modal/src/main.rs index 6fe951ee51..1dac0075eb 100644 --- a/examples/modal/src/main.rs +++ b/examples/modal/src/main.rs @@ -157,7 +157,7 @@ impl Application for App { text_input("", &self.password) .on_input(Message::Password) .on_submit(Message::Submit) - .password() + .secure(true) .padding(5), ] .spacing(5), diff --git a/examples/tour/src/main.rs b/examples/tour/src/main.rs index 6d24b5ec9c..15d378967d 100644 --- a/examples/tour/src/main.rs +++ b/examples/tour/src/main.rs @@ -613,11 +613,7 @@ impl<'a> Step { Self::container("Text input") .push("Use a text input to ask for different kinds of information.") - .push(if is_secure { - text_input.password() - } else { - text_input - }) + .push(text_input.secure(is_secure)) .push( checkbox("Enable password mode", is_secure) .on_toggle(StepMessage::ToggleSecureInput), diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index f5b57422d9..72ed1ef388 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -122,8 +122,8 @@ where } /// Converts the [`TextInput`] into a secure password input. - pub fn password(mut self) -> Self { - self.is_secure = true; + pub fn secure(mut self, is_secure: bool) -> Self { + self.is_secure = is_secure; self } @@ -991,9 +991,9 @@ where } return event::Status::Captured; - } else { - state.is_pasting = None; } + + state.is_pasting = None; } Event::Keyboard(keyboard::Event::ModifiersChanged(modifiers)) => { let state = state(); From e8049af23dbf4988ff24b75b90104295f61098a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 15 Feb 2024 02:08:22 +0100 Subject: [PATCH 2/5] Make `horizontal_space` and `vertical_space` fill by default --- examples/combo_box/src/main.rs | 2 +- examples/editor/src/main.rs | 4 ++-- examples/gradient/src/main.rs | 2 +- examples/layout/src/main.rs | 10 +++++----- examples/lazy/src/main.rs | 2 +- examples/modal/src/main.rs | 12 ++++-------- examples/pick_list/src/main.rs | 4 ++-- examples/scrollable/src/main.rs | 20 ++++++++++---------- examples/styling/src/main.rs | 2 +- examples/toast/src/main.rs | 2 +- examples/tour/src/main.rs | 6 +++--- examples/vectorial_text/src/main.rs | 2 +- examples/visible_bounds/src/main.rs | 10 +++++----- widget/src/helpers.rs | 8 ++++---- widget/src/lazy/responsive.rs | 2 +- widget/src/space.rs | 12 ++++++++++++ 16 files changed, 54 insertions(+), 46 deletions(-) diff --git a/examples/combo_box/src/main.rs b/examples/combo_box/src/main.rs index 4f347667e2..fcf5feaa8e 100644 --- a/examples/combo_box/src/main.rs +++ b/examples/combo_box/src/main.rs @@ -68,7 +68,7 @@ impl Sandbox for Example { text(&self.text), "What is your language?", combo_box, - vertical_space(150), + vertical_space().height(150), ] .width(Length::Fill) .align_items(Alignment::Center) diff --git a/examples/editor/src/main.rs b/examples/editor/src/main.rs index 75b6626445..53c9cf7cb2 100644 --- a/examples/editor/src/main.rs +++ b/examples/editor/src/main.rs @@ -155,7 +155,7 @@ impl Application for Editor { "Save file", self.is_dirty.then_some(Message::SaveFile) ), - horizontal_space(Length::Fill), + horizontal_space(), pick_list( highlighter::Theme::ALL, Some(self.theme), @@ -179,7 +179,7 @@ impl Application for Editor { } else { String::from("New file") }), - horizontal_space(Length::Fill), + horizontal_space(), text({ let (line, column) = self.content.cursor_position(); diff --git a/examples/gradient/src/main.rs b/examples/gradient/src/main.rs index 32b2e4aaa6..a021c16450 100644 --- a/examples/gradient/src/main.rs +++ b/examples/gradient/src/main.rs @@ -71,7 +71,7 @@ impl Sandbox for Gradient { transparent, } = *self; - let gradient_box = container(horizontal_space(Length::Fill)) + let gradient_box = container(horizontal_space()) .width(Length::Fill) .height(Length::Fill) .style(move |_: &_| { diff --git a/examples/layout/src/main.rs b/examples/layout/src/main.rs index f41c9986f8..06a476be5e 100644 --- a/examples/layout/src/main.rs +++ b/examples/layout/src/main.rs @@ -85,7 +85,7 @@ impl Application for Layout { fn view(&self) -> Element { let header = row![ text(self.example.title).size(20).font(Font::MONOSPACE), - horizontal_space(Length::Fill), + horizontal_space(), checkbox("Explain", self.explain) .on_toggle(Message::ExplainToggled), pick_list(Theme::ALL, Some(&self.theme), Message::ThemeSelected), @@ -117,7 +117,7 @@ impl Application for Layout { .on_press(Message::Previous) .into(), ), - Some(horizontal_space(Length::Fill).into()), + Some(horizontal_space().into()), (!self.example.is_last()).then_some( button("Next →") .padding([5, 10]) @@ -251,16 +251,16 @@ fn row_<'a>() -> Element<'a, Message> { } fn space<'a>() -> Element<'a, Message> { - row!["Left!", horizontal_space(Length::Fill), "Right!"].into() + row!["Left!", horizontal_space(), "Right!"].into() } fn application<'a>() -> Element<'a, Message> { let header = container( row![ square(40), - horizontal_space(Length::Fill), + horizontal_space(), "Header!", - horizontal_space(Length::Fill), + horizontal_space(), square(40), ] .padding(10) diff --git a/examples/lazy/src/main.rs b/examples/lazy/src/main.rs index 04df0744f9..9d8c0e35f7 100644 --- a/examples/lazy/src/main.rs +++ b/examples/lazy/src/main.rs @@ -186,7 +186,7 @@ impl Sandbox for App { row![ text(&item.name) .style(theme::Text::Color(item.color.into())), - horizontal_space(Length::Fill), + horizontal_space(), pick_list(Color::ALL, Some(item.color), move |color| { Message::ItemColorChanged(item.clone(), color) }), diff --git a/examples/modal/src/main.rs b/examples/modal/src/main.rs index 1dac0075eb..938ce32cc5 100644 --- a/examples/modal/src/main.rs +++ b/examples/modal/src/main.rs @@ -111,13 +111,9 @@ impl Application for App { fn view(&self) -> Element { let content = container( column![ - row![ - text("Top Left"), - horizontal_space(Length::Fill), - text("Top Right") - ] - .align_items(Alignment::Start) - .height(Length::Fill), + row![text("Top Left"), horizontal_space(), text("Top Right")] + .align_items(Alignment::Start) + .height(Length::Fill), container( button(text("Show Modal")).on_press(Message::ShowModal) ) @@ -127,7 +123,7 @@ impl Application for App { .height(Length::Fill), row![ text("Bottom Left"), - horizontal_space(Length::Fill), + horizontal_space(), text("Bottom Right") ] .align_items(Alignment::End) diff --git a/examples/pick_list/src/main.rs b/examples/pick_list/src/main.rs index e4d96dc8e9..c40493e2db 100644 --- a/examples/pick_list/src/main.rs +++ b/examples/pick_list/src/main.rs @@ -43,10 +43,10 @@ impl Sandbox for Example { .placeholder("Choose a language..."); let content = column![ - vertical_space(600), + vertical_space().height(600), "Which is your favorite language?", pick_list, - vertical_space(600), + vertical_space().height(600), ] .width(Length::Fill) .align_items(Alignment::Center) diff --git a/examples/scrollable/src/main.rs b/examples/scrollable/src/main.rs index 29c39c3617..ac18fd3893 100644 --- a/examples/scrollable/src/main.rs +++ b/examples/scrollable/src/main.rs @@ -216,9 +216,9 @@ impl Application for ScrollableDemo { column![ scroll_to_end_button(), text("Beginning!"), - vertical_space(1200), + vertical_space().height(1200), text("Middle!"), - vertical_space(1200), + vertical_space().height(1200), text("End!"), scroll_to_beginning_button(), ] @@ -241,9 +241,9 @@ impl Application for ScrollableDemo { row![ scroll_to_end_button(), text("Beginning!"), - horizontal_space(1200), + horizontal_space().width(1200), text("Middle!"), - horizontal_space(1200), + horizontal_space().width(1200), text("End!"), scroll_to_beginning_button(), ] @@ -268,25 +268,25 @@ impl Application for ScrollableDemo { row![ column![ text("Let's do some scrolling!"), - vertical_space(2400) + vertical_space().height(2400) ], scroll_to_end_button(), text("Horizontal - Beginning!"), - horizontal_space(1200), + horizontal_space().width(1200), //vertical content column![ text("Horizontal - Middle!"), scroll_to_end_button(), text("Vertical - Beginning!"), - vertical_space(1200), + vertical_space().height(1200), text("Vertical - Middle!"), - vertical_space(1200), + vertical_space().height(1200), text("Vertical - End!"), scroll_to_beginning_button(), - vertical_space(40), + vertical_space().height(40), ] .spacing(40), - horizontal_space(1200), + horizontal_space().width(1200), text("Horizontal - End!"), scroll_to_beginning_button(), ] diff --git a/examples/styling/src/main.rs b/examples/styling/src/main.rs index c26215b6f2..befdfc1b81 100644 --- a/examples/styling/src/main.rs +++ b/examples/styling/src/main.rs @@ -76,7 +76,7 @@ impl Sandbox for Styling { let scrollable = scrollable(column![ "Scroll me!", - vertical_space(800), + vertical_space().height(800), "You did it!" ]) .width(Length::Fill) diff --git a/examples/toast/src/main.rs b/examples/toast/src/main.rs index 7f067e2fae..ae947acb5b 100644 --- a/examples/toast/src/main.rs +++ b/examples/toast/src/main.rs @@ -274,7 +274,7 @@ mod toast { container( row![ text(toast.title.as_str()), - horizontal_space(Length::Fill), + horizontal_space(), button("X") .on_press((on_close)(index)) .padding(3), diff --git a/examples/tour/src/main.rs b/examples/tour/src/main.rs index 15d378967d..509f46e7c0 100644 --- a/examples/tour/src/main.rs +++ b/examples/tour/src/main.rs @@ -66,7 +66,7 @@ impl Sandbox for Tour { ); } - controls = controls.push(horizontal_space(Length::Fill)); + controls = controls.push(horizontal_space()); if steps.can_continue() { controls = @@ -574,14 +574,14 @@ impl<'a> Step { text("Tip: You can use the scrollbar to scroll down faster!") .size(16), ) - .push(vertical_space(4096)) + .push(vertical_space().height(4096)) .push( text("You are halfway there!") .width(Length::Fill) .size(30) .horizontal_alignment(alignment::Horizontal::Center), ) - .push(vertical_space(4096)) + .push(vertical_space().height(4096)) .push(ferris(300, image::FilterMethod::Linear)) .push( text("You made it!") diff --git a/examples/vectorial_text/src/main.rs b/examples/vectorial_text/src/main.rs index c2212b22ca..0b9ea938c0 100644 --- a/examples/vectorial_text/src/main.rs +++ b/examples/vectorial_text/src/main.rs @@ -64,7 +64,7 @@ impl Sandbox for VectorialText { column![ row![ text(label), - horizontal_space(Length::Fill), + horizontal_space(), text(format!("{:.2}", value)) ], slider(range, value, message).step(0.01) diff --git a/examples/visible_bounds/src/main.rs b/examples/visible_bounds/src/main.rs index 33d76da842..bef5d29694 100644 --- a/examples/visible_bounds/src/main.rs +++ b/examples/visible_bounds/src/main.rs @@ -81,7 +81,7 @@ impl Application for Example { let data_row = |label, value, color| { row![ text(label), - horizontal_space(Length::Fill), + horizontal_space(), text(value).font(Font::MONOSPACE).size(14).style(color), ] .height(40) @@ -127,21 +127,21 @@ impl Application for Example { scrollable( column![ text("Scroll me!"), - vertical_space(400), + vertical_space().height(400), container(text("I am the outer container!")) .id(OUTER_CONTAINER.clone()) .padding(40) .style(theme::Container::Box), - vertical_space(400), + vertical_space().height(400), scrollable( column![ text("Scroll me!"), - vertical_space(400), + vertical_space().height(400), container(text("I am the inner container!")) .id(INNER_CONTAINER.clone()) .padding(40) .style(theme::Container::Box), - vertical_space(400) + vertical_space().height(400), ] .padding(20) ) diff --git a/widget/src/helpers.rs b/widget/src/helpers.rs index e9898d6743..400fced53b 100644 --- a/widget/src/helpers.rs +++ b/widget/src/helpers.rs @@ -305,15 +305,15 @@ where /// Creates a new horizontal [`Space`] with the given [`Length`]. /// /// [`Space`]: crate::Space -pub fn horizontal_space(width: impl Into) -> Space { - Space::with_width(width) +pub fn horizontal_space() -> Space { + Space::with_width(Length::Fill) } /// Creates a new vertical [`Space`] with the given [`Length`]. /// /// [`Space`]: crate::Space -pub fn vertical_space(height: impl Into) -> Space { - Space::with_height(height) +pub fn vertical_space() -> Space { + Space::with_height(Length::Fill) } /// Creates a horizontal [`Rule`] with the given height. diff --git a/widget/src/lazy/responsive.rs b/widget/src/lazy/responsive.rs index 44312a2158..313e1edb5b 100644 --- a/widget/src/lazy/responsive.rs +++ b/widget/src/lazy/responsive.rs @@ -50,7 +50,7 @@ where content: RefCell::new(Content { size: Size::ZERO, layout: None, - element: Element::new(horizontal_space(0)), + element: Element::new(horizontal_space().width(0)), }), } } diff --git a/widget/src/space.rs b/widget/src/space.rs index aeec91f99c..35bb30c4d2 100644 --- a/widget/src/space.rs +++ b/widget/src/space.rs @@ -39,6 +39,18 @@ impl Space { height: height.into(), } } + + /// Sets the width of the [`Space`]. + pub fn width(mut self, width: impl Into) -> Self { + self.width = width.into(); + self + } + + /// Sets the height of the [`Space`]. + pub fn height(mut self, height: impl Into) -> Self { + self.height = height.into(); + self + } } impl Widget for Space From e57668d6776d4354b6d3df049aee64be0dc8eda2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 15 Feb 2024 02:09:41 +0100 Subject: [PATCH 3/5] Update `CHANGELOG` --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b5dc7769a..978b9c667c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -71,6 +71,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add a capacity limit to the `GlyphCache` in `iced_tiny_skia`. [#2210](https://github.com/iced-rs/iced/pull/2210) - Use pointer equality to speed up `PartialEq` implementation of `image::Bytes`. [#2220](https://github.com/iced-rs/iced/pull/2220) - Update `bitflags`, `glam`, `kurbo`, `ouroboros`, `qrcode`, and `sysinfo` dependencies. [#2227](https://github.com/iced-rs/iced/pull/2227) +- Improve some widget ergonomics. [#2253](https://github.com/iced-rs/iced/pull/2253) ### Fixed - Clipping of `TextInput` selection. [#2199](https://github.com/iced-rs/iced/pull/2199) From feab96f323189ebae070a5d025531f86e436e21f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 15 Feb 2024 02:38:07 +0100 Subject: [PATCH 4/5] Add `push_maybe` to `Column` and `Row` --- examples/pane_grid/src/main.rs | 55 +++++++++++---------- examples/qr_code/src/main.rs | 16 +++--- examples/screenshot/src/main.rs | 88 +++++++++++++++++---------------- examples/toast/src/main.rs | 9 ++-- examples/tour/src/main.rs | 22 ++++----- widget/src/column.rs | 12 +++++ widget/src/helpers.rs | 12 +++++ widget/src/keyed/column.rs | 13 +++++ widget/src/row.rs | 12 +++++ 9 files changed, 144 insertions(+), 95 deletions(-) diff --git a/examples/pane_grid/src/main.rs b/examples/pane_grid/src/main.rs index 742dc344c7..39719420aa 100644 --- a/examples/pane_grid/src/main.rs +++ b/examples/pane_grid/src/main.rs @@ -276,7 +276,7 @@ fn view_content<'a>( .on_press(message) }; - let mut controls = column![ + let controls = column![ button( "Split horizontally", Message::Split(pane_grid::Axis::Horizontal, pane), @@ -286,15 +286,16 @@ fn view_content<'a>( Message::Split(pane_grid::Axis::Vertical, pane), ) ] - .spacing(5) - .max_width(160); - - if total_panes > 1 && !is_pinned { - controls = controls.push( + .push_maybe(if total_panes > 1 && !is_pinned { + Some( button("Close", Message::Close(pane)) .style(theme::Button::Destructive), - ); - } + ) + } else { + None + }) + .spacing(5) + .max_width(160); let content = column![ text(format!("{}x{}", size.width, size.height)).size(24), @@ -317,31 +318,31 @@ fn view_controls<'a>( is_pinned: bool, is_maximized: bool, ) -> Element<'a, Message> { - let mut row = row![].spacing(5); + let row = row![].spacing(5).push_maybe(if total_panes > 1 { + let (content, message) = if is_maximized { + ("Restore", Message::Restore) + } else { + ("Maximize", Message::Maximize(pane)) + }; - if total_panes > 1 { - let toggle = { - let (content, message) = if is_maximized { - ("Restore", Message::Restore) - } else { - ("Maximize", Message::Maximize(pane)) - }; + Some( button(text(content).size(14)) .style(theme::Button::Secondary) .padding(3) - .on_press(message) - }; - - row = row.push(toggle); - } + .on_press(message), + ) + } else { + None + }); - let mut close = button(text("Close").size(14)) + let close = button(text("Close").size(14)) .style(theme::Button::Destructive) - .padding(3); - - if total_panes > 1 && !is_pinned { - close = close.on_press(Message::Close(pane)); - } + .padding(3) + .on_press_maybe(if total_panes > 1 && !is_pinned { + Some(Message::Close(pane)) + } else { + None + }); row.push(close).into() } diff --git a/examples/qr_code/src/main.rs b/examples/qr_code/src/main.rs index 9f75eaf6c8..36f79a3109 100644 --- a/examples/qr_code/src/main.rs +++ b/examples/qr_code/src/main.rs @@ -1,5 +1,6 @@ -use iced::widget::qr_code::{self, QRCode}; -use iced::widget::{column, container, pick_list, row, text, text_input}; +use iced::widget::{ + column, container, pick_list, qr_code, row, text, text_input, +}; use iced::{Alignment, Element, Length, Sandbox, Settings, Theme}; pub fn main() -> iced::Result { @@ -65,15 +66,16 @@ impl Sandbox for QRGenerator { .spacing(10) .align_items(Alignment::Center); - let mut content = column![title, input, choose_theme] + let content = column![title, input, choose_theme] + .push_maybe( + self.qr_code + .as_ref() + .map(|data| qr_code(data).cell_size(10)), + ) .width(700) .spacing(20) .align_items(Alignment::Center); - if let Some(qr_code) = self.qr_code.as_ref() { - content = content.push(QRCode::new(qr_code).cell_size(10)); - } - container(content) .width(Length::Fill) .height(Length::Fill) diff --git a/examples/screenshot/src/main.rs b/examples/screenshot/src/main.rs index 64aa1a7a8c..79749956d7 100644 --- a/examples/screenshot/src/main.rs +++ b/examples/screenshot/src/main.rs @@ -183,58 +183,60 @@ impl Application for Example { .spacing(10) .align_items(Alignment::Center); - let mut crop_controls = + let crop_controls = column![crop_origin_controls, crop_dimension_controls] + .push_maybe( + self.crop_error + .as_ref() + .map(|error| text(format!("Crop error! \n{error}"))), + ) .spacing(10) .align_items(Alignment::Center); - if let Some(crop_error) = &self.crop_error { - crop_controls = - crop_controls.push(text(format!("Crop error! \n{crop_error}"))); - } + let controls = { + let save_result = + self.saved_png_path.as_ref().map( + |png_result| match png_result { + Ok(path) => format!("Png saved as: {path:?}!"), + Err(PngError(error)) => { + format!("Png could not be saved due to:\n{}", error) + } + }, + ); - let mut controls = column![ column![ - button(centered_text("Screenshot!")) + column![ + button(centered_text("Screenshot!")) + .padding([10, 20, 10, 20]) + .width(Length::Fill) + .on_press(Message::Screenshot), + if !self.png_saving { + button(centered_text("Save as png")).on_press_maybe( + self.screenshot.is_some().then(|| Message::Png), + ) + } else { + button(centered_text("Saving...")) + .style(theme::Button::Secondary) + } + .style(theme::Button::Secondary) .padding([10, 20, 10, 20]) .width(Length::Fill) - .on_press(Message::Screenshot), - if !self.png_saving { - button(centered_text("Save as png")).on_press_maybe( - self.screenshot.is_some().then(|| Message::Png), - ) - } else { - button(centered_text("Saving...")) - .style(theme::Button::Secondary) - } - .style(theme::Button::Secondary) - .padding([10, 20, 10, 20]) - .width(Length::Fill) - ] - .spacing(10), - column![ - crop_controls, - button(centered_text("Crop")) - .on_press(Message::Crop) - .style(theme::Button::Destructive) - .padding([10, 20, 10, 20]) - .width(Length::Fill), + ] + .spacing(10), + column![ + crop_controls, + button(centered_text("Crop")) + .on_press(Message::Crop) + .style(theme::Button::Destructive) + .padding([10, 20, 10, 20]) + .width(Length::Fill), + ] + .spacing(10) + .align_items(Alignment::Center), ] - .spacing(10) - .align_items(Alignment::Center), - ] - .spacing(40); - - if let Some(png_result) = &self.saved_png_path { - let msg = match png_result { - Ok(path) => format!("Png saved as: {path:?}!"), - Err(PngError(error)) => { - format!("Png could not be saved due to:\n{}", error) - } - }; - - controls = controls.push(text(msg)); - } + .push_maybe(save_result.map(text)) + .spacing(40) + }; let side_content = container(controls) .align_x(alignment::Horizontal::Center) diff --git a/examples/toast/src/main.rs b/examples/toast/src/main.rs index ae947acb5b..c1d2919317 100644 --- a/examples/toast/src/main.rs +++ b/examples/toast/src/main.rs @@ -111,11 +111,10 @@ impl Application for App { column![text(title).size(14), content].spacing(5) }; - let mut add_toast = button("Add Toast"); - - if !self.editing.body.is_empty() && !self.editing.title.is_empty() { - add_toast = add_toast.on_press(Message::Add); - } + let add_toast = button("Add Toast").on_press_maybe( + (!self.editing.body.is_empty() && !self.editing.title.is_empty()) + .then_some(Message::Add), + ); let content = container( column![ diff --git a/examples/tour/src/main.rs b/examples/tour/src/main.rs index 509f46e7c0..588abbe88a 100644 --- a/examples/tour/src/main.rs +++ b/examples/tour/src/main.rs @@ -56,22 +56,18 @@ impl Sandbox for Tour { fn view(&self) -> Element { let Tour { steps, .. } = self; - let mut controls = row![]; - - if steps.has_previous() { - controls = controls.push( + let controls = row![] + .push_maybe(steps.has_previous().then(|| { button("Back") .on_press(Message::BackPressed) - .style(theme::Button::Secondary), + .style(theme::Button::Secondary) + })) + .push(horizontal_space()) + .push_maybe( + steps + .can_continue() + .then(|| button("Next").on_press(Message::NextPressed)), ); - } - - controls = controls.push(horizontal_space()); - - if steps.can_continue() { - controls = - controls.push(button("Next").on_press(Message::NextPressed)); - } let content: Element<_> = column![ steps.view(self.debug).map(Message::StepMessage), diff --git a/widget/src/column.rs b/widget/src/column.rs index 8154ad8532..b9eb5d93df 100644 --- a/widget/src/column.rs +++ b/widget/src/column.rs @@ -115,6 +115,18 @@ where self.children.push(child); self } + + /// Adds an element to the [`Column`], if `Some`. + pub fn push_maybe( + self, + child: Option>>, + ) -> Self { + if let Some(child) = child { + self.push(child) + } else { + self + } + } } impl<'a, Message, Renderer> Default for Column<'a, Message, Renderer> diff --git a/widget/src/helpers.rs b/widget/src/helpers.rs index 400fced53b..6ae35aeeb0 100644 --- a/widget/src/helpers.rs +++ b/widget/src/helpers.rs @@ -387,6 +387,18 @@ where crate::Canvas::new(program) } +/// Creates a new [`QRCode`] widget from the given [`Data`]. +/// +/// [`Svg`]: crate::QRCode +/// [`Data`]: crate::qr_code::Data +#[cfg(feature = "qr_code")] +pub fn qr_code(data: &crate::qr_code::Data) -> crate::QRCode<'_, Theme> +where + Theme: crate::qr_code::StyleSheet, +{ + crate::QRCode::new(data) +} + /// Creates a new [`Shader`]. /// /// [`Shader`]: crate::Shader diff --git a/widget/src/keyed/column.rs b/widget/src/keyed/column.rs index 88a6e503c8..ce74e70173 100644 --- a/widget/src/keyed/column.rs +++ b/widget/src/keyed/column.rs @@ -124,6 +124,19 @@ where self.children.push(child); self } + + /// Adds an element to the [`Column`], if `Some`. + pub fn push_maybe( + self, + key: Key, + child: Option>>, + ) -> Self { + if let Some(child) = child { + self.push(key, child) + } else { + self + } + } } impl<'a, Key, Message, Renderer> Default for Column<'a, Key, Message, Renderer> diff --git a/widget/src/row.rs b/widget/src/row.rs index 735fbbc076..20b47a4143 100644 --- a/widget/src/row.rs +++ b/widget/src/row.rs @@ -106,6 +106,18 @@ where self.children.push(child); self } + + /// Adds an element to the [`Row`], if `Some`. + pub fn push_maybe( + self, + child: Option>>, + ) -> Self { + if let Some(child) = child { + self.push(child) + } else { + self + } + } } impl<'a, Message, Renderer> Default for Row<'a, Message, Renderer> From 777e2e34f50c440f59d9a407f75be80fbbfaccae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 15 Feb 2024 02:47:35 +0100 Subject: [PATCH 5/5] Fix documentation for `qr_code` widget helper --- widget/src/helpers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widget/src/helpers.rs b/widget/src/helpers.rs index 6ae35aeeb0..3f2e56cd5d 100644 --- a/widget/src/helpers.rs +++ b/widget/src/helpers.rs @@ -389,7 +389,7 @@ where /// Creates a new [`QRCode`] widget from the given [`Data`]. /// -/// [`Svg`]: crate::QRCode +/// [`QRCode`]: crate::QRCode /// [`Data`]: crate::qr_code::Data #[cfg(feature = "qr_code")] pub fn qr_code(data: &crate::qr_code::Data) -> crate::QRCode<'_, Theme>