soundboard/src/ui.rs

134 lines
4.4 KiB
Rust

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<Mutex<ServerSettings>>,
should_run: Arc<Mutex<bool>>,
tx: mpsc::Sender<ServerMessage>,
) {
// Create an atomic bool to track window visibility
static VISIBLE: once_cell::sync::Lazy<Mutex<bool>> =
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<Mutex<ServerSettings>>,
#[allow(dead_code)]
should_run: Arc<Mutex<bool>>,
tx: mpsc::Sender<ServerMessage>,
#[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");
}
}
}