use std::{cell::RefCell, collections::BTreeMap, rc::Rc};
use dces::prelude::*;
use crate::{prelude::*, render_object::RenderObject, theming::Theme, tree::Tree};
use super::State;
pub type WidgetBuildContext = Option<Box<dyn Fn(&mut BuildContext, usize) -> Entity + 'static>>;
#[derive(Constructor)]
pub struct BuildContext<'a> {
ecm: &'a mut EntityComponentManager<Tree, StringComponentStore>,
render_objects: &'a RefCell<BTreeMap<Entity, Box<dyn RenderObject>>>,
layouts: &'a RefCell<BTreeMap<Entity, Box<dyn Layout>>>,
handlers: &'a RefCell<EventHandlerMap>,
states: &'a mut BTreeMap<Entity, Box<dyn State>>,
theme: &'a Theme,
event_queue: &'a Rc<RefCell<EventQueue>>,
}
impl<'a> BuildContext<'a> {
pub fn get_widget(&mut self, entity: Entity) -> WidgetContainer {
WidgetContainer::new(entity, self.ecm, self.theme, Some(self.event_queue))
}
pub fn create_entity(&mut self) -> Entity {
self.ecm.create_entity().build()
}
pub fn update_theme_by_state(&mut self, entity: Entity) {
self.get_widget(entity).update(true);
}
pub fn append_child(&mut self, parent: Entity, child: Entity) {
self.ecm
.entity_store_mut()
.append_child(parent, child)
.unwrap();
}
pub fn append_child_to_overlay(&mut self, child: Entity) -> Result<(), String> {
if let Some(overlay) = self.ecm.entity_store().overlay {
self.append_child(overlay, child);
return Ok(());
}
Err("BuildContext.append_child_to_overlay: Could not find overlay.".to_string())
}
pub fn register_property<P: Component>(&mut self, key: &str, widget: Entity, property: P) {
self.ecm
.component_store_mut()
.register(key, widget, property);
}
pub fn register_property_box(&mut self, key: &str, widget: Entity, property: ComponentBox) {
self.ecm
.component_store_mut()
.register_box(key, widget, property);
}
pub fn register_shared_property<P: Component>(
&mut self,
key: &str,
target: Entity,
source: Entity,
) {
self.register_shared_property_by_source_key::<P>(key, key, target, source);
}
pub fn register_shared_property_by_source_key<P: Component>(
&mut self,
key: &str,
source_key: &str,
target: Entity,
source: Entity,
) {
self.ecm
.component_store_mut()
.register_shared_by_source_key::<P>(key, source_key, target, source);
}
pub fn register_property_shared_box(
&mut self,
key: &str,
widget: Entity,
property: SharedComponentBox,
) {
self.register_property_shared_box_by_source_key(key, key, widget, property);
}
pub fn register_property_shared_box_by_source_key(
&mut self,
key: &str,
source_key: &str,
widget: Entity,
property: SharedComponentBox,
) {
self.ecm
.component_store_mut()
.register_shared_box_by_source_key(key, source_key, widget, property);
}
pub fn register_state(&mut self, widget: Entity, state: Box<dyn State>) {
self.states.insert(widget, state);
}
pub fn register_render_object(&mut self, widget: Entity, render_object: Box<dyn RenderObject>) {
self.render_objects
.borrow_mut()
.insert(widget, render_object);
}
pub fn register_handler(&mut self, widget: Entity, handler: Rc<dyn EventHandler>) {
if !self.handlers.borrow().contains_key(&widget) {
self.handlers.borrow_mut().insert(widget, vec![]);
}
self.handlers
.borrow_mut()
.get_mut(&widget)
.unwrap()
.push(handler);
}
pub fn register_layout(&mut self, widget: Entity, layout: Box<dyn Layout>) {
self.layouts.borrow_mut().insert(widget, layout);
}
}
pub fn register_property<P: Component>(
ctx: &mut BuildContext,
key: &str,
entity: Entity,
property: P,
) {
ctx.register_property(key, entity, property);
}