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
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 nav_scroll_paper(context: WidgetContext) -> WidgetNode {
    let WidgetContext {
        idref,
        key,
        props,
        named_slots,
        ..
    } = context;
    unpack_named_slots!(named_slots => {content, scrollbars});

    widget! {
        (#{key} | {idref.cloned()} paper: {props.clone()} [
            (#{"scroll"} nav_scroll_box: {props.clone()} {
                content = {content}
                scrollbars = {scrollbars}
            })
        ])
    }
}

pub fn nav_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,
    });

    widget! {
        (#{key} | {idref.cloned()} nav_scroll_box_side_scrollbars: {props.clone()})
    }
}