raui_core/widget/component/containers/
context_box.rs1use crate::{
2 PropsData, make_widget, pre_hooks, unpack_named_slots,
3 widget::{
4 component::containers::{
5 anchor_box::{AnchorProps, PivotBoxProps, pivot_to_anchor_and_align, use_anchor_box},
6 content_box::content_box,
7 portal_box::{portal_box, use_portals_container_relative_layout},
8 },
9 context::WidgetContext,
10 node::WidgetNode,
11 unit::{area::AreaBoxNode, content::ContentBoxItemLayout},
12 utils::{Rect, Vec2},
13 },
14};
15use serde::{Deserialize, Serialize};
16
17#[derive(PropsData, Debug, Default, Copy, Clone, Serialize, Deserialize)]
18#[props_data(crate::props::PropsData)]
19#[prefab(crate::Prefab)]
20pub struct ContextBoxProps {
21 #[serde(default)]
22 pub show: bool,
23}
24
25#[pre_hooks(use_anchor_box)]
26pub fn context_box(mut context: WidgetContext) -> WidgetNode {
27 let WidgetContext {
28 id,
29 idref,
30 key,
31 props,
32 state,
33 named_slots,
34 ..
35 } = context;
36 unpack_named_slots!(named_slots => {content, context, backdrop});
37
38 let ContextBoxProps { show } = props.read_cloned_or_default();
39 let anchor_state = state.read_cloned_or_default::<AnchorProps>();
40 let pivot_props = props.read_cloned_or_default::<PivotBoxProps>();
41 let (Vec2 { x, y }, align) = pivot_to_anchor_and_align(&pivot_props, &anchor_state);
42
43 let context = if show {
44 context.remap_props(|content_props| {
45 let mut item_props = content_props.read_cloned_or_default::<ContentBoxItemLayout>();
46 item_props.anchors = Rect {
47 left: x,
48 right: x,
49 top: y,
50 bottom: y,
51 };
52 item_props.align = align;
53 content_props.with(item_props)
54 });
55
56 make_widget!(portal_box)
57 .named_slot(
58 "content",
59 make_widget!(content_box)
60 .key("content")
61 .listed_slot(backdrop)
62 .listed_slot(context),
63 )
64 .into()
65 } else {
66 WidgetNode::default()
67 };
68
69 let content = make_widget!(content_box)
70 .key(key)
71 .maybe_idref(idref.cloned())
72 .merge_props(props.clone())
73 .listed_slot(content)
74 .listed_slot(context)
75 .into();
76
77 AreaBoxNode {
78 id: id.to_owned(),
79 slot: Box::new(content),
80 }
81 .into()
82}
83
84#[pre_hooks(use_portals_container_relative_layout)]
85pub fn portals_context_box(mut context: WidgetContext) -> WidgetNode {
86 context_box(context)
87}