material_ui_rs/design/style/
scrollable.rs1use iced_widget::core::{Background, Border, Shadow, border};
2use iced_widget::scrollable::{AutoScroll, Catalog, Rail, Scroller, Status, Style, StyleFn};
3
4use crate::Theme;
5use crate::style::container::surface_container;
6use crate::utils::{
7 HOVERED_LAYER_OPACITY, PRESSED_LAYER_OPACITY, disabled_container, disabled_text, mix,
8};
9
10impl Catalog for Theme {
11 type Class<'a> = StyleFn<'a, Self>;
12
13 fn default<'a>() -> Self::Class<'a> {
14 Box::new(default)
15 }
16
17 fn style(&self, class: &Self::Class<'_>, status: Status) -> Style {
18 class(self, status)
19 }
20}
21
22pub fn default(theme: &Theme, status: Status) -> Style {
23 let surface = theme.colors().surface;
24
25 let active_rail = Rail {
26 background: None,
27 scroller: Scroller {
28 background: surface.text.into(),
29 border: border::rounded(9999),
30 },
31 border: Border::default(),
32 };
33
34 let disabled_rail = Rail {
35 background: Some(Background::Color(disabled_container(surface.text))),
36 scroller: Scroller {
37 background: disabled_text(surface.text).into(),
38 border: border::rounded(9999),
39 },
40 ..active_rail
41 };
42
43 let active_auto_scroll = AutoScroll {
44 background: surface.color.into(),
45 border: border::rounded(500).width(1).color(surface.text),
46 icon: surface.text,
47 shadow: Shadow::default(),
48 };
49
50 let disabled_auto_scroll = AutoScroll {
51 background: disabled_container(surface.text).into(),
52 border: border::rounded(9999),
53 icon: disabled_text(surface.text),
54 shadow: Shadow::default(),
55 };
56
57 let style = Style {
58 container: surface_container(theme),
59 vertical_rail: active_rail,
60 horizontal_rail: active_rail,
61 gap: None,
62 auto_scroll: active_auto_scroll,
63 };
64
65 match status {
66 Status::Active {
67 is_horizontal_scrollbar_disabled,
68 is_vertical_scrollbar_disabled,
69 } => Style {
70 horizontal_rail: if is_horizontal_scrollbar_disabled {
71 disabled_rail
72 } else {
73 active_rail
74 },
75 vertical_rail: if is_vertical_scrollbar_disabled {
76 disabled_rail
77 } else {
78 active_rail
79 },
80 auto_scroll: if is_vertical_scrollbar_disabled && is_horizontal_scrollbar_disabled {
81 disabled_auto_scroll
82 } else {
83 active_auto_scroll
84 },
85 ..style
86 },
87 Status::Hovered {
88 is_horizontal_scrollbar_hovered,
89 is_vertical_scrollbar_hovered,
90 is_horizontal_scrollbar_disabled,
91 is_vertical_scrollbar_disabled,
92 } => {
93 let hovered_rail = Rail {
94 scroller: Scroller {
95 background: mix(surface.text, surface.color, HOVERED_LAYER_OPACITY).into(),
96 border: border::rounded(9999),
97 },
98 ..active_rail
99 };
100
101 Style {
102 horizontal_rail: if is_horizontal_scrollbar_disabled {
103 disabled_rail
104 } else if is_horizontal_scrollbar_hovered {
105 hovered_rail
106 } else {
107 active_rail
108 },
109 vertical_rail: if is_vertical_scrollbar_disabled {
110 disabled_rail
111 } else if is_vertical_scrollbar_hovered {
112 hovered_rail
113 } else {
114 active_rail
115 },
116 auto_scroll: if is_vertical_scrollbar_disabled && is_horizontal_scrollbar_disabled {
117 disabled_auto_scroll
118 } else {
119 active_auto_scroll
120 },
121 ..style
122 }
123 }
124 Status::Dragged {
125 is_horizontal_scrollbar_dragged,
126 is_vertical_scrollbar_dragged,
127 is_horizontal_scrollbar_disabled,
128 is_vertical_scrollbar_disabled,
129 } => {
130 let dragged_rail = Rail {
131 scroller: Scroller {
132 background: mix(surface.text, surface.color, PRESSED_LAYER_OPACITY).into(),
133 border: border::rounded(9999),
134 },
135 ..active_rail
136 };
137
138 Style {
139 horizontal_rail: if is_horizontal_scrollbar_disabled {
140 disabled_rail
141 } else if is_horizontal_scrollbar_dragged {
142 dragged_rail
143 } else {
144 active_rail
145 },
146 vertical_rail: if is_vertical_scrollbar_disabled {
147 disabled_rail
148 } else if is_vertical_scrollbar_dragged {
149 dragged_rail
150 } else {
151 active_rail
152 },
153 auto_scroll: if is_vertical_scrollbar_disabled && is_horizontal_scrollbar_disabled {
154 disabled_auto_scroll
155 } else {
156 active_auto_scroll
157 },
158 ..style
159 }
160 }
161 }
162}