From c91e6ba50cc2e07da44848c661aaf564a749f1b2 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Fri, 1 Mar 2024 18:21:02 +0100 Subject: [PATCH] idk a bunch of changes i forgor to commit --- README.md | 4 +- hui-examples/assets/blink/Blink-ynYZ.otf | Bin 0 -> 115688 bytes .../assets/blink/SIL Open Font License.txt | 94 ++++++++++++++ hui-examples/assets/blink/info.txt | 2 + hui-examples/boilerplate.rs | 55 +++++--- hui-examples/examples/mom_downloader.rs | 8 +- hui-examples/examples/text_weird.rs | 2 +- hui-examples/examples/ui_test.rs | 2 +- hui-examples/examples/ui_test2.rs | 119 ++++++++++++++++++ hui-glium/src/lib.rs | 26 ++-- hui/src/element.rs | 35 +++--- hui/src/element/builtin/container.rs | 9 +- hui/src/element/builtin/text.rs | 33 +++-- hui/src/instance.rs | 24 ++++ hui/src/text.rs | 36 ++++-- hui/src/text/stack.rs | 32 +++++ 16 files changed, 395 insertions(+), 86 deletions(-) create mode 100644 hui-examples/assets/blink/Blink-ynYZ.otf create mode 100644 hui-examples/assets/blink/SIL Open Font License.txt create mode 100644 hui-examples/assets/blink/info.txt create mode 100644 hui-examples/examples/ui_test2.rs create mode 100644 hui/src/text/stack.rs diff --git a/README.md b/README.md index 316336b..b7deb54 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

-

hui

+

hUI

Simple UI library for games and other interactive applications @@ -9,7 +9,7 @@
license - Formerly kubi-ui + (Formerly kubi-ui)

