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        _: &mut Self::LayoutState,
48        cx: &mut PaintContext,
49    ) -> Self::PaintState {
50        self.child.paint(bounds.origin(), cx);
51    }
52
53    fn dispatch_event(
54        &mut self,
55        event: &Event,
56        bounds: RectF,
57        _: &mut Self::LayoutState,
58        _: &mut Self::PaintState,
59        cx: &mut EventContext,
60    ) -> bool {
61        if self.child.dispatch_event(event, cx) {
62            true
63        } else {
64            match event {
65                Event::LeftMouseDown { position, .. } => {
66                    if let Some(callback) = self.mouse_down.as_mut() {
67                        if bounds.contains_point(*position) {
68                            return callback(cx);
69                        }
70                    }
71                    false
72                }
73                _ => false,
74            }
75        }
76    }
77
78    fn debug(
79        &self,
80        _: RectF,
81        _: &Self::LayoutState,
82        _: &Self::PaintState,
83        cx: &DebugContext,
84    ) -> serde_json::Value {
85        json!({
86            "type": "EventHandler",
87            "child": self.child.debug(cx),
88        })
89    }
90}