fission_core/ui/widgets/
grid.rs1use crate::internal::InternalLower;
2use crate::lowering::{InternalIrBuilder, InternalLoweringCx};
3use crate::ui::Widget;
4use fission_ir::{
5 op::{GridPlacement, GridTrack, LayoutOp, Op},
6 WidgetId,
7};
8use serde::{Deserialize, Serialize};
9
10#[derive(Debug, Default, Clone, Serialize, Deserialize)]
34pub struct Grid {
35 pub id: Option<WidgetId>,
37 pub children: Vec<Widget>,
39 pub columns: Vec<GridTrack>,
41 pub rows: Vec<GridTrack>,
43 pub column_gap: Option<f32>,
45 pub row_gap: Option<f32>,
47 pub padding: [f32; 4],
49}
50
51impl Grid {}
52
53impl InternalLower for Grid {
54 fn lower(&self, cx: &mut InternalLoweringCx) -> WidgetId {
55 let id = self.id.map(Into::into).unwrap_or_else(|| cx.next_node_id());
56 cx.push_scope(id);
57
58 let mut builder = InternalIrBuilder::new(
59 id,
60 Op::Layout(LayoutOp::Grid {
61 columns: self.columns.clone(),
62 rows: self.rows.clone(),
63 column_gap: self.column_gap,
64 row_gap: self.row_gap,
65 padding: self.padding,
66 }),
67 );
68
69 for child in &self.children {
70 builder.add_child(child.lower(cx));
71 }
72
73 cx.pop_scope();
74 builder.build(cx)
75 }
76}
77
78#[derive(Debug, Clone, Serialize, Deserialize)]
91pub struct GridItem {
92 pub id: Option<WidgetId>,
94 pub child: Widget,
96 pub row_start: GridPlacement,
98 pub row_end: GridPlacement,
100 pub col_start: GridPlacement,
102 pub col_end: GridPlacement,
104}
105
106impl Default for GridItem {
107 fn default() -> Self {
108 Self {
109 id: None,
110 child: crate::ui::Row::default().into(),
112 row_start: GridPlacement::Auto,
113 row_end: GridPlacement::Auto,
114 col_start: GridPlacement::Auto,
115 col_end: GridPlacement::Auto,
116 }
117 }
118}
119
120impl GridItem {
121 pub fn new(child: impl Into<Widget>) -> Self {
122 Self {
123 child: child.into(),
124 ..Default::default()
125 }
126 }
127
128 pub fn cell(mut self, row: i16, col: i16) -> Self {
129 self.row_start = GridPlacement::Line(row);
130 self.col_start = GridPlacement::Line(col);
131 self
132 }
133
134 pub fn span(mut self, row_span: u16, col_span: u16) -> Self {
135 self.row_end = GridPlacement::Span(row_span);
136 self.col_end = GridPlacement::Span(col_span);
137 self
138 }
139}
140
141impl InternalLower for GridItem {
142 fn lower(&self, cx: &mut InternalLoweringCx) -> WidgetId {
143 let id = self.id.map(Into::into).unwrap_or_else(|| cx.next_node_id());
144 cx.push_scope(id);
145
146 let child_id = self.child.lower(cx);
147
148 cx.pop_scope();
149
150 let mut builder = InternalIrBuilder::new(
151 id,
152 Op::Layout(LayoutOp::GridItem {
153 row_start: self.row_start,
154 row_end: self.row_end,
155 col_start: self.col_start,
156 col_end: self.col_end,
157 }),
158 );
159 builder.add_child(child_id);
160 builder.build(cx)
161 }
162}