use crate::ecs::world::World;
use winit::event::WindowEvent;
pub(crate) fn initialize(world: &mut World) {
let Some(window_handle) = world.resources.window.handle.as_ref() else {
return;
};
let window_handle = 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.egui.state = Some(gui_state);
#[cfg(target_arch = "wasm32")]
{
use wasm_bindgen::JsCast;
use winit::platform::web::WindowExtWebSys;
if let Some(canvas) = window_handle.canvas() {
let queue = std::sync::Arc::clone(&world.resources.egui.wasm_paste_queue);
let closure = wasm_bindgen::closure::Closure::wrap(Box::new(
move |event: web_sys::ClipboardEvent| {
if let Some(data) = event.clipboard_data()
&& let Ok(text) = data.get_data("text/plain")
&& !text.is_empty()
&& let Ok(mut queue) = queue.lock()
{
queue.push(text);
event.prevent_default();
}
},
)
as Box<dyn FnMut(web_sys::ClipboardEvent)>);
let _ =
canvas.add_event_listener_with_callback("paste", closure.as_ref().unchecked_ref());
closure.forget();
}
}
}
pub(crate) fn handle_window_event(world: &mut World, window_event: &WindowEvent) {
let Some(gui_state) = world.resources.egui.state.as_mut() 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 begin_frame(world: &mut World) {
world.resources.egui.frame_active = false;
if !world.resources.egui.enabled {
return;
}
let Some(gui_state) = world.resources.egui.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
.render_settings
.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));
}
if let Ok(mut queue) = world.resources.egui.wasm_paste_queue.lock() {
for text in queue.drain(..) {
input.events.push(egui::Event::Paste(text));
}
}
input
};
gui_state.egui_ctx().begin_pass(gui_input);
world.resources.egui.frame_active = true;
}
pub(crate) fn finish_frame(world: &mut World) {
if !world.resources.egui.frame_active {
return;
}
let Some(gui_state) = world.resources.egui.state.as_mut() else {
return;
};
let Some(window_handle) = world.resources.window.handle.as_ref() else {
return;
};
let context = gui_state.egui_ctx().clone();
let output = context.end_pass();
gui_state.handle_platform_output(window_handle, output.platform_output.clone());
let paint_jobs = context.tessellate(output.shapes.clone(), output.pixels_per_point);
world.resources.egui.frame_active = false;
world.resources.egui.frame_output = Some((output, paint_jobs));
}