use std::any::Any;
use std::ops::{Deref, DerefMut};
use crate::{NativeContainerWidget, NativeWidget, StrongNodeType, VNodeType};
pub trait VNode: AsRef<dyn Any> + AsMut<dyn Any> + 'static {
fn new() -> Self
where
Self: Sized;
fn into_strong_node_type(self) -> StrongNodeType;
}
pub trait VWidget:
VNode + AsRef<dyn VNode> + AsMut<dyn VNode> + Deref<Target = NativeWidget> + DerefMut
{
fn push(&mut self, _member: StrongNodeType) {
panic!("can't add child to this widget")
}
}
pub trait VContainerWidget:
VNode + AsRef<dyn VNode> + AsMut<dyn VNode> + Deref<Target = NativeContainerWidget> + DerefMut
{
fn get_children(&self) -> &Vec<Option<StrongNodeType>>;
fn get_children_mut(&mut self) -> &mut Vec<Option<StrongNodeType>>;
fn push(&mut self, member: Option<StrongNodeType>) {
if let Some(member) = &member {
match member.as_ref().borrow_mut().deref() {
VNodeType::Widget(w) => {
#[cfg(feature = "web")]
self.append_child(w.deref()).unwrap();
}
VNodeType::ContainerWidget(w) => {
#[cfg(feature = "web")]
self.append_child(w.deref()).unwrap();
}
VNodeType::TopLevelContainerWidget(_) => (),
}
}
self.get_children_mut().push(member);
}
fn set_at_index(&mut self, new_member: Option<StrongNodeType>, index: usize) {
let old_member = self.get_children()[index].clone();
self.get_children_mut()[index] = new_member.clone();
match (old_member, new_member) {
(Some(old_member), Some(new_member)) => {
#[cfg(feature = "web")]
self.replace_child(
new_member.as_ref().borrow().get_native_widget(),
old_member.as_ref().borrow().get_native_widget(),
)
.unwrap();
}
(None, Some(new_member)) => {
let new_member_widget = new_member.as_ref().borrow();
let new_member_widget = new_member_widget.deref().get_native_widget();
let children = self.get_children();
for i in (index + 1)..children.len() {
if let Some(next_member) = &children[i] {
#[cfg(feature = "web")]
self.deref()
.insert_before(
new_member_widget,
Some(next_member.as_ref().borrow().get_native_widget()),
)
.unwrap();
return;
}
}
#[cfg(feature = "web")]
self.append_child(new_member_widget).unwrap();
}
(Some(old_member), None) => {
#[cfg(feature = "web")]
self.remove_child(old_member.as_ref().borrow().get_native_widget())
.unwrap();
}
(None, None) => {}
}
}
}