diff --git a/core/src/element.rs b/core/src/element.rs index 9d083d79..a3f60127 100644 --- a/core/src/element.rs +++ b/core/src/element.rs @@ -532,3 +532,49 @@ where ) } } + +impl<'a, T, Message, Theme, Renderer> From> + for Element<'a, Message, Theme, Renderer> +where + T: Into, + Renderer: crate::Renderer, +{ + fn from(element: Option) -> Self { + struct Void; + + impl Widget for Void + where + Renderer: crate::Renderer, + { + fn size(&self) -> Size { + Size { + width: Length::Fixed(0.0), + height: Length::Fixed(0.0), + } + } + + fn layout( + &self, + _tree: &mut Tree, + _renderer: &Renderer, + _limits: &layout::Limits, + ) -> layout::Node { + layout::Node::new(Size::ZERO) + } + + fn draw( + &self, + _tree: &Tree, + _renderer: &mut Renderer, + _theme: &Theme, + _style: &renderer::Style, + _layout: Layout<'_>, + _cursor: mouse::Cursor, + _viewport: &Rectangle, + ) { + } + } + + element.map(T::into).unwrap_or_else(|| Element::new(Void)) + } +} diff --git a/core/src/length.rs b/core/src/length.rs index 363833c4..073465ae 100644 --- a/core/src/length.rs +++ b/core/src/length.rs @@ -57,6 +57,7 @@ impl Length { /// Adapts the [`Length`] so it can contain the other [`Length`] and /// match its fluidity. + #[inline] pub fn enclose(self, other: Length) -> Self { match (self, other) { (Length::Shrink, Length::Fill | Length::FillPortion(_)) => other, diff --git a/core/src/size.rs b/core/src/size.rs index 95089236..9503cf59 100644 --- a/core/src/size.rs +++ b/core/src/size.rs @@ -1,4 +1,4 @@ -use crate::{Radians, Vector}; +use crate::{Length, Radians, Vector}; /// An amount of space in 2 dimensions. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)] @@ -66,6 +66,15 @@ impl Size { } } +impl Size { + /// Returns true if either `width` or `height` are 0-sized. + #[inline] + pub fn is_void(&self) -> bool { + matches!(self.width, Length::Fixed(0.0)) + || matches!(self.height, Length::Fixed(0.0)) + } +} + impl From<[T; 2]> for Size { fn from([width, height]: [T; 2]) -> Self { Size { width, height } diff --git a/examples/pane_grid/src/main.rs b/examples/pane_grid/src/main.rs index c44fc1f1..2d2b92d9 100644 --- a/examples/pane_grid/src/main.rs +++ b/examples/pane_grid/src/main.rs @@ -276,13 +276,13 @@ fn view_content<'a>( button( "Split vertically", Message::Split(pane_grid::Axis::Vertical, pane), - ) + ), + if total_panes > 1 && !is_pinned { + Some(button("Close", Message::Close(pane)).style(button::danger)) + } else { + None + } ] - .push_maybe(if total_panes > 1 && !is_pinned { - Some(button("Close", Message::Close(pane)).style(button::danger)) - } else { - None - }) .spacing(5) .max_width(160); @@ -300,7 +300,7 @@ fn view_controls<'a>( is_pinned: bool, is_maximized: bool, ) -> Element<'a, Message> { - let row = row![].spacing(5).push_maybe(if total_panes > 1 { + let maximize = if total_panes > 1 { let (content, message) = if is_maximized { ("Restore", Message::Restore) } else { @@ -315,7 +315,7 @@ fn view_controls<'a>( ) } else { None - }); + }; let close = button(text("Close").size(14)) .style(button::danger) @@ -326,7 +326,7 @@ fn view_controls<'a>( None }); - row.push(close).into() + row![maximize, close].spacing(5).into() } mod style { diff --git a/examples/qr_code/src/main.rs b/examples/qr_code/src/main.rs index 20217615..6b6989d0 100644 --- a/examples/qr_code/src/main.rs +++ b/examples/qr_code/src/main.rs @@ -88,18 +88,18 @@ impl QRGenerator { input, row![toggle_total_size, choose_theme] .spacing(20) - .align_y(Center) + .align_y(Center), + self.total_size.map(|total_size| { + slider(Self::SIZE_RANGE, total_size, Message::TotalSizeChanged) + }), + self.qr_code.as_ref().map(|data| { + if let Some(total_size) = self.total_size { + qr_code(data).total_size(total_size) + } else { + qr_code(data).cell_size(10.0) + } + }) ] - .push_maybe(self.total_size.map(|total_size| { - slider(Self::SIZE_RANGE, total_size, Message::TotalSizeChanged) - })) - .push_maybe(self.qr_code.as_ref().map(|data| { - if let Some(total_size) = self.total_size { - qr_code(data).total_size(total_size) - } else { - qr_code(data).cell_size(10.0) - } - })) .width(700) .spacing(20) .align_x(Center); diff --git a/examples/screenshot/src/main.rs b/examples/screenshot/src/main.rs index 1f18e285..61285b72 100644 --- a/examples/screenshot/src/main.rs +++ b/examples/screenshot/src/main.rs @@ -158,15 +158,15 @@ impl Example { .spacing(10) .align_y(Center); - let crop_controls = - column![crop_origin_controls, crop_dimension_controls] - .push_maybe( - self.crop_error - .as_ref() - .map(|error| text!("Crop error! \n{error}")), - ) - .spacing(10) - .align_x(Center); + let crop_controls = column![ + crop_origin_controls, + crop_dimension_controls, + self.crop_error + .as_ref() + .map(|error| text!("Crop error! \n{error}")), + ] + .spacing(10) + .align_x(Center); let controls = { let save_result = @@ -208,8 +208,8 @@ impl Example { ] .spacing(10) .align_x(Center), + save_result.map(text) ] - .push_maybe(save_result.map(text)) .spacing(40) }; diff --git a/examples/tour/src/main.rs b/examples/tour/src/main.rs index 984cf272..5d009da6 100644 --- a/examples/tour/src/main.rs +++ b/examples/tour/src/main.rs @@ -142,17 +142,17 @@ impl Tour { } fn view(&self) -> Element<'_, Message> { - let controls = - row![] - .push_maybe(self.screen.previous().is_some().then(|| { - padded_button("Back") - .on_press(Message::BackPressed) - .style(button::secondary) - })) - .push(horizontal_space()) - .push_maybe(self.can_continue().then(|| { - padded_button("Next").on_press(Message::NextPressed) - })); + let controls = row![ + self.screen.previous().is_some().then(|| { + padded_button("Back") + .on_press(Message::BackPressed) + .style(button::secondary) + }), + horizontal_space(), + self.can_continue().then(|| { + padded_button("Next").on_press(Message::NextPressed) + }) + ]; let screen = match self.screen { Screen::Welcome => self.welcome(), diff --git a/widget/src/column.rs b/widget/src/column.rs index 4ab56c89..6c126048 100644 --- a/widget/src/column.rs +++ b/widget/src/column.rs @@ -145,23 +145,13 @@ where let child = child.into(); let child_size = child.as_widget().size_hint(); - self.width = self.width.enclose(child_size.width); - self.height = self.height.enclose(child_size.height); - - 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 + if !child_size.is_void() { + self.width = self.width.enclose(child_size.width); + self.height = self.height.enclose(child_size.height); + self.children.push(child); } + + self } /// Extends the [`Column`] with the given children. diff --git a/widget/src/row.rs b/widget/src/row.rs index a51106d1..7bd8799f 100644 --- a/widget/src/row.rs +++ b/widget/src/row.rs @@ -136,23 +136,13 @@ where let child = child.into(); let child_size = child.as_widget().size_hint(); - self.width = self.width.enclose(child_size.width); - self.height = self.height.enclose(child_size.height); - - 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 + if !child_size.is_void() { + self.width = self.width.enclose(child_size.width); + self.height = self.height.enclose(child_size.height); + self.children.push(child); } + + self } /// Extends the [`Row`] with the given children.