diff options
| author | 2019-11-03 05:19:12 +0100 | |
|---|---|---|
| committer | 2019-11-03 05:19:12 +0100 | |
| commit | 0ea911ae36bbde8c288f7ae1ba8a0049b696d7c4 (patch) | |
| tree | 929cb493b674512520f1b6a92f86d7a09e5801f6 /core | |
| parent | de3c87b9a793c0d0799948e16ad1b14e5b4892ba (diff) | |
| parent | 022dc0139b7437f167a8d3ae483bf8e83f1dab04 (diff) | |
| download | iced-0ea911ae36bbde8c288f7ae1ba8a0049b696d7c4.tar.gz iced-0ea911ae36bbde8c288f7ae1ba8a0049b696d7c4.tar.bz2 iced-0ea911ae36bbde8c288f7ae1ba8a0049b696d7c4.zip | |
Merge pull request #35 from hecrj/feature/scrollables
Scrollable widget
Diffstat (limited to '')
| -rw-r--r-- | core/src/widget.rs | 4 | ||||
| -rw-r--r-- | core/src/widget/scrollable.rs | 151 | 
2 files changed, 155 insertions, 0 deletions
| diff --git a/core/src/widget.rs b/core/src/widget.rs index f9d4bf2a..3ee8e347 100644 --- a/core/src/widget.rs +++ b/core/src/widget.rs @@ -14,6 +14,7 @@ mod radio;  mod row;  pub mod button; +pub mod scrollable;  pub mod slider;  pub mod text; @@ -26,6 +27,9 @@ pub use slider::Slider;  #[doc(no_inline)]  pub use text::Text; +#[doc(no_inline)] +pub use scrollable::Scrollable; +  pub use checkbox::Checkbox;  pub use column::Column;  pub use image::Image; diff --git a/core/src/widget/scrollable.rs b/core/src/widget/scrollable.rs new file mode 100644 index 00000000..31a5abed --- /dev/null +++ b/core/src/widget/scrollable.rs @@ -0,0 +1,151 @@ +use crate::{Align, Column, Length, Point, Rectangle}; + +#[derive(Debug)] +pub struct Scrollable<'a, Element> { +    pub state: &'a mut State, +    pub height: Length, +    pub max_height: Length, +    pub align_self: Option<Align>, +    pub content: Column<Element>, +} + +impl<'a, Element> Scrollable<'a, Element> { +    pub fn new(state: &'a mut State) -> Self { +        Scrollable { +            state, +            height: Length::Shrink, +            max_height: Length::Shrink, +            align_self: None, +            content: Column::new(), +        } +    } + +    /// Sets the vertical spacing _between_ elements. +    /// +    /// Custom margins per element do not exist in Iced. You should use this +    /// method instead! While less flexible, it helps you keep spacing between +    /// elements consistent. +    pub fn spacing(mut self, units: u16) -> Self { +        self.content = self.content.spacing(units); +        self +    } + +    /// Sets the padding of the [`Scrollable`]. +    /// +    /// [`Scrollable`]: struct.Scrollable.html +    pub fn padding(mut self, units: u16) -> Self { +        self.content = self.content.padding(units); +        self +    } + +    /// Sets the width of the [`Scrollable`]. +    /// +    /// [`Scrollable`]: struct.Scrollable.html +    pub fn width(mut self, width: Length) -> Self { +        self.content = self.content.width(width); +        self +    } + +    /// Sets the height of the [`Scrollable`]. +    /// +    /// [`Scrollable`]: struct.Scrollable.html +    pub fn height(mut self, height: Length) -> Self { +        self.height = height; +        self +    } + +    /// Sets the maximum width of the [`Scrollable`]. +    /// +    /// [`Scrollable`]: struct.Scrollable.html +    pub fn max_width(mut self, max_width: Length) -> Self { +        self.content = self.content.max_width(max_width); +        self +    } + +    /// Sets the maximum height of the [`Scrollable`] in pixels. +    /// +    /// [`Scrollable`]: struct.Scrollable.html +    pub fn max_height(mut self, max_height: Length) -> Self { +        self.max_height = max_height; +        self +    } + +    /// Sets the alignment of the [`Scrollable`] itself. +    /// +    /// This is useful if you want to override the default alignment given by +    /// the parent container. +    /// +    /// [`Scrollable`]: struct.Scrollable.html +    pub fn align_self(mut self, align: Align) -> Self { +        self.align_self = Some(align); +        self +    } + +    /// Sets the horizontal alignment of the contents of the [`Scrollable`] . +    /// +    /// [`Scrollable`]: struct.Scrollable.html +    pub fn align_items(mut self, align_items: Align) -> Self { +        self.content = self.content.align_items(align_items); +        self +    } + +    /// Adds an element to the [`Scrollable`]. +    /// +    /// [`Scrollable`]: struct.Scrollable.html +    pub fn push<E>(mut self, child: E) -> Scrollable<'a, Element> +    where +        E: Into<Element>, +    { +        self.content = self.content.push(child); +        self +    } +} + +#[derive(Debug, Clone, Copy, Default)] +pub struct State { +    pub scrollbar_grabbed_at: Option<Point>, +    offset: u32, +} + +impl State { +    pub fn new() -> Self { +        State::default() +    } + +    pub fn scroll( +        &mut self, +        delta_y: f32, +        bounds: Rectangle, +        content_bounds: Rectangle, +    ) { +        if bounds.height >= content_bounds.height { +            return; +        } + +        self.offset = (self.offset as i32 - delta_y.round() as i32) +            .max(0) +            .min((content_bounds.height - bounds.height) as i32) +            as u32; +    } + +    pub fn scroll_to( +        &mut self, +        percentage: f32, +        bounds: Rectangle, +        content_bounds: Rectangle, +    ) { +        self.offset = ((content_bounds.height - bounds.height) * percentage) +            .max(0.0) as u32; +    } + +    pub fn offset(&self, bounds: Rectangle, content_bounds: Rectangle) -> u32 { +        let hidden_content = +            (content_bounds.height - bounds.height).round() as u32; + +        self.offset.min(hidden_content).max(0) +    } + +    pub fn is_scrollbar_grabbed(&self) -> bool { +        self.scrollbar_grabbed_at.is_some() +    } +} | 
