use crate::{components::Component, style::Style};
pub struct Renderer {
backend: Box<dyn RenderBackend>,
}
pub trait RenderBackend {
fn initialize(&mut self) -> Result<(), Box<dyn std::error::Error>>;
fn cleanup(&mut self);
fn begin_frame(&mut self);
fn end_frame(&mut self);
fn render_component(&mut self, component: &Component, x: f32, y: f32, width: f32, height: f32);
fn draw_rect(&mut self, x: f32, y: f32, width: f32, height: f32, style: &Style);
fn draw_text(&mut self, text: &str, x: f32, y: f32, style: &Style);
fn measure_text(&mut self, text: &str, style: &Style) -> (f32, f32);
}
impl Renderer {
pub fn new(backend: Box<dyn RenderBackend>) -> Self {
Self { backend }
}
pub fn initialize(&mut self) -> Result<(), Box<dyn std::error::Error>> {
self.backend.initialize()
}
pub fn cleanup(&mut self) {
self.backend.cleanup();
}
pub fn begin_frame(&mut self) {
self.backend.begin_frame();
}
pub fn end_frame(&mut self) {
self.backend.end_frame();
}
pub fn render(&mut self, root: &Component, width: f32, height: f32) {
self.begin_frame();
self.render_component_recursive(root, 0.0, 0.0, width, height);
self.end_frame();
}
fn render_component_recursive(&mut self, component: &Component, x: f32, y: f32, width: f32, height: f32) {
if !component.properties().visible {
return;
}
self.backend.render_component(component, x, y, width, height);
for child in component.children() {
let child_y = y + 50.0; self.render_component_recursive(child, x + 20.0, child_y, width - 40.0, 40.0);
}
}
}
#[derive(Debug)]
pub struct ExampleRenderBackend {
initialized: bool,
}
impl ExampleRenderBackend {
pub fn new() -> Self {
Self { initialized: false }
}
}
impl RenderBackend for ExampleRenderBackend {
fn initialize(&mut self) -> Result<(), Box<dyn std::error::Error>> {
println!("Initializing example render backend");
self.initialized = true;
Ok(())
}
fn cleanup(&mut self) {
println!("Cleaning up example render backend");
self.initialized = false;
}
fn begin_frame(&mut self) {
println!("Beginning render frame");
}
fn end_frame(&mut self) {
println!("Ending render frame");
}
fn render_component(&mut self, component: &Component, x: f32, y: f32, width: f32, height: f32) {
println!("Rendering component {} at ({}, {}, {}, {})", component.id(), x, y, width, height);
}
fn draw_rect(&mut self, x: f32, y: f32, width: f32, height: f32, _style: &Style) {
println!("Drawing rect at ({}, {}, {}, {})", x, y, width, height);
}
fn draw_text(&mut self, text: &str, x: f32, y: f32, _style: &Style) {
println!("Drawing text '{}' at ({}, {})", text, x, y);
}
fn measure_text(&mut self, text: &str, _style: &Style) -> (f32, f32) {
(text.len() as f32 * 8.0, 16.0)
}
}