Skip to main content

guise/layout/
group.rs

1//! `Group` — children laid out in a row with consistent spacing.
2
3use gpui::prelude::*;
4use gpui::{div, px, AnyElement, App, IntoElement, Window};
5
6use super::{apply_align, apply_justify, Align, Justify};
7use crate::devtools::Probed;
8use crate::theme::{theme, Size};
9
10/// A horizontal flex container.
11#[derive(IntoElement)]
12pub struct Group {
13  children: Vec<AnyElement>,
14  gap: Size,
15  align: Align,
16  justify: Justify,
17  wrap: bool,
18  grow: bool,
19}
20
21impl Group {
22  pub fn new() -> Self {
23    Group {
24      children: Vec::new(),
25      gap: Size::Md,
26      align: Align::Center,
27      justify: Justify::Start,
28      wrap: true,
29      grow: false,
30    }
31  }
32
33  pub fn gap(mut self, gap: Size) -> Self {
34    self.gap = gap;
35    self
36  }
37
38  pub fn align(mut self, align: Align) -> Self {
39    self.align = align;
40    self
41  }
42
43  pub fn justify(mut self, justify: Justify) -> Self {
44    self.justify = justify;
45    self
46  }
47
48  /// Allow children to wrap onto multiple lines (default true).
49  pub fn wrap(mut self, wrap: bool) -> Self {
50    self.wrap = wrap;
51    self
52  }
53
54  /// Stretch children to share the available width equally.
55  pub fn grow(mut self, grow: bool) -> Self {
56    self.grow = grow;
57    self
58  }
59}
60
61impl Default for Group {
62  fn default() -> Self {
63    Group::new()
64  }
65}
66
67impl ParentElement for Group {
68  fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) {
69    self.children.extend(elements);
70  }
71}
72
73impl RenderOnce for Group {
74  fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
75    let gap = theme(cx).spacing(self.gap);
76    let mut base = div().flex().flex_row().gap(px(gap));
77    if self.wrap {
78      base = base.flex_wrap();
79    }
80    let grow = self.grow;
81    apply_justify(apply_align(base, self.align), self.justify)
82      .children(self.children.into_iter().map(move |c| {
83        if grow {
84          div().flex_1().child(c).into_any_element()
85        } else {
86          c
87        }
88      }))
89      .probe("Group")
90  }
91}