wip refactor

This commit is contained in:
griffi-gh 2024-02-26 01:15:55 +01:00
parent 23dc81a921
commit 9aa61f392e
10 changed files with 105 additions and 162 deletions

View file

@ -6,15 +6,9 @@ use winit::{
event_loop::{EventLoopBuilder, ControlFlow} event_loop::{EventLoopBuilder, ControlFlow}
}; };
use hui::{ use hui::{
UiInstance,
layout::{Alignment, UiSize, UiDirection},
rectangle::{Sides, Corners},
element::{ element::{
UiElement, container::Container, progress_bar::ProgressBar, rect::Rect, ElementList, UiElement
progress_bar::ProgressBar, }, layout::{Alignment, UiDirection, UiSize}, rectangle::{Corners, Sides}, UiInstance
container::Container,
rect::Rect
},
}; };
use hui_glium::GliumUiRenderer; use hui_glium::GliumUiRenderer;
@ -49,12 +43,12 @@ fn main() {
padding: Sides::all(5.), padding: Sides::all(5.),
align: (Alignment::Begin, Alignment::Center).into(), align: (Alignment::Begin, Alignment::Center).into(),
size: (UiSize::Fraction(1.), UiSize::Fraction(1.)), size: (UiSize::Fraction(1.), UiSize::Fraction(1.)),
elements: vec![ children: ElementList(vec![
Box::new(ProgressBar { Box::new(ProgressBar {
value: 0.5, value: 0.5,
..Default::default() ..Default::default()
}), }),
], ]),
..Default::default() ..Default::default()
}, resolution); }, resolution);
@ -63,7 +57,7 @@ fn main() {
padding: Sides::all(5.), padding: Sides::all(5.),
align: (Alignment::End, Alignment::Center).into(), align: (Alignment::End, Alignment::Center).into(),
size: (UiSize::Fraction(1.), UiSize::Fraction(1.)), size: (UiSize::Fraction(1.), UiSize::Fraction(1.)),
elements: vec![ children: ElementList(vec![
Box::new(ProgressBar { Box::new(ProgressBar {
value: z, value: z,
corner_radius: Corners::all(0.25 * ProgressBar::DEFAULT_HEIGHT), corner_radius: Corners::all(0.25 * ProgressBar::DEFAULT_HEIGHT),
@ -74,7 +68,7 @@ fn main() {
align: (Alignment::Center, Alignment::End).into(), align: (Alignment::Center, Alignment::End).into(),
padding: Sides::all(5.), padding: Sides::all(5.),
gap: 10., gap: 10.,
elements: vec![ children: ElementList(vec![
Box::new(Rect { Box::new(Rect {
size: (UiSize::Fraction(0.5), UiSize::Static(30.)), size: (UiSize::Fraction(0.5), UiSize::Static(30.)),
color: vec4(0.75, 0., 0., 1.).into() color: vec4(0.75, 0., 0., 1.).into()
@ -86,7 +80,7 @@ fn main() {
vec4(0., 1., 0., 1.) vec4(0., 1., 0., 1.)
).into(), ).into(),
}), }),
], ]),
..Default::default() ..Default::default()
}), }),
Box::new(Rect { Box::new(Rect {
@ -98,7 +92,7 @@ fn main() {
padding: Sides::all(5.), padding: Sides::all(5.),
background: vec4(0., 0., 0., 0.5).into(), background: vec4(0., 0., 0., 0.5).into(),
direction: UiDirection::Horizontal, direction: UiDirection::Horizontal,
elements: { children: {
let mut x: Vec<Box<dyn UiElement>> = vec![]; let mut x: Vec<Box<dyn UiElement>> = vec![];
for i in 0..10 { for i in 0..10 {
x.push(Box::new(Rect { x.push(Box::new(Rect {
@ -110,7 +104,7 @@ fn main() {
} }
})); }));
} }
x ElementList(x)
}, },
..Default::default() ..Default::default()
}), }),
@ -128,15 +122,15 @@ fn main() {
bottom_left: 0., bottom_left: 0.,
bottom_right: 0., bottom_right: 0.,
}, },
elements: vec![ children: ElementList(vec![
Box::new(Rect { Box::new(Rect {
size: (UiSize::Static(50.), UiSize::Static(50.)), size: (UiSize::Static(50.), UiSize::Static(50.)),
color: vec4(1., 1., 1., 0.75).into() color: vec4(1., 1., 1., 0.75).into()
}), }),
], ]),
..Default::default() ..Default::default()
}), }),
], ]),
..Default::default() ..Default::default()
}, resolution); }, resolution);

View file

