From 5d771a83b82c5cc3dd58cca3f969d900369262e6 Mon Sep 17 00:00:00 2001 From: Jonathan Spira Date: Thu, 23 May 2024 22:46:21 -0400 Subject: [PATCH] better example framework --- imgui-examples/examples/custom_textures.rs | 21 ++++-- imgui-examples/examples/multiple_fonts.rs | 80 ++++++++++++++-------- imgui-examples/examples/support/mod.rs | 33 +++++---- 3 files changed, 84 insertions(+), 50 deletions(-) diff --git a/imgui-examples/examples/custom_textures.rs b/imgui-examples/examples/custom_textures.rs index 2649a7c..3c6be5d 100644 --- a/imgui-examples/examples/custom_textures.rs +++ b/imgui-examples/examples/custom_textures.rs @@ -215,12 +215,19 @@ impl Lenna { } fn main() { - let mut my_app = CustomTexturesApp::default(); + let my_app = std::rc::Rc::new(std::cell::RefCell::new(CustomTexturesApp::default())); + let app_clone = my_app.clone(); - let mut system = support::simple_init(file!()); - - my_app - .register_textures(system.display.get_context(), system.renderer.textures()) - .expect("Failed to register textures"); - system.main_loop(move |_, ui| my_app.show_textures(ui)); + support::init_with_startup( + file!(), + move |_ctx, renderer, display| { + app_clone + .borrow_mut() + .register_textures(display.get_context(), renderer.textures()) + .expect("Failed to register textures"); + }, + move |_, ui| { + my_app.borrow_mut().show_textures(ui); + }, + ); } diff --git a/imgui-examples/examples/multiple_fonts.rs b/imgui-examples/examples/multiple_fonts.rs index 4568b7c..77e8246 100644 --- a/imgui-examples/examples/multiple_fonts.rs +++ b/imgui-examples/examples/multiple_fonts.rs @@ -2,33 +2,57 @@ use imgui::*; mod support; +/// NOTE on this example: +/// Most of this complexity is because of how we initialize our support +/// (which primarily is a result of `winit`'s requirements for making a window). +/// In reality, most of these two functions can be made directly after each other -- +/// to run the initialization code (which loads a font), all you need is imgui + a renderer. fn main() { - let mut system = support::simple_init(file!()); - let dokdo = system.imgui.fonts().add_font(&[FontSource::TtfData { - data: include_bytes!("../../resources/Dokdo-Regular.ttf"), - size_pixels: system.font_size, - config: None, - }]); - let roboto = system.imgui.fonts().add_font(&[FontSource::TtfData { - data: include_bytes!("../../resources/Roboto-Regular.ttf"), - size_pixels: system.font_size, - config: None, - }]); - system - .renderer - .reload_font_texture(&mut system.imgui) - .expect("Failed to reload fonts"); - system.main_loop(move |run, ui| { - ui.window("Hello world").opened(run).build(|| { - ui.text("Hello, I'm the default font!"); - let _roboto = ui.push_font(roboto); - ui.text("Hello, I'm Roboto Regular!"); - let _dokdo = ui.push_font(dokdo); - ui.text("Hello, I'm Dokdo Regular!"); - _dokdo.pop(); - ui.text("Hello, I'm Roboto Regular again!"); - _roboto.pop(); - ui.text("Hello, I'm the default font again!"); - }); - }); + let dokdo = std::rc::Rc::new(std::cell::RefCell::new(None)); + let roboto = std::rc::Rc::new(std::cell::RefCell::new(None)); + + let dokdo_init = dokdo.clone(); + let roboto_init = roboto.clone(); + + support::init_with_startup( + file!(), + move |ctx, renderer, _| { + let mut dokdo_handle = dokdo_init.borrow_mut(); + let mut roboto_handle = roboto_init.borrow_mut(); + + // this function runs right after the window is created. + // In your own code, this can be done whenever you have a renderer + // and a context. + *dokdo_handle = Some(ctx.fonts().add_font(&[FontSource::TtfData { + data: include_bytes!("../../resources/Dokdo-Regular.ttf"), + size_pixels: support::FONT_SIZE, + config: None, + }])); + *roboto_handle = Some(ctx.fonts().add_font(&[FontSource::TtfData { + data: include_bytes!("../../resources/Roboto-Regular.ttf"), + size_pixels: support::FONT_SIZE, + config: None, + }])); + + renderer + .reload_font_texture(ctx) + .expect("Failed to reload fonts"); + }, + move |run, ui| { + let dokdo = dokdo.borrow().unwrap(); + let roboto = roboto.borrow().unwrap(); + + ui.window("Hello world").opened(run).build(|| { + ui.text("Hello, I'm the default font!"); + let _roboto = ui.push_font(roboto); + ui.text("Hello, I'm Roboto Regular!"); + let _dokdo = ui.push_font(dokdo); + ui.text("Hello, I'm Dokdo Regular!"); + _dokdo.pop(); + ui.text("Hello, I'm Roboto Regular again!"); + _roboto.pop(); + ui.text("Hello, I'm the default font again!"); + }); + }, + ); } diff --git a/imgui-examples/examples/support/mod.rs b/imgui-examples/examples/support/mod.rs index 654a559..8a730ab 100644 --- a/imgui-examples/examples/support/mod.rs +++ b/imgui-examples/examples/support/mod.rs @@ -1,18 +1,29 @@ use glium::glutin::surface::WindowSurface; -use glium::Surface; +use glium::{Display, Surface}; use imgui::{Context, FontConfig, FontGlyphRanges, FontSource, Ui}; use imgui_glium_renderer::Renderer; use imgui_winit_support::winit::dpi::LogicalSize; use imgui_winit_support::winit::event::{Event, WindowEvent}; use imgui_winit_support::winit::event_loop::EventLoop; -use imgui_winit_support::winit::window::{Window, WindowBuilder}; +use imgui_winit_support::winit::window::WindowBuilder; use imgui_winit_support::{HiDpiMode, WinitPlatform}; use std::path::Path; use std::time::Instant; mod clipboard; -pub fn simple_init(title: &str, mut run_ui: F) { +pub const FONT_SIZE: f32 = 13.0; + +#[allow(dead_code)] // annoyingly, RA yells that this is unusued +pub fn simple_init(title: &str, run_ui: F) { + init_with_startup(title, |_, _, _| {}, run_ui); +} + +pub fn init_with_startup(title: &str, mut startup: FInit, mut run_ui: FUi) +where + FInit: FnMut(&mut Context, &mut Renderer, &Display) + 'static, + FUi: FnMut(&mut bool, &mut Ui) + 'static, +{ let mut imgui = create_context(); let title = match Path::new(&title).file_name() { @@ -52,6 +63,8 @@ pub fn simple_init(title: &str, mut run_ let mut last_frame = Instant::now(); + startup(&mut imgui, &mut renderer, &display); + event_loop .run(move |event, window_target| match event { Event::NewEvents(_) => { @@ -114,11 +127,10 @@ pub fn create_context() -> imgui::Context { // scaling factor. Meaning, 13.0 pixels should look the same size // on two different screens, and thus we do not need to scale this // value (as the scaling is handled by winit) - let font_size = 13.0; imgui.fonts().add_font(&[ FontSource::TtfData { data: include_bytes!("../../../resources/Roboto-Regular.ttf"), - size_pixels: font_size, + size_pixels: FONT_SIZE, config: Some(FontConfig { // As imgui-glium-renderer isn't gamma-correct with // it's font rendering, we apply an arbitrary @@ -134,7 +146,7 @@ pub fn create_context() -> imgui::Context { }, FontSource::TtfData { data: include_bytes!("../../../resources/mplus-1p-regular.ttf"), - size_pixels: font_size, + size_pixels: FONT_SIZE, config: Some(FontConfig { // Oversampling font helps improve text rendering at // expense of larger font atlas texture. @@ -150,12 +162,3 @@ pub fn create_context() -> imgui::Context { imgui } - -/// Initialize the example with imgui and the renderer -pub fn init_with( - title: &str, - mut imgui: imgui::Context, - mut renderer: Renderer, - mut run_ui: F, -) { -}