fission_core/ui/widgets/
focus_scope.rs1use crate::internal::InternalLower;
2use crate::lowering::{wrap_zstack_child, InternalIrBuilder, InternalLoweringCx};
3use crate::ui::Widget;
4use fission_ir::{semantics::Role, Op, Semantics, WidgetId};
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct FocusScope {
9 pub id: Option<WidgetId>,
10 pub children: Vec<Widget>,
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
26impl InternalLower for FocusScope {
27 fn lower(&self, cx: &mut InternalLoweringCx) -> WidgetId {
28 let id = self.id.map(Into::into).unwrap_or_else(|| cx.next_node_id());
29
30 cx.push_scope(id);
31 let mut child_ids = Vec::new();
32 for child in &self.children {
33 child_ids.push(child.lower(cx));
34 }
35 cx.pop_scope();
36
37 let layout_id = cx.next_node_id();
39 cx.push_scope(layout_id);
40 let mut wrapped_children = Vec::with_capacity(child_ids.len());
41 for cid in child_ids {
42 wrapped_children.push(wrap_zstack_child(cx, cid));
43 }
44 cx.pop_scope();
45
46 let mut layout_builder =
47 InternalIrBuilder::new(layout_id, Op::Layout(fission_ir::LayoutOp::ZStack));
48 for cid in wrapped_children {
49 layout_builder.add_child(cid);
50 }
51 let layout_id = layout_builder.build(cx);
52
53 let semantics = Semantics {
54 role: Role::Generic,
55 label: None,
56 identifier: None,
57 value: None,
58 actions: Default::default(),
59 action_scope_id: None,
60 focusable: false,
61 multiline: false,
62 masked: false,
63 input_mask: None,
64 ime_preedit_range: None,
65 checked: None,
66 disabled: false,
67 read_only: false,
68 autofocus: false,
69 draggable: false,
70 scrollable_x: false,
71 scrollable_y: false,
72 min_value: None,
73 max_value: None,
74 current_value: None,
75 is_focus_scope: true,
76 is_focus_barrier: self.is_barrier,
77 drag_payload: None,
78 hero_tag: None,
79 focus_index: None,
80 text_input_type: fission_ir::semantics::TextInputType::Text,
81 text_input_action: fission_ir::semantics::TextInputAction::Done,
82 text_capitalization: fission_ir::semantics::TextCapitalization::None,
83 max_length: None,
84 max_length_enforcement: fission_ir::semantics::MaxLengthEnforcement::Enforced,
85 input_formatters: Vec::new(),
86 autocorrect: true,
87 enable_suggestions: true,
88 spell_check: true,
89 smart_dashes: true,
90 smart_quotes: true,
91 autofill_hints: Vec::new(),
92 scroll_padding: None,
93 capture_tab: false,
94 auto_indent: false,
95 };
96
97 let mut node = InternalIrBuilder::new(id, Op::Semantics(semantics));
98 node.add_child(layout_id);
99 node.build(cx)
100 }
101}