raui_material/component/
icon_paper.rs

1use crate::theme::{ThemeColor, ThemeProps, ThemedWidgetProps};
2use raui_core::{
3    PropsData, make_widget,
4    widget::{
5        component::image_box::{ImageBoxProps, image_box},
6        context::WidgetContext,
7        node::WidgetNode,
8        unit::image::{
9            ImageBoxAspectRatio, ImageBoxImage, ImageBoxImageScaling, ImageBoxMaterial,
10            ImageBoxSizeValue,
11        },
12        utils::{Rect, Transform},
13    },
14};
15use serde::{Deserialize, Serialize};
16
17#[derive(Debug, Default, Clone, Serialize, Deserialize)]
18pub struct IconImage {
19    #[serde(default)]
20    pub id: String,
21    #[serde(default)]
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub source_rect: Option<Rect>,
24    #[serde(default)]
25    pub scaling: ImageBoxImageScaling,
26}
27
28#[derive(PropsData, Debug, Default, Clone, Serialize, Deserialize)]
29#[props_data(raui_core::props::PropsData)]
30#[prefab(raui_core::Prefab)]
31pub struct IconPaperProps {
32    #[serde(default)]
33    pub image: IconImage,
34    #[serde(default)]
35    pub size_level: usize,
36    #[serde(default)]
37    pub transform: Transform,
38}
39
40pub fn icon_paper(context: WidgetContext) -> WidgetNode {
41    let WidgetContext {
42        idref,
43        key,
44        props,
45        shared_props,
46        ..
47    } = context;
48
49    let themed_props = props.read_cloned_or_default::<ThemedWidgetProps>();
50    let tint = match shared_props.read::<ThemeProps>() {
51        Ok(props) => match themed_props.color {
52            ThemeColor::Default => props.active_colors.contrast.default.main,
53            ThemeColor::Primary => props.active_colors.contrast.primary.main,
54            ThemeColor::Secondary => props.active_colors.contrast.secondary.main,
55        },
56        Err(_) => Default::default(),
57    };
58    let icon_props = props.read_cloned_or_default::<IconPaperProps>();
59    let size = match shared_props.read::<ThemeProps>() {
60        Ok(props) => props
61            .icons_level_sizes
62            .get(icon_props.size_level)
63            .copied()
64            .unwrap_or(24.0),
65        Err(_) => 24.0,
66    };
67    let IconImage {
68        id,
69        source_rect,
70        scaling,
71    } = icon_props.image;
72    let image = ImageBoxImage {
73        id,
74        source_rect,
75        scaling,
76        tint,
77    };
78    let props = ImageBoxProps {
79        width: ImageBoxSizeValue::Exact(size),
80        height: ImageBoxSizeValue::Exact(size),
81        content_keep_aspect_ratio: Some(ImageBoxAspectRatio {
82            horizontal_alignment: 0.5,
83            vertical_alignment: 0.5,
84            outside: false,
85        }),
86        material: ImageBoxMaterial::Image(image),
87        transform: icon_props.transform,
88    };
89
90    make_widget!(image_box)
91        .key(key)
92        .maybe_idref(idref.cloned())
93        .with_props(props)
94        .into()
95}