stack.rs

  1use std::ops::Range;
  2
  3use crate::{
  4    geometry::{rect::RectF, vector::Vector2F},
  5    json::{self, json, ToJson},
  6    presenter::MeasurementContext,
  7    DebugContext, Element, ElementBox, Event, EventContext, LayoutContext, PaintContext,
  8    SizeConstraint,
  9};
 10
 11#[derive(Default)]
 12pub struct Stack {
 13    children: Vec<ElementBox>,
 14}
 15
 16impl Stack {
 17    pub fn new() -> Self {
 18        Self::default()
 19    }
 20}
 21
 22impl Element for Stack {
 23    type LayoutState = ();
 24    type PaintState = ();
 25
 26    fn layout(
 27        &mut self,
 28        constraint: SizeConstraint,
 29        cx: &mut LayoutContext,
 30    ) -> (Vector2F, Self::LayoutState) {
 31        let mut size = constraint.min;
 32        for child in &mut self.children {
 33            size = size.max(child.layout(constraint, cx));
 34        }
 35        (size, ())
 36    }
 37
 38    fn paint(
 39        &mut self,
 40        bounds: RectF,
 41        visible_bounds: RectF,
 42        _: &mut Self::LayoutState,
 43        cx: &mut PaintContext,
 44    ) -> Self::PaintState {
 45        for child in &mut self.children {
 46            cx.scene.push_layer(None);
 47            child.paint(bounds.origin(), visible_bounds, cx);
 48            cx.scene.pop_layer();
 49        }
 50    }
 51
 52    fn dispatch_event(
 53        &mut self,
 54        event: &Event,
 55        _: RectF,
 56        _: RectF,
 57        _: &mut Self::LayoutState,
 58        _: &mut Self::PaintState,
 59        cx: &mut EventContext,
 60    ) -> bool {
 61        for child in self.children.iter_mut().rev() {
 62            if child.dispatch_event(event, cx) {
 63                return true;
 64            }
 65        }
 66        false
 67    }
 68
 69    fn rect_for_text_range(
 70        &self,
 71        range_utf16: Range<usize>,
 72        _: RectF,
 73        _: RectF,
 74        _: &Self::LayoutState,
 75        _: &Self::PaintState,
 76        cx: &MeasurementContext,
 77    ) -> Option<RectF> {
 78        self.children
 79            .iter()
 80            .rev()
 81            .find_map(|child| child.rect_for_text_range(range_utf16.clone(), cx))
 82    }
 83
 84    fn debug(
 85        &self,
 86        bounds: RectF,
 87        _: &Self::LayoutState,
 88        _: &Self::PaintState,
 89        cx: &DebugContext,
 90    ) -> json::Value {
 91        json!({
 92            "type": "Stack",
 93            "bounds": bounds.to_json(),
 94            "children": self.children.iter().map(|child| child.debug(cx)).collect::<Vec<json::Value>>()
 95        })
 96    }
 97}
 98
 99impl Extend<ElementBox> for Stack {
100    fn extend<T: IntoIterator<Item = ElementBox>>(&mut self, children: T) {
101        self.children.extend(children)
102    }
103}