From d9d107bd80881f0cda137c66bfd20c0e1e325498 Mon Sep 17 00:00:00 2001 From: Leo dev Date: Sat, 2 Aug 2025 12:18:52 -0500 Subject: [PATCH 1/2] Added rsx element fields #20 --- src/demos/mod.rs | 10 +++++----- src/elements/flex.rs | 12 ++++++------ src/frontend.rs | 10 ++++------ src/macros.rs | 21 ++++++++++++++------- src/widget.rs | 7 +++++-- 5 files changed, 34 insertions(+), 26 deletions(-) diff --git a/src/demos/mod.rs b/src/demos/mod.rs index f832b29..06766a8 100644 --- a/src/demos/mod.rs +++ b/src/demos/mod.rs @@ -19,7 +19,7 @@ pub fn app(screen: Arc) -> Rsx { move |_, _: &crossterm::event::Event| { screen.close(); }}); - FlexRow { + FlexRow, gap: 1, { FlexCol { @Transform::new().padding(2, 2); @Style { foreground: None, background: Background::RoundedOutline(0x00ff00) }; @@ -34,14 +34,14 @@ pub fn app(screen: Arc) -> Rsx { } // TODO: div with width full - } (1) + } FlexCol { - Div { + static Div { // static only affects the element, not children %count "This will increment every second: {count}" } - } (2) - } (0) + } + } } } diff --git a/src/elements/flex.rs b/src/elements/flex.rs index 3dc95e3..71849a1 100644 --- a/src/elements/flex.rs +++ b/src/elements/flex.rs @@ -6,33 +6,33 @@ use crate::{ }; pub struct FlexRow { - gap: u16, + pub gap: u16, children: Mutex>>, size: (u16, u16), } pub struct FlexCol { - gap: u16, + pub gap: u16, children: Mutex>>, size: (u16, u16), } impl FlexRow { - pub fn new(gap: u16) -> Self { + pub fn new() -> Self { Self { children: Mutex::new(Vec::new()), size: (0, 0), - gap, + gap: 0, } } } impl FlexCol { - pub fn new(gap: u16) -> Self { + pub fn new() -> Self { Self { children: Mutex::new(Vec::new()), size: (0, 0), - gap, + gap: 0, } } } diff --git a/src/frontend.rs b/src/frontend.rs index f50b086..2d47ac2 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -46,13 +46,11 @@ impl Rsx { for rsx_elem in self.0 { match rsx_elem { RsxElement::DynElement(f, dep, child) => { - let w = if let Some(parent) = &parent { - let w = screen.draw_box_dyn(f); + let w = screen.draw_box_dyn(f); + + if let Some(parent) = &parent { parent.get_elem().draw_child(&w); - w - } else { - screen.draw_box_dyn(f) - }; + } for d in dep { w.dependency_box(d); diff --git a/src/macros.rs b/src/macros.rs index 7ae8b76..4b4ed3c 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -256,24 +256,31 @@ macro_rules! rsx_inner { }; // static - ($r:expr, $(@$comp:expr;)* static $name:path { $($inner:tt)* } ($($e:expr),*) $($rest:tt)*) => { - let w = $crate::widget::StaticWidget::new(Box::new(<$name>::new($($e),*))); + ($r:expr, $(@$comp:expr;)* static $name:path, $($f:ident $(: $v:expr)?),+, { $($inner:tt)* } $($rest:tt)*) => { + let w = $crate::widget::StaticWidget::new(Box::new({ + let mut elem = <$name>::new(); + $(elem.$f = $($v)?;)+ + elem + })); $(w.component($comp);)* - $r.create_element_static(w, $crate::frontend::Rsx(Vec::new())); + $r.create_element_static(w, $crate::rsx!{ $($inner)* }); $crate::rsx_inner! { $r, $($rest)* }; }; - // static ($r:expr, $(@$comp:expr;)* static $name:path { $($inner:tt)* } $($rest:tt)*) => { let w = $crate::widget::StaticWidget::new(Box::new(<$name>::new())); $(w.component($comp);)* - $r.create_element_static(w, $crate::frontend::Rsx(Vec::new())); + $r.create_element_static(w, $crate::rsx!{ $($inner)* }); $crate::rsx_inner! { $r, $($rest)* }; }; - ($r:expr, $(@$comp:expr;)* $(%$dep:ident)* $name:path { $($inner:tt)* } ($($e:expr),*) $($rest:tt)*) => { + ($r:expr, $(@$comp:expr;)* $(%$dep:ident)* $name:path, $($f:ident $(: $v:expr)?),+, { $($inner:tt)* } $($rest:tt)*) => { $r.create_element({ $(let $dep = $dep.clone();)* move || { - $crate::widget::WidgetLoad::new(<$name>::new($($e),*)) $(.component($comp))* + $crate::widget::WidgetLoad::new({ + let mut elem = <$name>::new(); + $(elem.$f = $($v)?;)+ + elem + }) $(.component($comp))* } }, vec![$(Box::new($dep.clone())),*], $crate::rsx!{ $($inner)* }); $crate::rsx_inner! { $r, $($rest)* }; }; diff --git a/src/widget.rs b/src/widget.rs index a2e282d..8b12285 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -173,13 +173,16 @@ impl Widget { pub fn inject WidgetLoad + 'static + Send + Sync>( self: &Arc, - f: F, + mut f: F, ) { match &**self { Widget::Dynamic(w) => { w.inject(f); } - Widget::Static(_) => {} + Widget::Static(w) => { + let wl = WidgetLoad::new(String::new()); + w.1.lock().unwrap().extend(f(wl).1); + } } } From 2d8755b13cab43a7139114914273904ba0a17534 Mon Sep 17 00:00:00 2001 From: Leo dev Date: Sat, 2 Aug 2025 12:58:45 -0500 Subject: [PATCH 2/2] added heading #19 --- Cargo.toml | 1 + src/demos/mod.rs | 3 ++- src/elements/heading.rs | 55 +++++++++++++++++++++++++++++++++++++++++ src/elements/mod.rs | 2 ++ 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 src/elements/heading.rs diff --git a/Cargo.toml b/Cargo.toml index 9a61700..bbf4fc5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ cc = "1.0" [dependencies] crossterm = "0.28.1" +figlet-rs = "0.1.5" [profile.dev] opt-level = 1 diff --git a/src/demos/mod.rs b/src/demos/mod.rs index 06766a8..410cde4 100644 --- a/src/demos/mod.rs +++ b/src/demos/mod.rs @@ -20,7 +20,8 @@ pub fn app(screen: Arc) -> Rsx { screen.close(); }}); FlexRow, gap: 1, { - FlexCol { + FlexCol, gap: 3, { + Heading, smooth: false, { "OSUI" } @Transform::new().padding(2, 2); @Style { foreground: None, background: Background::RoundedOutline(0x00ff00) }; Div { diff --git a/src/elements/heading.rs b/src/elements/heading.rs new file mode 100644 index 0000000..cafffa8 --- /dev/null +++ b/src/elements/heading.rs @@ -0,0 +1,55 @@ +use std::sync::{Arc, Mutex}; + +use figlet_rs::FIGfont; + +use crate::{ + widget::{Element, Widget}, + NoRender, +}; + +pub struct Heading { + pub font: FIGfont, + pub smooth: bool, + children: Mutex>>, +} + +impl Heading { + pub fn new() -> Heading { + Heading { + font: FIGfont::standard().unwrap(), + smooth: false, + children: Mutex::new(Vec::new()), + } + } +} + +impl Element for Heading { + fn render(&mut self, scope: &mut crate::prelude::RenderScope) { + let mut s = String::new(); + for element in self.children.lock().unwrap().iter() { + if let Some(e) = element.get_elem().as_any().downcast_ref::() { + s += e; + } + } + if let Some(t) = self.font.convert(&s) { + scope.draw_text(&if self.smooth { + format!("{t}").replace("-", "─").replace("|", "│") + } else { + format!("{t}") + }); + } + } + + fn draw_child(&self, element: &Arc) { + element.inject(|w| w.component(NoRender)); + self.children.lock().unwrap().push(element.clone()); + } + + fn as_any(&self) -> &dyn std::any::Any { + self + } + + fn as_any_mut(&mut self) -> &mut dyn std::any::Any { + self + } +} diff --git a/src/elements/mod.rs b/src/elements/mod.rs index 8ea79e0..38732e3 100644 --- a/src/elements/mod.rs +++ b/src/elements/mod.rs @@ -1,8 +1,10 @@ pub mod div; pub mod flex; +pub mod heading; pub use div::*; pub use flex::*; +pub use heading::*; use crate::Element;