feat: refine system specs screen layout
Build And Push Container / build-and-push (push) Successful in 56s
Build And Push Container / build-and-push (push) Successful in 56s
This commit is contained in:
@@ -14,6 +14,13 @@ use crate::types::SystemView;
|
||||
pub(crate) const DISPLAY_WIDTH: u32 = 960;
|
||||
pub(crate) const DISPLAY_HEIGHT: u32 = 376;
|
||||
|
||||
pub(crate) fn normalize_specs_mode(mode: &str) -> &'static str {
|
||||
match mode {
|
||||
"meters" => "meters",
|
||||
_ => "cards",
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn collect_system_view() -> SystemView {
|
||||
fn mount_usage(disks: &Disks, mount_point: &str) -> (String, String, String) {
|
||||
disks
|
||||
@@ -140,7 +147,14 @@ fn format_bytes(bytes: u64) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn render_system_panel() -> RgbImage {
|
||||
pub(crate) fn render_system_panel(mode: &str) -> RgbImage {
|
||||
match normalize_specs_mode(mode) {
|
||||
"meters" => render_system_panel_meters(),
|
||||
_ => render_system_panel_cards(),
|
||||
}
|
||||
}
|
||||
|
||||
fn render_system_panel_cards() -> RgbImage {
|
||||
let system = collect_system_view();
|
||||
let mut canvas = RgbImage::from_pixel(DISPLAY_WIDTH, DISPLAY_HEIGHT, Rgb([10, 14, 18]));
|
||||
let host_name = System::host_name().unwrap_or_else(|| "Unraid".into());
|
||||
@@ -229,7 +243,10 @@ pub(crate) fn render_system_panel() -> RgbImage {
|
||||
236,
|
||||
"System",
|
||||
system.uptime.clone(),
|
||||
format!("{} CPU / {} proc", system.cpu_count, system.process_count),
|
||||
format!(
|
||||
"{} cores | {} procs",
|
||||
system.cpu_count, system.process_count
|
||||
),
|
||||
Rgb([216, 253, 114]),
|
||||
),
|
||||
];
|
||||
@@ -241,6 +258,109 @@ pub(crate) fn render_system_panel() -> RgbImage {
|
||||
canvas
|
||||
}
|
||||
|
||||
fn render_system_panel_meters() -> RgbImage {
|
||||
let system = collect_system_view();
|
||||
let mut canvas = RgbImage::from_pixel(DISPLAY_WIDTH, DISPLAY_HEIGHT, Rgb([9, 13, 17]));
|
||||
let host_name = System::host_name().unwrap_or_else(|| "Unraid".into());
|
||||
let timestamp = Local::now().format("%d.%m.%Y %H:%M:%S").to_string();
|
||||
|
||||
draw_filled_rect_mut(
|
||||
&mut canvas,
|
||||
Rect::at(0, 0).of_size(DISPLAY_WIDTH, 72),
|
||||
Rgb([15, 23, 30]),
|
||||
);
|
||||
draw_text_line(
|
||||
&mut canvas,
|
||||
Rgb([216, 253, 114]),
|
||||
26,
|
||||
18,
|
||||
32.0,
|
||||
"AOOSTAR System Monitor",
|
||||
);
|
||||
draw_text_line(
|
||||
&mut canvas,
|
||||
Rgb([146, 163, 181]),
|
||||
28,
|
||||
48,
|
||||
18.0,
|
||||
&format!("{host_name} | {timestamp}"),
|
||||
);
|
||||
|
||||
draw_meter_row(
|
||||
&mut canvas,
|
||||
26,
|
||||
102,
|
||||
"CPU",
|
||||
&format!("{}%", system.cpu_usage_percent),
|
||||
parse_metric_percent(&system.cpu_usage_percent),
|
||||
Rgb([110, 231, 183]),
|
||||
&format!(
|
||||
"Load {} / {} / {} {} cores {} procs",
|
||||
system.load_avg_one,
|
||||
system.load_avg_five,
|
||||
system.load_avg_fifteen,
|
||||
system.cpu_count,
|
||||
system.process_count
|
||||
),
|
||||
);
|
||||
draw_meter_row(
|
||||
&mut canvas,
|
||||
26,
|
||||
170,
|
||||
"RAM",
|
||||
&format!("{}%", system.mem_usage_percent),
|
||||
parse_metric_percent(&system.mem_usage_percent),
|
||||
Rgb([120, 189, 247]),
|
||||
&format!("{} / {}", system.mem_used, system.mem_total),
|
||||
);
|
||||
draw_meter_row(
|
||||
&mut canvas,
|
||||
26,
|
||||
238,
|
||||
"GPU",
|
||||
system.temperature_gpu.as_deref().unwrap_or("-"),
|
||||
normalize_temperature_bar(system.temperature_gpu.as_deref()),
|
||||
Rgb([241, 132, 121]),
|
||||
&format!(
|
||||
"Temp meter CPU {} Cache {}% User {}%",
|
||||
system.temperature_cpu.as_deref().unwrap_or("-"),
|
||||
system.cache_usage_percent,
|
||||
system.user_usage_percent
|
||||
),
|
||||
);
|
||||
|
||||
draw_filled_rect_mut(
|
||||
&mut canvas,
|
||||
Rect::at(26, 308).of_size(908, 42),
|
||||
Rgb([12, 18, 24]),
|
||||
);
|
||||
draw_hollow_rect_mut(
|
||||
&mut canvas,
|
||||
Rect::at(26, 308).of_size(908, 42),
|
||||
Rgb([31, 44, 58]),
|
||||
);
|
||||
draw_text_line(
|
||||
&mut canvas,
|
||||
Rgb([146, 163, 181]),
|
||||
42,
|
||||
321,
|
||||
18.0,
|
||||
&format!(
|
||||
"Swap {}% {} / {} Cache {} / {} User {} / {} Uptime {}",
|
||||
system.swap_usage_percent,
|
||||
system.swap_used,
|
||||
system.swap_total,
|
||||
system.cache_used,
|
||||
system.cache_total,
|
||||
system.user_used,
|
||||
system.user_total,
|
||||
system.uptime
|
||||
),
|
||||
);
|
||||
|
||||
canvas
|
||||
}
|
||||
|
||||
pub(crate) fn overlay_system_specs(canvas: &mut RgbImage) {
|
||||
let system = collect_system_view();
|
||||
let host_name = System::host_name().unwrap_or_else(|| "Unraid".into());
|
||||
@@ -309,6 +429,69 @@ pub(crate) fn overlay_system_specs(canvas: &mut RgbImage) {
|
||||
);
|
||||
}
|
||||
|
||||
fn draw_meter_row(
|
||||
canvas: &mut RgbImage,
|
||||
x: i32,
|
||||
y: i32,
|
||||
label: &str,
|
||||
value: &str,
|
||||
percent: f32,
|
||||
accent: Rgb<u8>,
|
||||
meta: &str,
|
||||
) {
|
||||
draw_text_line(canvas, accent, x, y, 19.0, label);
|
||||
draw_text_line(canvas, Rgb([237, 242, 247]), x + 112, y, 19.0, value);
|
||||
draw_meter_bar(canvas, x, y + 28, 840, 20, percent, accent);
|
||||
draw_text_line(canvas, Rgb([146, 163, 181]), x, y + 56, 17.0, meta);
|
||||
}
|
||||
|
||||
fn draw_meter_bar(
|
||||
canvas: &mut RgbImage,
|
||||
x: i32,
|
||||
y: i32,
|
||||
width: u32,
|
||||
height: u32,
|
||||
percent: f32,
|
||||
accent: Rgb<u8>,
|
||||
) {
|
||||
draw_filled_rect_mut(
|
||||
canvas,
|
||||
Rect::at(x, y).of_size(width, height),
|
||||
Rgb([19, 27, 35]),
|
||||
);
|
||||
draw_hollow_rect_mut(
|
||||
canvas,
|
||||
Rect::at(x, y).of_size(width, height),
|
||||
Rgb([36, 50, 67]),
|
||||
);
|
||||
let fill_width =
|
||||
((width.saturating_sub(2)) as f32 * (percent.clamp(0.0, 100.0) / 100.0)).round() as u32;
|
||||
if fill_width > 0 {
|
||||
draw_filled_rect_mut(
|
||||
canvas,
|
||||
Rect::at(x + 1, y + 1).of_size(fill_width, height.saturating_sub(2)),
|
||||
accent,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_metric_percent(value: &str) -> f32 {
|
||||
value.parse::<f32>().unwrap_or(0.0)
|
||||
}
|
||||
|
||||
fn normalize_temperature_bar(value: Option<&str>) -> f32 {
|
||||
let Some(raw) = value else {
|
||||
return 0.0;
|
||||
};
|
||||
let numeric = raw
|
||||
.replace(" °C", "")
|
||||
.replace('C', "")
|
||||
.trim()
|
||||
.parse::<f32>()
|
||||
.unwrap_or(0.0);
|
||||
(numeric / 100.0 * 100.0).clamp(0.0, 100.0)
|
||||
}
|
||||
|
||||
fn draw_metric_card(
|
||||
canvas: &mut RgbImage,
|
||||
x: i32,
|
||||
|
||||
Reference in New Issue
Block a user