diff --git a/Cargo.toml b/Cargo.toml index 4dedff9..a7b33db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,6 @@ documentation = "https://osui.netlify.app/docs/" [features] no_rsx = [] portable = [] -engine = [] no_elem = [] [lib] diff --git a/src/console.rs b/src/console.rs index 0d4e91b..16530d5 100644 --- a/src/console.rs +++ b/src/console.rs @@ -58,14 +58,12 @@ impl Console { /// Runs the console loop, rendering the UI and handling events. /// - /// This method is disabled when the `engine` feature is enabled. /// /// # Arguments /// * `ui` - The UI element to render. /// /// # Returns /// A `Result` indicating success or failure. - #[cfg(not(feature = "engine"))] pub fn run(&mut self, ui: Element) -> crate::Result<()> { self.draw(ui.clone(), None)?; loop { diff --git a/src/elements.rs b/src/elements.rs index fb99bb8..f78a9ec 100644 --- a/src/elements.rs +++ b/src/elements.rs @@ -1,4 +1,4 @@ -use crate::Widget; +use crate::prelude::*; impl Widget for &str { fn render(&self) -> String { @@ -11,3 +11,64 @@ impl Widget for String { self.clone() } } + +pub struct Button { + pub on_click: Box, + children: String, + width: u16, + height: u16, + last_elem: (u16, u16), +} + +pub fn btn() -> Button { + Button { + on_click: Box::new(|| {}), + children: String::new(), + width: 0, + height: 0, + last_elem: (0, 0), + } +} + +impl Widget for Button { + fn render(&self) -> String { + self.children.clone() + } + fn event(&mut self, _: crate::console::Event) { + (self.on_click)() + } +} + +impl Button { + pub fn draw(&mut self, w: &W, props: crate::Area) -> crate::Result<()> + where + W: Widget, + { + let written = w.render(); + + let (ww, wh) = utils::str_size(&written); + + let (width, height) = ( + props.width.get(ww, self.width), + props.height.get(wh, self.height), + ); + + let (x, y) = ( + props.x.get(self.last_elem.0, width, self.width), + props.y.get(self.last_elem.1, height, self.height), + ); + + self.children += written + .lines() + .enumerate() + .filter(|(i, _)| -> bool { height > (*i as u16) }) + .map(|(_, s)| s.chars().take(width as usize).collect::()) + .collect::>() + .join("\n") + .as_str(); + + self.last_elem.0 = x + width; + self.last_elem.1 = y + height; + Ok(()) + } +} diff --git a/src/lib.rs b/src/lib.rs index bed1648..5c6eca4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,6 +20,7 @@ pub mod utils; /// Commonly used imports for convenience. pub mod prelude { + pub use crate::elements::*; pub use crate::*; pub use console::Event; pub use crossterm::event::{KeyCode, KeyEvent}; diff --git a/src/main.rs b/src/main.rs index 0190fef..f406ee4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ use osui::prelude::*; fn main() -> osui::Result<()> { - let mut con = console::init(true)?; + let mut con = console::init(false)?; con.run(app())?; @@ -10,6 +10,8 @@ fn main() -> osui::Result<()> { pub fn app() -> Element { rsx! { - "" + btn { on_click: Box::new(|| { + panic!("Testing"); + }), "Click me" } } } diff --git a/src/rsx.rs b/src/rsx.rs index 54c19c6..e17bfca 100644 --- a/src/rsx.rs +++ b/src/rsx.rs @@ -11,7 +11,7 @@ /// "Hello, World!" /// } /// ``` -/// +/// /// Button example /// ```rust /// rsx! { @@ -89,15 +89,47 @@ macro_rules! rsx_inner { $crate::rsx_inner!($frame, $event; $($rest)*); }; - // name { rsx } + // Name { rsx } ( area ) ($frame:expr, $event:expr; $elem:path { - $($einner:tt)* - } ($($inner:tt)*) + $($n:ident: $v:expr),+ + $(, + $($inner:tt)* + )? + } ($($area_inner:tt)*) $($rest:tt)*) => { let mut area = $crate::Area::new(); - $crate::tw_area!(area, $($inner)*); - $elem()($frame, $event)?; + $crate::tw_area!(area, $($area_inner)*); + let mut e = $elem(); + $( + e.$n = $v; + )* + $( + $crate::rsx_inner!(e, $event; $($inner)*); + )? + + $frame.draw(&e, area)?; + $crate::rsx_inner!($frame, $event; $($rest)*); + }; + + // Name { rsx } + ($frame:expr, $event:expr; + $elem:path { + $($n:ident: $v:expr),+ + $(, + $($inner:tt)* + )? + } + $($rest:tt)*) => { + let mut e = $elem(); + $( + e.$n = $v; + )* + $( + $crate::rsx_inner!(e, $event; $($inner)*); + )? + + $frame.draw(&e, $crate::Area::new())?; $crate::rsx_inner!($frame, $event; $($rest)*); };