use eframe::egui; use raw_window_handle::{HasWindowHandle, RawWindowHandle}; use std::sync::{Arc, Mutex}; use tokio::sync::mpsc; use tray_item::TrayItem; use crate::server::{ServerMessage, ServerSettings}; pub fn run_ui( settings: Arc>, should_run: Arc>, tx: mpsc::Sender, ) { // Create an atomic bool to track window visibility static VISIBLE: once_cell::sync::Lazy> = once_cell::sync::Lazy::new(|| Mutex::new(true)); let native_options = eframe::NativeOptions::default(); eframe::run_native( "App", native_options, Box::new(|cc| { // Set up the tray icon event handler let window_handle = cc.window_handle().unwrap(); let window_handle = window_handle.as_raw(); let mut tray = TrayItem::new("Soundboard", tray_item::IconSource::Resource("icon-red")).unwrap(); if let RawWindowHandle::Win32(handle) = window_handle { // Windows Only. use windows::Win32::Foundation::HWND; use windows::Win32::UI::WindowsAndMessaging::{ ShowWindow, SW_HIDE, SW_RESTORE, // SW_SHOWDEFAULT, SW_SHOWNORMAL, }; tray.add_label("Server Control").unwrap(); tray.add_menu_item("Show/Hide", { move || { let mut visible_lock = VISIBLE.lock().unwrap(); let window_handle = HWND(handle.hwnd.into()); if *visible_lock { unsafe { _ = ShowWindow(window_handle, SW_HIDE); } *visible_lock = false; } else { unsafe { _ = ShowWindow(window_handle, SW_RESTORE); } *visible_lock = true; } } }) .unwrap(); } else { println!("Unsupported platform for tray icon."); } let my_tx = tx.clone(); tray.add_menu_item("Quit", move || { my_tx.try_send(ServerMessage::Shutdown).unwrap(); //std::process::exit(0); }) .unwrap(); let app = NativeApp { settings, should_run, tx, tray, }; Box::new(app) }), ) .expect("Error running UI."); } struct NativeApp { settings: Arc>, #[allow(dead_code)] should_run: Arc>, tx: mpsc::Sender, #[allow(dead_code)] tray: TrayItem, } impl eframe::App for NativeApp { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { egui::CentralPanel::default().show(ctx, |ui| { let mut settings = self.settings.lock().unwrap(); ui.heading("Server Settings"); ui.horizontal(|ui| { ui.label("Port:"); if ui.text_edit_singleline(&mut settings.port).changed() {} }); if ui.button("Apply").clicked() { if self .tx .try_send(ServerMessage::UpdateSettings(settings.clone())) .is_err() { eprintln!("Failed to send settings update"); } } if ui.button("Interact").clicked() { if self.tx.try_send(ServerMessage::Interact).is_err() { eprintln!("Failed to send interaction message"); } } if ui.button("Shutdown Server").clicked() { if self.tx.try_send(ServerMessage::Shutdown).is_err() { eprintln!("Failed to send shutdown message"); } } drop(settings); }); } fn on_exit(&mut self, _gl: Option<&eframe::glow::Context>) { if self.tx.try_send(ServerMessage::Shutdown).is_err() { eprintln!("Failed to send shutdown message"); } } }