facepile.rs

 1use crate::prelude::*;
 2use gpui::{AnyElement, StyleRefinement};
 3use smallvec::SmallVec;
 4
 5/// A facepile is a collection of faces stacked horizontally–
 6/// always with the leftmost face on top and descending in z-index
 7///
 8/// Facepiles are used to display a group of people or things,
 9/// such as a list of participants in a collaboration session.
10#[derive(IntoElement)]
11pub struct Facepile {
12    base: Div,
13    faces: SmallVec<[AnyElement; 2]>,
14}
15
16impl Facepile {
17    pub fn empty() -> Self {
18        Self::new(SmallVec::new())
19    }
20
21    pub fn new(faces: SmallVec<[AnyElement; 2]>) -> Self {
22        Self { base: div(), faces }
23    }
24}
25
26impl ParentElement for Facepile {
27    fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) {
28        self.faces.extend(elements);
29    }
30}
31
32// Style methods.
33impl Facepile {
34    fn style(&mut self) -> &mut StyleRefinement {
35        self.base.style()
36    }
37
38    gpui::padding_style_methods!({
39        visibility: pub
40    });
41}
42
43impl RenderOnce for Facepile {
44    fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
45        // Lay the faces out in reverse so they overlap in the desired order (left to right, front to back)
46        self.base
47            .flex()
48            .flex_row_reverse()
49            .items_center()
50            .justify_start()
51            .children(
52                self.faces
53                    .into_iter()
54                    .enumerate()
55                    .rev()
56                    .map(|(ix, player)| div().when(ix > 0, |div| div.ml_neg_1()).child(player)),
57            )
58    }
59}