use std::sync::{Arc, Mutex}; use raidillon_app::prelude::*; use crate::systems::common::should_draw_menu; #[derive(Clone, Copy, PartialEq, Eq)] enum SettingsTab { Display, } impl Default for SettingsTab { fn default() -> Self { SettingsTab::Display } } #[derive(Clone, Default)] struct DisplaySettingsUiState { selected_fullscreen_mode: WindowMode, active_tab: SettingsTab, } #[derive(Default)] pub struct DisplaySettings { ui_state: Arc>, } impl System for DisplaySettings { fn load_world(&mut self, res: &mut EngineResources, scene: &mut Scene) { let pctx = res.get_mut::().unwrap(); // sync the settings with UI state once if let (Ok(settings_handle), Ok(mut state)) = (pctx.settings.read(), self.ui_state.lock()) { state.selected_fullscreen_mode = settings_handle.display_settings.fullscreen_mode; } } fn frame_update(&mut self, res: &mut EngineResources, scene: &mut Scene) { if should_draw_menu(scene) { let pctx = res.get_mut::().unwrap(); let settings = pctx.settings.clone(); let ui_state = self.ui_state.clone(); pctx.egui_queue.borrow_mut().queue(move |egui_ctx| { egui::Window::new("Settings").default_open(false).show(egui_ctx, |ui| { let mut state = ui_state.lock().unwrap(); ui.horizontal(|ui| { ui.selectable_value(&mut state.active_tab, SettingsTab::Display, "Display Settings"); }); ui.separator(); match state.active_tab { SettingsTab::Display => { ui.label("Window Mode"); egui::ComboBox::from_id_salt("window_mode") .selected_text(window_mode_label(state.selected_fullscreen_mode)) .show_ui(ui, |ui| { for mode in [ WindowMode::Windowed, WindowMode::BorderlessFullscreen, ] { ui.selectable_value( &mut state.selected_fullscreen_mode, mode, window_mode_label(mode), ); } }); ui.add_space(8.0); ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { if ui.button("Apply").clicked() { if let Ok(mut settings_handle) = settings.write() { settings_handle.display_settings.fullscreen_mode = state.selected_fullscreen_mode; settings_handle.display_settings.dirty = true; } } }); } } }); }); } } } fn window_mode_label(mode: WindowMode) -> &'static str { match mode { WindowMode::Windowed => "Windowed", WindowMode::BorderlessFullscreen => "Borderless Fullscreen", } }