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