1use std::ops::{Deref, DerefMut};
2
3use collections::{HashMap, HashSet};
4
5use crate::{Action, ElementBox, Event, FontCache, MutableAppContext, TextLayoutCache};
6
7pub struct EventContext<'a> {
8 rendered_views: &'a mut HashMap<usize, ElementBox>,
9 pub font_cache: &'a FontCache,
10 pub text_layout_cache: &'a TextLayoutCache,
11 pub app: &'a mut MutableAppContext,
12 pub window_id: usize,
13 pub notify_count: usize,
14 view_stack: Vec<usize>,
15 pub(crate) handled: bool,
16 pub(crate) invalidated_views: HashSet<usize>,
17}
18
19impl<'a> EventContext<'a> {
20 pub(crate) fn dispatch_event(&mut self, view_id: usize, event: &Event) -> bool {
21 if let Some(mut element) = self.rendered_views.remove(&view_id) {
22 let result =
23 self.with_current_view(view_id, |this| element.dispatch_event(event, this));
24 self.rendered_views.insert(view_id, element);
25 result
26 } else {
27 false
28 }
29 }
30
31 pub(crate) fn with_current_view<F, T>(&mut self, view_id: usize, f: F) -> T
32 where
33 F: FnOnce(&mut Self) -> T,
34 {
35 self.view_stack.push(view_id);
36 let result = f(self);
37 self.view_stack.pop();
38 result
39 }
40
41 pub fn window_id(&self) -> usize {
42 self.window_id
43 }
44
45 pub fn view_id(&self) -> Option<usize> {
46 self.view_stack.last().copied()
47 }
48
49 pub fn is_parent_view_focused(&self) -> bool {
50 if let Some(parent_view_id) = self.view_stack.last() {
51 self.app.focused_view_id(self.window_id) == Some(*parent_view_id)
52 } else {
53 false
54 }
55 }
56
57 pub fn focus_parent_view(&mut self) {
58 if let Some(parent_view_id) = self.view_stack.last() {
59 self.app.focus(self.window_id, Some(*parent_view_id))
60 }
61 }
62
63 pub fn dispatch_any_action(&mut self, action: Box<dyn Action>) {
64 self.app
65 .dispatch_any_action_at(self.window_id, *self.view_stack.last().unwrap(), action)
66 }
67
68 pub fn dispatch_action<A: Action>(&mut self, action: A) {
69 self.dispatch_any_action(Box::new(action));
70 }
71
72 pub fn notify(&mut self) {
73 self.notify_count += 1;
74 if let Some(view_id) = self.view_stack.last() {
75 self.invalidated_views.insert(*view_id);
76 }
77 }
78
79 pub fn notify_count(&self) -> usize {
80 self.notify_count
81 }
82
83 pub fn propogate_event(&mut self) {
84 self.handled = false;
85 }
86}
87
88impl<'a> Deref for EventContext<'a> {
89 type Target = MutableAppContext;
90
91 fn deref(&self) -> &Self::Target {
92 self.app
93 }
94}
95
96impl<'a> DerefMut for EventContext<'a> {
97 fn deref_mut(&mut self) -> &mut Self::Target {
98 self.app
99 }
100}