fission_core/ui/widgets/
overlay.rs1use crate::internal::InternalLower;
2use crate::lowering::{wrap_zstack_child, InternalIrBuilder, InternalLoweringCx};
3use crate::ui::{Text, TextContent, Widget};
4use fission_ir::{LayoutOp, Op, WidgetId};
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
22pub struct Overlay {
23 pub id: Option<WidgetId>,
25 pub content: Widget,
27 pub overlay: Widget,
29}
30
31impl Overlay {}
32
33impl Default for Overlay {
34 fn default() -> Self {
35 Self {
36 id: None,
37 content: Text {
38 content: TextContent::Literal("".into()),
39 ..Default::default()
40 }
41 .into(),
42 overlay: Text {
43 content: TextContent::Literal("".into()),
44 ..Default::default()
45 }
46 .into(),
47 }
48 }
49}
50
51impl InternalLower for Overlay {
52 fn lower(&self, cx: &mut InternalLoweringCx) -> WidgetId {
53 let id = self.id.map(Into::into).unwrap_or_else(|| cx.next_node_id());
54
55 cx.push_scope(id);
56
57 let overlay_scope = cx.next_node_id();
60 cx.push_scope(overlay_scope);
61 let overlay_child_id = self.overlay.lower(cx);
62 cx.pop_scope();
63 let mut overlay_fill =
64 InternalIrBuilder::new(cx.next_node_id(), Op::Layout(LayoutOp::AbsoluteFill));
65 overlay_fill.add_child(overlay_child_id);
66 let overlay_fill_id = overlay_fill.build(cx);
67
68 let stack_id = cx.next_node_id();
70 let content_id = self.content.lower(cx);
71 cx.push_scope(stack_id);
72 let content_wrapped = wrap_zstack_child(cx, content_id);
73 let overlay_wrapped = wrap_zstack_child(cx, overlay_fill_id);
74 cx.pop_scope();
75
76 let mut stack = InternalIrBuilder::new(stack_id, Op::Layout(LayoutOp::ZStack));
77 stack.add_child(content_wrapped);
78 stack.add_child(overlay_wrapped);
79 let stack_id = stack.build(cx);
80
81 let mut stack_wrapper = InternalIrBuilder::new(
84 cx.next_node_id(),
85 Op::Layout(LayoutOp::Box {
86 width: None,
87 height: None,
88 min_width: None,
89 max_width: None,
90 min_height: None,
91 max_height: None,
92 padding: [0.0; 4],
93 flex_grow: 1.0,
94 flex_shrink: 1.0,
95 aspect_ratio: None,
96 }),
97 );
98 stack_wrapper.add_child(stack_id);
99 let stack_wrapper_id = stack_wrapper.build(cx);
100
101 let mut root = InternalIrBuilder::new(
104 id,
105 Op::Layout(LayoutOp::Flex {
106 direction: fission_ir::FlexDirection::Column,
107 wrap: fission_ir::FlexWrap::NoWrap,
108 flex_grow: 1.0,
109 flex_shrink: 1.0,
110 padding: [0.0; 4],
111 gap: None,
112 align_items: fission_ir::op::AlignItems::Stretch,
113 justify_content: fission_ir::op::JustifyContent::Start,
114 }),
115 );
116 root.add_child(stack_wrapper_id);
117
118 cx.pop_scope();
119
120 root.build(cx)
121 }
122}