mod layout;
use crate::components::{InputKey, Window};
use crate::ecs::FontHandle;
use crate::gfx::backend::{FrameParams, RenderBackend};
use crate::gfx::backend_init::BackendInit;
use crate::gfx::text::{FontSet, build_text_calls};
const FONT_HANDLE: FontHandle = FontHandle(0);
const IDENTITY_VIEW: [[f32; 4]; 4] = [
[1.0, 0.0, 0.0, 0.0],
[0.0, 1.0, 0.0, 0.0],
[0.0, 0.0, 1.0, 0.0],
[0.0, 0.0, 0.0, 1.0],
];
pub(crate) fn show(title: &str, message: &str) -> bool {
let Some(builtin) = crate::gfx::builtin_font::load(FONT_HANDLE) else {
return false;
};
let atlases = vec![builtin.atlas];
let mut fonts = FontSet::default();
fonts.insert(FONT_HANDLE, builtin.loaded);
let window = Window {
title: title.to_string(),
resizable: true,
..Window::default()
};
#[cfg(target_os = "macos")]
crate::app::runloop::activate_app_macos();
let init = BackendInit::minimal(&window, atlases);
let Some(mut backend) = concinnity_device::init_backend(init) else {
tracing::error!("error screen: no render backend; reporting on the console instead");
return false;
};
run_loop(backend.as_mut(), message, &fonts);
backend.wait_idle();
true
}
fn run_loop(backend: &mut dyn RenderBackend, message: &str, fonts: &FontSet) {
let started = std::time::Instant::now();
let mut hovered = false;
loop {
if backend.window_closed() {
return;
}
let (win_w, win_h) = backend.logical_size();
let screen = layout::build(message, win_w, win_h, fonts, FONT_HANDLE, hovered);
let text_calls = build_text_calls(
&screen.labels,
fonts,
win_w,
win_h,
&crate::gfx::overlay_maps::ClipRects::new(),
&crate::gfx::overlay_maps::OverlayLayers::new(),
);
backend.update_view(IDENTITY_VIEW);
if let Err(e) = backend.draw_frame(FrameParams {
elapsed: started.elapsed().as_secs_f32(),
fov_y_radians: 1.0,
near: 0.1,
far: 100.0,
cam_pos: [0.0, 0.0, 0.0],
text_calls: &text_calls,
lines: &[],
world_hidden: true,
view_mode: Default::default(),
show: Default::default(),
}) {
tracing::error!("error screen: draw failed, closing: {e}");
return;
}
let input = backend.take_input();
hovered = screen.quit_hit(input.mouse_x, input.mouse_y);
if input.escape || input.left_click && hovered {
return;
}
if matches!(input.captured_key, Some(InputKey::Enter)) {
return;
}
}
}