raui_material/component/containers/
scroll_paper.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
use crate::{
    component::containers::paper::paper,
    theme::{ThemeColor, ThemeProps, ThemedImageMaterial, ThemedWidgetProps},
};
use raui_core::prelude::*;
use serde::{Deserialize, Serialize};

#[derive(PropsData, Debug, Clone, Serialize, Deserialize)]
#[props_data(raui_core::props::PropsData)]
#[prefab(raui_core::Prefab)]
pub struct SideScrollbarsPaperProps {
    #[serde(default)]
    pub size: Scalar,
    #[serde(default)]
    pub back_variant: Option<String>,
    #[serde(default)]
    pub front_variant: String,
}

impl Default for SideScrollbarsPaperProps {
    fn default() -> Self {
        Self {
            size: 10.0,
            back_variant: None,
            front_variant: Default::default(),
        }
    }
}

pub fn scroll_paper(context: WidgetContext) -> WidgetNode {
    let WidgetContext {
        idref,
        key,
        props,
        named_slots,
        ..
    } = context;
    unpack_named_slots!(named_slots => {content, scrollbars});

    let inner_props = props.clone().without::<ContentBoxItemLayout>();

    make_widget!(paper)
        .key(key)
        .maybe_idref(idref.cloned())
        .merge_props(props.clone())
        .listed_slot(
            make_widget!(nav_scroll_box)
                .key("scroll")
                .merge_props(inner_props)
                .named_slot("content", content)
                .named_slot("scrollbars", scrollbars),
        )
        .into()
}

pub fn scroll_paper_side_scrollbars(context: WidgetContext) -> WidgetNode {
    let WidgetContext {
        idref,
        key,
        props,
        shared_props,
        ..
    } = context;

    let scrollbars_props = props.read_cloned_or_default::<SideScrollbarsPaperProps>();
    let themed_props = props.read_cloned_or_default::<ThemedWidgetProps>();
    let colors =
        shared_props.map_or_default::<ThemeProps, _, _>(|props| props.active_colors.clone());

    let back_material = if let Some(back_variant) = &scrollbars_props.back_variant {
        let background = shared_props.map_or_default::<ThemeProps, _, _>(|props| {
            props
                .button_backgrounds
                .get(back_variant)
                .cloned()
                .unwrap_or_default()
                .default
        });
        Some(match background {
            ThemedImageMaterial::Color => {
                let color = match themed_props.color {
                    ThemeColor::Default => colors.main.default.main,
                    ThemeColor::Primary => colors.main.primary.main,
                    ThemeColor::Secondary => colors.main.secondary.main,
                };
                ImageBoxMaterial::Color(ImageBoxColor {
                    color,
                    ..Default::default()
                })
            }
            ThemedImageMaterial::Image(material) => ImageBoxMaterial::Image(material),
            ThemedImageMaterial::Procedural(material) => ImageBoxMaterial::Procedural(material),
        })
    } else {
        None
    };

    let front_material = {
        let background = shared_props.map_or_default::<ThemeProps, _, _>(|props| {
            props
                .button_backgrounds
                .get(&scrollbars_props.front_variant)
                .cloned()
                .unwrap_or_default()
                .trigger
        });
        match background {
            ThemedImageMaterial::Color => {
                let color = match themed_props.color {
                    ThemeColor::Default => colors.main.default.main,
                    ThemeColor::Primary => colors.main.primary.main,
                    ThemeColor::Secondary => colors.main.secondary.main,
                };
                ImageBoxMaterial::Color(ImageBoxColor {
                    color,
                    ..Default::default()
                })
            }
            ThemedImageMaterial::Image(material) => ImageBoxMaterial::Image(material),
            ThemedImageMaterial::Procedural(material) => ImageBoxMaterial::Procedural(material),
        }
    };

    props.write(SideScrollbarsProps {
        size: scrollbars_props.size,
        back_material,
        front_material,
    });

    make_widget!(nav_scroll_box_side_scrollbars)
        .key(key)
        .maybe_idref(idref.cloned())
        .merge_props(props.clone())
        .into()
}