bones_bevy_renderer/
ui.rs1use super::*;
2use bevy_egui::EguiContext;
3
4pub fn setup_egui(world: &mut World) {
6 world.resource_scope(|world: &mut World, mut game: Mut<BonesGame>| {
7 let ctx = {
8 let mut egui_query = world.query_filtered::<&mut EguiContext, With<Window>>();
9 let mut egui_ctx = egui_query.get_single_mut(world).unwrap();
10 egui_ctx.get_mut().clone()
11 };
12
13 game.insert_shared_resource(bones::EguiCtx(ctx.clone()));
15
16 if let Some(bones_assets) = &game.asset_server() {
17 update_egui_fonts(&ctx, bones_assets);
18
19 ctx.data_mut(|map| {
21 map.insert_temp(
22 bevy_egui::egui::Id::null(),
23 game.shared_resource_cell::<bones::EguiTextures>().unwrap(),
24 );
25 });
26 }
27 });
28}
29
30pub fn egui_input_hook(
32 mut egui_query: Query<&mut bevy_egui::EguiInput, With<Window>>,
33 mut game: ResMut<BonesGame>,
34) {
35 if let Some(hook) = game.shared_resource_cell::<bones::EguiInputHook>() {
36 let hook = hook.borrow().unwrap();
37 let mut egui_input = egui_query.get_single_mut().unwrap();
38 (hook.0)(&mut game, &mut egui_input);
39 }
40}
41
42pub fn sync_egui_settings(
44 game: Res<BonesGame>,
45 mut bevy_egui_settings: ResMut<bevy_egui::EguiSettings>,
46) {
47 for session_name in &game.sorted_session_keys {
48 let session = game.sessions.get(*session_name).unwrap();
49 let world = &session.world;
50
51 if let Some(settings) = world.get_resource::<bones::EguiSettings>() {
52 bevy_egui_settings.scale_factor = settings.scale;
53 }
54 }
55}
56
57pub fn update_egui_fonts(ctx: &bevy_egui::egui::Context, bones_assets: &bones::AssetServer) {
59 use bevy_egui::egui;
60 let mut fonts = egui::FontDefinitions::default();
61
62 for entry in bones_assets.store.assets.iter() {
63 let asset = entry.value();
64 if let Ok(font) = asset.try_cast_ref::<bones::Font>() {
65 let previous = fonts
66 .font_data
67 .insert(font.family_name.to_string(), font.data.clone());
68 if previous.is_some() {
69 warn!(
70 name=%font.family_name,
71 "Found two fonts with the same family name, using \
72 only the latest one"
73 );
74 }
75 fonts
76 .families
77 .entry(egui::FontFamily::Name(font.family_name.clone()))
78 .or_default()
79 .push(font.family_name.to_string());
80 }
81 }
82
83 ctx.set_fonts(fonts);
84}
85
86pub fn default_load_progress(asset_server: &bones::AssetServer, ctx: &bevy_egui::egui::Context) {
88 use bevy_egui::egui;
89 let errored = asset_server.load_progress.errored();
90
91 egui::CentralPanel::default().show(ctx, |ui| {
92 let height = ui.available_height();
93 let ctx = ui.ctx().clone();
94
95 let space_size = 0.03;
96 let spinner_size = 0.07;
97 let text_size = 0.034;
98 ui.vertical_centered(|ui| {
99 ui.add_space(height * 0.3);
100
101 if errored > 0 {
102 ui.label(
103 egui::RichText::new("⚠")
104 .color(egui::Color32::RED)
105 .size(height * spinner_size),
106 );
107 ui.add_space(height * space_size);
108 ui.label(
109 egui::RichText::new(format!(
110 "Error loading {errored} asset{}.",
111 if errored > 1 { "s" } else { "" }
112 ))
113 .color(egui::Color32::RED)
114 .size(height * text_size * 0.75),
115 );
116 } else {
117 ui.add(egui::Spinner::new().size(height * spinner_size));
118 ui.add_space(height * space_size);
119 ui.label(egui::RichText::new("Loading").size(height * text_size));
120 }
121 });
122
123 ctx.data_mut(|d| {
124 d.insert_temp(ui.id(), (spinner_size, space_size, text_size));
125 })
126 });
127}