From a49d462e65941c7da955e35d776a6038c51093d0 Mon Sep 17 00:00:00 2001 From: Ettore Pane <ettore.pane4@gmail.com> Date: Fri, 21 Mar 2025 16:49:41 +0100 Subject: [PATCH] GUI Improvements --- src/main.rs | 163 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 136 insertions(+), 27 deletions(-) diff --git a/src/main.rs b/src/main.rs index 29fccbc..cb01bd6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,7 @@ use std::{ }; use serde::{Deserialize, Serialize}; use parking_lot::Mutex; -use eframe::{self, egui}; +use eframe::{self, egui::{self, Color32, RichText, FontId, ProgressBar, Visuals}}; use tokio::runtime::Runtime; use chrono; @@ -81,31 +81,132 @@ impl RovieAdminApp { impl eframe::App for RovieAdminApp { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { + ctx.set_visuals(Visuals { + window_rounding: 4.0.into(), + widgets: egui::style::Widgets::default(), + override_text_color: Some(Color32::from_gray(220)), + ..Default::default() + }); + egui::CentralPanel::default().show(ctx, |ui| { - ui.heading("RovieAdmin v1.0"); - ui.separator(); - ui.heading("Camera Statuses"); - - let statuses = self.camera_statuses.lock(); - for status in statuses.iter() { - let online_text = if let Some(latency) = status.latency { - format!("✅ Online ({}ms)", latency) - } else { - "⌠Offline".to_owned() - }; - let recording_text = if status.recording { - "🔴 Recording" - } else { - "âš« Stopped" - }; - ui.label( - egui::RichText::new(format!( - "{}: {} - {}", - status.camera.name, online_text, recording_text - )) - .size(16.0), - ); - } + ui.vertical(|ui| { + // Header + ui.horizontal(|ui| { + ui.heading( + RichText::new("📷 RovieAdmin v1.0") + .color(Color32::from_rgb(110, 200, 250)) + .heading(), + ); + ui.add_space(20.0); + + // Statistics + let statuses = self.camera_statuses.lock(); + let online_count = statuses.iter().filter(|s| s.latency.is_some()).count(); + let recording_count = statuses.iter().filter(|s| s.recording).count(); + + ui.label( + RichText::new(format!("🌠Online: {} | 🔴 Recording: {}", online_count, recording_count)) + ); + }); + + ui.separator(); + + // Camera grid + egui::Grid::new("cameras_grid") + .num_columns(2) + .spacing([20.0, 10.0]) + .show(ui, |ui| { + let statuses = self.camera_statuses.lock(); + for status in statuses.iter() { + ui.vertical(|ui| { + let frame = egui::Frame::group(ui.style()) + .inner_margin(10.0) + .rounding(4.0) + .fill(if status.latency.is_some() { + Color32::from_rgb(30, 35, 40) + } else { + Color32::from_rgb(45, 25, 25) + }); + + frame.show(ui, |ui| { + ui.horizontal(|ui| { + // Status indicator + ui.vertical(|ui| { + let (icon, color) = if status.latency.is_some() { + ("â—", Color32::from_rgb(50, 200, 50)) + } else { + ("â—", Color32::from_rgb(200, 50, 50)) + }; + + ui.label( + RichText::new(icon) + .color(color) + .monospace() + ); + }); + + // Camera info + ui.vertical(|ui| { + // Name and recording status + ui.horizontal(|ui| { + ui.label( + RichText::new(&status.camera.name) + .strong() + ); + + if status.recording { + ui.label( + RichText::new("🔴") + .color(Color32::from_rgb(200, 50, 50)) + ).on_hover_text("Recording"); + } + }); + + // Latency info + if let Some(latency) = status.latency { + let latency_normalized = (latency as f32 / 300.0).clamp(0.0, 1.0); + ui.add( + ProgressBar::new(latency_normalized) + .text(format!("{} ms", latency)) + .fill(Color32::from_rgb( + (255.0 * latency_normalized) as u8, + (255.0 * (1.0 - latency_normalized)) as u8, + 50 + )) + ); + } else { + ui.label( + RichText::new("Offline") + .color(Color32::from_rgb(200, 50, 50)) + ); + } + + // Connection info + ui.label( + RichText::new(format!("{}:{}", status.camera.ip, status.camera.port)) + .color(Color32::from_gray(150)) + ); + }); + }); + }); + }); + + if ui.available_width() > 400.0 { + ui.end_row(); + } + } + }); + + // Footer + ui.separator(); + ui.horizontal(|ui| { + ui.label("🕒 Updated: "); + ui.label(chrono::Local::now().format("%H:%M:%S").to_string()); + ui.add_space(20.0); + ui.label(format!("📠Save location: recordings/{}", + chrono::Local::now().format("%Y-%m-%d_%H-%M-%S"))); + }); + }); }); ctx.request_repaint_after(Duration::from_secs(1)); @@ -200,10 +301,18 @@ fn main() -> Result<(), eframe::Error> { }); }); - let options = eframe::NativeOptions::default(); + let options = eframe::NativeOptions { + initial_window_size: Some(egui::vec2(800.0, 600.0)), + vsync: true, + ..Default::default() + }; + eframe::run_native( "RovieAdmin", options, - Box::new(|_cc| Box::new(RovieAdminApp::new(camera_statuses))), + Box::new(|cc| { + cc.egui_ctx.set_visuals(egui::Visuals::dark()); + Box::new(RovieAdminApp::new(camera_statuses)) + }), ) } \ No newline at end of file -- GitLab