face_pile.rs

  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}