Dynamic Widget system

This commit is contained in:
2025-07-28 15:02:22 +02:00
parent 00f7493741
commit 02bdca151b
7 changed files with 82 additions and 224 deletions
+56 -3
View File
@@ -4,7 +4,7 @@ use std::{
sync::{Arc, Mutex},
};
use crate::render_scope::RenderScope;
use crate::{render_scope::RenderScope, state::DependencyHandler};
pub type BoxedElement = Box<dyn Element + Send + Sync>;
pub type BoxedComponent = Box<dyn Component + Send + Sync>;
@@ -26,11 +26,39 @@ pub trait Component: Send + Sync {
pub struct Widget(
pub Mutex<BoxedElement>,
Mutex<HashMap<TypeId, BoxedComponent>>,
Mutex<Box<dyn FnMut() -> WidgetLoad + Send + Sync>>,
Mutex<Vec<Box<dyn DependencyHandler>>>,
);
impl Widget {
pub fn new(e: Box<dyn Element>) -> Self {
Self(Mutex::new(e), Mutex::new(HashMap::new()))
pub fn new<F: FnMut() -> WidgetLoad + 'static + Send + Sync>(mut e: F) -> Self {
let wl = e();
Self(
Mutex::new(wl.0),
Mutex::new(wl.1),
Mutex::new(Box::new(e)),
Mutex::new(Vec::new()),
)
}
pub fn refresh(self: &Arc<Self>) {
let w = (self.2.lock().unwrap())();
*self.0.lock().unwrap() = w.0;
*self.1.lock().unwrap() = w.1;
}
pub fn auto_refresh(self: &Arc<Self>) {
for d in self.3.lock().unwrap().iter() {
if d.check() {
self.refresh();
}
}
}
pub fn dependency<D: DependencyHandler + 'static>(self: &Arc<Self>, d: D) -> &Arc<Self> {
d.add();
self.3.lock().unwrap().push(Box::new(d));
self
}
pub fn component<C: Component + 'static>(self: &Arc<Self>, c: C) -> &Arc<Self> {
@@ -56,3 +84,28 @@ impl Widget {
.map(|c| c.clone())
}
}
pub struct WidgetLoad(BoxedElement, HashMap<TypeId, BoxedComponent>);
impl WidgetLoad {
pub fn new<E: Element + 'static>(e: E) -> Self {
Self(Box::new(e), HashMap::new())
}
pub fn component<C: Component + 'static>(mut self, c: C) -> Self {
self.1.entry(c.type_id()).or_insert_with(|| Box::new(c));
self
}
pub fn set_component<C: Component + 'static>(mut self, c: C) -> Self {
self.1.insert(c.type_id(), Box::new(c));
self
}
pub fn get<C: Component + 'static + Clone>(&self) -> Option<C> {
self.1
.get(&TypeId::of::<C>())
.and_then(|c| c.as_any().downcast_ref::<C>())
.map(|c| c.clone())
}
}