summaryrefslogtreecommitdiffstats
path: root/examples/scrollable/src
diff options
context:
space:
mode:
authorLibravatar Clark Moody <clark@clarkmoody.com>2020-10-22 16:10:10 -0500
committerLibravatar Clark Moody <clark@clarkmoody.com>2020-10-22 16:24:54 -0500
commite43a46952ad3b76f76a7050430ec26477c795c4f (patch)
treeb88a768eeeb3b440dc2198ec393115a51963cf7e /examples/scrollable/src
parentf05578c8f88b38cb538657e40c2feb725e72c7d8 (diff)
downloadiced-e43a46952ad3b76f76a7050430ec26477c795c4f.tar.gz
iced-e43a46952ad3b76f76a7050430ec26477c795c4f.tar.bz2
iced-e43a46952ad3b76f76a7050430ec26477c795c4f.zip
Add scrollable example program
Diffstat (limited to 'examples/scrollable/src')
-rw-r--r--examples/scrollable/src/main.rs365
1 files changed, 365 insertions, 0 deletions
diff --git a/examples/scrollable/src/main.rs b/examples/scrollable/src/main.rs
new file mode 100644
index 00000000..da38cd7d
--- /dev/null
+++ b/examples/scrollable/src/main.rs
@@ -0,0 +1,365 @@
+use iced::{
+ scrollable, Column, Container, Element, Length, Radio, Row, Rule, Sandbox,
+ Scrollable, Settings, Space, Text,
+};
+
+pub fn main() -> iced::Result {
+ ScrollableDemo::run(Settings::default())
+}
+
+struct ScrollableDemo {
+ theme: style::Theme,
+ scroll: Vec<scrollable::State>,
+ config: Vec<Config>,
+}
+
+#[derive(Debug, Clone)]
+enum Message {
+ ThemeChanged(style::Theme),
+}
+
+/// Contains configuration for a single scrollbar
+struct Config {
+ top_content: String,
+ scrollbar_width: Option<u16>,
+ scrollbar_margin: Option<u16>,
+ scroller_width: Option<u16>,
+}
+
+fn get_configs() -> Vec<Config> {
+ vec![
+ Config {
+ top_content: "Default Scrollbar".into(),
+ scrollbar_width: None,
+ scrollbar_margin: None,
+ scroller_width: None,
+ },
+ Config {
+ top_content: "Slimmed & Margin".into(),
+ scrollbar_width: Some(4),
+ scrollbar_margin: Some(3),
+ scroller_width: Some(4),
+ },
+ Config {
+ top_content: "Wide Scroller".into(),
+ scrollbar_width: Some(4),
+ scrollbar_margin: None,
+ scroller_width: Some(10),
+ },
+ Config {
+ top_content: "Narrow Scroller".into(),
+ scrollbar_width: Some(10),
+ scrollbar_margin: None,
+ scroller_width: Some(4),
+ },
+ ]
+}
+
+impl Sandbox for ScrollableDemo {
+ type Message = Message;
+
+ fn new() -> Self {
+ let config = get_configs();
+ ScrollableDemo {
+ theme: Default::default(),
+ scroll: vec![scrollable::State::default(); config.len()],
+ config,
+ }
+ }
+
+ fn title(&self) -> String {
+ String::from("Scrollable - Iced")
+ }
+
+ fn update(&mut self, message: Message) {
+ match message {
+ Message::ThemeChanged(theme) => self.theme = theme,
+ }
+ }
+
+ fn view(&mut self) -> Element<Message> {
+ let choose_theme = style::Theme::ALL.iter().fold(
+ Column::new().spacing(10).push(Text::new("Choose a theme:")),
+ |column, theme| {
+ column.push(
+ Radio::new(
+ *theme,
+ &format!("{:?}", theme),
+ Some(self.theme),
+ Message::ThemeChanged,
+ )
+ .style(self.theme),
+ )
+ },
+ );
+
+ let ScrollableDemo { scroll, theme, .. } = self;
+
+ let scrollable_row = Row::with_children(
+ scroll
+ .iter_mut()
+ .zip(self.config.iter())
+ .map(|(state, config)| {
+ let mut scrollable = Scrollable::new(state)
+ .padding(10)
+ .width(Length::Fill)
+ .height(Length::Fill)
+ .style(*theme)
+ .push(Text::new(config.top_content.clone()));
+
+ if let Some(scrollbar_width) = config.scrollbar_width {
+ scrollable = scrollable
+ .scrollbar_width(scrollbar_width)
+ .push(Text::new(format!(
+ "scrollbar_width: {:?}",
+ scrollbar_width
+ )));
+ }
+ if let Some(scrollbar_margin) = config.scrollbar_margin {
+ scrollable = scrollable
+ .scrollbar_margin(scrollbar_margin)
+ .push(Text::new(format!(
+ "scrollbar_margin: {:?}",
+ scrollbar_margin
+ )));
+ }
+ if let Some(scroller_width) = config.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."));
+
+ Container::new(scrollable)
+ .width(Length::Fill)
+ .height(Length::Fill)
+ .style(*theme)
+ .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()
+ }
+}
+
+mod style {
+ 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(
+ 0x0f as f32 / 255.0,
+ 0x14 as f32 / 255.0,
+ 0x19 as f32 / 255.0,
+ );
+
+ const LIGHTER_BACKGROUND: Color = Color::from_rgb(
+ 0x14 as f32 / 255.0,
+ 0x19 as f32 / 255.0,
+ 0x1f as f32 / 255.0,
+ );
+
+ const YELLOW: Color = Color::from_rgb(
+ 0xff as f32 / 255.0,
+ 0xb4 as f32 / 255.0,
+ 0x54 as f32 / 255.0,
+ );
+
+ const CYAN: Color = Color::from_rgb(
+ 0x39 as f32 / 255.0,
+ 0xaf as f32 / 255.0,
+ 0xd7 as f32 / 255.0,
+ );
+
+ const CYAN_LIGHT: Color = Color::from_rgb(
+ 0x5d as f32 / 255.0,
+ 0xb7 as f32 / 255.0,
+ 0xd5 as f32 / 255.0,
+ );
+
+ const ORANGE: Color = Color::from_rgb(
+ 0xff as f32 / 255.0,
+ 0x77 as f32 / 255.0,
+ 0x33 as f32 / 255.0,
+ );
+
+ const ORANGE_DARK: Color = Color::from_rgb(
+ 0xe6 as f32 / 255.0,
+ 0x5b as f32 / 255.0,
+ 0x16 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: BACKGROUND.into(),
+ dot_color: CYAN,
+ border_width: 1,
+ border_color: CYAN,
+ }
+ }
+
+ fn hovered(&self) -> radio::Style {
+ radio::Style {
+ background: LIGHTER_BACKGROUND.into(),
+ ..self.active()
+ }
+ }
+ }
+
+ pub struct Scrollable;
+
+ impl scrollable::StyleSheet for Scrollable {
+ fn active(&self) -> scrollable::Scrollbar {
+ scrollable::Scrollbar {
+ background: CYAN.into(),
+ border_radius: 2,
+ border_width: 0,
+ border_color: Color::TRANSPARENT,
+ scroller: scrollable::Scroller {
+ color: YELLOW,
+ border_radius: 2,
+ border_width: 0,
+ border_color: Color::TRANSPARENT,
+ },
+ }
+ }
+
+ fn hovered(&self) -> scrollable::Scrollbar {
+ let active = self.active();
+
+ scrollable::Scrollbar {
+ background: CYAN_LIGHT.into(),
+ scroller: scrollable::Scroller {
+ color: ORANGE,
+ ..active.scroller
+ },
+ ..active
+ }
+ }
+
+ fn dragging(&self) -> scrollable::Scrollbar {
+ let hovered = self.hovered();
+
+ scrollable::Scrollbar {
+ scroller: scrollable::Scroller {
+ color: ORANGE_DARK,
+ ..hovered.scroller
+ },
+ ..hovered
+ }
+ }
+ }
+
+ pub struct Rule;
+
+ impl rule::StyleSheet for Rule {
+ fn style(&self) -> rule::Style {
+ rule::Style {
+ color: CYAN,
+ width: 2,
+ radius: 1,
+ fill_mode: rule::FillMode::Percent(15.0),
+ }
+ }
+ }
+ }
+}