fission_core/ui/widgets/
focus_scope.rs1use crate::lowering::{LoweringContext, NodeBuilder, wrap_zstack_child};
2use crate::ui::traits::Lower;
3use crate::ui::Node;
4use fission_ir::{NodeId, Op, Semantics, semantics::Role};
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct FocusScope {
9 pub id: Option<NodeId>,
10 pub children: Vec<Node>,
11 pub is_barrier: bool,
12}
13
14impl Default for FocusScope {
15 fn default() -> Self {
16 Self {
17 id: None,
18 children: Vec::new(),
19 is_barrier: false,
20 }
21 }
22}
23
24impl FocusScope {
25 pub fn into_node(self) -> Node {
26 Node::FocusScope(self)
27 }
28}
29
30impl Lower for FocusScope {
31 fn lower(&self, cx: &mut LoweringContext) -> NodeId {
32 let id = self.id.unwrap_or_else(|| cx.next_node_id());
33
34 cx.push_scope(id);
35 let mut child_ids = Vec::new();
36 for child in &self.children {
37 child_ids.push(child.lower(cx));
38 }
39 cx.pop_scope();
40
41 let layout_id = cx.next_node_id();
43 cx.push_scope(layout_id);
44 let mut wrapped_children = Vec::with_capacity(child_ids.len());
45 for cid in child_ids {
46 wrapped_children.push(wrap_zstack_child(cx, cid));
47 }
48 cx.pop_scope();
49
50 let mut layout_builder = NodeBuilder::new(layout_id, Op::Layout(fission_ir::LayoutOp::ZStack));
51 for cid in wrapped_children {
52 layout_builder.add_child(cid);
53 }
54 let layout_id = layout_builder.build(cx);
55
56 let semantics = Semantics {
57 role: Role::Generic,
58 label: None,
59 value: None,
60 actions: Default::default(),
61 focusable: false,
62 multiline: false,
63 masked: false,
64 input_mask: None,
65 ime_preedit_range: None,
66 checked: None,
67 disabled: false,
68 draggable: false,
69 scrollable_x: false,
70 scrollable_y: false,
71 min_value: None,
72 max_value: None,
73 current_value: None,
74 is_focus_scope: true,
75 is_focus_barrier: self.is_barrier,
76 drag_payload: None,
77 hero_tag: None,
78 focus_index: None, capture_tab: false, auto_indent: false,
79 };
80
81 let mut node = NodeBuilder::new(id, Op::Semantics(semantics));
82 node.add_child(layout_id);
83 node.build(cx)
84 }
85}