raui_material/component/containers/
scroll_paper.rs

1use 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}