diff --git a/hui-examples/assets/blink/Blink-ynYZ.otf b/hui-examples/assets/blink/Blink-ynYZ.otf new file mode 100644 index 0000000000000000000000000000000000000000..c26013f84a09e059790000ffba2b67fa5304b1a2 GIT binary patch literal 115688 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 { + fn main() { + $crate::boilerplate::ui($closure0, $closure1); + } + }; ($closure: expr) => { fn main() { - $crate::boilerplate::ui($closure); + $crate::boilerplate::ui(|_|(), $closure); } }; } /// Initializes glium renderer, `UiInstance`, and runs the event loop. -pub fn ui(mut x: impl FnMut(&mut UiInstance, Vec2)) { +pub fn ui(mut init: impl FnMut(&mut UiInstance) -> T, mut draw: impl FnMut(&mut UiInstance, Vec2, &T)) { kubi_logging::init(); let event_loop = EventLoopBuilder::new().build().unwrap(); - let (_window, display) = SimpleWindowBuilder::new().build(&event_loop); + let (window, display) = SimpleWindowBuilder::new().build(&event_loop); let mut hui = UiInstance::new(); let mut backend = GliumUiRenderer::new(&display); + let result = init(&mut hui); + event_loop.run(|event, window_target| { + window.request_redraw(); window_target.set_control_flow(ControlFlow::Poll); hui_winit::handle_winit_event(&mut hui, &event); match event { - Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => { + Event::WindowEvent { event, .. } => match event { + WindowEvent::CloseRequested => { + window_target.exit(); + }, + WindowEvent::RedrawRequested => { + let mut frame = display.draw(); + frame.clear_color_srgb(0.5, 0.5, 0.5, 0.); + + hui.begin(); + + let size = UVec2::from(display.get_framebuffer_dimensions()).as_vec2(); + draw(&mut hui, size, &result); + + hui.end(); + + backend.update(&hui); + backend.draw(&mut frame, size); + + frame.finish().unwrap(); + }, + _ => (), + }, + Event::Suspended => { + #[cfg(target_os = "android")] window_target.exit(); }, - Event::AboutToWait => { - let mut frame = display.draw(); - frame.clear_color_srgb(0.5, 0.5, 0.5, 0.); - - hui.begin(); - - let size = UVec2::from(display.get_framebuffer_dimensions()).as_vec2(); - x(&mut hui, size); - - hui.end(); - - backend.update(&hui); - backend.draw(&mut frame, size); - - frame.finish().unwrap(); - } _ => (), } }).unwrap(); diff --git a/hui-examples/examples/mom_downloader.rs b/hui-examples/examples/mom_downloader.rs index 1b15018..448daa8 100644 --- a/hui-examples/examples/mom_downloader.rs +++ b/hui-examples/examples/mom_downloader.rs @@ -69,7 +69,7 @@ fn main() { if instant.elapsed().as_secs_f32() < 5. { el.push(Box::new(Text { text: "Downloading your mom...".into(), - font: font_handle, + font: Some(font_handle), text_size: 24, ..Default::default() })); @@ -84,7 +84,7 @@ fn main() { size: (Size::Fraction(1.), Size::Auto).into(), children: ElementList(vec![Box::new(Text { text: format!("{:.2}% ({:.1} GB)", mom_ratio * 100., mom_ratio * 10000.).into(), - font: font_handle, + font: Some(font_handle), text_size: 16, ..Default::default() })]), @@ -93,14 +93,14 @@ fn main() { } else if instant.elapsed().as_secs() < 10 { el.push(Box::new(Text { text: "Error 413: Request Entity Too Large".into(), - font: font_handle, + font: Some(font_handle), color: vec4(1., 0.125, 0.125, 1.), text_size: 20, ..Default::default() })); el.push(Box::new(Text { text: format!("Exiting in {}...", 10 - instant.elapsed().as_secs()).into(), - font: font_handle, + font: Some(font_handle), text_size: 16, ..Default::default() })); diff --git a/hui-examples/examples/text_weird.rs b/hui-examples/examples/text_weird.rs index 24eca1a..ebe6bce 100644 --- a/hui-examples/examples/text_weird.rs +++ b/hui-examples/examples/text_weird.rs @@ -83,7 +83,7 @@ fn main() { })); elem.push(Box::new(Text { text: "Hello, world!\nżółty liść. życie nie ma sensu i wszyscy zginemy;\nтест кирилиці їїїїїїїїїїї\njapanese text: テスト".into(), - font: font_handle, + font: Some(font_handle), text_size: 32, ..Default::default() })); diff --git a/hui-examples/examples/ui_test.rs b/hui-examples/examples/ui_test.rs index f6ed78a..8849040 100644 --- a/hui-examples/examples/ui_test.rs +++ b/hui-examples/examples/ui_test.rs @@ -8,7 +8,7 @@ use hui::{ #[macro_use] mod boilerplate; -ui_main!(|ui, size| { +ui_main!(|ui, size, _| { Container::default() .with_size(size!(100%, 50%)) .with_align(Alignment::Center) diff --git a/hui-examples/examples/ui_test2.rs b/hui-examples/examples/ui_test2.rs new file mode 100644 index 0000000..011c06d --- /dev/null +++ b/hui-examples/examples/ui_test2.rs @@ -0,0 +1,119 @@ +use glam::vec4; +use hui::{ + color, size, + element::{container::Container, progress_bar::ProgressBar, text::Text, UiElementExt}, + layout::Alignment, + rectangle::Corners, + text::FontHandle, +}; + +#[path = "../boilerplate.rs"] +#[macro_use] +mod boilerplate; + +ui_main!( + init: |ui| { + let font = ui.add_font(include_bytes!("../assets/blink/Blink-ynYZ.otf")); + ui.push_font(font); + (std::time::Instant::now(),) + }, + run: |ui, size, (instant,)| { + // Background color (gradient) + Container::default() + .with_size(size!(100%)) + .with_background(Corners { + top_left: vec4(0.2, 0.2, 0.3, 1.), + top_right: vec4(0.3, 0.3, 0.4, 1.), + bottom_left: vec4(0.2, 0.3, 0.2, 1.), + bottom_right: vec4(0.5, 0.4, 0.4, 1.), + }) + .add_root(ui, size); + + // Loading text in the bottom right corner + Container::default() + .with_size(size!(100%)) + .with_align(Alignment::End) + .with_padding(20.) + .with_children(|ui| { + Container::default() + .with_padding((10., 15.)) + .with_corner_radius(8.) + .with_background((0., 0., 0., 0.5)) + .with_children(|ui| { + let flash = 1. - 0.5 * (4. * instant.elapsed().as_secs_f32()).sin().powi(2); + Text::default() + .with_text("Loading...") + .with_color((1., 1., 1., flash)) + .with_text_size(24) + .add_child(ui); + }) + .add_child(ui); + }) + .add_root(ui, size); + + // Did you know? box in the center + Container::default() + .with_size(size!(100%)) + .with_align(Alignment::Center) + .with_children(|ui| { + Container::default() + .with_align((Alignment::Center, Alignment::Begin)) + .with_padding(15.) + .with_gap(10.) + .with_corner_radius(8.) + .with_background((0., 0., 0., 0.5)) + .with_children(|ui| { + Text::default() + .with_text("Did you know?") + .with_text_size(18) + .add_child(ui); + Text::default() + .with_text("You can die by jumping into the spike pit! :D\nCheck out the tutorial section for more tips.") + .with_text_size(24) + .with_font(FontHandle::default()) + .add_child(ui); + }) + .add_child(ui); + }) + .add_root(ui, size); + + // Progress bar at the bottom + Container::default() + .with_size(size!(100%)) + .with_align((Alignment::Center, Alignment::End)) + .with_children(|ui| { + ProgressBar::default() + .with_value((instant.elapsed().as_secs_f32() * 0.1) % 1.) + .with_size(size!(100%, 5)) + .with_background((0., 0., 0., 0.5)) + .with_foreground(color::DARK_GREEN) + .add_child(ui); + }) + .add_root(ui, size); + + // Player XP and level (mock) in the top right corner + Container::default() + .with_size(size!(100%)) + .with_align((Alignment::End, Alignment::Begin)) + .with_padding(20.) + .with_children(|ui| { + Container::default() + .with_padding(10.) + .with_corner_radius(8.) + .with_background((0., 0., 0., 0.5)) + .with_children(|ui| { + Text::default() + .with_text("Level 5") + .with_text_size(24) + .add_child(ui); + Text::default() + .with_text("XP: 1234 / 5000") + .with_text_size(18) + .with_font(FontHandle::default()) + .add_child(ui); + }) + .add_child(ui); + }) + .add_root(ui, size); + } +); diff --git a/hui-glium/src/lib.rs b/hui-glium/src/lib.rs index 86e9299..ade2336 100644 --- a/hui-glium/src/lib.rs +++ b/hui-glium/src/lib.rs @@ -59,8 +59,8 @@ impl BufferPair { Self { vertex_buffer: VertexBuffer::dynamic(facade, vtx).unwrap(), index_buffer: IndexBuffer::dynamic(facade, PrimitiveType::TrianglesList, idx).unwrap(), - vertex_count: 0, - index_count: 0, + vertex_count: vtx.len(), + index_count: idx.len(), } } @@ -122,7 +122,7 @@ pub struct GliumUiRenderer { impl GliumUiRenderer { pub fn new(facade: &F) -> Self { - log::info!("initializing hui glium backend"); + log::info!("initializing hui-glium"); Self { program: Program::from_source(facade, VERTEX_SHADER, FRAGMENT_SHADER, None).unwrap(), context: Rc::clone(facade.get_context()), @@ -131,7 +131,8 @@ impl GliumUiRenderer { } } - pub fn update_buffers(&mut self, call: &UiDrawCall) { + fn update_buffers(&mut self, call: &UiDrawCall) { + log::trace!("updating ui buffers (i={})", call.indices.len()); let data_vtx = &call.vertices.iter().copied().map(Vertex::from).collect::>()[..]; let data_idx = &call.indices[..]; if let Some(buffer) = &mut self.buffer_pair { @@ -141,7 +142,7 @@ impl GliumUiRenderer { } } - pub fn update_texture_atlas(&mut self, atlas: &TextureAtlasMeta) { + fn update_texture_atlas(&mut self, atlas: &TextureAtlasMeta) { log::trace!("updating ui atlas texture"); self.ui_texture = Some(SrgbTexture2d::new( &self.context, @@ -152,16 +153,13 @@ impl GliumUiRenderer { ).unwrap()); } - pub fn update(&mut self, hui: &UiInstance) { - if self.ui_texture.is_none() || hui.atlas().modified { - self.update_texture_atlas(&hui.atlas()); + pub fn update(&mut self, instance: &UiInstance) { + if self.ui_texture.is_none() || instance.atlas().modified { + self.update_texture_atlas(&instance.atlas()); + } + if self.buffer_pair.is_none() || instance.draw_call().0 { + self.update_buffers(instance.draw_call().1); } - //HACK: modified is incorrect, this is a hack - self.update_buffers(hui.draw_call().1); - //FIXME before release - // if (self.buffer_pair.is_none() && !hui.draw_call().1.indices.is_empty()) || hui.draw_call().0 { - // self.update_buffers(hui.draw_call().1); - // } } pub fn draw(&self, frame: &mut glium::Frame, resolution: Vec2) { diff --git a/hui/src/element.rs b/hui/src/element.rs index 8cb2504..ffca9b4 100644 --- a/hui/src/element.rs +++ b/hui/src/element.rs @@ -1,7 +1,12 @@ //! element API, built-in elements like `Container`, `Button`, `Text`, etc. use std::any::Any; use crate::{ - draw::UiDrawCommandList, layout::LayoutInfo, measure::Response, state::StateRepo, text::TextMeasure, UiInstance + draw::UiDrawCommandList, + layout::LayoutInfo, + measure::Response, + state::StateRepo, + text::{FontHandle, TextMeasure}, + UiInstance }; mod builtin; @@ -12,6 +17,7 @@ pub struct MeasureContext<'a> { pub state: &'a StateRepo, pub layout: &'a LayoutInfo, pub text_measure: TextMeasure<'a>, + pub current_font: FontHandle, } /// Context for the `Element::process` function @@ -21,6 +27,7 @@ pub struct ProcessContext<'a> { pub layout: &'a LayoutInfo, pub draw: &'a mut UiDrawCommandList, pub text_measure: TextMeasure<'a>, + pub current_font: FontHandle, } pub trait UiElement { @@ -58,13 +65,18 @@ pub trait UiElement { fn process(&self, ctx: ProcessContext); } +/// A list of elements\ +/// Use the [`add`](`ElementList::add`) method to add elements to the list pub struct ElementList(pub Vec>); impl ElementList { + /// Add an element to the list pub fn add(&mut self, element: impl UiElement + 'static) { self.0.push(Box::new(element)) } + /// Create a new `ElementList` from a callback\ + /// The callback will be called with a reference to the newly list pub(crate) fn from_callback(cb: impl FnOnce(&mut ElementList)) -> Self { let mut list = ElementList(Vec::new()); cb(&mut list); @@ -72,29 +84,10 @@ impl ElementList { } } -// impl From for ElementList { -// fn from(cb: T) -> Self { -// let mut list = ElementList(Vec::new()); -// cb(&mut list); -// list -// } -// } - -// impl From for ElementList { -// fn from(value: T) -> Self { -// ElementList(vec![Box::new(value)]) -// } -// } - -// impl From>> for ElementList { -// fn from(value: Vec>) -> Self { -// Self(value) -// } -// } - pub trait UiElementExt: UiElement { /// Add element as a child/nested element. fn add_child(self, ui: &mut ElementList); + /// Add element as a ui root. fn add_root(self, ui: &mut UiInstance, max_size: glam::Vec2); } diff --git a/hui/src/element/builtin/container.rs b/hui/src/element/builtin/container.rs index d1e9f52..06290e2 100644 --- a/hui/src/element/builtin/container.rs +++ b/hui/src/element/builtin/container.rs @@ -92,6 +92,7 @@ impl UiElement for Container { direction: self.direction, }, text_measure: ctx.text_measure, + current_font: ctx.current_font, }); match self.direction { UiDirection::Horizontal => { @@ -160,7 +161,7 @@ impl UiElement for Container { //.0 = primary, .1 = secondary let pri_sec_align = match self.direction { UiDirection::Horizontal => (self.align.horizontal, self.align.vertical), - UiDirection::Vertical => (self.align.horizontal, self.align.vertical), + UiDirection::Vertical => (self.align.vertical, self.align.horizontal), }; //alignment @@ -194,6 +195,7 @@ impl UiElement for Container { state: ctx.state, layout: &el_layout, text_measure: ctx.text_measure, + current_font: ctx.current_font, }); //align (on sec. axis) @@ -206,10 +208,10 @@ impl UiElement for Container { el_layout.position.x += (ctx.measure.size.x - self.padding.left - self.padding.right - el_measure.size.x) / 2.; }, (Alignment::End, UiDirection::Horizontal) => { - el_layout.position.y += ctx.measure.size.y - el_measure.size.y - self.padding.bottom; + el_layout.position.y += ctx.measure.size.y - el_measure.size.y - self.padding.bottom - self.padding.top; }, (Alignment::End, UiDirection::Vertical) => { - el_layout.position.x += ctx.measure.size.x - el_measure.size.x - self.padding.right; + el_layout.position.x += ctx.measure.size.x - el_measure.size.x - self.padding.right - self.padding.left; } } @@ -220,6 +222,7 @@ impl UiElement for Container { layout: &el_layout, draw: ctx.draw, text_measure: ctx.text_measure, + current_font: ctx.current_font, }); //layout diff --git a/hui/src/element/builtin/text.rs b/hui/src/element/builtin/text.rs index 0610d9a..fe7d419 100644 --- a/hui/src/element/builtin/text.rs +++ b/hui/src/element/builtin/text.rs @@ -4,7 +4,7 @@ use glam::{vec2, Vec4}; use crate::{ draw::UiDrawCommand, element::{MeasureContext, ProcessContext, UiElement}, - layout::Size, + layout::{Size, Size2d}, measure::Response, text::FontHandle, }; @@ -22,9 +22,12 @@ use crate::{ pub struct Text { #[setters(into)] pub text: Cow<'static, str>, - pub size: (Size, Size), + #[setters(into)] + pub size: Size2d, + #[setters(into)] pub color: Vec4, - pub font: FontHandle, + #[setters(into)] + pub font: Option, pub text_size: u16, } @@ -32,30 +35,37 @@ impl Default for Text { fn default() -> Self { Self { text: "".into(), - size: (Size::Auto, Size::Auto), + size: (Size::Auto, Size::Auto).into(), color: Vec4::new(1., 1., 1., 1.), - font: FontHandle::default(), + font: None, text_size: 16, } } } +impl Text { + fn font(&self, f: FontHandle) -> FontHandle { + self.font.unwrap_or(f) + } +} + impl UiElement for Text { fn measure(&self, ctx: MeasureContext) -> Response { let mut size = (0., 0.); - if matches!(self.size.0, Size::Auto) || matches!(self.size.1, Size::Auto) { - let res = ctx.text_measure.measure(self.font, self.text_size, &self.text); + if matches!(self.size.width, Size::Auto) || matches!(self.size.height, Size::Auto) { + //TODO optimized measure if only one of the sizes is auto + let res = ctx.text_measure.measure(self.font(ctx.current_font), self.text_size, &self.text); size.0 = res.max_width; size.1 = res.height; } Response { size: vec2( - match self.size.0 { + match self.size.width { Size::Auto => size.0, Size::Fraction(percentage) => ctx.layout.max_size.x * percentage, Size::Static(pixels) => pixels, }, - match self.size.1 { + match self.size.height { Size::Auto => size.1, Size::Fraction(percentage) => ctx.layout.max_size.y * percentage, Size::Static(pixels) => pixels, @@ -67,12 +77,15 @@ impl UiElement for Text { } fn process(&self, ctx: ProcessContext) { + if self.text.is_empty() || self.color.w == 0. { + return + } ctx.draw.add(UiDrawCommand::Text { text: self.text.clone(), position: ctx.layout.position, size: self.text_size, color: self.color, - font: self.font + font: self.font(ctx.current_font), }); } } diff --git a/hui/src/instance.rs b/hui/src/instance.rs index 1610d92..c5f88f9 100644 --- a/hui/src/instance.rs +++ b/hui/src/instance.rs @@ -62,6 +62,28 @@ impl UiInstance { self.text_renderer.add_font_from_bytes(font) } + /// Push a font to the font stack\ + /// The font will be used for all text rendering until it is popped + /// + /// This function is useful for replacing the default font, use sparingly\ + /// (This library attempts to be stateless, however passing the font to every text element is not very practical) + pub fn push_font(&mut self, font: FontHandle) { + self.text_renderer.push_font(font); + } + + /// Pop a font from the font stack\ + /// + /// ## Panics: + /// If the font stack is empty + pub fn pop_font(&mut self) { + self.text_renderer.pop_font(); + } + + /// Get the current default font + pub fn current_font(&self) -> FontHandle { + self.text_renderer.current_font() + } + /// Add an element or an element tree to the UI /// /// Use the `max_size` parameter to specify the maximum size of the element\ @@ -77,6 +99,7 @@ impl UiInstance { state: &self.stateful_state, layout: &layout, text_measure: self.text_renderer.to_measure(), + current_font: self.text_renderer.current_font(), }); element.process(ProcessContext { measure: &measure, @@ -84,6 +107,7 @@ impl UiInstance { layout: &layout, draw: &mut self.draw_commands, text_measure: self.text_renderer.to_measure(), + current_font: self.text_renderer.current_font(), }); } diff --git a/hui/src/text.rs b/hui/src/text.rs index 3855013..6004a8c 100644 --- a/hui/src/text.rs +++ b/hui/src/text.rs @@ -1,43 +1,59 @@ //! text rendering, styling, measuring use std::sync::Arc; +use fontdue::{Font, FontSettings}; +use crate::draw::atlas::TextureAtlasManager; mod font; mod ftm; +mod stack; -use font::FontManager; -pub use font::FontHandle; #[cfg(feature="builtin_font")] pub use font::BUILTIN_FONT; -use fontdue::{Font, FontSettings}; +pub use font::FontHandle; + +use font::FontManager; use ftm::FontTextureManager; use ftm::GlyphCacheEntry; - -use crate::draw::atlas::TextureAtlasManager; +use stack::FontStack; pub struct TextRenderer { - fm: FontManager, + manager: FontManager, ftm: FontTextureManager, + stack: FontStack, } impl TextRenderer { pub fn new() -> Self { Self { - fm: FontManager::new(), + manager: FontManager::new(), ftm: FontTextureManager::default(), + stack: FontStack::new(), } } pub fn add_font_from_bytes(&mut self, font: &[u8]) -> FontHandle { - self.fm.add_font(Font::from_bytes(font, FontSettings::default()).unwrap()) + self.manager.add_font(Font::from_bytes(font, FontSettings::default()).unwrap()) } pub fn glyph(&mut self, atlas: &mut TextureAtlasManager, font_handle: FontHandle, character: char, size: u8) -> Arc { - self.ftm.glyph(atlas, &self.fm, font_handle, character, size) + self.ftm.glyph(atlas, &self.manager, font_handle, character, size) + } + + pub fn push_font(&mut self, font: FontHandle) { + self.stack.push(font); + } + + pub fn pop_font(&mut self) { + self.stack.pop(); + } + + pub fn current_font(&self) -> FontHandle { + self.stack.current_or_default() } pub(crate) fn internal_font(&self, handle: FontHandle) -> &Font { - self.fm.get(handle).unwrap() + self.manager.get(handle).unwrap() } } diff --git a/hui/src/text/stack.rs b/hui/src/text/stack.rs new file mode 100644 index 0000000..a61f5e9 --- /dev/null +++ b/hui/src/text/stack.rs @@ -0,0 +1,32 @@ +use super::FontHandle; + +pub struct FontStack { + fonts: Vec, +} + +impl FontStack { + pub fn new() -> Self { + Self { + #[cfg(not(feature = "builtin_font"))] + fonts: Vec::new(), + #[cfg(feature = "builtin_font")] + fonts: vec![super::BUILTIN_FONT], + } + } + + pub fn push(&mut self, font: FontHandle) { + self.fonts.push(font); + } + + pub fn pop(&mut self) { + assert!(self.fonts.pop().is_some()) + } + + pub fn current(&self) -> Option { + self.fonts.last().copied() + } + + pub fn current_or_default(&self) -> FontHandle { + self.current().unwrap_or_default() + } +}