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