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