diff --git a/src/elements/div.rs b/src/elements/div.rs new file mode 100644 index 0000000..73ecb14 --- /dev/null +++ b/src/elements/div.rs @@ -0,0 +1,50 @@ +use std::sync::Arc; + +use crate::{ + render::RenderScope, + widget::{Element, Widget}, +}; + +pub struct Div(Vec>); + +impl Element for Div { + fn render(&mut self, scope_parent: &mut crate::render::RenderScope) { + let (w, h) = scope_parent.get_size_or_parent(); + let mut scope = RenderScope::new(w, h); + + for elem in &self.0 { + scope.clear(); + + if let Some(t) = elem.get() { + scope.set_transform(&t); + } + + elem.0.lock().unwrap().render(&mut scope); + + if let Some(t) = elem.get() { + scope.set_transform(&t); + } + + scope.draw_buf(scope_parent.get_buffer_mut()); + } + } + + 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() -> Self { + Self(Vec::new()) + } + + pub fn draw(&mut self, element: E) -> &Arc { + self.0.push(Arc::new(Widget::new(Box::new(element)))); + self.0.last().unwrap() + } +} diff --git a/src/elements/mod.rs b/src/elements/mod.rs index d686fb6..fdd2c95 100644 --- a/src/elements/mod.rs +++ b/src/elements/mod.rs @@ -1,3 +1,5 @@ +pub mod div; + use crate::widget::Element; pub struct Rect; diff --git a/src/main.rs b/src/main.rs index fb9ee30..3f13986 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,7 @@ use minifb::{Window, WindowOptions}; -use osgui::{extensions::velocity::VelocityExtension, style::Transform, Screen}; +use osgui::{ + elements::div::Div, extensions::velocity::VelocityExtension, style::Transform, Screen, +}; fn main() { let window = Window::new( @@ -16,7 +18,13 @@ fn main() { let mut app = Screen::new(window); app.extension(VelocityExtension); - app.draw("test".to_string()).component(Transform::center()); + let mut d = Div::new(); + + d.draw("test".to_string()); + d.draw("abc".to_string()); + + app.draw(d) + .component(Transform::center().dimensions(150, 80)); app.run().unwrap(); } diff --git a/src/render.rs b/src/render.rs index a6673bd..60f535a 100644 --- a/src/render.rs +++ b/src/render.rs @@ -7,7 +7,8 @@ use crate::{ const FONT: &[u8] = include_bytes!("../assets/DejaVuSans.ttf"); -enum RenderMethod { +#[derive(Debug, Clone)] +pub enum RenderMethod { Text(String, usize, usize, f32, u32), Rectangle(usize, usize, usize, usize, u32), } @@ -53,15 +54,19 @@ impl RenderScope { } pub fn draw(&mut self) { + let mut b = self.buffer.clone(); + self.draw_buf(&mut b); + self.buffer = b; + } + + pub fn draw_buf(&mut self, buf: &mut Vec) { for m in &self.render_stack { match m { &RenderMethod::Rectangle(pos_x, pos_y, width, height, color) => { for x in self.transform.x + pos_x..self.transform.x + pos_x + width { for y in self.transform.y + pos_y..self.transform.y + pos_y + height { - if self.buffer.len() > y * self.parent_height + x - && self.parent_width > x - { - self.buffer[y * self.parent_height + x] = color; + if buf.len() > y * self.parent_height + x && self.parent_width > x { + buf[y * self.parent_height + x] = color; } } } @@ -101,7 +106,7 @@ impl RenderScope { let g = (g_base * v) as u32; let b = (b_base * v) as u32; let color = (r << 16) | (g << 8) | b; - self.buffer[index] = color; + buf[index] = color; } }); } @@ -121,6 +126,21 @@ impl RenderScope { (self.transform.width, self.transform.height) } + pub fn get_size_or_parent(&self) -> (usize, usize) { + ( + if self.transform.width > 0 { + self.transform.width + } else { + self.parent_width + }, + if self.transform.height > 0 { + self.transform.height + } else { + self.parent_height + }, + ) + } + pub fn get_parent_size(&self) -> (usize, usize) { (self.parent_width, self.parent_height) } @@ -128,4 +148,8 @@ impl RenderScope { pub fn get_buffer(&self) -> Vec { self.buffer.clone() } + + pub fn get_buffer_mut(&mut self) -> &mut Vec { + &mut self.buffer + } }