1use std::sync::Arc;
2
3use crate::builder::LayoutBuilder;
4use crate::error::PaneError;
5use crate::layout::Layout;
6use crate::preset::master_stack::row_style;
7use crate::preset::{collect_kinds, validate_kinds};
8
9pub struct Grid {
11 cols: usize,
12 kinds: Arc<[Arc<str>]>,
13 gap: f32,
14}
15
16impl Grid {
17 pub(crate) fn new(cols: usize, kinds: impl IntoIterator<Item = impl Into<Arc<str>>>) -> Self {
18 Self {
19 cols,
20 kinds: collect_kinds(kinds),
21 gap: 0.0,
22 }
23 }
24
25 pub fn gap(mut self, gap: f32) -> Self {
27 self.gap = gap;
28 self
29 }
30
31 pub fn build(&self) -> Result<Layout, PaneError> {
33 match self.cols {
34 0 => {
35 return Err(PaneError::InvalidTree(
36 crate::error::TreeError::ColumnsCountZero,
37 ));
38 }
39 _ => {}
40 }
41 validate_kinds(&self.kinds)?;
42
43 let mut b = LayoutBuilder::new();
44 let gap_px = self.gap;
45
46 b.col_gap(gap_px, |outer| {
47 for chunk in self.kinds.chunks(self.cols) {
48 outer.taffy_node(row_style(1.0, gap_px), |r| {
49 super::add_grow_panels(r, chunk);
50 });
51 }
52 })?;
53
54 b.build()
55 }
56}
57
58impl Grid {
59 pub fn into_runtime(self) -> Result<crate::runtime::LayoutRuntime, PaneError> {
61 let strategy = crate::strategy::StrategyKind::ColumnGrid {
62 columns: self.cols,
63 gap: self.gap,
64 };
65 crate::runtime::LayoutRuntime::from_strategy(strategy, &self.kinds)
66 }
67}
68
69super::impl_preset!(Grid);