use raylib::{ color::Color, drawing::{RaylibDraw, RaylibDrawHandle}, RaylibHandle, }; pub type EId = String; // pub enum EId{ // } #[derive(Debug, Default)] pub struct UiCtx { active: Option, hovered: Option, kb_selected: Option, layout: LayoutState, draw_queue: Vec, } #[derive(Debug, Default, Clone, Copy)] pub enum Axis { #[default] Horizontal, Vertical, } #[derive(Debug, Clone)] pub enum DrawCommand { Rect(Rect, Color), Text(String), } #[derive(Debug, Clone)] pub struct Rect { x: i32, y: i32, width: i32, height: i32, } #[derive(Debug, Default, Clone)] pub struct LayoutState { pub direction: Axis, cursor_x: i32, cursor_y: i32, width: i32, height: i32, pub padding: i32, } type Widget = fn(&mut UiCtx) -> (); // type Widget = FnMut<; impl UiCtx { pub fn layout(&mut self) -> &mut LayoutState { &mut self.layout } pub fn begin(&mut self, d: &mut RaylibDrawHandle) { self.layout = LayoutState::default(); } pub fn draw(&mut self, d: &mut RaylibDrawHandle) { while let Some(cmd) = self.draw_queue.pop() { match cmd { DrawCommand::Rect(r, col) => d.draw_rectangle(r.x, r.y, r.width, r.height, col), DrawCommand::Text(_) => todo!(), } } } pub fn padded_container(&mut self, color: Color, axis: Axis, widget: Widget) { self.layout.padding = 4; self.layout.direction = axis; self.layout.width = 0; self.layout.height = 0; let old_layout_state = self.layout.clone(); widget(self); let width = self.layout.width; let height = self.layout.height; self.layout = old_layout_state; self.layout.update_size_with_child(width, height); // old_layout_state.update_size_with_child(self.layout.width, self.layout.height); // old_layout_state.step(self.layout.width, self.layout.height); self.draw_queue .push(DrawCommand::Rect(self.layout.rect(), color)); self.layout.step(width, height); // self.layout.step(width, height); } pub fn square(&mut self, color: Color, width: i32) { let height = 50; // self.layout.update_size_with_child(width, height); self.layout.width = width; self.layout.height = height; self.draw_queue.push(DrawCommand::Rect( self.layout.rect(), color, )); self.layout.step(width, height) // self.layout.width = width; // self.layout.height = height; // self.layout.step(width, height) } } impl LayoutState { fn step(&mut self, width: i32, height: i32) { match self.direction { Axis::Horizontal => self.cursor_x += width + self.padding, Axis::Vertical => self.cursor_y += height + self.padding, } } fn update_size_with_child(&mut self, width: i32, height: i32) { match self.direction { Axis::Horizontal => { self.width += width + self.padding; self.height = self.height.max(height + self.padding); } Axis::Vertical => { self.width = self.width.max(width + self.padding); self.height += height + self.padding; } } } fn rect(&self) -> Rect { Rect::new(self.cursor_x, self.cursor_y, self.width, self.height) } } impl Rect { pub fn new(x: i32, y: i32, width: i32, height: i32) -> Self { Self { x, y, width, height, } } }