hook.rs

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