use eframe::egui;
use std::sync::mpsc;
use crate::cache::CacheMessage;
use crate::frame::{Frame, PixelFormat};
use crate::player::Player;
use crate::progress_bar::ProgressBar;
use crate::viewport::ViewportState;
pub struct StatusBar {
message_rx: mpsc::Receiver<CacheMessage>,
pub current_message: String,
cached_count: usize,
total_count: usize,
progress_bar: ProgressBar,
}
impl StatusBar {
pub fn new(rx: mpsc::Receiver<CacheMessage>) -> Self {
Self {
message_rx: rx,
current_message: String::new(),
cached_count: 0,
total_count: 0,
progress_bar: ProgressBar::new(150.0, 10.0), }
}
pub fn update(&mut self, ctx: &egui::Context) {
let mut has_updates = false;
while let Ok(msg) = self.message_rx.try_recv() {
match msg {
CacheMessage::LoadProgress { cached_count, total_count } => {
self.cached_count = cached_count;
self.total_count = total_count;
self.progress_bar.set_progress(cached_count, total_count);
}
CacheMessage::FrameLoaded => {
}
}
has_updates = true;
}
if has_updates {
ctx.request_repaint();
}
}
pub fn render(
&self,
ctx: &egui::Context,
frame: Option<&Frame>,
player: &Player,
viewport_state: &ViewportState,
render_time_ms: f32,
) {
egui::TopBottomPanel::bottom("status_bar").show(ctx, |ui| {
ui.horizontal(|ui| {
if let Some(frame) = frame {
if let Some(path) = frame.file() {
if let Some(filename) = path.file_name().and_then(|n| n.to_str()) {
ui.monospace(filename);
} else {
ui.monospace("---");
}
} else {
ui.monospace("No file");
}
} else {
ui.monospace("No file");
}
ui.separator();
if let Some(img) = frame {
ui.monospace(format!("{:>4}x{:<4}", img.width(), img.height()));
} else {
ui.monospace(" 0x0 ");
}
ui.separator();
if let Some(img) = frame {
ui.monospace(Self::format_pixel_format(img.pixel_format()));
} else {
ui.monospace("---");
}
ui.separator();
ui.monospace(format!("{:>6.1}%", viewport_state.zoom * 100.0));
ui.separator();
ui.monospace(format!("{:>5.1}", player.fps));
ui.separator();
let (used_bytes, max_bytes) = player.cache.mem();
let used_mb = used_bytes / 1024 / 1024;
let max_mb = max_bytes / 1024 / 1024;
ui.monospace(format!("{}M/{}M", used_mb, max_mb));
ui.separator();
self.progress_bar.render(ui);
ui.separator();
ui.monospace(format!("{:.1}ms", render_time_ms));
if !self.current_message.is_empty() {
ui.separator();
ui.monospace(&self.current_message);
}
});
});
}
fn format_pixel_format(format: PixelFormat) -> &'static str {
match format {
PixelFormat::Rgba8 => "RGBA u8",
PixelFormat::RgbaF16 => "RGBA f16",
PixelFormat::RgbaF32 => "RGBA f32",
}
}
}