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