marble-machinations/src/ui2.rs

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,
}
}
}