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 WindowClosed {
107 window: &'a Window,
108 tree: &'a Tree,
109 },
110
111 AfterRedraw {
113 window: &'a Window,
114 font_collection: &'a FontCollection,
115 tree: &'a Tree,
116 },
117
118 BeforePresenting {
120 window: &'a Window,
121 font_collection: &'a FontCollection,
122 tree: &'a Tree,
123 },
124
125 AfterPresenting {
127 window: &'a Window,
128 font_collection: &'a FontCollection,
129 tree: &'a Tree,
130 },
131
132 BeforeRender {
134 window: &'a Window,
135 canvas: &'a Canvas,
136 font_collection: &'a FontCollection,
137 tree: &'a Tree,
138 },
139
140 AfterRender {
142 window: &'a Window,
143 canvas: &'a Canvas,
144 font_collection: &'a FontCollection,
145 tree: &'a Tree,
146 animation_clock: &'a AnimationClock,
147 },
148
149 StartedMeasuringLayout {
151 window: &'a Window,
152 tree: &'a Tree,
153 },
154
155 FinishedMeasuringLayout {
157 window: &'a Window,
158 tree: &'a Tree,
159 },
160
161 StartedMeasuringEvents {
163 window: &'a Window,
164 tree: &'a Tree,
165 },
166
167 FinishedMeasuringEvents {
169 window: &'a Window,
170 tree: &'a Tree,
171 },
172
173 StartedUpdatingTree {
174 window: &'a Window,
175 tree: &'a Tree,
176 },
177
178 FinishedUpdatingTree {
179 window: &'a Window,
180 tree: &'a Tree,
181 },
182
183 BeforeAccessibility {
184 window: &'a Window,
185 font_collection: &'a FontCollection,
186 tree: &'a Tree,
187 },
188
189 AfterAccessibility {
190 window: &'a Window,
191 font_collection: &'a FontCollection,
192 tree: &'a Tree,
193 },
194
195 KeyboardInput {
197 window: &'a Window,
198 key: Key,
199 code: Code,
200 modifiers: Modifiers,
201 is_pressed: bool,
202 },
203}
204
205pub trait FreyaPlugin {
207 fn plugin_id(&self) -> &'static str;
209
210 fn on_event(&mut self, event: &mut PluginEvent, handle: PluginHandle);
212
213 fn root_component(&self, root: Element) -> Element {
216 root
217 }
218}