142 lines
3.1 KiB
Rust
142 lines
3.1 KiB
Rust
use raylib::{
|
|
color::Color,
|
|
drawing::{RaylibDraw, RaylibDrawHandle},
|
|
RaylibHandle,
|
|
};
|
|
|
|
pub type EId = String;
|
|
// pub enum EId{
|
|
// }
|
|
|
|
#[derive(Debug, Default)]
|
|
pub struct UiCtx {
|
|
active: Option<EId>,
|
|
hovered: Option<EId>,
|
|
kb_selected: Option<EId>,
|
|
layout: LayoutState,
|
|
draw_queue: Vec<DrawCommand>,
|
|
}
|
|
|
|
#[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,
|
|
}
|
|
}
|
|
}
|