diff options
Diffstat (limited to '')
| -rw-r--r-- | pure/src/widget.rs | 6 | ||||
| -rw-r--r-- | pure/src/widget/row.rs | 223 | 
2 files changed, 229 insertions, 0 deletions
| diff --git a/pure/src/widget.rs b/pure/src/widget.rs index 9a4dffe3..1cbd3b78 100644 --- a/pure/src/widget.rs +++ b/pure/src/widget.rs @@ -1,12 +1,14 @@  mod button;  mod column;  mod element; +mod row;  mod text;  mod tree;  pub use button::Button;  pub use column::Column;  pub use element::Element; +pub use row::Row;  pub use text::Text;  pub use tree::Tree; @@ -76,6 +78,10 @@ pub fn column<'a, Message, Renderer>() -> Column<'a, Message, Renderer> {      Column::new()  } +pub fn row<'a, Message, Renderer>() -> Row<'a, Message, Renderer> { +    Row::new() +} +  pub fn button<'a, Message, Renderer>(      content: impl Into<Element<'a, Message, Renderer>>,  ) -> Button<'a, Message, Renderer> { diff --git a/pure/src/widget/row.rs b/pure/src/widget/row.rs new file mode 100644 index 00000000..2581b38a --- /dev/null +++ b/pure/src/widget/row.rs @@ -0,0 +1,223 @@ +use crate::flex; +use crate::widget::{Element, Tree, Widget}; + +use iced_native::event::{self, Event}; +use iced_native::layout::{self, Layout}; +use iced_native::mouse; +use iced_native::renderer; +use iced_native::{ +    Alignment, Clipboard, Hasher, Length, Padding, Point, Rectangle, Shell, +}; + +use std::any::{self, Any}; + +pub struct Row<'a, Message, Renderer> { +    spacing: u16, +    padding: Padding, +    width: Length, +    height: Length, +    align_items: Alignment, +    children: Vec<Element<'a, Message, Renderer>>, +} + +impl<'a, Message, Renderer> Row<'a, Message, Renderer> { +    pub fn new() -> Self { +        Self::with_children(Vec::new()) +    } + +    pub fn with_children( +        children: Vec<Element<'a, Message, Renderer>>, +    ) -> Self { +        Row { +            spacing: 0, +            padding: Padding::ZERO, +            width: Length::Shrink, +            height: Length::Shrink, +            align_items: Alignment::Start, +            children, +        } +    } + +    pub fn spacing(mut self, units: u16) -> Self { +        self.spacing = units; +        self +    } + +    pub fn padding<P: Into<Padding>>(mut self, padding: P) -> Self { +        self.padding = padding.into(); +        self +    } + +    pub fn width(mut self, width: Length) -> Self { +        self.width = width; +        self +    } + +    pub fn height(mut self, height: Length) -> Self { +        self.height = height; +        self +    } + +    pub fn align_items(mut self, align: Alignment) -> Self { +        self.align_items = align; +        self +    } + +    pub fn push( +        mut self, +        child: impl Into<Element<'a, Message, Renderer>>, +    ) -> Self { +        self.children.push(child.into()); +        self +    } +} + +impl<'a, Message, Renderer> Widget<Message, Renderer> +    for Row<'a, Message, Renderer> +where +    Renderer: iced_native::Renderer, +{ +    fn tag(&self) -> any::TypeId { +        struct Marker; +        any::TypeId::of::<Marker>() +    } + +    fn state(&self) -> Box<dyn Any> { +        Box::new(()) +    } + +    fn children(&self) -> &[Element<Message, Renderer>] { +        &self.children +    } + +    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); + +        flex::resolve( +            flex::Axis::Horizontal, +            renderer, +            &limits, +            self.padding, +            self.spacing as f32, +            self.align_items, +            &self.children, +        ) +    } + +    fn on_event( +        &mut self, +        tree: &mut Tree, +        event: Event, +        layout: Layout<'_>, +        cursor_position: Point, +        renderer: &Renderer, +        clipboard: &mut dyn Clipboard, +        shell: &mut Shell<'_, Message>, +    ) -> event::Status { +        self.children +            .iter_mut() +            .zip(&mut tree.children) +            .zip(layout.children()) +            .map(|((child, state), layout)| { +                child.as_widget_mut().on_event( +                    state, +                    event.clone(), +                    layout, +                    cursor_position, +                    renderer, +                    clipboard, +                    shell, +                ) +            }) +            .fold(event::Status::Ignored, event::Status::merge) +    } + +    fn mouse_interaction( +        &self, +        tree: &Tree, +        layout: Layout<'_>, +        cursor_position: Point, +        viewport: &Rectangle, +        renderer: &Renderer, +    ) -> mouse::Interaction { +        self.children +            .iter() +            .zip(&tree.children) +            .zip(layout.children()) +            .map(|((child, state), layout)| { +                child.as_widget().mouse_interaction( +                    state, +                    layout, +                    cursor_position, +                    viewport, +                    renderer, +                ) +            }) +            .max() +            .unwrap_or_default() +    } + +    fn draw( +        &self, +        tree: &Tree, +        renderer: &mut Renderer, +        style: &renderer::Style, +        layout: Layout<'_>, +        cursor_position: Point, +        viewport: &Rectangle, +    ) { +        for ((child, state), layout) in self +            .children +            .iter() +            .zip(&tree.children) +            .zip(layout.children()) +        { +            child.as_widget().draw( +                state, +                renderer, +                style, +                layout, +                cursor_position, +                viewport, +            ); +        } +    } + +    fn hash_layout(&self, state: &mut Hasher) { +        use std::hash::Hash; + +        self.tag().hash(state); +        self.width.hash(state); +        self.height.hash(state); +        self.align_items.hash(state); +        self.spacing.hash(state); +        self.padding.hash(state); + +        for child in &self.children { +            child.as_widget().hash_layout(state); +        } +    } +} + +impl<'a, Message, Renderer> Into<Element<'a, Message, Renderer>> +    for Row<'a, Message, Renderer> +where +    Message: 'static, +    Renderer: iced_native::Renderer + 'static, +{ +    fn into(self) -> Element<'a, Message, Renderer> { +        Element::new(self) +    } +} | 
