raui_material/component/containers/
scroll_paper.rs1use crate::{
2 component::containers::paper::paper,
3 theme::{ThemeColor, ThemeProps, ThemedImageMaterial, ThemedWidgetProps},
4};
5use raui_core::{
6 PropsData, Scalar, make_widget, unpack_named_slots,
7 widget::{
8 component::containers::scroll_box::{
9 SideScrollbarsProps, nav_scroll_box, nav_scroll_box_side_scrollbars,
10 },
11 context::WidgetContext,
12 node::WidgetNode,
13 unit::{
14 content::ContentBoxItemLayout,
15 image::{ImageBoxColor, ImageBoxMaterial},
16 },
17 },
18};
19use serde::{Deserialize, Serialize};
20
21#[derive(PropsData, Debug, Clone, Serialize, Deserialize)]
22#[props_data(raui_core::props::PropsData)]
23#[prefab(raui_core::Prefab)]
24pub struct SideScrollbarsPaperProps {
25 #[serde(default)]
26 pub size: Scalar,
27 #[serde(default)]
28 pub back_variant: Option<String>,
29 #[serde(default)]
30 pub front_variant: String,
31}
32
33impl Default for SideScrollbarsPaperProps {
34 fn default() -> Self {
35 Self {
36 size: 10.0,
37 back_variant: None,
38 front_variant: Default::default(),
39 }
40 }
41}
42
43pub fn scroll_paper(context: WidgetContext) -> WidgetNode {
44 let WidgetContext {
45 idref,
46 key,
47 props,
48 named_slots,
49 ..
50 } = context;
51 unpack_named_slots!(named_slots => {content, scrollbars});
52
53 let inner_props = props.clone().without::<ContentBoxItemLayout>();
54
55 make_widget!(paper)
56 .key(key)
57 .maybe_idref(idref.cloned())
58 .merge_props(props.clone())
59 .listed_slot(
60 make_widget!(nav_scroll_box)
61 .key("scroll")
62 .merge_props(inner_props)
63 .named_slot("content", content)
64 .named_slot("scrollbars", scrollbars),
65 )
66 .into()
67}
68
69pub fn scroll_paper_side_scrollbars(context: WidgetContext) -> WidgetNode {
70 let WidgetContext {
71 idref,
72 key,
73 props,
74 shared_props,
75 ..
76 } = context;
77
78 let scrollbars_props = props.read_cloned_or_default::<SideScrollbarsPaperProps>();
79 let themed_props = props.read_cloned_or_default::<ThemedWidgetProps>();
80 let colors =
81 shared_props.map_or_default::<ThemeProps, _, _>(|props| props.active_colors.clone());
82
83 let back_material = if let Some(back_variant) = &scrollbars_props.back_variant {
84 let background = shared_props.map_or_default::<ThemeProps, _, _>(|props| {
85 props
86 .button_backgrounds
87 .get(back_variant)
88 .cloned()
89 .unwrap_or_default()
90 .default
91 });
92 Some(match background {
93 ThemedImageMaterial::Color => {
94 let color = match themed_props.color {
95 ThemeColor::Default => colors.main.default.main,
96 ThemeColor::Primary => colors.main.primary.main,
97 ThemeColor::Secondary => colors.main.secondary.main,
98 };
99 ImageBoxMaterial::Color(ImageBoxColor {
100 color,
101 ..Default::default()
102 })
103 }
104 ThemedImageMaterial::Image(material) => ImageBoxMaterial::Image(material),
105 ThemedImageMaterial::Procedural(material) => ImageBoxMaterial::Procedural(material),
106 })
107 } else {
108 None
109 };
110
111 let front_material = {
112 let background = shared_props.map_or_default::<ThemeProps, _, _>(|props| {
113 props
114 .button_backgrounds
115 .get(&scrollbars_props.front_variant)
116 .cloned()
117 .unwrap_or_default()
118 .trigger
119 });
120 match background {
121 ThemedImageMaterial::Color => {
122 let color = match themed_props.color {
123 ThemeColor::Default => colors.main.default.main,
124 ThemeColor::Primary => colors.main.primary.main,
125 ThemeColor::Secondary => colors.main.secondary.main,
126 };
127 ImageBoxMaterial::Color(ImageBoxColor {
128 color,
129 ..Default::default()
130 })
131 }
132 ThemedImageMaterial::Image(material) => ImageBoxMaterial::Image(material),
133 ThemedImageMaterial::Procedural(material) => ImageBoxMaterial::Procedural(material),
134 }
135 };
136
137 props.write(SideScrollbarsProps {
138 size: scrollbars_props.size,
139 back_material,
140 front_material,
141 });
142
143 make_widget!(nav_scroll_box_side_scrollbars)
144 .key(key)
145 .maybe_idref(idref.cloned())
146 .merge_props(props.clone())
147 .into()
148}