use crate::core::{ObjectId, Rect};
use crate::event::Event;
use crate::render::RenderContext;
use std::collections::HashMap;
pub struct SimpleRegistry {
entries: HashMap<ObjectId, RegistryEntry>,
}
type DrawClosure = Box<dyn FnMut(&mut RenderContext) + Send>;
type EventClosure = Box<dyn FnMut(&Event) + Send>;
type GeometryClosure = Box<dyn FnMut(Rect) + Send>;
struct RegistryEntry {
draw: DrawClosure,
event: EventClosure,
geometry: Option<GeometryClosure>,
}
unsafe impl Send for SimpleRegistry {}
impl Default for SimpleRegistry {
fn default() -> Self {
Self::new()
}
}
impl SimpleRegistry {
pub fn new() -> Self {
Self { entries: HashMap::new() }
}
pub fn register<D, E>(&mut self, id: ObjectId, draw: D, event: E)
where
D: FnMut(&mut RenderContext) + Send + 'static,
E: FnMut(&Event) + Send + 'static,
{
self.entries.insert(
id,
RegistryEntry { draw: Box::new(draw), event: Box::new(event), geometry: None },
);
}
pub fn register_with_geometry<D, E, G>(&mut self, id: ObjectId, draw: D, event: E, geometry: G)
where
D: FnMut(&mut RenderContext) + Send + 'static,
E: FnMut(&Event) + Send + 'static,
G: FnMut(Rect) + Send + 'static,
{
self.entries.insert(
id,
RegistryEntry {
draw: Box::new(draw),
event: Box::new(event),
geometry: Some(Box::new(geometry)),
},
);
}
pub fn unregister(&mut self, id: ObjectId) {
self.entries.remove(&id);
}
pub fn draw_widget(&mut self, id: ObjectId, context: &mut RenderContext) -> bool {
if let Some(entry) = self.entries.get_mut(&id) {
(entry.draw)(context);
true
} else {
false
}
}
pub fn forward_event(&mut self, id: ObjectId, event: &Event) -> bool {
if let Some(entry) = self.entries.get_mut(&id) {
(entry.event)(event);
true
} else {
false
}
}
pub fn set_widget_geometry(&mut self, id: ObjectId, geometry: Rect) -> bool {
if let Some(entry) = self.entries.get_mut(&id) {
if let Some(callback) = entry.geometry.as_mut() {
callback(geometry);
return true;
}
}
false
}
pub fn contains(&self, id: ObjectId) -> bool {
self.entries.contains_key(&id)
}
pub fn len(&self) -> usize {
self.entries.len()
}
pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
}