blitz_dom/events/
driver.rs1use crate::{BaseDocument, DocumentMutator};
2use blitz_traits::events::{BlitzMouseButtonEvent, DomEvent, DomEventData, EventState, UiEvent};
3use std::collections::VecDeque;
4
5pub trait EventHandler {
6 fn handle_event(
7 &mut self,
8 chain: &[usize],
9 event: &mut DomEvent,
10 mutr: &mut DocumentMutator<'_>,
11 event_state: &mut EventState,
12 );
13}
14
15pub struct NoopEventHandler;
16impl EventHandler for NoopEventHandler {
17 fn handle_event(
18 &mut self,
19 _chain: &[usize],
20 _event: &mut DomEvent,
21 _mutr: &mut DocumentMutator<'_>,
22 _event_state: &mut EventState,
23 ) {
24 }
26}
27
28pub struct EventDriver<'doc, Handler: EventHandler> {
29 mutr: DocumentMutator<'doc>,
30 handler: Handler,
31}
32
33impl<'doc, Handler: EventHandler> EventDriver<'doc, Handler> {
34 fn doc_mut(&mut self) -> &mut BaseDocument {
35 self.mutr.doc
36 }
37
38 fn doc(&self) -> &BaseDocument {
39 &*self.mutr.doc
40 }
41
42 pub fn new(mutr: DocumentMutator<'doc>, handler: Handler) -> Self {
43 EventDriver { mutr, handler }
44 }
45
46 pub fn handle_ui_event(&mut self, event: UiEvent) {
47 let viewport_scroll = self.doc().viewport_scroll();
48 let zoom = self.doc().viewport.zoom();
49
50 let mut hover_node_id = self.doc().hover_node_id;
51 let focussed_node_id = self.doc().focus_node_id;
52
53 match &event {
55 UiEvent::MouseMove(event) => {
56 let dom_x = event.x + viewport_scroll.x as f32 / zoom;
57 let dom_y = event.y + viewport_scroll.y as f32 / zoom;
58 self.doc_mut().set_hover_to(dom_x, dom_y);
59 hover_node_id = self.doc().hover_node_id;
60 }
61 UiEvent::MouseDown(_) => {
62 self.doc_mut().active_node();
63 self.doc_mut().set_mousedown_node_id(hover_node_id);
64 }
65 UiEvent::MouseUp(_) => {
66 self.doc_mut().unactive_node();
67 }
68 _ => {}
69 };
70
71 let target = match event {
72 UiEvent::MouseMove(_) => hover_node_id,
73 UiEvent::MouseUp(_) => hover_node_id,
74 UiEvent::MouseDown(_) => hover_node_id,
75 UiEvent::KeyUp(_) => focussed_node_id,
76 UiEvent::KeyDown(_) => focussed_node_id,
77 UiEvent::Ime(_) => focussed_node_id,
78 };
79
80 let data = match event {
81 UiEvent::MouseMove(data) => DomEventData::MouseMove(BlitzMouseButtonEvent {
82 x: data.x + viewport_scroll.x as f32 / zoom,
83 y: data.y + viewport_scroll.y as f32 / zoom,
84 ..data
85 }),
86 UiEvent::MouseUp(data) => DomEventData::MouseUp(BlitzMouseButtonEvent {
87 x: data.x + viewport_scroll.x as f32 / zoom,
88 y: data.y + viewport_scroll.y as f32 / zoom,
89 ..data
90 }),
91 UiEvent::MouseDown(data) => DomEventData::MouseDown(BlitzMouseButtonEvent {
92 x: data.x + viewport_scroll.x as f32 / zoom,
93 y: data.y + viewport_scroll.y as f32 / zoom,
94 ..data
95 }),
96 UiEvent::KeyUp(data) => DomEventData::KeyUp(data),
97 UiEvent::KeyDown(data) => DomEventData::KeyDown(data),
98 UiEvent::Ime(data) => DomEventData::Ime(data),
99 };
100
101 let target = target.unwrap_or_else(|| self.doc().root_element().id);
102 let dom_event = DomEvent::new(target, data);
103
104 self.handle_dom_event(dom_event);
105 }
106
107 pub fn handle_dom_event(&mut self, event: DomEvent) {
108 let mut queue = VecDeque::with_capacity(4);
109 queue.push_back(event);
110
111 while let Some(mut event) = queue.pop_front() {
112 let chain = if event.bubbles {
113 self.doc().node_chain(event.target)
114 } else {
115 vec![event.target]
116 };
117
118 let mut event_state = EventState::default();
119 self.handler
120 .handle_event(&chain, &mut event, &mut self.mutr, &mut event_state);
121
122 if !event_state.is_cancelled() {
123 self.doc_mut()
124 .handle_dom_event(&mut event, |new_evt| queue.push_back(new_evt));
125 }
126 }
127 }
128}