event_handler.rs

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