From a8e832892b35bbc29ba55e113980d5bbeaa416df Mon Sep 17 00:00:00 2001 From: Leo dev Date: Mon, 28 Jul 2025 18:47:59 +0200 Subject: [PATCH] rsx child --- src/elements/div.rs | 40 +++++++++---------- src/elements/grid.rs | 93 +++++++++++++++++++++----------------------- src/frontend.rs | 41 ++++++++++++++----- src/macros.rs | 17 +++++++- src/main.rs | 14 +++++-- src/widget.rs | 2 + 6 files changed, 123 insertions(+), 84 deletions(-) diff --git a/src/elements/div.rs b/src/elements/div.rs index 26a1bd9..2aef76b 100644 --- a/src/elements/div.rs +++ b/src/elements/div.rs @@ -22,31 +22,13 @@ impl Element for Arc
{ *self.transform.lock().unwrap() = scope.get_transform().clone(); } - fn as_any(&self) -> &dyn std::any::Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn std::any::Any { - self - } -} - -impl Div { - pub fn new(color: u32) -> Arc { - Arc::new(Div { - transform: Mutex::new(RawTransform::new()), - color, - }) - } - - pub fn draw(self: &Arc, element: &Arc) -> Arc { - let r2 = self.clone(); + fn draw_child(&self, element: &Arc) { let r = self.clone(); element.component(Handler::new(move |elem, e: &RenderWrapperEvent| { let scope = e.get_scope(); scope.clear(); - let transform = r2.transform.lock().unwrap(); + let transform = r.transform.lock().unwrap(); let (w, h) = scope.get_parent_size(); scope.set_parent_size(transform.width, transform.height); @@ -70,6 +52,22 @@ impl Div { scope.set_parent_size(w, h); })); - r + } + + fn as_any(&self) -> &dyn std::any::Any { + self + } + + fn as_any_mut(&mut self) -> &mut dyn std::any::Any { + self + } +} + +impl Div { + pub fn new(color: u32) -> Arc { + Arc::new(Div { + transform: Mutex::new(RawTransform::new()), + color, + }) } } diff --git a/src/elements/grid.rs b/src/elements/grid.rs index 27ecb3e..6dd6aef 100644 --- a/src/elements/grid.rs +++ b/src/elements/grid.rs @@ -36,31 +36,13 @@ impl Element for Arc { t.height = 0; } - fn as_any(&self) -> &dyn std::any::Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn std::any::Any { - self - } -} - -impl VGrid { - pub fn new(color: u32, gap: u16) -> Arc { - Arc::new(Self { - transform: Mutex::new(RawTransform::new()), - color, - gap, - }) - } - - pub fn draw(self: &Arc, element: &Arc) -> Arc { - let r2 = self.clone(); + fn draw_child(&self, element: &Arc) { + let r = self.clone(); element.component(Handler::new(move |elem, e: &RenderWrapperEvent| { let scope = e.get_scope(); scope.clear(); - let mut transform = r2.transform.lock().unwrap(); + let mut transform = r.transform.lock().unwrap(); let (w, h) = scope.get_parent_size(); scope.set_parent_size(transform.width, transform.height); @@ -80,20 +62,37 @@ impl VGrid { transform.height += if transform.height == 0 { elem_transform.height } else { - elem_transform.height + r2.gap + elem_transform.height + r.gap }; transform.width = transform.width.max(elem_transform.width); elem_transform.x = transform.x; elem_transform.y = transform.y; - transform.y += elem_transform.height + r2.gap; + transform.y += elem_transform.height + r.gap; scope.draw(); elem.0.lock().unwrap().after_render(&scope); scope.set_parent_size(w, h); })); - element.clone() + } + + fn as_any(&self) -> &dyn std::any::Any { + self + } + + fn as_any_mut(&mut self) -> &mut dyn std::any::Any { + self + } +} + +impl VGrid { + pub fn new(color: u32, gap: u16) -> Arc { + Arc::new(Self { + transform: Mutex::new(RawTransform::new()), + color, + gap, + }) } } @@ -115,32 +114,13 @@ impl Element for Arc { t.height = 0; } - fn as_any(&self) -> &dyn std::any::Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn std::any::Any { - self - } -} - -impl HGrid { - pub fn new(color: u32, gap: u16) -> Arc { - Arc::new(Self { - transform: Mutex::new(RawTransform::new()), - color, - gap, - }) - } - - pub fn draw(self: &Arc, element: &Arc) -> Arc { - let r2 = self.clone(); + fn draw_child(&self, element: &Arc) { let r = self.clone(); element.component(Handler::new(move |elem, e: &RenderWrapperEvent| { let scope = e.get_scope(); scope.clear(); - let mut transform = r2.transform.lock().unwrap(); + let mut transform = r.transform.lock().unwrap(); let (w, h) = scope.get_parent_size(); scope.set_parent_size(transform.width, transform.height); @@ -160,19 +140,36 @@ impl HGrid { transform.width += if transform.width == 0 { elem_transform.width } else { - elem_transform.width + r2.gap + elem_transform.width + r.gap }; transform.height = transform.height.max(elem_transform.height); elem_transform.x = transform.x; elem_transform.y = transform.y; - transform.x += elem_transform.width + r2.gap; + transform.x += elem_transform.width + r.gap; scope.draw(); elem.0.lock().unwrap().after_render(&scope); scope.set_parent_size(w, h); })); - r + } + + fn as_any(&self) -> &dyn std::any::Any { + self + } + + fn as_any_mut(&mut self) -> &mut dyn std::any::Any { + self + } +} + +impl HGrid { + pub fn new(color: u32, gap: u16) -> Arc { + Arc::new(Self { + transform: Mutex::new(RawTransform::new()), + color, + gap, + }) } } diff --git a/src/frontend.rs b/src/frontend.rs index 81b33c5..8c2b1b1 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -1,20 +1,39 @@ use std::sync::Arc; -use crate::{state::DependencyHandler, widget::WidgetLoad, Screen}; +use crate::{ + state::DependencyHandler, + widget::{Widget, WidgetLoad}, + Screen, +}; -pub struct Rsx( - pub Vec<( +pub enum RsxElement { + Element( Box WidgetLoad + Send + Sync>, Vec>, - )>, -); + Rsx, + ), +} + +pub struct Rsx(pub Vec); impl Rsx { pub fn draw(self, screen: &Arc) { - for i in self.0 { - let w = screen.draw_box(i.0); - for d in i.1 { - w.dependency_box(d); + self.draw_parent(screen, None); + } + + pub fn draw_parent(self, screen: &Arc, parent: Option>) { + for rsx_elem in self.0 { + match rsx_elem { + RsxElement::Element(f, dep, child) => { + let w = screen.draw_box(f); + for d in dep { + w.dependency_box(d); + } + child.draw_parent(screen, Some(w.clone())); + if let Some(parent) = &parent { + parent.0.lock().unwrap().draw_child(&w); + } + } } } } @@ -23,7 +42,9 @@ impl Rsx { &mut self, load: F, dependencies: Vec>, + children: Rsx, ) { - self.0.push((Box::new(load), dependencies)); + self.0 + .push(RsxElement::Element(Box::new(load), dependencies, children)); } } diff --git a/src/macros.rs b/src/macros.rs index e98c68e..2becf63 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -139,8 +139,23 @@ macro_rules! rsx_inner { ($r:expr, $(%$dep:ident)* $(@$comp:expr;)* $s:literal $($rest:tt)*) => { $r.create_element({ $(let $dep = $dep.clone();)* move || { $crate::widget::WidgetLoad::new(format!($s)) $(.component($comp))* - } }, vec![$(Box::new($dep.clone())),*]); + } }, vec![$(Box::new($dep.clone())),*], $crate::frontend::Rsx(Vec::new())); $crate::rsx_inner!{ $r, $($rest)* }; }; + + ($r:expr, $(%$dep:ident)* $(@$comp:expr;)* $name:path { $($inner:tt)* } ($($e:expr),*) $($rest:tt)*) => { + $r.create_element({ $(let $dep = $dep.clone();)* move || { + $crate::widget::WidgetLoad::new(<$name>::new($($e),*)) $(.component($comp))* + } }, vec![$(Box::new($dep.clone())),*], $crate::rsx!{ $($inner)* }); + $crate::rsx_inner!{ $r, $($rest)* }; + }; + + ($r:expr, $(%$dep:ident)* $(@$comp:expr;)* $name:path { $($inner:tt)* } $($rest:tt)*) => { + $r.create_element({ $(let $dep = $dep.clone();)* move || { + $crate::widget::WidgetLoad::new(<$name>::new()) $(.component($comp))* + } }, vec![$(Box::new($dep.clone())),*], $crate::rsx!{ $($inner)* }); + $crate::rsx_inner!{ $r, $($rest)* }; + }; + ($r:expr,) => {}; } diff --git a/src/main.rs b/src/main.rs index 8c05568..49907db 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,19 @@ -use osui::{rsx, state::use_state, style::Transform, Screen}; +use osui::{elements::grid::HGrid, rsx, state::use_state, style::Transform, Screen}; fn main() -> std::io::Result<()> { let screen = Screen::new(); let count = use_state(0); rsx! { - %count - @Transform::center(); - "{count}" + @Transform::new().dimensions(10, 1); + HGrid { + %count + "{count}" + + %count + @Transform::center(); + "{count}" + } (0xff0000, 1) } .draw(&screen); diff --git a/src/widget.rs b/src/widget.rs index 5dbf6b3..07a2f53 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -14,6 +14,8 @@ pub trait Element: Send + Sync { fn render(&mut self, scope: &mut RenderScope) {} #[allow(unused)] fn after_render(&mut self, scope: &RenderScope) {} + #[allow(unused)] + fn draw_child(&self, element: &Arc) {} fn as_any(&self) -> &dyn Any; fn as_any_mut(&mut self) -> &mut dyn Any; }