diff options
Diffstat (limited to 'examples/scrollable')
| -rw-r--r-- | examples/scrollable/Cargo.toml | 9 | ||||
| -rw-r--r-- | examples/scrollable/README.md | 15 | ||||
| -rw-r--r-- | examples/scrollable/screenshot.png | bin | 0 -> 148253 bytes | |||
| -rw-r--r-- | examples/scrollable/src/main.rs | 255 | ||||
| -rw-r--r-- | examples/scrollable/src/style.rs | 190 | 
5 files changed, 469 insertions, 0 deletions
diff --git a/examples/scrollable/Cargo.toml b/examples/scrollable/Cargo.toml new file mode 100644 index 00000000..08502458 --- /dev/null +++ b/examples/scrollable/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "scrollable" +version = "0.1.0" +authors = ["Clark Moody <clark@clarkmoody.com>"] +edition = "2018" +publish = false + +[dependencies] +iced = { path = "../..", features = ["debug"] } diff --git a/examples/scrollable/README.md b/examples/scrollable/README.md new file mode 100644 index 00000000..ed0e31b5 --- /dev/null +++ b/examples/scrollable/README.md @@ -0,0 +1,15 @@ +# Scrollable +An example showcasing the various size and style options for the Scrollable. + +All the example code is located in the __[`main`](src/main.rs)__ file. + +<div align="center"> +  <a href="./screenshot.png"> +    <img src="./screenshot.png" height="640px"> +  </a> +</div> + +You can run it with `cargo run`: +``` +cargo run --package scrollable +``` diff --git a/examples/scrollable/screenshot.png b/examples/scrollable/screenshot.png Binary files differnew file mode 100644 index 00000000..2d800251 --- /dev/null +++ b/examples/scrollable/screenshot.png diff --git a/examples/scrollable/src/main.rs b/examples/scrollable/src/main.rs new file mode 100644 index 00000000..3416b83d --- /dev/null +++ b/examples/scrollable/src/main.rs @@ -0,0 +1,255 @@ +mod style; + +use iced::{ +    button, scrollable, Button, Column, Container, Element, Length, +    ProgressBar, Radio, Row, Rule, Sandbox, Scrollable, Settings, Space, Text, +}; + +pub fn main() -> iced::Result { +    ScrollableDemo::run(Settings::default()) +} + +struct ScrollableDemo { +    theme: style::Theme, +    variants: Vec<Variant>, +} + +#[derive(Debug, Clone)] +enum Message { +    ThemeChanged(style::Theme), +    ScrollToTop(usize), +    ScrollToBottom(usize), +    Scrolled(usize, f32), +} + +impl Sandbox for ScrollableDemo { +    type Message = Message; + +    fn new() -> Self { +        ScrollableDemo { +            theme: Default::default(), +            variants: Variant::all(), +        } +    } + +    fn title(&self) -> String { +        String::from("Scrollable - Iced") +    } + +    fn update(&mut self, message: Message) { +        match message { +            Message::ThemeChanged(theme) => self.theme = theme, +            Message::ScrollToTop(i) => { +                if let Some(variant) = self.variants.get_mut(i) { +                    variant.scrollable.snap_to(0.0); + +                    variant.latest_offset = 0.0; +                } +            } +            Message::ScrollToBottom(i) => { +                if let Some(variant) = self.variants.get_mut(i) { +                    variant.scrollable.snap_to(1.0); + +                    variant.latest_offset = 1.0; +                } +            } +            Message::Scrolled(i, offset) => { +                if let Some(variant) = self.variants.get_mut(i) { +                    variant.latest_offset = offset; +                } +            } +        } +    } + +    fn view(&mut self) -> Element<Message> { +        let ScrollableDemo { +            theme, variants, .. +        } = self; + +        let choose_theme = style::Theme::ALL.iter().fold( +            Column::new().spacing(10).push(Text::new("Choose a theme:")), +            |column, option| { +                column.push( +                    Radio::new( +                        *option, +                        &format!("{:?}", option), +                        Some(*theme), +                        Message::ThemeChanged, +                    ) +                    .style(*theme), +                ) +            }, +        ); + +        let scrollable_row = Row::with_children( +            variants +                .iter_mut() +                .enumerate() +                .map(|(i, variant)| { +                    let mut scrollable = +                        Scrollable::new(&mut variant.scrollable) +                            .padding(10) +                            .spacing(10) +                            .width(Length::Fill) +                            .height(Length::Fill) +                            .on_scroll(move |offset| { +                                Message::Scrolled(i, offset) +                            }) +                            .style(*theme) +                            .push(Text::new(variant.title)) +                            .push( +                                Button::new( +                                    &mut variant.scroll_to_bottom, +                                    Text::new("Scroll to bottom"), +                                ) +                                .width(Length::Fill) +                                .padding(10) +                                .on_press(Message::ScrollToBottom(i)), +                            ); + +                    if let Some(scrollbar_width) = variant.scrollbar_width { +                        scrollable = scrollable +                            .scrollbar_width(scrollbar_width) +                            .push(Text::new(format!( +                                "scrollbar_width: {:?}", +                                scrollbar_width +                            ))); +                    } + +                    if let Some(scrollbar_margin) = variant.scrollbar_margin { +                        scrollable = scrollable +                            .scrollbar_margin(scrollbar_margin) +                            .push(Text::new(format!( +                                "scrollbar_margin: {:?}", +                                scrollbar_margin +                            ))); +                    } + +                    if let Some(scroller_width) = variant.scroller_width { +                        scrollable = scrollable +                            .scroller_width(scroller_width) +                            .push(Text::new(format!( +                                "scroller_width: {:?}", +                                scroller_width +                            ))); +                    } + +                    scrollable = scrollable +                        .push(Space::with_height(Length::Units(100))) +                        .push(Text::new( +                            "Some content that should wrap within the \ +                            scrollable. Let's output a lot of short words, so \ +                            that we'll make sure to see how wrapping works \ +                            with these scrollbars.", +                        )) +                        .push(Space::with_height(Length::Units(1200))) +                        .push(Text::new("Middle")) +                        .push(Space::with_height(Length::Units(1200))) +                        .push(Text::new("The End.")) +                        .push( +                            Button::new( +                                &mut variant.scroll_to_top, +                                Text::new("Scroll to top"), +                            ) +                            .width(Length::Fill) +                            .padding(10) +                            .on_press(Message::ScrollToTop(i)), +                        ); + +                    Column::new() +                        .width(Length::Fill) +                        .height(Length::Fill) +                        .spacing(10) +                        .push( +                            Container::new(scrollable) +                                .width(Length::Fill) +                                .height(Length::Fill) +                                .style(*theme), +                        ) +                        .push(ProgressBar::new( +                            0.0..=1.0, +                            variant.latest_offset, +                        )) +                        .into() +                }) +                .collect(), +        ) +        .spacing(20) +        .width(Length::Fill) +        .height(Length::Fill); + +        let content = Column::new() +            .spacing(20) +            .padding(20) +            .push(choose_theme) +            .push(Rule::horizontal(20).style(self.theme)) +            .push(scrollable_row); + +        Container::new(content) +            .width(Length::Fill) +            .height(Length::Fill) +            .center_x() +            .center_y() +            .style(self.theme) +            .into() +    } +} + +/// A version of a scrollable +struct Variant { +    title: &'static str, +    scrollable: scrollable::State, +    scroll_to_top: button::State, +    scroll_to_bottom: button::State, +    scrollbar_width: Option<u16>, +    scrollbar_margin: Option<u16>, +    scroller_width: Option<u16>, +    latest_offset: f32, +} + +impl Variant { +    pub fn all() -> Vec<Self> { +        vec![ +            Self { +                title: "Default Scrollbar", +                scrollable: scrollable::State::new(), +                scroll_to_top: button::State::new(), +                scroll_to_bottom: button::State::new(), +                scrollbar_width: None, +                scrollbar_margin: None, +                scroller_width: None, +                latest_offset: 0.0, +            }, +            Self { +                title: "Slimmed & Margin", +                scrollable: scrollable::State::new(), +                scroll_to_top: button::State::new(), +                scroll_to_bottom: button::State::new(), +                scrollbar_width: Some(4), +                scrollbar_margin: Some(3), +                scroller_width: Some(4), +                latest_offset: 0.0, +            }, +            Self { +                title: "Wide Scroller", +                scrollable: scrollable::State::new(), +                scroll_to_top: button::State::new(), +                scroll_to_bottom: button::State::new(), +                scrollbar_width: Some(4), +                scrollbar_margin: None, +                scroller_width: Some(10), +                latest_offset: 0.0, +            }, +            Self { +                title: "Narrow Scroller", +                scrollable: scrollable::State::new(), +                scroll_to_top: button::State::new(), +                scroll_to_bottom: button::State::new(), +                scrollbar_width: Some(10), +                scrollbar_margin: None, +                scroller_width: Some(4), +                latest_offset: 0.0, +            }, +        ] +    } +} diff --git a/examples/scrollable/src/style.rs b/examples/scrollable/src/style.rs new file mode 100644 index 00000000..ae449141 --- /dev/null +++ b/examples/scrollable/src/style.rs @@ -0,0 +1,190 @@ +use iced::{container, radio, rule, scrollable}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Theme { +    Light, +    Dark, +} + +impl Theme { +    pub const ALL: [Theme; 2] = [Theme::Light, Theme::Dark]; +} + +impl Default for Theme { +    fn default() -> Theme { +        Theme::Light +    } +} + +impl From<Theme> for Box<dyn container::StyleSheet> { +    fn from(theme: Theme) -> Self { +        match theme { +            Theme::Light => Default::default(), +            Theme::Dark => dark::Container.into(), +        } +    } +} + +impl From<Theme> for Box<dyn radio::StyleSheet> { +    fn from(theme: Theme) -> Self { +        match theme { +            Theme::Light => Default::default(), +            Theme::Dark => dark::Radio.into(), +        } +    } +} + +impl From<Theme> for Box<dyn scrollable::StyleSheet> { +    fn from(theme: Theme) -> Self { +        match theme { +            Theme::Light => Default::default(), +            Theme::Dark => dark::Scrollable.into(), +        } +    } +} + +impl From<Theme> for Box<dyn rule::StyleSheet> { +    fn from(theme: Theme) -> Self { +        match theme { +            Theme::Light => Default::default(), +            Theme::Dark => dark::Rule.into(), +        } +    } +} + +mod dark { +    use iced::{container, radio, rule, scrollable, Color}; + +    const BACKGROUND: Color = Color::from_rgb( +        0x36 as f32 / 255.0, +        0x39 as f32 / 255.0, +        0x3F as f32 / 255.0, +    ); + +    const SURFACE: Color = Color::from_rgb( +        0x40 as f32 / 255.0, +        0x44 as f32 / 255.0, +        0x4B as f32 / 255.0, +    ); + +    const ACCENT: Color = Color::from_rgb( +        0x6F as f32 / 255.0, +        0xFF as f32 / 255.0, +        0xE9 as f32 / 255.0, +    ); + +    const ACTIVE: Color = Color::from_rgb( +        0x72 as f32 / 255.0, +        0x89 as f32 / 255.0, +        0xDA as f32 / 255.0, +    ); + +    const SCROLLBAR: Color = Color::from_rgb( +        0x2E as f32 / 255.0, +        0x33 as f32 / 255.0, +        0x38 as f32 / 255.0, +    ); + +    const SCROLLER: Color = Color::from_rgb( +        0x20 as f32 / 255.0, +        0x22 as f32 / 255.0, +        0x25 as f32 / 255.0, +    ); + +    pub struct Container; + +    impl container::StyleSheet for Container { +        fn style(&self) -> container::Style { +            container::Style { +                background: Color { +                    a: 0.99, +                    ..BACKGROUND +                } +                .into(), +                text_color: Color::WHITE.into(), +                ..container::Style::default() +            } +        } +    } + +    pub struct Radio; + +    impl radio::StyleSheet for Radio { +        fn active(&self) -> radio::Style { +            radio::Style { +                background: SURFACE.into(), +                dot_color: ACTIVE, +                border_width: 1.0, +                border_color: ACTIVE, +            } +        } + +        fn hovered(&self) -> radio::Style { +            radio::Style { +                background: Color { a: 0.5, ..SURFACE }.into(), +                ..self.active() +            } +        } +    } + +    pub struct Scrollable; + +    impl scrollable::StyleSheet for Scrollable { +        fn active(&self) -> scrollable::Scrollbar { +            scrollable::Scrollbar { +                background: Color { +                    a: 0.8, +                    ..SCROLLBAR +                } +                .into(), +                border_radius: 2.0, +                border_width: 0.0, +                border_color: Color::TRANSPARENT, +                scroller: scrollable::Scroller { +                    color: Color { a: 0.7, ..SCROLLER }, +                    border_radius: 2.0, +                    border_width: 0.0, +                    border_color: Color::TRANSPARENT, +                }, +            } +        } + +        fn hovered(&self) -> scrollable::Scrollbar { +            let active = self.active(); + +            scrollable::Scrollbar { +                background: SCROLLBAR.into(), +                scroller: scrollable::Scroller { +                    color: SCROLLER, +                    ..active.scroller +                }, +                ..active +            } +        } + +        fn dragging(&self) -> scrollable::Scrollbar { +            let hovered = self.hovered(); + +            scrollable::Scrollbar { +                scroller: scrollable::Scroller { +                    color: ACCENT, +                    ..hovered.scroller +                }, +                ..hovered +            } +        } +    } + +    pub struct Rule; + +    impl rule::StyleSheet for Rule { +        fn style(&self) -> rule::Style { +            rule::Style { +                color: SURFACE, +                width: 2, +                radius: 1.0, +                fill_mode: rule::FillMode::Percent(30.0), +            } +        } +    } +}  | 
