diff --git a/src/components.rs b/src/components.rs index e65b5b3..ab41e9f 100644 --- a/src/components.rs +++ b/src/components.rs @@ -1,25 +1,15 @@ -use crate::{Component, ComponentParams}; +use crate::{utils::render_to_frame, Component, Params}; -#[derive(Debug)] -pub struct Div { - pub children: Vec>, +pub fn div(params: Params) -> Component { + Component::new(params, |s| { + let mut frame: Vec = vec![" ".repeat(s.width); s.height]; + for c in &mut s.children { + render_to_frame(s.width, &mut frame, c); + } + frame.join("\n") + }) } -impl Component for Div {} - -pub fn div(params: ComponentParams) -> Div { - Div { - children: params.children, - } -} - -#[derive(Debug)] -pub struct Text { - pub text: String, -} - -impl Component for Text {} - -pub fn text(params: ComponentParams) -> Text { - Text { text: params.expr } +pub fn text(params: Params) -> Component { + Component::new(params, |c| c.expr.clone()) } diff --git a/src/lib.rs b/src/lib.rs index 124f3b4..fc49c9b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,15 +1,88 @@ -use std::fmt::Debug; +use std::{thread::sleep, time::Duration}; + +use crossterm::terminal; +use utils::{clear, hide_cursor, render_to_frame}; pub mod components; pub mod macros; +pub mod utils; -pub trait Component: Debug { - fn render(&mut self) -> String { - String::new() +#[derive(Debug)] +pub struct Params { + pub expr: String, + pub children: Vec, +} + +#[derive(Debug, Clone)] +pub struct Component { + pub render: fn(&mut Component) -> String, + pub update: fn(&mut Component), + pub x: usize, + pub y: usize, + pub width: usize, + pub height: usize, + pub expr: String, + pub children: Vec, +} + +impl Component { + fn new(params: Params, render: fn(&mut Component) -> String) -> Component { + Component { + render, + update: |_| {}, + x: 0, + y: 0, + width: 0, + height: 0, + expr: params.expr, + children: params.children, + } } } -pub struct ComponentParams { - pub children: Vec>, - pub expr: String, +#[derive(Debug, Clone)] +pub struct Screen { + component: Component, +} + +impl Screen { + pub fn new() -> Screen { + Screen { + component: Component::new( + Params { + expr: "".to_string(), + children: vec![], + }, + |_| String::new(), + ), + } + } + pub fn set_component(&mut self, component: Component) { + let (width, height) = terminal::size().unwrap(); + self.component = component; + if self.component.width == 0 { + self.component.width = width as usize; + } + if self.component.width == 0 { + self.component.height = height as usize; + } + self.render(); + } + + pub fn render(&mut self) { + let (width, height) = terminal::size().unwrap(); + let mut frame: Vec = vec![" ".repeat(width as usize); height as usize]; + render_to_frame(width as usize, &mut frame, &mut self.component); + clear(); + print!("{}", frame.join("\n")); + } + + pub fn run(&mut self) { + hide_cursor(); + // enable_raw_mode().unwrap(); + loop { + self.render(); + sleep(Duration::from_millis(500)); + } + } } diff --git a/src/macros.rs b/src/macros.rs index e120f0c..17f70ab 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -8,7 +8,7 @@ macro_rules! __oml { }}; ($tag:ident ($($k:ident = $v:expr),*) {$($inner:tt)*} $($rest:tt)+) => {{ - let mut comps: Vec> = osui::__oml!($($rest)+); + let mut comps: Vec = osui::__oml!($($rest)+); comps.insert(0, oml!($tag ($($k = $v),*) {$($inner)*})); comps }}; @@ -19,7 +19,7 @@ macro_rules! __oml { }}; ($tag:ident {$($inner:tt)*} $($rest:tt)+) => {{ - let mut comps: Vec> = osui::__oml!($($rest)+); + let mut comps: Vec = osui::__oml!($($rest)+); comps.insert(0, oml!($tag {$($inner)*})); comps }}; @@ -30,7 +30,7 @@ macro_rules! __oml { }}; ($tag:ident ($expr:expr; $($k:ident = $v:expr),*) {$($inner:tt)*} $($rest:tt)+) => {{ - let mut comps: Vec> = osui::__oml!($($rest)+); + let mut comps: Vec = osui::__oml!($($rest)+); comps.insert(0, oml!($tag ($expr; $($k = $v),*) {$($inner)*})); comps }}; @@ -41,7 +41,7 @@ macro_rules! __oml { }}; ($tag:ident ($expr:expr; $($k:ident = $v:expr),*) $($rest:tt)+) => {{ - let mut comps: Vec> = osui::__oml!($($rest)+); + let mut comps: Vec = osui::__oml!($($rest)+); comps.insert(0, oml!($tag ($expr; $($k = $v),*))); comps }}; @@ -52,7 +52,7 @@ macro_rules! __oml { }}; ($tag:ident ($($k:ident = $v:expr),*) $($rest:tt)+) => {{ - let mut comps: Vec> = osui::__oml!($($rest)+); + let mut comps: Vec = osui::__oml!($($rest)+); comps.insert(0, oml!($tag ($($k = $v),*))); comps }}; @@ -63,7 +63,7 @@ macro_rules! __oml { }}; ($expr:expr; $($rest:tt)+) => {{ - let mut comps: Vec> = osui::__oml!($($rest)+); + let mut comps: Vec = osui::__oml!($($rest)+); comps.insert(0, oml!($expr)); comps }}; @@ -73,43 +73,43 @@ macro_rules! __oml { macro_rules! oml { // Props (P) ($tag:ident ($($k:ident = $v:expr),*)) => {{ - let mut c = $tag(osui::ComponentParams { children: Vec::new(), expr: String::new() }); + let mut c = $tag(osui::Params { children: Vec::new(), expr: String::new() }); $( c.$k = $v; )* - Box::new(c) + c }}; // Expression, With components (EC) ( $tag:ident ($expr:expr; $($k:ident = $v:expr),* ) {$($inner:tt)*} ) => {{ - let mut c = $tag(osui::ComponentParams { children: osui::__oml!($($inner)*), expr: String::from($expr) }); + let mut c = $tag(osui::Params { children: osui::__oml!($($inner)*), expr: String::from($expr) }); $( c.$k = $v; )* - Box::new(c) + c }}; // Expression (E) ( $tag:ident ($expr:expr; $($k:ident = $v:expr),*) ) => {{ - let mut c = $tag(osui::ComponentParams { children: Vec::new(), expr: String::from($expr) }); + let mut c = $tag(osui::Params { children: Vec::new(), expr: String::from($expr) }); $( c.$k = $v; )* - Box::new(c) + c }}; // Components (C) ( $tag:ident {$($inner:tt)*} ) => { - Box::new($tag(osui::ComponentParams { children: osui::__oml!($($inner)*), expr: String::new() })) + $tag(osui::Params { children: osui::__oml!($($inner)*), expr: String::new() }) }; // Props, With components (PC) ( $tag:ident ($($k:ident = $v:expr),*) {$($inner:tt)*} ) => {{ - let mut c = $tag(osui::ComponentParams { children: osui::__oml!($($inner)*), expr: String::new() }); + let mut c = $tag(osui::Params { children: osui::__oml!($($inner)*), expr: String::new() }); $( c.$k = $v; )* - Box::new(c) + c }}; // Pre-Defined (D) diff --git a/src/main.rs b/src/main.rs index 1f3e917..ab16053 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,31 +1,34 @@ use osui::{ - components::{div, text, Div}, - oml, ComponentParams, + components::{div, text}, + oml, Component, Params, Screen, }; fn main() { - let doc = oml!(div {app()}); - - println!("{:?}", doc); + let mut screen = Screen::new(); + screen.set_component(oml!(app())); + screen.run(); } -fn app(_: ComponentParams) -> Div { - *oml!( +fn app(_: Params) -> Component { + oml!( // Components (C) - div { - // Props, With components (PC) - div () { - // Props (P) - text(/* Properties go here, Example: x = 20 y = 5 */) - } + div (width = 5, height = 3) { - // Expression (E) - text("Hello";) + text("Hello, World! daddy"; width = 30) - // Expression, With components (EC) - text("World!";) { - // Components in here - } + // // Props, With components (PC) + // div () { + // // Props (P) + // text(/* Properties go here, Example: x = 20 y = 5 */) + // } + + // // Expression (E) + // text("Hello";) + + // // Expression, With components (EC) + // text("World!";) { + // // Components in here + // } } ) }