use crate::ecs::world::World;
use crate::run::State;
use winit::event::WindowEvent;
pub(crate) fn initialize_user_interface(world: &mut World) {
let window_handle = {
let Some(window_handle) = world.resources.window.handle.as_mut() else {
return;
};
window_handle.clone()
};
let gui_context = egui::Context::default();
#[cfg(target_arch = "wasm32")]
{
gui_context.set_pixels_per_point(1.0);
}
let viewport_id = gui_context.viewport_id();
let gui_state = egui_winit::State::new(
gui_context,
viewport_id,
&window_handle,
Some(window_handle.scale_factor() as _),
Some(winit::window::Theme::Dark),
None,
);
egui_extras::install_image_loaders(gui_state.egui_ctx());
world.resources.user_interface.state = Some(gui_state);
}
pub(crate) fn create_ui_system(world: &mut World, state: &mut Box<dyn State + 'static>) {
let _span = tracing::info_span!("ui").entered();
if !world.resources.user_interface.enabled {
return;
}
let ui = {
let Some(gui_state) = world.resources.user_interface.state.as_mut() else {
return;
};
let Some(window_handle) = world.resources.window.handle.as_ref() else {
return;
};
#[cfg(not(target_arch = "wasm32"))]
{
let scale_factor = world
.resources
.graphics
.ui_scale
.unwrap_or_else(|| window_handle.scale_factor() as f32);
gui_state.egui_ctx().set_pixels_per_point(scale_factor);
}
#[cfg(not(target_arch = "wasm32"))]
let gui_input = gui_state.take_egui_input(window_handle);
#[cfg(target_arch = "wasm32")]
let gui_input = {
use winit::platform::web::WindowExtWebSys;
let mut input = gui_state.take_egui_input(window_handle);
if let Some(canvas) = window_handle.canvas() {
let dpr = window_handle.scale_factor() as f32;
let canvas_size =
egui::vec2(canvas.width() as f32 / dpr, canvas.height() as f32 / dpr);
input.screen_rect = Some(egui::Rect::from_min_size(egui::Pos2::ZERO, canvas_size));
}
input
};
gui_state.egui_ctx().begin_pass(gui_input);
gui_state.egui_ctx().clone()
};
state.ui(world, &ui);
let Some(gui_state) = world.resources.user_interface.state.as_mut() else {
return;
};
let Some(window_handle) = world.resources.window.handle.as_ref() else {
return;
};
let output = ui.end_pass();
gui_state.handle_platform_output(window_handle, output.platform_output.clone());
let paint_jobs = ui.tessellate(output.shapes.clone(), output.pixels_per_point);
world.resources.user_interface.frame_output = Some((output, paint_jobs));
}
pub(crate) fn ui_event_system(world: &mut World, window_event: &WindowEvent) {
let _span = tracing::info_span!("ui_event").entered();
let Some(gui_state) = &mut world.resources.user_interface.state else {
return;
};
let Some(window_handle) = world.resources.window.handle.as_ref() else {
return;
};
world.resources.user_interface.consumed_event = gui_state
.on_window_event(window_handle, window_event)
.consumed;
}
pub(crate) fn update_egui_scale_factor(world: &mut World) {
let Some(gui_state) = world.resources.user_interface.state.as_mut() else {
return;
};
#[cfg(not(target_arch = "wasm32"))]
{
let scale_factor = world.resources.graphics.ui_scale.unwrap_or_else(|| {
world
.resources
.window
.handle
.as_ref()
.map(|w| w.scale_factor() as f32)
.unwrap_or(1.0)
});
gui_state.egui_ctx().set_pixels_per_point(scale_factor);
}
#[cfg(target_arch = "wasm32")]
{
gui_state.egui_ctx().set_pixels_per_point(1.0);
}
}