diff options
Diffstat (limited to 'widget/src/container.rs')
-rw-r--r-- | widget/src/container.rs | 162 |
1 files changed, 89 insertions, 73 deletions
diff --git a/widget/src/container.rs b/widget/src/container.rs index e917471f..3b794099 100644 --- a/widget/src/container.rs +++ b/widget/src/container.rs @@ -1,5 +1,6 @@ //! Decorate content and apply alignment. use crate::core::alignment::{self, Alignment}; +use crate::core::border::{self, Border}; use crate::core::event::{self, Event}; use crate::core::gradient::{self, Gradient}; use crate::core::layout; @@ -9,11 +10,11 @@ use crate::core::renderer; use crate::core::widget::tree::{self, Tree}; use crate::core::widget::{self, Operation}; use crate::core::{ - self, Background, Border, Clipboard, Color, Element, Layout, Length, + self, color, Background, Clipboard, Color, Element, Layout, Length, Padding, Pixels, Point, Rectangle, Shadow, Shell, Size, Theme, Vector, Widget, }; -use crate::runtime::Task; +use crate::runtime::task::{self, Task}; /// An element decorating some content. /// @@ -92,46 +93,6 @@ where self } - /// Sets the [`Container`] to fill the available space in the horizontal axis. - /// - /// This can be useful to quickly position content when chained with - /// alignment functions—like [`center_x`]. - /// - /// Calling this method is equivalent to calling [`width`] with a - /// [`Length::Fill`]. - /// - /// [`center_x`]: Self::center_x - /// [`width`]: Self::width - pub fn fill_x(self) -> Self { - self.width(Length::Fill) - } - - /// Sets the [`Container`] to fill the available space in the vetical axis. - /// - /// This can be useful to quickly position content when chained with - /// alignment functions—like [`center_y`]. - /// - /// Calling this method is equivalent to calling [`height`] with a - /// [`Length::Fill`]. - /// - /// [`center_y`]: Self::center_x - /// [`height`]: Self::height - pub fn fill_y(self) -> Self { - self.height(Length::Fill) - } - - /// Sets the [`Container`] to fill all the available space. - /// - /// Calling this method is equivalent to chaining [`fill_x`] and - /// [`fill_y`]. - /// - /// [`center`]: Self::center - /// [`fill_x`]: Self::fill_x - /// [`fill_y`]: Self::fill_y - pub fn fill(self) -> Self { - self.width(Length::Fill).height(Length::Fill) - } - /// Sets the maximum width of the [`Container`]. pub fn max_width(mut self, max_width: impl Into<Pixels>) -> Self { self.max_width = max_width.into().0; @@ -144,18 +105,6 @@ where self } - /// Sets the content alignment for the horizontal axis of the [`Container`]. - pub fn align_x(mut self, alignment: alignment::Horizontal) -> Self { - self.horizontal_alignment = alignment; - self - } - - /// Sets the content alignment for the vertical axis of the [`Container`]. - pub fn align_y(mut self, alignment: alignment::Vertical) -> Self { - self.vertical_alignment = alignment; - self - } - /// Sets the width of the [`Container`] and centers its contents horizontally. pub fn center_x(self, width: impl Into<Length>) -> Self { self.width(width).align_x(alignment::Horizontal::Center) @@ -179,6 +128,44 @@ where self.center_x(length).center_y(length) } + /// Aligns the contents of the [`Container`] to the left. + pub fn align_left(self, width: impl Into<Length>) -> Self { + self.width(width).align_x(alignment::Horizontal::Left) + } + + /// Aligns the contents of the [`Container`] to the right. + pub fn align_right(self, width: impl Into<Length>) -> Self { + self.width(width).align_x(alignment::Horizontal::Right) + } + + /// Aligns the contents of the [`Container`] to the top. + pub fn align_top(self, height: impl Into<Length>) -> Self { + self.height(height).align_y(alignment::Vertical::Top) + } + + /// Aligns the contents of the [`Container`] to the bottom. + pub fn align_bottom(self, height: impl Into<Length>) -> Self { + self.height(height).align_y(alignment::Vertical::Bottom) + } + + /// Sets the content alignment for the horizontal axis of the [`Container`]. + pub fn align_x( + mut self, + alignment: impl Into<alignment::Horizontal>, + ) -> Self { + self.horizontal_alignment = alignment.into(); + self + } + + /// Sets the content alignment for the vertical axis of the [`Container`]. + pub fn align_y( + mut self, + alignment: impl Into<alignment::Vertical>, + ) -> Self { + self.vertical_alignment = alignment.into(); + self + } + /// Sets whether the contents of the [`Container`] should be clipped on /// overflow. pub fn clip(mut self, clip: bool) -> Self { @@ -197,7 +184,6 @@ where } /// Sets the style class of the [`Container`]. - #[cfg(feature = "advanced")] #[must_use] pub fn class(mut self, class: impl Into<Theme::Class<'a>>) -> Self { self.class = class.into(); @@ -258,7 +244,7 @@ where tree: &mut Tree, layout: Layout<'_>, renderer: &Renderer, - operation: &mut dyn Operation<()>, + operation: &mut dyn Operation, ) { operation.container( self.id.as_ref().map(|id| &id.0), @@ -473,6 +459,7 @@ pub fn visible_bounds(id: Id) -> Task<Option<Rectangle>> { _state: &mut dyn widget::operation::Scrollable, _id: Option<&widget::Id>, bounds: Rectangle, + _content_bounds: Rectangle, translation: Vector, ) { match self.scrollables.last() { @@ -538,7 +525,7 @@ pub fn visible_bounds(id: Id) -> Task<Option<Rectangle>> { } } - Task::widget(VisibleBounds { + task::widget(VisibleBounds { target: id.into(), depth: 0, scrollables: Vec::new(), @@ -560,46 +547,54 @@ pub struct Style { } impl Style { - /// Updates the border of the [`Style`] with the given [`Color`] and `width`. - pub fn with_border( - self, - color: impl Into<Color>, - width: impl Into<Pixels>, - ) -> Self { + /// Updates the text color of the [`Style`]. + pub fn color(self, color: impl Into<Color>) -> Self { Self { - border: Border { - color: color.into(), - width: width.into().0, - ..Border::default() - }, + text_color: Some(color.into()), + ..self + } + } + + /// Updates the border of the [`Style`]. + pub fn border(self, border: impl Into<Border>) -> Self { + Self { + border: border.into(), ..self } } /// Updates the background of the [`Style`]. - pub fn with_background(self, background: impl Into<Background>) -> Self { + pub fn background(self, background: impl Into<Background>) -> Self { Self { background: Some(background.into()), ..self } } + + /// Updates the shadow of the [`Style`]. + pub fn shadow(self, shadow: impl Into<Shadow>) -> Self { + Self { + shadow: shadow.into(), + ..self + } + } } impl From<Color> for Style { fn from(color: Color) -> Self { - Self::default().with_background(color) + Self::default().background(color) } } impl From<Gradient> for Style { fn from(gradient: Gradient) -> Self { - Self::default().with_background(gradient) + Self::default().background(gradient) } } impl From<gradient::Linear> for Style { fn from(gradient: gradient::Linear) -> Self { - Self::default().with_background(gradient) + Self::default().background(gradient) } } @@ -618,6 +613,12 @@ pub trait Catalog { /// A styling function for a [`Container`]. pub type StyleFn<'a, Theme> = Box<dyn Fn(&Theme) -> Style + 'a>; +impl<'a, Theme> From<Style> for StyleFn<'a, Theme> { + fn from(style: Style) -> Self { + Box::new(move |_theme| style) + } +} + impl Catalog for Theme { type Class<'a> = StyleFn<'a, Self>; @@ -635,13 +636,18 @@ pub fn transparent<Theme>(_theme: &Theme) -> Style { Style::default() } +/// A [`Container`] with the given [`Background`]. +pub fn background(background: impl Into<Background>) -> Style { + Style::default().background(background) +} + /// A rounded [`Container`] with a background. pub fn rounded_box(theme: &Theme) -> Style { let palette = theme.extended_palette(); Style { background: Some(palette.background.weak.color.into()), - border: Border::rounded(2), + border: border::rounded(2), ..Style::default() } } @@ -660,3 +666,13 @@ pub fn bordered_box(theme: &Theme) -> Style { ..Style::default() } } + +/// A [`Container`] with a dark background and white text. +pub fn dark(_theme: &Theme) -> Style { + Style { + background: Some(color!(0x111111).into()), + text_color: Some(Color::WHITE), + border: border::rounded(2), + ..Style::default() + } +} |