hook.rs

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