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