raui_material/component/
icon_paper.rs1use 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}