fission_core/ui/widgets/
row.rs1use crate::{Lower, LoweringContext, Node, NodeBuilder};
2use fission_ir::{FlexDirection, LayoutOp, NodeId, Op, Semantics};
3use fission_ir::op::{FlexWrap, AlignItems, JustifyContent};
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct Row {
28 pub id: Option<NodeId>,
30 pub children: Vec<Node>,
32 pub semantics: Option<Semantics>,
34 pub flex_grow: f32,
36 pub flex_shrink: f32,
38 pub gap: Option<f32>,
40 pub wrap: FlexWrap,
42 pub align_items: AlignItems,
44 pub justify_content: JustifyContent,
46}
47
48impl Default for Row {
49 fn default() -> Self {
50 Self {
51 id: None,
52 children: Vec::new(),
53 semantics: None,
54 flex_grow: 0.0,
55 flex_shrink: 1.0,
56 gap: None,
57 wrap: FlexWrap::NoWrap,
58 align_items: AlignItems::Center,
59 justify_content: JustifyContent::Start,
60 }
61 }
62}
63
64impl Row {
65 pub fn children(mut self, children: Vec<Node>) -> Self {
66 self.children = children;
67 self
68 }
69
70 pub fn flex_grow(mut self, flex_grow: f32) -> Self {
71 self.flex_grow = flex_grow;
72 self
73 }
74
75 pub fn gap(mut self, gap: f32) -> Self {
76 self.gap = Some(gap);
77 self
78 }
79
80 pub fn align_items(mut self, align: AlignItems) -> Self {
81 self.align_items = align;
82 self
83 }
84
85 pub fn justify_content(mut self, justify: JustifyContent) -> Self {
86 self.justify_content = justify;
87 self
88 }
89
90 pub fn into_node(self) -> Node {
91 Node::Row(self)
92 }
93}
94
95impl Lower for Row {
96 fn lower(&self, cx: &mut LoweringContext) -> NodeId {
97 let layout_id = self.id.unwrap_or_else(|| cx.next_node_id());
98
99 cx.push_scope(layout_id);
100
101 let mut builder = NodeBuilder::new(
102 layout_id,
103 Op::Layout(LayoutOp::Flex {
104 direction: FlexDirection::Row,
105 wrap: self.wrap,
106 flex_grow: self.flex_grow,
107 flex_shrink: self.flex_shrink,
108 padding: [0.0; 4],
109 gap: self.gap,
110 align_items: self.align_items,
111 justify_content: self.justify_content,
112 }),
113 );
114 for child in &self.children {
115 builder.add_child(child.lower(cx));
116 }
117
118 cx.pop_scope();
119
120 let layout_id = builder.build(cx);
121
122 if let Some(s) = &self.semantics {
123 let mut semantics_builder =
124 NodeBuilder::new(cx.next_node_id(), Op::Semantics(s.clone()));
125 semantics_builder.add_child(layout_id);
126 return semantics_builder.build(cx);
127 }
128
129 layout_id
130 }
131}