raui_material/component/containers/
tooltip_paper.rs

1use crate::{
2    component::containers::{paper::PaperProps, wrap_paper::wrap_paper},
3    theme::{ThemeColor, ThemedWidgetProps},
4};
5use raui_core::{
6    PropsData, Scalar, make_widget, unpack_named_slots,
7    widget::{
8        component::containers::{
9            size_box::{SizeBoxProps, size_box},
10            tooltip_box::portals_tooltip_box,
11            wrap_box::WrapBoxProps,
12        },
13        context::WidgetContext,
14        node::WidgetNode,
15        unit::{image::ImageBoxFrame, size::SizeBoxSizeValue},
16        utils::Rect,
17    },
18};
19use serde::{Deserialize, Serialize};
20
21#[derive(PropsData, Debug, Copy, Clone, Serialize, Deserialize)]
22#[props_data(raui_core::props::PropsData)]
23#[prefab(raui_core::Prefab)]
24pub struct TooltipPaperProps {
25    #[serde(default = "TooltipPaperProps::default_margin")]
26    pub margin: Rect,
27    #[serde(default = "TooltipPaperProps::default_frame")]
28    pub frame: Option<Scalar>,
29}
30
31impl Default for TooltipPaperProps {
32    fn default() -> Self {
33        Self {
34            margin: Self::default_margin(),
35            frame: Self::default_frame(),
36        }
37    }
38}
39
40impl TooltipPaperProps {
41    fn default_margin() -> Rect {
42        Rect {
43            left: 10.0,
44            right: 10.0,
45            top: 10.0,
46            bottom: 10.0,
47        }
48    }
49
50    #[allow(clippy::unnecessary_wraps)]
51    fn default_frame() -> Option<Scalar> {
52        Some(2.0)
53    }
54}
55
56pub fn tooltip_paper(context: WidgetContext) -> WidgetNode {
57    let WidgetContext {
58        idref,
59        key,
60        props,
61        named_slots,
62        ..
63    } = context;
64    unpack_named_slots!(named_slots => {content, tooltip});
65
66    let TooltipPaperProps { margin, frame } = props.read_cloned_or_default();
67
68    let size_props = SizeBoxProps {
69        width: SizeBoxSizeValue::Content,
70        height: SizeBoxSizeValue::Content,
71        ..Default::default()
72    };
73    let themed_props = props.read_cloned_or_else(|| ThemedWidgetProps {
74        color: ThemeColor::Primary,
75        ..Default::default()
76    });
77    let paper_props = props.read_cloned_or_else(|| PaperProps {
78        frame: frame.map(|v| ImageBoxFrame::from((v, true))),
79        ..Default::default()
80    });
81    let wrap_props = props
82        .clone()
83        .with(themed_props)
84        .with(paper_props)
85        .with(WrapBoxProps {
86            margin,
87            fill: false,
88        });
89
90    make_widget!(portals_tooltip_box)
91        .key(key)
92        .maybe_idref(idref.cloned())
93        .merge_props(props.clone())
94        .named_slot("content", content)
95        .named_slot(
96            "tooltip",
97            make_widget!(size_box)
98                .key("size")
99                .with_props(size_props)
100                .named_slot(
101                    "content",
102                    make_widget!(wrap_paper)
103                        .key("wrap")
104                        .merge_props(wrap_props)
105                        .named_slot("content", tooltip),
106                ),
107        )
108        .into()
109}