use std::{
cell::RefCell,
collections::HashMap,
rc::Rc,
};
use freya_core::integration::*;
use freya_engine::prelude::{
Canvas,
FontCollection,
};
pub use keyboard_types::{
Code,
Key,
Modifiers,
};
use winit::{
event_loop::EventLoopProxy,
window::{
Window,
WindowId,
},
};
use crate::renderer::{
NativeEvent,
NativeWindowEvent,
NativeWindowEventAction,
};
#[derive(Clone)]
pub struct PluginHandle {
pub proxy: EventLoopProxy<NativeEvent>,
}
impl PluginHandle {
pub fn new(proxy: &EventLoopProxy<NativeEvent>) -> Self {
Self {
proxy: proxy.clone(),
}
}
pub fn send_platform_event(&self, event: PlatformEvent, window_id: WindowId) {
self.proxy
.send_event(NativeEvent::Window(NativeWindowEvent {
window_id,
action: NativeWindowEventAction::PlatformEvent(event),
}))
.ok();
}
pub fn send_event_loop_event(&self, event: NativeEvent) {
self.proxy.send_event(event).ok();
}
}
#[derive(Default, Clone)]
pub struct PluginsManager {
plugins: Rc<RefCell<HashMap<&'static str, Box<dyn FreyaPlugin>>>>,
}
impl PluginsManager {
pub fn add_plugin(&mut self, plugin: impl FreyaPlugin + 'static) {
self.plugins
.borrow_mut()
.entry(plugin.plugin_id())
.or_insert(Box::new(plugin));
}
pub fn send(&mut self, mut event: PluginEvent, handle: PluginHandle) {
for plugin in self.plugins.borrow_mut().values_mut() {
plugin.on_event(&mut event, handle.clone())
}
}
pub fn wrap_root(&self, mut root: Element) -> Element {
for plugin in self.plugins.borrow().values() {
root = plugin.root_component(root);
}
root
}
}
pub enum PluginEvent<'a> {
RunnerCreated {
runner: &'a mut Runner,
},
WindowCreated {
window: &'a Window,
font_collection: &'a FontCollection,
tree: &'a Tree,
animation_clock: &'a AnimationClock,
runner: &'a mut Runner,
graphics_driver: &'static str,
},
WindowClosed {
window: &'a Window,
tree: &'a Tree,
},
AfterRedraw {
window: &'a Window,
font_collection: &'a FontCollection,
tree: &'a Tree,
},
BeforePresenting {
window: &'a Window,
font_collection: &'a FontCollection,
tree: &'a Tree,
},
AfterPresenting {
window: &'a Window,
font_collection: &'a FontCollection,
tree: &'a Tree,
},
BeforeRender {
window: &'a Window,
canvas: &'a Canvas,
font_collection: &'a FontCollection,
tree: &'a Tree,
},
AfterRender {
window: &'a Window,
canvas: &'a Canvas,
font_collection: &'a FontCollection,
tree: &'a Tree,
animation_clock: &'a AnimationClock,
},
StartedMeasuringLayout {
window: &'a Window,
tree: &'a Tree,
},
FinishedMeasuringLayout {
window: &'a Window,
tree: &'a Tree,
},
StartedMeasuringEvents {
window: &'a Window,
tree: &'a Tree,
},
FinishedMeasuringEvents {
window: &'a Window,
tree: &'a Tree,
},
StartedUpdatingTree {
window: &'a Window,
tree: &'a Tree,
},
FinishedUpdatingTree {
window: &'a Window,
tree: &'a Tree,
},
BeforeAccessibility {
window: &'a Window,
font_collection: &'a FontCollection,
tree: &'a Tree,
},
AfterAccessibility {
window: &'a Window,
font_collection: &'a FontCollection,
tree: &'a Tree,
},
KeyboardInput {
window: &'a Window,
key: Key,
code: Code,
modifiers: Modifiers,
is_pressed: bool,
},
}
pub trait FreyaPlugin {
fn plugin_id(&self) -> &'static str;
fn on_event(&mut self, event: &mut PluginEvent, handle: PluginHandle);
fn root_component(&self, root: Element) -> Element {
root
}
}