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:
@@ -8,6 +8,7 @@ use serde_json::Value;
|
||||
|
||||
pub struct PerCpuPlugin {
|
||||
pub model: PluginModel,
|
||||
pub max_cpu_display: usize,
|
||||
}
|
||||
|
||||
impl PerCpuPlugin {
|
||||
@@ -39,7 +40,8 @@ impl PerCpuPlugin {
|
||||
args.disable_config_exec,
|
||||
);
|
||||
model.set_item_key("cpu_number");
|
||||
Self { model }
|
||||
let max_cpu_display = config.get_int_value("percpu", "max_cpu_display", 4).max(1) as usize;
|
||||
Self { model, max_cpu_display }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,4 +66,71 @@ impl Plugin for PerCpuPlugin {
|
||||
let mut state = cpu_percent().lock().unwrap();
|
||||
Ok(Value::Array(state.get_percpu().to_vec()))
|
||||
}
|
||||
|
||||
fn render(&mut self, ctx: &glances_core::RenderContext) -> Vec<glances_core::StatLine> {
|
||||
let mut ret = Vec::new();
|
||||
let items: Vec<Value> = self.model.stats.as_array().cloned().unwrap_or_default();
|
||||
if items.is_empty() || !ctx.runtime.percpu {
|
||||
return ret;
|
||||
}
|
||||
let items = &items;
|
||||
let quicklook_disabled = !ctx.runtime.is_plugin_enabled("quicklook");
|
||||
let mut header = vec!["user", "system", "iowait", "idle", "irq", "nice", "steal", "guest"];
|
||||
if quicklook_disabled {
|
||||
ret.push(self.model.curse_add_line(format!("{:5}", "CPU"), glances_core::Decoration::Title, false, false, false));
|
||||
header.insert(0, "total");
|
||||
}
|
||||
for stat in &header {
|
||||
ret.push(self.model.curse_add_line(format!("{stat:>7}"), glances_core::Decoration::Default, false, false, false));
|
||||
}
|
||||
// Sort by total and keep the top max_cpu_display cores.
|
||||
let mut sorted: Vec<Value> = items.clone();
|
||||
if sorted.len() > self.max_cpu_display {
|
||||
sorted.sort_by(|a, b| {
|
||||
b.get("total")
|
||||
.and_then(Value::as_f64)
|
||||
.unwrap_or(0.0)
|
||||
.partial_cmp(&a.get("total").and_then(Value::as_f64).unwrap_or(0.0))
|
||||
.unwrap_or(std::cmp::Ordering::Equal)
|
||||
});
|
||||
}
|
||||
let displayed: Vec<Value> = sorted.iter().take(self.max_cpu_display).cloned().collect();
|
||||
for cpu in &displayed {
|
||||
ret.push(self.model.curse_new_line());
|
||||
if quicklook_disabled {
|
||||
let cpu_id = cpu.get("cpu_number").and_then(Value::as_i64).unwrap_or(0);
|
||||
let msg = if cpu_id < 10 { format!("CPU{cpu_id:1} ") } else { format!("{cpu_id:4} ") };
|
||||
ret.push(self.model.curse_add_line(msg, glances_core::Decoration::Default, false, false, false));
|
||||
}
|
||||
for stat in &header {
|
||||
let value = cpu.get(*stat).and_then(Value::as_f64);
|
||||
let decoration = match value {
|
||||
Some(value) => self.model.get_alert(value, 0.0, 100.0, true, false, Some(stat), None, false),
|
||||
None => glances_core::Decoration::Default,
|
||||
};
|
||||
let msg = match value {
|
||||
Some(value) => format!("{value:6.1}%"),
|
||||
None => format!("{:>6}%", "?"),
|
||||
};
|
||||
ret.push(self.model.curse_add_line(msg, decoration, false, false, false));
|
||||
}
|
||||
}
|
||||
if items.len() > self.max_cpu_display {
|
||||
ret.push(self.model.curse_new_line());
|
||||
if quicklook_disabled {
|
||||
ret.push(self.model.curse_add_line("CPU* ", glances_core::Decoration::Default, false, false, false));
|
||||
}
|
||||
for stat in &header {
|
||||
let values: Vec<f64> = sorted
|
||||
.iter()
|
||||
.skip(self.max_cpu_display)
|
||||
.filter_map(|cpu| cpu.get(*stat).and_then(Value::as_f64))
|
||||
.collect();
|
||||
let mean = if values.is_empty() { 0.0 } else { values.iter().sum::<f64>() / values.len() as f64 };
|
||||
let decoration = self.model.get_alert(mean, 0.0, 100.0, true, false, Some(stat), None, false);
|
||||
ret.push(self.model.curse_add_line(format!("{mean:6.1}%"), decoration, false, false, false));
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user