diff options
Diffstat (limited to '')
| -rw-r--r-- | native/src/widget.rs | 3 | ||||
| -rw-r--r-- | native/src/widget/rule.rs | 125 | 
2 files changed, 128 insertions, 0 deletions
| diff --git a/native/src/widget.rs b/native/src/widget.rs index 8539e519..a10281df 100644 --- a/native/src/widget.rs +++ b/native/src/widget.rs @@ -30,6 +30,7 @@ pub mod pick_list;  pub mod progress_bar;  pub mod radio;  pub mod row; +pub mod rule;  pub mod scrollable;  pub mod slider;  pub mod space; @@ -58,6 +59,8 @@ pub use radio::Radio;  #[doc(no_inline)]  pub use row::Row;  #[doc(no_inline)] +pub use rule::Rule; +#[doc(no_inline)]  pub use scrollable::Scrollable;  #[doc(no_inline)]  pub use slider::Slider; diff --git a/native/src/widget/rule.rs b/native/src/widget/rule.rs new file mode 100644 index 00000000..25cec53b --- /dev/null +++ b/native/src/widget/rule.rs @@ -0,0 +1,125 @@ +//! Display a horizontal or vertical rule for dividing content. + +use std::hash::Hash; + +use crate::{ +    layout, Element, Hasher, Layout, Length, Point, Rectangle, Size, Widget, +}; + +/// Display a horizontal or vertical rule for dividing content. +#[derive(Debug, Copy, Clone)] +pub struct Rule<Renderer: self::Renderer> { +    width: Length, +    height: Length, +    style: Renderer::Style, +    is_horizontal: bool, +} + +impl<Renderer: self::Renderer> Rule<Renderer> { +    /// Creates a horizontal [`Rule`] for dividing content by the given vertical spacing. +    /// +    /// [`Rule`]: struct.Rule.html +    pub fn horizontal(spacing: u16) -> Self { +        Rule { +            width: Length::Fill, +            height: Length::from(Length::Units(spacing)), +            style: Renderer::Style::default(), +            is_horizontal: true, +        } +    } + +    /// Creates a vertical [`Rule`] for dividing content by the given horizontal spacing. +    /// +    /// [`Rule`]: struct.Rule.html +    pub fn vertical(spacing: u16) -> Self { +        Rule { +            width: Length::from(Length::Units(spacing)), +            height: Length::Fill, +            style: Renderer::Style::default(), +            is_horizontal: false, +        } +    } + +    /// Sets the style of the [`Rule`]. +    /// +    /// [`Rule`]: struct.Rule.html +    pub fn style(mut self, style: impl Into<Renderer::Style>) -> Self { +        self.style = style.into(); +        self +    } +} + +impl<Message, Renderer> Widget<Message, Renderer> for Rule<Renderer> +where +    Renderer: self::Renderer, +{ +    fn width(&self) -> Length { +        self.width +    } + +    fn height(&self) -> Length { +        self.height +    } + +    fn layout( +        &self, +        _renderer: &Renderer, +        limits: &layout::Limits, +    ) -> layout::Node { +        let limits = limits.width(self.width).height(self.height); + +        layout::Node::new(limits.resolve(Size::ZERO)) +    } + +    fn draw( +        &self, +        renderer: &mut Renderer, +        _defaults: &Renderer::Defaults, +        layout: Layout<'_>, +        _cursor_position: Point, +    ) -> Renderer::Output { +        renderer.draw(layout.bounds(), &self.style, self.is_horizontal) +    } + +    fn hash_layout(&self, state: &mut Hasher) { +        struct Marker; +        std::any::TypeId::of::<Marker>().hash(state); + +        self.width.hash(state); +        self.height.hash(state); +    } +} + +/// The renderer of a [`Rule`]. +/// +/// [`Rule`]: struct.Rule.html +pub trait Renderer: crate::Renderer { +    /// The style supported by this renderer. +    type Style: Default; + +    /// Draws a [`Rule`]. +    /// +    /// It receives: +    ///   * the bounds of the [`Rule`] +    ///   * the style of the [`Rule`] +    ///   * whether the [`Rule`] is horizontal (true) or vertical (false) +    /// +    /// [`Rule`]: struct.Rule.html +    fn draw( +        &mut self, +        bounds: Rectangle, +        style: &Self::Style, +        is_horizontal: bool, +    ) -> Self::Output; +} + +impl<'a, Message, Renderer> From<Rule<Renderer>> +    for Element<'a, Message, Renderer> +where +    Renderer: 'a + self::Renderer, +    Message: 'a, +{ +    fn from(rule: Rule<Renderer>) -> Element<'a, Message, Renderer> { +        Element::new(rule) +    } +} | 
