diff --git a/src/elements/grid.rs b/src/elements/grid.rs new file mode 100644 index 0000000..fa79f9c --- /dev/null +++ b/src/elements/grid.rs @@ -0,0 +1,79 @@ +use std::sync::{Arc, Mutex}; + +use crate::{ + extensions::Handler, + style::RawTransform, + widget::{Element, Widget}, + RenderWrapperEvent, +}; + +pub struct VGrid { + transform: Mutex, + color: u32, + gap: u16, +} + +impl Element for Arc { + fn render(&mut self, scope: &mut crate::render_scope::RenderScope) { + let transform = self.transform.lock().unwrap(); + let (w, h) = scope.get_size_or(transform.width, transform.height); + scope.draw_rect(w, h, self.color); + } + + fn after_render(&mut self, scope: &crate::render_scope::RenderScope) { + *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 VGrid { + pub fn new(color: u32, gap: u16) -> Arc { + Arc::new(VGrid { + transform: Mutex::new(RawTransform::new()), + color, + gap, + }) + } + + pub fn draw(self: &Arc, element: &Arc) -> Arc { + let r2 = self.clone(); + 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 (w, h) = scope.get_parent_size(); + scope.set_parent_size(transform.width, transform.height); + + if let Some(t) = elem.get() { + scope.set_transform(&t); + } + + elem.0.lock().unwrap().render(scope); + + if let Some(t) = elem.get() { + scope.set_transform(&t); + } + + let elem_transform = scope.get_transform_mut(); + elem_transform.x += transform.x; + elem_transform.y = transform.y; + transform.y += elem_transform.height + r2.gap; + + scope.draw(); + elem.0.lock().unwrap().after_render(&scope); + + scope.set_parent_size(w, h); + })); + r + } +} diff --git a/src/elements/mod.rs b/src/elements/mod.rs index a9d82ef..67b8379 100644 --- a/src/elements/mod.rs +++ b/src/elements/mod.rs @@ -1,4 +1,5 @@ pub mod div; +pub mod grid; use crate::Element; diff --git a/src/main.rs b/src/main.rs index 368060f..e0112ef 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ use osui::{ - elements::div::Div, + elements::grid::VGrid, extensions::{id::IdExtension, tick::TickExtension}, style::Transform, Screen, @@ -11,17 +11,19 @@ fn main() { screen.extension(document.clone()); screen.extension(TickExtension(10)); - let my_div = Div::new(0xff0000); + let my_div = VGrid::new(0xff0000, 1); screen .draw(my_div.clone()) - .component(Transform::center().dimensions(21, 3)); + .component(Transform::center().dimensions(16, 9)); - my_div.draw( - screen - .draw(format!("Hello, World!")) - .component(Transform::center()), - ); + for i in 1..6 { + my_div.draw( + screen + .draw(format!("Item {i}")) + .component(Transform::center()), + ); + } screen.run().unwrap(); } diff --git a/src/render_scope.rs b/src/render_scope.rs index 41646f9..a295c4d 100644 --- a/src/render_scope.rs +++ b/src/render_scope.rs @@ -79,6 +79,21 @@ impl RenderScope { (self.transform.width, self.transform.height) } + pub fn get_size_or(&self, width: u16, height: u16) -> (u16, u16) { + ( + if self.transform.width == 0 { + width + } else { + self.transform.width + }, + if self.transform.height == 0 { + height + } else { + self.transform.height + }, + ) + } + pub fn get_size_or_parent(&self) -> (u16, u16) { ( if self.transform.width == 0 {