lgui_core/core/input/
event_context.rs1use std::{future::Future, sync::Arc};
2
3use crate::{
4 application::ApplicationContext,
5 window::{WindowHandle, WindowId, WindowManager},
6};
7use crate::{
8 command::{Command, CommandHandle},
9 events::Event,
10};
11
12#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
13pub struct UiEventFlags {
14 pub consumed: bool,
15 pub changed: bool,
16 pub route_changed: bool,
17 pub needs_frame: bool,
18 pub default_prevented: bool,
19}
20
21pub struct UiEventContext {
23 application: ApplicationContext,
24 window: WindowHandle,
25 flags: UiEventFlags,
26 propagation_stopped: bool,
27}
28
29#[derive(Clone)]
30pub struct UiAsyncContext {
31 application: ApplicationContext,
32 window: Option<WindowHandle>,
33}
34
35impl UiEventContext {
36 pub fn new(application: ApplicationContext, window_id: WindowId) -> Self {
37 let window = WindowHandle::new(window_id, application.windows());
38 Self {
39 application,
40 window,
41 flags: UiEventFlags::default(),
42 propagation_stopped: false,
43 }
44 }
45
46 pub fn application(&self) -> ApplicationContext {
47 self.application.clone()
48 }
49
50 pub fn resource<T>(&self) -> Arc<T>
51 where
52 T: Send + Sync + 'static,
53 {
54 self.application.resource::<T>()
55 }
56
57 pub fn try_resource<T>(&self) -> Option<Arc<T>>
58 where
59 T: Send + Sync + 'static,
60 {
61 self.application.try_resource::<T>()
62 }
63
64 pub fn command<C>(&self) -> CommandHandle<C>
65 where
66 C: Command,
67 {
68 self.application.command::<C>()
69 }
70
71 pub fn emit<E>(&self, event: E) -> usize
72 where
73 E: Event,
74 {
75 self.application.emit(event)
76 }
77
78 pub fn spawn(&mut self, task: impl Future<Output = ()> + Send + 'static) -> bool {
79 self.mark_consumed();
80 self.application.spawn(task)
81 }
82
83 pub fn spawn_or_else(
84 &mut self,
85 task: impl Future<Output = ()> + Send + 'static,
86 unavailable: impl FnOnce(),
87 ) {
88 if !self.spawn(task) {
89 unavailable();
90 }
91 }
92
93 pub fn spawn_async<Fut>(&mut self, handler: impl FnOnce(UiAsyncContext) -> Fut + Send + 'static)
94 where
95 Fut: Future<Output = ()> + Send + 'static,
96 {
97 let context = self.async_context();
98 let _ = self.spawn(handler(context));
99 }
100
101 pub fn async_context(&self) -> UiAsyncContext {
102 UiAsyncContext {
103 application: self.application.clone(),
104 window: Some(self.window.clone()),
105 }
106 }
107
108 pub fn window(&self) -> WindowHandle {
109 self.window.clone()
110 }
111
112 pub fn windows(&self) -> WindowManager {
113 self.application.windows()
114 }
115
116 pub fn stop_propagation(&mut self) {
117 self.propagation_stopped = true;
118 self.flags.consumed = true;
119 }
120
121 pub fn prevent_default(&mut self) {
122 self.flags.default_prevented = true;
123 self.flags.consumed = true;
124 }
125
126 pub fn propagation_stopped(&self) -> bool {
127 self.propagation_stopped
128 }
129
130 pub fn default_prevented(&self) -> bool {
131 self.flags.default_prevented
132 }
133
134 pub fn flags(&self) -> UiEventFlags {
135 self.flags
136 }
137
138 pub fn mark_consumed(&mut self) {
139 self.flags.consumed = true;
140 }
141
142 pub fn mark_changed(&mut self, route_changed: bool) {
143 self.flags.consumed = true;
144 self.flags.changed = true;
145 self.flags.route_changed |= route_changed;
146 }
147
148 pub fn request_frame(&mut self) {
149 self.flags.needs_frame = true;
150 }
151}
152
153impl UiAsyncContext {
154 pub(crate) fn application_only(application: ApplicationContext) -> Self {
155 Self {
156 application,
157 window: None,
158 }
159 }
160
161 pub fn application(&self) -> ApplicationContext {
162 self.application.clone()
163 }
164
165 pub fn resource<T>(&self) -> Arc<T>
166 where
167 T: Send + Sync + 'static,
168 {
169 self.application.resource::<T>()
170 }
171
172 pub fn try_resource<T>(&self) -> Option<Arc<T>>
173 where
174 T: Send + Sync + 'static,
175 {
176 self.application.try_resource::<T>()
177 }
178
179 pub fn command<C>(&self) -> CommandHandle<C>
180 where
181 C: Command,
182 {
183 self.application.command::<C>()
184 }
185
186 pub async fn invoke<C>(&self, args: C::Args) -> Result<C::Output, C::Error>
187 where
188 C: Command,
189 {
190 self.application.invoke::<C>(args).await
191 }
192
193 pub fn emit<E>(&self, event: E) -> usize
194 where
195 E: Event,
196 {
197 self.application.emit(event)
198 }
199
200 pub fn window(&self) -> Option<WindowHandle> {
201 self.window.clone()
202 }
203
204 pub fn windows(&self) -> WindowManager {
205 self.application.windows()
206 }
207}
208
209#[cfg(test)]
210#[path = "event_context_test.rs"]
211mod tests;