M2: terminal UI (ratatui)

- layout: header, top menu (quicklook, cpu, mem, swap, load), left sidebar,
  process list and alert footer
- decorations/colors, bars, per-plugin render implementations
- hotkeys: quit, help, modes, sorting, cursor, nice, kill, filters, toggles
- TestBackend layout test
This commit is contained in:
glances-rs
2026-10-09 23:35:23 +00:00
parent 975385da5d
commit 8385900ac1
27 changed files with 2053 additions and 31 deletions
@@ -160,4 +160,77 @@ impl Plugin for DiskioPlugin {
fn display_curse(&self) -> bool {
true
}
fn render(&mut self, ctx: &glances_core::RenderContext) -> Vec<glances_core::StatLine> {
let mut ret = Vec::new();
if self.model.stats.as_array().map(|a| a.is_empty()).unwrap_or(true) || ctx.max_width == 0 {
return ret;
}
let name_max_width = ctx.max_width.saturating_sub(13);
ret.push(self.model.curse_add_line(
format!("{:<width$}", "DISK I/O", width = name_max_width),
glances_core::Decoration::Title,
false,
false,
false,
));
if ctx.args.diskio_iops {
ret.push(self.model.curse_add_line(format!("{:>8}", "IOR/s"), glances_core::Decoration::Default, false, false, false));
ret.push(self.model.curse_add_line(format!("{:>7}", "IOW/s"), glances_core::Decoration::Default, false, false, false));
} else if ctx.args.diskio_latency {
ret.push(self.model.curse_add_line(format!("{:>8}", "ms/opR"), glances_core::Decoration::Default, false, false, false));
ret.push(self.model.curse_add_line(format!("{:>7}", "ms/opW"), glances_core::Decoration::Default, false, false, false));
} else {
ret.push(self.model.curse_add_line(format!("{:>8}", "R/s"), glances_core::Decoration::Default, false, false, false));
ret.push(self.model.curse_add_line(format!("{:>7}", "W/s"), glances_core::Decoration::Default, false, false, false));
}
let stats = self.model.sorted_stats();
let Some(items) = stats.as_array() else {
return ret;
};
for i in items {
let disk_real_name = i.get("disk_name").and_then(Value::as_str).unwrap_or("").to_string();
if self
.model
.hide_zero_fields
.iter()
.all(|field| self.model.view_bool(Some(&disk_real_name), field, "hidden"))
{
continue;
}
let mut disk_name = i
.get("alias")
.and_then(Value::as_str)
.map(|s| s.to_string())
.unwrap_or_else(|| disk_real_name.clone());
if disk_name.chars().count() > name_max_width {
disk_name = format!("{}_", disk_name.chars().take(name_max_width).collect::<String>());
}
ret.push(self.model.curse_new_line());
ret.push(self.model.curse_add_line(
format!("{:<width$}", disk_name, width = name_max_width + 1),
glances_core::Decoration::Default,
false,
false,
false,
));
if ctx.args.diskio_iops {
let rx = self.model.auto_unit(i.get("read_count_rate_per_sec").and_then(Value::as_f64).unwrap_or(0.0), false, "K");
let tx = self.model.auto_unit(i.get("write_count_rate_per_sec").and_then(Value::as_f64).unwrap_or(0.0), false, "K");
ret.push(self.model.curse_add_line(format!("{rx:>7}"), self.model.view_decoration(Some(&disk_real_name), "read_count"), false, false, false));
ret.push(self.model.curse_add_line(format!("{tx:>7}"), self.model.view_decoration(Some(&disk_real_name), "write_count"), false, false, false));
} else if ctx.args.diskio_latency {
let rx = self.model.auto_unit(i.get("read_latency").and_then(Value::as_f64).unwrap_or(0.0), true, "K");
let tx = self.model.auto_unit(i.get("write_latency").and_then(Value::as_f64).unwrap_or(0.0), true, "K");
ret.push(self.model.curse_add_line(format!("{rx:>7}"), self.model.view_decoration(Some(&disk_real_name), "read_latency"), false, false, false));
ret.push(self.model.curse_add_line(format!("{tx:>7}"), self.model.view_decoration(Some(&disk_real_name), "write_latency"), false, false, false));
} else {
let rx = self.model.auto_unit(i.get("read_bytes_rate_per_sec").and_then(Value::as_f64).unwrap_or(0.0), false, "K");
let tx = self.model.auto_unit(i.get("write_bytes_rate_per_sec").and_then(Value::as_f64).unwrap_or(0.0), false, "K");
ret.push(self.model.curse_add_line(format!("{rx:>7}"), self.model.view_decoration(Some(&disk_real_name), "read_bytes"), false, false, false));
ret.push(self.model.curse_add_line(format!("{tx:>7}"), self.model.view_decoration(Some(&disk_real_name), "write_bytes"), false, false, false));
}
}
ret
}
}