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}