1use std::{
2 cell::RefCell,
3 collections::HashMap,
4 rc::Rc,
5};
6
7use freya_core::integration::*;
8use freya_engine::prelude::{
9 Canvas,
10 FontCollection,
11};
12pub use keyboard_types::{
13 Code,
14 Key,
15 Modifiers,
16};
17use winit::{
18 event_loop::EventLoopProxy,
19 window::{
20 Window,
21 WindowId,
22 },
23};
24
25use crate::renderer::{
26 NativeEvent,
27 NativeWindowEvent,
28 NativeWindowEventAction,
29};
30
31#[derive(Clone)]
32pub struct PluginHandle {
33 pub proxy: EventLoopProxy<NativeEvent>,
34}
35
36impl PluginHandle {
37 pub fn new(proxy: &EventLoopProxy<NativeEvent>) -> Self {
38 Self {
39 proxy: proxy.clone(),
40 }
41 }
42
43 pub fn send_platform_event(&self, event: PlatformEvent, window_id: WindowId) {
45 self.proxy
46 .send_event(NativeEvent::Window(NativeWindowEvent {
47 window_id,
48 action: NativeWindowEventAction::PlatformEvent(event),
49 }))
50 .ok();
51 }
52
53 pub fn send_event_loop_event(&self, event: NativeEvent) {
55 self.proxy.send_event(event).ok();
56 }
57}
58
59#[derive(Default, Clone)]
61pub struct PluginsManager {
62 plugins: Rc<RefCell<HashMap<&'static str, Box<dyn FreyaPlugin>>>>,
63}
64
65impl PluginsManager {
66 pub fn add_plugin(&mut self, plugin: impl FreyaPlugin + 'static) {
68 self.plugins
69 .borrow_mut()
70 .entry(plugin.plugin_id())
71 .or_insert(Box::new(plugin));
72 }
73
74 pub fn send(&mut self, mut event: PluginEvent, handle: PluginHandle) {
75 for plugin in self.plugins.borrow_mut().values_mut() {
76 plugin.on_event(&mut event, handle.clone())
77 }
78 }
79
80 pub fn wrap_root(&self, mut root: Element) -> Element {
82 for plugin in self.plugins.borrow().values() {
83 root = plugin.root_component(root);
84 }
85 root
86 }
87}
88
89pub enum PluginEvent<'a> {
91 RunnerCreated {
93 runner: &'a mut Runner,
94 },
95 WindowCreated {
97 window: &'a Window,
98 font_collection: &'a FontCollection,
99 tree: &'a Tree,
100 animation_clock: &'a AnimationClock,
101 runner: &'a mut Runner,
102 graphics_driver: &'static str,
103 },
104
105 GraphicsDriverChanged {
107 window: &'a Window,
108 graphics_driver: &'static str,
109 },
110
111 WindowClosed {
113 window: &'a Window,
114 tree: &'a Tree,
115 },
116
117 AfterRedraw {
119 window: &'a Window,
120 font_collection: &'a FontCollection,
121 tree: &'a Tree,
122 },
123
124 BeforePresenting {
126 window: &'a Window,
127 font_collection: &'a FontCollection,
128 tree: &'a Tree,
129 },
130
131 AfterPresenting {
133 window: &'a Window,
134 font_collection: &'a FontCollection,
135 tree: &'a Tree,
136 },
137
138 BeforeRender {
140 window: &'a Window,
141 canvas: &'a Canvas,
142 font_collection: &'a FontCollection,
143 tree: &'a Tree,
144 },
145
146 AfterRender {
148 window: &'a Window,
149 canvas: &'a Canvas,
150 font_collection: &'a FontCollection,
151 tree: &'a Tree,
152 animation_clock: &'a AnimationClock,
153 },
154
155 StartedMeasuringLayout {
157 window: &'a Window,
158 tree: &'a Tree,
159 },
160
161 FinishedMeasuringLayout {
163 window: &'a Window,
164 tree: &'a Tree,
165 },
166
167 StartedMeasuringEvents {
169 window: &'a Window,
170 tree: &'a Tree,
171 },
172
173 FinishedMeasuringEvents {
175 window: &'a Window,
176 tree: &'a Tree,
177 },
178
179 StartedUpdatingTree {
180 window: &'a Window,
181 tree: &'a Tree,
182 },
183
184 FinishedUpdatingTree {
185 window: &'a Window,
186 tree: &'a Tree,
187 },
188
189 BeforeAccessibility {
190 window: &'a Window,
191 font_collection: &'a FontCollection,
192 tree: &'a Tree,
193 },
194
195 AfterAccessibility {
196 window: &'a Window,
197 font_collection: &'a FontCollection,
198 tree: &'a Tree,
199 },
200
201 KeyboardInput {
203 window: &'a Window,
204 key: Key,
205 code: Code,
206 modifiers: Modifiers,
207 is_pressed: bool,
208 },
209}
210
211pub trait FreyaPlugin {
213 fn plugin_id(&self) -> &'static str;
215
216 fn on_event(&mut self, event: &mut PluginEvent, handle: PluginHandle);
218
219 fn root_component(&self, root: Element) -> Element {
222 root
223 }
224}