use crate::accessibility::IntoNode;
use crate::prelude::*;
use crate::systems::get_access_node;
use std::any::Any;
mod handle;
pub use handle::Handle;
use hashbrown::HashMap;
use crate::events::ViewHandler;
use accesskit::{Node, TreeUpdate};
pub trait View: 'static + Sized {
fn build<F>(self, cx: &mut Context, content: F) -> Handle<Self>
where
F: FnOnce(&mut Context),
{
let id = cx.entity_manager.create();
let current = cx.current();
cx.tree.add(id, current).expect("Failed to add to tree");
cx.cache.add(id);
cx.style.add(id);
cx.needs_redraw(id);
if let Some(element) = self.element() {
cx.style.element.insert(id, fxhash::hash32(element));
}
cx.views.insert(id, Box::new(self));
let parent_id = cx.tree.get_layout_parent(id).unwrap();
let parent_node_id = parent_id.accesskit_id();
let node_id = id.accesskit_id();
let mut access_context = AccessContext {
current: id,
tree: &cx.tree,
cache: &cx.cache,
style: &cx.style,
text_context: &mut cx.text_context,
entity_identifiers: &cx.entity_identifiers,
};
if let Some(parent_node) = get_access_node(&mut access_context, &mut cx.views, parent_id) {
let parent_node = parent_node.node_builder;
let node = Node::default();
cx.tree_updates.push(Some(TreeUpdate {
nodes: vec![(parent_node_id, parent_node), (node_id, node)],
tree: None,
tree_id: accesskit::TreeId::ROOT,
focus: cx.focused.accesskit_id(),
}));
}
cx.models.insert(id, HashMap::default());
let handle = Handle { current: id, entity: id, p: Default::default(), cx };
handle.cx.with_current(handle.entity, content);
handle
}
fn element(&self) -> Option<&'static str> {
None
}
#[allow(unused_variables)]
fn event(&mut self, cx: &mut EventContext, event: &mut Event) {}
fn draw(&self, cx: &mut DrawContext, canvas: &Canvas) {
let bounds = cx.bounds();
if bounds.w == 0.0 || bounds.h == 0.0 {
return;
}
cx.draw_background(canvas);
cx.draw_shadows(canvas);
cx.draw_border(canvas);
cx.draw_outline(canvas);
cx.draw_text(canvas);
}
#[allow(unused_variables)]
fn accessibility(&self, cx: &mut AccessContext, node: &mut AccessNode) {}
}
impl<T: View> ViewHandler for T
where
T: std::marker::Sized + View + 'static,
{
fn element(&self) -> Option<&'static str> {
<T as View>::element(self)
}
fn event(&mut self, cx: &mut EventContext, event: &mut Event) {
<T as View>::event(self, cx, event);
}
fn draw(&self, cx: &mut DrawContext, canvas: &Canvas) {
<T as View>::draw(self, cx, canvas);
}
fn accessibility(&self, cx: &mut AccessContext, node: &mut AccessNode) {
<T as View>::accessibility(self, cx, node);
}
fn as_any_ref(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}