1use std::ops::Range;
2
3use gpui::{
4 geometry::{
5 rect::RectF,
6 vector::{vec2f, Vector2F},
7 },
8 json::ToJson,
9 serde_json::{self, json},
10 Axis, DebugContext, Element, ElementBox, MeasurementContext, PaintContext,
11};
12
13pub(crate) struct FacePile {
14 overlap: f32,
15 faces: Vec<ElementBox>,
16}
17
18impl FacePile {
19 pub fn new(overlap: f32) -> FacePile {
20 FacePile {
21 overlap,
22 faces: Vec::new(),
23 }
24 }
25}
26
27impl Element for FacePile {
28 type LayoutState = ();
29 type PaintState = ();
30
31 fn layout(
32 &mut self,
33 constraint: gpui::SizeConstraint,
34 cx: &mut gpui::LayoutContext,
35 ) -> (Vector2F, Self::LayoutState) {
36 debug_assert!(constraint.max_along(Axis::Horizontal) == f32::INFINITY);
37
38 let mut width = 0.;
39 for face in &mut self.faces {
40 width += face.layout(constraint, cx).x();
41 }
42 width -= self.overlap * self.faces.len().saturating_sub(1) as f32;
43
44 (Vector2F::new(width, constraint.max.y()), ())
45 }
46
47 fn paint(
48 &mut self,
49 bounds: RectF,
50 visible_bounds: RectF,
51 _layout: &mut Self::LayoutState,
52 cx: &mut PaintContext,
53 ) -> Self::PaintState {
54 let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default();
55
56 let origin_y = bounds.upper_right().y();
57 let mut origin_x = bounds.upper_right().x();
58
59 for face in self.faces.iter_mut().rev() {
60 let size = face.size();
61 origin_x -= size.x();
62 cx.paint_layer(None, |cx| {
63 face.paint(vec2f(origin_x, origin_y), visible_bounds, cx);
64 });
65 origin_x += self.overlap;
66 }
67
68 ()
69 }
70
71 fn rect_for_text_range(
72 &self,
73 _: Range<usize>,
74 _: RectF,
75 _: RectF,
76 _: &Self::LayoutState,
77 _: &Self::PaintState,
78 _: &MeasurementContext,
79 ) -> Option<RectF> {
80 None
81 }
82
83 fn debug(
84 &self,
85 bounds: RectF,
86 _: &Self::LayoutState,
87 _: &Self::PaintState,
88 _: &DebugContext,
89 ) -> serde_json::Value {
90 json!({
91 "type": "FacePile",
92 "bounds": bounds.to_json()
93 })
94 }
95}
96
97impl Extend<ElementBox> for FacePile {
98 fn extend<T: IntoIterator<Item = ElementBox>>(&mut self, children: T) {
99 self.faces.extend(children);
100 }
101}