hook.rs

 1use std::ops::Range;
 2
 3use crate::{
 4    geometry::{rect::RectF, vector::Vector2F},
 5    json::json,
 6    presenter::MeasurementContext,
 7    DebugContext, Element, ElementBox, Event, EventContext, LayoutContext, PaintContext,
 8    SizeConstraint,
 9};
10
11pub struct Hook {
12    child: ElementBox,
13    after_layout: Option<Box<dyn FnMut(Vector2F, &mut LayoutContext)>>,
14}
15
16impl Hook {
17    pub fn new(child: ElementBox) -> Self {
18        Self {
19            child,
20            after_layout: None,
21        }
22    }
23
24    pub fn on_after_layout(
25        mut self,
26        f: impl 'static + FnMut(Vector2F, &mut LayoutContext),
27    ) -> Self {
28        self.after_layout = Some(Box::new(f));
29        self
30    }
31}
32
33impl Element for Hook {
34    type LayoutState = ();
35    type PaintState = ();
36
37    fn layout(
38        &mut self,
39        constraint: SizeConstraint,
40        cx: &mut LayoutContext,
41    ) -> (Vector2F, Self::LayoutState) {
42        let size = self.child.layout(constraint, cx);
43        if let Some(handler) = self.after_layout.as_mut() {
44            handler(size, cx);
45        }
46        (size, ())
47    }
48
49    fn paint(
50        &mut self,
51        bounds: RectF,
52        visible_bounds: RectF,
53        _: &mut Self::LayoutState,
54        cx: &mut PaintContext,
55    ) {
56        self.child.paint(bounds.origin(), visible_bounds, cx);
57    }
58
59    fn dispatch_event(
60        &mut self,
61        event: &Event,
62        _: RectF,
63        _: RectF,
64        _: &mut Self::LayoutState,
65        _: &mut Self::PaintState,
66        cx: &mut EventContext,
67    ) -> bool {
68        self.child.dispatch_event(event, cx)
69    }
70
71    fn rect_for_text_range(
72        &self,
73        range_utf16: Range<usize>,
74        _: RectF,
75        _: RectF,
76        _: &Self::LayoutState,
77        _: &Self::PaintState,
78        cx: &MeasurementContext,
79    ) -> Option<RectF> {
80        self.child.rect_for_text_range(range_utf16, cx)
81    }
82
83    fn debug(
84        &self,
85        _: RectF,
86        _: &Self::LayoutState,
87        _: &Self::PaintState,
88        cx: &DebugContext,
89    ) -> serde_json::Value {
90        json!({
91            "type": "Hooks",
92            "child": self.child.debug(cx),
93        })
94    }
95}