@ -1,4 +1,5 @@
use glam::UVec2; use std::time::Instant;
use glam::{UVec2, vec4};
use glium::{backend::glutin::SimpleWindowBuilder, Surface}; use glium::{backend::glutin::SimpleWindowBuilder, Surface};
use winit::{ use winit::{
event::{Event, WindowEvent}, event::{Event, WindowEvent},
@ -6,12 +7,13 @@ use winit::{
}; };
use hui::{ use hui::{
UiInstance, UiInstance,
rectangle::Sides,
layout::{UiSize, Alignment},
element::{ element::{
ElementList, UiElementListExt,
container::Container, container::Container,
text::Text, text::Text,
} },
layout::{Alignment, UiDirection, UiSize},
rectangle::{Corners, Sides},
}; };
use hui_glium::GliumUiRenderer; use hui_glium::GliumUiRenderer;
@ -23,6 +25,7 @@ fn main() {
let mut hui = UiInstance::new(); let mut hui = UiInstance::new();
let mut backend = GliumUiRenderer::new(&display); let mut backend = GliumUiRenderer::new(&display);
event_loop.run(|event, window_target| { event_loop.run(|event, window_target| {
window_target.set_control_flow(ControlFlow::Poll); window_target.set_control_flow(ControlFlow::Poll);
match event { match event {
@ -37,19 +40,15 @@ fn main() {
hui.begin(); hui.begin();
hui.add(Container { hui.add({
gap: 5., Container::default()
padding: Sides::all(5.), .with_padding(Sides::all(5.))
align: Alignment::Center.into(), .with_children(|ui: &mut ElementList| {
size: (UiSize::Fraction(1.), UiSize::Fraction(1.)), Text::default()
elements: vec![ .with_text("Hello, world")
Box::new(Text { .with_text_size(12)
text: "Hello, world!\nGoodbye, world!\nowo\nuwu".into(), .add_to(ui);
text_size: 120, })
..Default::default()
}),
],
..Default::default()
}, resolution); }, resolution);
hui.end(); hui.end();

View file

@ -6,21 +6,21 @@ use winit::{
event_loop::{EventLoopBuilder, ControlFlow} event_loop::{EventLoopBuilder, ControlFlow}
}; };
use hui::{ use hui::{
UiInstance,
layout::{Alignment, UiDirection, UiSize},
rectangle::{Corners, Sides},
element::{ element::{
container::Container, container::Container,
progress_bar::ProgressBar, progress_bar::ProgressBar,
text::Text, text::Text, ElementList,
}, },
layout::{Alignment, UiDirection, UiSize},
rectangle::{Corners, Sides},
UiInstance,
}; };
use hui_glium::GliumUiRenderer; use hui_glium::GliumUiRenderer;
fn elements(mut f: impl FnMut(&mut Vec<Box<dyn hui::element::UiElement>>)) -> Vec<Box<dyn hui::element::UiElement>> { fn elements(mut f: impl FnMut(&mut Vec<Box<dyn hui::element::UiElement>>)) -> ElementList {
let mut e = vec![]; let mut e = vec![];
f(&mut e); f(&mut e);
e ElementList(e)
} }
fn main() { fn main() {
@ -57,13 +57,13 @@ fn main() {
align: Alignment::Center.into(), align: Alignment::Center.into(),
size: (UiSize::Fraction(1.), UiSize::Fraction(1.)), size: (UiSize::Fraction(1.), UiSize::Fraction(1.)),
background: vec4(0.1, 0.1, 0.1, 1.).into(), background: vec4(0.1, 0.1, 0.1, 1.).into(),
elements: vec![Box::new(Container { children: ElementList(vec![Box::new(Container {
gap: 5., gap: 5.,
padding: Sides::all(10.), padding: Sides::all(10.),
size: (UiSize::Static(450.), UiSize::Auto), size: (UiSize::Static(450.), UiSize::Auto),
background: vec4(0.2, 0.2, 0.5, 1.).into(), background: vec4(0.2, 0.2, 0.5, 1.).into(),
corner_radius: Corners::all(8.), corner_radius: Corners::all(8.),
elements: elements(|el| { children: elements(|el| {
if instant.elapsed().as_secs_f32() < 5. { if instant.elapsed().as_secs_f32() < 5. {
el.push(Box::new(Text { el.push(Box::new(Text {
text: "Downloading your mom...".into(), text: "Downloading your mom...".into(),
@ -80,12 +80,12 @@ fn main() {
direction: UiDirection::Horizontal, direction: UiDirection::Horizontal,
align: (Alignment::End, Alignment::Center).into(), align: (Alignment::End, Alignment::Center).into(),
size: (UiSize::Fraction(1.), UiSize::Auto), size: (UiSize::Fraction(1.), UiSize::Auto),
elements: vec![Box::new(Text { children: ElementList(vec![Box::new(Text {
text: format!("{:.2}% ({:.1} GB)", mom_ratio * 100., mom_ratio * 10000.).into(), text: format!("{:.2}% ({:.1} GB)", mom_ratio * 100., mom_ratio * 10000.).into(),
font: font_handle, font: font_handle,
text_size: 16, text_size: 16,
..Default::default() ..Default::default()
})], })]),
..Default::default() ..Default::default()
})); }));
} else if instant.elapsed().as_secs() < 10 { } else if instant.elapsed().as_secs() < 10 {
@ -107,7 +107,7 @@ fn main() {
} }
}), }),
..Default::default() ..Default::default()
})], })]),
..Default::default() ..Default::default()
}, resolution); }, resolution);

View file

@ -5,13 +5,13 @@ use winit::{
event_loop::{EventLoopBuilder, ControlFlow} event_loop::{EventLoopBuilder, ControlFlow}
}; };
use hui::{ use hui::{
UiInstance,
layout::{Alignment, UiSize, UiDirection},
rectangle::{Corners, Sides},
element::{ element::{
container::Container, container::Container,
text::Text text::Text, ElementList
}, },
layout::{Alignment, UiDirection, UiSize},
rectangle::{Corners, Sides},
UiInstance
}; };
use hui_glium::GliumUiRenderer; use hui_glium::GliumUiRenderer;
@ -41,7 +41,7 @@ fn main() {
gap: 10., gap: 10.,
align: Alignment::Center.into(), align: Alignment::Center.into(),
size: (UiSize::Fraction(1.), UiSize::Fraction(1.)), size: (UiSize::Fraction(1.), UiSize::Fraction(1.)),
elements: vec![ children: ElementList(vec![
Box::new(Container { Box::new(Container {
align: Alignment::Center.into(), align: Alignment::Center.into(),
size: (UiSize::Fraction(0.5), UiSize::Fraction(0.5)), size: (UiSize::Fraction(0.5), UiSize::Fraction(0.5)),
@ -52,7 +52,7 @@ fn main() {
bottom_left: 50., bottom_left: 50.,
bottom_right: 80. bottom_right: 80.
}, },
elements: vec![ children: ElementList(vec![
Box::new(Container { Box::new(Container {
padding: Sides::all(20.), padding: Sides::all(20.),
direction: UiDirection::Horizontal, direction: UiDirection::Horizontal,
@ -60,7 +60,7 @@ fn main() {
size: (UiSize::Auto, UiSize::Auto), size: (UiSize::Auto, UiSize::Auto),
background: vec4(0.1, 0.1, 0.1, 0.5).into(), background: vec4(0.1, 0.1, 0.1, 0.5).into(),
corner_radius: Corners::all(8.), corner_radius: Corners::all(8.),
elements: vec![ children: ElementList(vec![
Box::new(Text { Box::new(Text {
text: "Corners".into(), text: "Corners".into(),
text_size: 50, text_size: 50,
@ -73,16 +73,16 @@ fn main() {
color: vec4(1., 1., 0., 1.), color: vec4(1., 1., 0., 1.),
..Default::default() ..Default::default()
}), }),
], ]),
..Default::default() ..Default::default()
}), }),
], ]),
..Default::default() ..Default::default()
}), }),
Box::new(Container { Box::new(Container {
gap: 10., gap: 10.,
direction: UiDirection::Horizontal, direction: UiDirection::Horizontal,
elements: vec![ children: ElementList(vec![
Box::new(Container { Box::new(Container {
size: (UiSize::Static(100.), UiSize::Static(100.)), size: (UiSize::Static(100.), UiSize::Static(100.)),
background: Corners::left_right( background: Corners::left_right(
@ -119,10 +119,10 @@ fn main() {
corner_radius: Corners::all(30.), corner_radius: Corners::all(30.),
..Default::default() ..Default::default()
}), }),
], ]),
..Default::default() ..Default::default()
}), }),
], ]),
..Default::default() ..Default::default()
}, resolution); }, resolution);

View file

@ -1,91 +0,0 @@
use std::time::Instant;
use glam::UVec2;
use glium::{backend::glutin::SimpleWindowBuilder, Surface};
use winit::{
event::{Event, WindowEvent},
event_loop::{EventLoopBuilder, ControlFlow}
};
use hui::{
UiInstance,
layout::UiSize,
rectangle::Sides,
element::{
container::Container,
progress_bar::ProgressBar,
UiElement
},
};
use hui_glium::GliumUiRenderer;
fn main() {
kubi_logging::init();
let event_loop = EventLoopBuilder::new().build().unwrap();
let (_window, display) = SimpleWindowBuilder::new().build(&event_loop);
let mut hui = UiInstance::new();
let mut backend = GliumUiRenderer::new(&display);
let instant = Instant::now();
let mut pcnt = 0;
event_loop.run(|event, window_target| {
window_target.set_control_flow(ControlFlow::Poll);
match event {
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => {
window_target.exit();
},
Event::AboutToWait => {
let mut frame = display.draw();
frame.clear_color_srgb(0.5, 0.5, 0.5, 0.);
let resolution = UVec2::from(display.get_framebuffer_dimensions()).as_vec2();
hui.begin();
hui.add(Container {
gap: 5.,
padding: Sides::all(5.),
elements: vec![
Box::new(ProgressBar {
value: 0.5,
..Default::default()
}),
Box::new(ProgressBar {
value: instant.elapsed().as_secs_f32().sin().powi(2),
..Default::default()
}),
Box::new(Container {
gap: 1.,
elements: {
let mut elements: Vec<Box<dyn UiElement>> = vec![];
let cnt = instant.elapsed().as_secs() * 10000;
if pcnt != cnt {
log::info!("{cnt}");
pcnt = cnt;
}
for i in 0..cnt {
elements.push(Box::new(ProgressBar {
value: (instant.elapsed().as_secs_f32() + (i as f32 / 10.)).sin().powi(2),
size: (UiSize::Auto, UiSize::Static(5.)),
..Default::default()
}));
}
elements
},
..Default::default()
})
],
..Default::default()
}, resolution);
hui.end();
backend.update(&hui);
backend.draw(&mut frame, resolution);
frame.finish().unwrap();
}
_ => (),
}
}).unwrap();
}

View file

@ -6,19 +6,16 @@ use winit::{
event_loop::{EventLoopBuilder, ControlFlow} event_loop::{EventLoopBuilder, ControlFlow}
}; };
use hui::{ use hui::{
UiInstance,
layout::UiSize,
element::{ element::{
container::Container, container::Container, rect::Rect, spacer::Spacer, text::Text, ElementList
text::Text, rect::Rect, spacer::Spacer }, layout::UiSize, UiInstance
},
}; };
use hui_glium::GliumUiRenderer; use hui_glium::GliumUiRenderer;
fn elements(mut f: impl FnMut(&mut Vec<Box<dyn hui::element::UiElement>>)) -> Vec<Box<dyn hui::element::UiElement>> { fn elements(mut f: impl FnMut(&mut Vec<Box<dyn hui::element::UiElement>>)) -> ElementList {
let mut e = vec![]; let mut e = vec![];
f(&mut e); f(&mut e);
e ElementList(e)
} }
fn main() { fn main() {
@ -51,7 +48,7 @@ fn main() {
hui.add(Container { hui.add(Container {
size: (UiSize::Fraction(1.), UiSize::Fraction(1.)), size: (UiSize::Fraction(1.), UiSize::Fraction(1.)),
background: vec4(0.1, 0.1, 0.1, 1.).into(), background: vec4(0.1, 0.1, 0.1, 1.).into(),
elements: elements(|elem| { children: elements(|elem| {
elem.push(Box::new(Text { elem.push(Box::new(Text {
text: "THIS LINE SHOULD BE SHARP!".into(), text: "THIS LINE SHOULD BE SHARP!".into(),
..Default::default() ..Default::default()

View file

@ -24,6 +24,7 @@ rect_packer = "0.2"
log = "0.4" log = "0.4"
nz = "0.3" nz = "0.3"
document-features = "0.2" document-features = "0.2"
derive_setters = "0.1"
[features] [features]
default = ["builtin_elements", "builtin_font", "pixel_perfect_text"] default = ["builtin_elements", "builtin_font", "pixel_perfect_text"]

View file

@ -60,3 +60,35 @@ pub trait UiElement {
/// You should process the user inputs and render the element here. /// You should process the user inputs and render the element here.
fn process(&self, ctx: ProcessContext); fn process(&self, ctx: ProcessContext);
} }
pub struct ElementList(pub Vec<Box<dyn UiElement>>);
impl ElementList {
pub fn add<'a>(&mut self, element: impl UiElement + 'static) {
self.0.push(Box::new(element))
}
}
impl<T: FnOnce(&mut ElementList)> From<T> for ElementList {
fn from(cb: T) -> Self {
let mut list = ElementList(Vec::new());
cb(&mut list);
list
}
}
impl From<Vec<Box<dyn UiElement>>> for ElementList {
fn from(value: Vec<Box<dyn UiElement>>) -> Self {
Self(value)
}
}
pub trait UiElementListExt {
fn add_to(self, list: &mut ElementList);
}
impl<T: UiElement + 'static> UiElementListExt for T {
fn add_to(self, list: &mut ElementList) {
list.add(self)
}
}

View file

@ -1,8 +1,9 @@
use derive_setters::Setters;
use glam::{Vec2, vec2}; use glam::{Vec2, vec2};
use crate::{ use crate::{
background::BackgroundColor, background::BackgroundColor,
draw::{RoundedCorners, UiDrawCommand}, draw::{RoundedCorners, UiDrawCommand},
element::{MeasureContext, ProcessContext, UiElement}, element::{ElementList, MeasureContext, ProcessContext, UiElement},
layout::{Alignment, Alignment2d, LayoutInfo, UiDirection, UiSize}, layout::{Alignment, Alignment2d, LayoutInfo, UiDirection, UiSize},
measure::{Hints, Response}, measure::{Hints, Response},
rectangle::{Corners, Sides} rectangle::{Corners, Sides}
@ -18,15 +19,21 @@ use crate::{
//TODO: borders //TODO: borders
//TODO: min/max size //TODO: min/max size
#[derive(Setters)]
#[setters(prefix = "with_")]
pub struct Container { pub struct Container {
pub size: (UiSize, UiSize), pub size: (UiSize, UiSize),
pub direction: UiDirection, pub direction: UiDirection,
pub gap: f32, pub gap: f32,
pub padding: Sides<f32>, pub padding: Sides<f32>,
#[setters(into)]
pub align: Alignment2d, pub align: Alignment2d,
#[setters(into)]
pub background: BackgroundColor, pub background: BackgroundColor,
#[setters(into)]
pub corner_radius: Corners<f32>, pub corner_radius: Corners<f32>,
pub elements: Vec<Box<dyn UiElement>>, #[setters(into)]
pub children: ElementList,
} }
impl Default for Container { impl Default for Container {
@ -38,7 +45,7 @@ impl Default for Container {
padding: Sides::all(0.), padding: Sides::all(0.),
align: Alignment2d::default(), align: Alignment2d::default(),
background: Default::default(), background: Default::default(),
elements: Vec::new(), children: ElementList(Vec::new()),
corner_radius: Corners::all(0.), corner_radius: Corners::all(0.),
} }
} }
@ -67,7 +74,7 @@ impl UiElement for Container {
fn measure(&self, ctx: MeasureContext) -> Response { fn measure(&self, ctx: MeasureContext) -> Response {
let mut size = Vec2::ZERO; let mut size = Vec2::ZERO;
let mut leftover_gap = Vec2::ZERO; let mut leftover_gap = Vec2::ZERO;
for element in &self.elements { for element in &self.children.0 {
let measure = element.measure(MeasureContext{ let measure = element.measure(MeasureContext{
state: ctx.state, state: ctx.state,
layout: &LayoutInfo { layout: &LayoutInfo {
@ -164,7 +171,7 @@ impl UiElement for Container {
} }
} }
for element in &self.elements { for element in &self.children.0 {
//(passing max size from layout rather than actual bounds for the sake of consistency with measure() above) //(passing max size from layout rather than actual bounds for the sake of consistency with measure() above)
let mut el_layout = LayoutInfo { let mut el_layout = LayoutInfo {

View file

@ -1,4 +1,5 @@
use std::borrow::Cow; use std::borrow::Cow;
use derive_setters::Setters;
use glam::{vec2, Vec4}; use glam::{vec2, Vec4};
use crate::{ use crate::{
draw::UiDrawCommand, element::{MeasureContext, ProcessContext, UiElement}, layout::UiSize, measure::Response, text::{FontHandle, DEFAULT_FONT} draw::UiDrawCommand, element::{MeasureContext, ProcessContext, UiElement}, layout::UiSize, measure::Response, text::{FontHandle, DEFAULT_FONT}
@ -12,7 +13,10 @@ use crate::{
// Constant(u8), // Constant(u8),
// } // }
#[derive(Setters)]
#[setters(prefix = "with_")]
pub struct Text { pub struct Text {
#[setters(into)]
pub text: Cow<'static, str>, pub text: Cow<'static, str>,
pub size: (UiSize, UiSize), pub size: (UiSize, UiSize),
pub color: Vec4, pub color: Vec4,