fission_core/ui/widgets/
column.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)]
28pub struct Column {
29 pub id: Option<WidgetId>,
31 pub children: Vec<Widget>,
33 pub semantics: Option<Semantics>,
35 pub flex_grow: f32,
37 pub flex_shrink: f32,
39 pub gap: Option<f32>,
41 pub wrap: FlexWrap,
43 pub align_items: AlignItems,
45 pub justify_content: JustifyContent,
47}
48
49impl Default for Column {
50 fn default() -> Self {
51 Self {
52 id: None,
53 children: Vec::new(),
54 gap: None,
55 flex_grow: 0.0,
56 flex_shrink: 1.0,
57 semantics: None,
58 wrap: FlexWrap::NoWrap,
59 align_items: AlignItems::Stretch,
60 justify_content: JustifyContent::Start,
61 }
62 }
63}
64
65impl Column {
66 pub fn children(mut self, children: Vec<Widget>) -> Self {
67 self.children = children;
68 self
69 }
70
71 pub fn flex_grow(mut self, flex_grow: f32) -> Self {
72 self.flex_grow = flex_grow;
73 self
74 }
75
76 pub fn gap(mut self, gap: Option<f32>) -> Self {
77 self.gap = gap;
78 self
79 }
80
81 pub fn align_items(mut self, align: AlignItems) -> Self {
82 self.align_items = align;
83 self
84 }
85
86 pub fn justify_content(mut self, justify: JustifyContent) -> Self {
87 self.justify_content = justify;
88 self
89 }
90}
91
92impl InternalLower for Column {
93 fn lower(&self, cx: &mut InternalLoweringCx) -> WidgetId {
94 let layout_id = self.id.map(Into::into).unwrap_or_else(|| cx.next_node_id());
95
96 cx.push_scope(layout_id);
97
98 let mut builder = InternalIrBuilder::new(
99 layout_id,
100 Op::Layout(LayoutOp::Flex {
101 direction: FlexDirection::Column,
102 wrap: self.wrap,
103 flex_grow: self.flex_grow,
104 flex_shrink: self.flex_shrink,
105 padding: [0.0; 4],
106 gap: self.gap,
107 align_items: self.align_items,
108 justify_content: self.justify_content,
109 }),
110 );
111 for child in &self.children {
112 builder.add_child(child.lower(cx));
113 }
114
115 cx.pop_scope();
116
117 let layout_id = builder.build(cx);
118
119 if let Some(s) = &self.semantics {
120 let mut semantics_builder =
121 InternalIrBuilder::new(cx.next_node_id(), Op::Semantics(s.clone()));
122 semantics_builder.add_child(layout_id);
123 return semantics_builder.build(cx);
124 }
125
126 layout_id
127 }
128}