raui_core/widget/component/
image_box.rs

1use crate::{
2    PropsData,
3    widget::{
4        component::WidgetAlpha,
5        context::WidgetContext,
6        node::WidgetNode,
7        unit::image::{
8            ImageBoxAspectRatio, ImageBoxColor, ImageBoxImage, ImageBoxMaterial, ImageBoxNode,
9            ImageBoxSizeValue,
10        },
11        utils::{Color, Transform},
12    },
13};
14use serde::{Deserialize, Serialize};
15
16#[derive(PropsData, Debug, Default, Clone, Serialize, Deserialize)]
17#[props_data(crate::props::PropsData)]
18#[prefab(crate::Prefab)]
19pub struct ImageBoxProps {
20    #[serde(default)]
21    pub width: ImageBoxSizeValue,
22    #[serde(default)]
23    pub height: ImageBoxSizeValue,
24    #[serde(default)]
25    #[serde(skip_serializing_if = "Option::is_none")]
26    pub content_keep_aspect_ratio: Option<ImageBoxAspectRatio>,
27    #[serde(default)]
28    pub material: ImageBoxMaterial,
29    #[serde(default)]
30    pub transform: Transform,
31}
32
33impl ImageBoxProps {
34    pub fn colored(color: Color) -> Self {
35        Self {
36            material: ImageBoxMaterial::Color(ImageBoxColor {
37                color,
38                ..Default::default()
39            }),
40            ..Default::default()
41        }
42    }
43
44    pub fn image(id: impl ToString) -> Self {
45        Self {
46            material: ImageBoxMaterial::Image(ImageBoxImage {
47                id: id.to_string(),
48                ..Default::default()
49            }),
50            ..Default::default()
51        }
52    }
53
54    pub fn image_aspect_ratio(id: impl ToString, outside: bool) -> Self {
55        Self {
56            material: ImageBoxMaterial::Image(ImageBoxImage {
57                id: id.to_string(),
58                ..Default::default()
59            }),
60            content_keep_aspect_ratio: Some(ImageBoxAspectRatio {
61                horizontal_alignment: 0.5,
62                vertical_alignment: 0.5,
63                outside,
64            }),
65            ..Default::default()
66        }
67    }
68}
69
70pub fn image_box(context: WidgetContext) -> WidgetNode {
71    let WidgetContext {
72        id,
73        props,
74        shared_props,
75        ..
76    } = context;
77
78    let ImageBoxProps {
79        width,
80        height,
81        content_keep_aspect_ratio,
82        mut material,
83        transform,
84    } = props.read_cloned_or_default();
85
86    let alpha = shared_props.read_cloned_or_default::<WidgetAlpha>().0;
87    match &mut material {
88        ImageBoxMaterial::Color(image) => {
89            image.color.a *= alpha;
90        }
91        ImageBoxMaterial::Image(image) => {
92            image.tint.a *= alpha;
93        }
94        _ => {}
95    }
96
97    ImageBoxNode {
98        id: id.to_owned(),
99        props: props.clone(),
100        width,
101        height,
102        content_keep_aspect_ratio,
103        material,
104        transform,
105    }
106    .into()
107}