mirror of
https://github.com/uutils/procps.git
synced 2026-05-06 06:06:43 -04:00
top: tui impl ^e
This commit is contained in:
+58
-34
@@ -3,7 +3,7 @@
|
||||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
|
||||
use crate::tui::stat::TuiStat;
|
||||
use crate::tui::stat::{TimeScale, TuiStat};
|
||||
use crate::Settings;
|
||||
use std::any::Any;
|
||||
use std::cmp::Ordering;
|
||||
@@ -24,13 +24,13 @@ pub fn sysinfo() -> &'static RwLock<System> {
|
||||
}
|
||||
|
||||
pub trait Column {
|
||||
fn as_string(&self, show_zeros: bool) -> String;
|
||||
fn as_string(&self, tui_stat: &TuiStat) -> String;
|
||||
fn cmp_dyn(&self, other: &dyn Column) -> Ordering;
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
}
|
||||
|
||||
impl Column for String {
|
||||
fn as_string(&self, _show_zeros: bool) -> String {
|
||||
fn as_string(&self, _tui_stat: &TuiStat) -> String {
|
||||
self.clone()
|
||||
}
|
||||
|
||||
@@ -47,8 +47,8 @@ impl Column for String {
|
||||
}
|
||||
|
||||
impl Column for u32 {
|
||||
fn as_string(&self, show_zeros: bool) -> String {
|
||||
if !show_zeros && self == &0 {
|
||||
fn as_string(&self, tui_stat: &TuiStat) -> String {
|
||||
if !tui_stat.show_zeros && self == &0 {
|
||||
return String::new();
|
||||
}
|
||||
self.to_string()
|
||||
@@ -67,8 +67,8 @@ impl Column for u32 {
|
||||
}
|
||||
|
||||
impl Column for Option<i32> {
|
||||
fn as_string(&self, show_zeros: bool) -> String {
|
||||
if !show_zeros && self == &Some(0) {
|
||||
fn as_string(&self, tui_stat: &TuiStat) -> String {
|
||||
if !tui_stat.show_zeros && self == &Some(0) {
|
||||
return String::new();
|
||||
}
|
||||
self.map(|v| v.to_string()).unwrap_or_default()
|
||||
@@ -102,8 +102,8 @@ impl PercentValue {
|
||||
}
|
||||
|
||||
impl Column for PercentValue {
|
||||
fn as_string(&self, show_zeros: bool) -> String {
|
||||
if !show_zeros && self.value == 0.0 {
|
||||
fn as_string(&self, tui_stat: &TuiStat) -> String {
|
||||
if !tui_stat.show_zeros && self.value == 0.0 {
|
||||
return String::new();
|
||||
}
|
||||
format!("{:.1}", self.value)
|
||||
@@ -132,8 +132,8 @@ impl MemValue {
|
||||
}
|
||||
|
||||
impl Column for MemValue {
|
||||
fn as_string(&self, show_zeros: bool) -> String {
|
||||
if !show_zeros && self.value == 0 {
|
||||
fn as_string(&self, tui_stat: &TuiStat) -> String {
|
||||
if !tui_stat.show_zeros && self.value == 0 {
|
||||
return String::new();
|
||||
}
|
||||
let mem_mb = self.value as f64 / bytesize::MIB as f64;
|
||||
@@ -156,33 +156,63 @@ impl Column for MemValue {
|
||||
}
|
||||
}
|
||||
|
||||
struct TimeMSValue {
|
||||
min: u64,
|
||||
struct TimeValue {
|
||||
sec: f64,
|
||||
}
|
||||
|
||||
impl TimeMSValue {
|
||||
fn new_boxed(min: u64, sec: f64) -> Box<Self> {
|
||||
Box::new(Self { min, sec })
|
||||
impl TimeValue {
|
||||
fn new_boxed(sec: f64) -> Box<Self> {
|
||||
Box::new(Self { sec })
|
||||
}
|
||||
}
|
||||
|
||||
impl Column for TimeMSValue {
|
||||
fn as_string(&self, show_zeros: bool) -> String {
|
||||
if !show_zeros && self.min == 0 && self.sec < 0.01 {
|
||||
impl Column for TimeValue {
|
||||
fn as_string(&self, tui_stat: &TuiStat) -> String {
|
||||
if !tui_stat.show_zeros && self.sec < 0.01 {
|
||||
return String::new();
|
||||
}
|
||||
format!("{}:{:0>5.2}", self.min, self.sec)
|
||||
match tui_stat.time_scale {
|
||||
TimeScale::MinSecondCent => {
|
||||
let min = (self.sec / 60.0).floor() as u32;
|
||||
let sec = self.sec - (min * 60) as f64;
|
||||
format!("{}:{:0>5.2}", min, sec)
|
||||
}
|
||||
TimeScale::MinSecond => {
|
||||
let min = (self.sec / 60.0).floor() as u32;
|
||||
let sec = (self.sec - (min * 60) as f64).floor() as u32;
|
||||
format!("{}:{:0>2}", min, sec)
|
||||
}
|
||||
TimeScale::HourMin => {
|
||||
let hour = (self.sec / 3600.0).floor() as u32;
|
||||
let min = ((self.sec - (hour * 3600) as f64) / 60.0).floor() as u32;
|
||||
format!("{},{:0>2}", hour, min)
|
||||
}
|
||||
TimeScale::DayHour => {
|
||||
let day = (self.sec / 86400.0).floor() as u32;
|
||||
let hour = ((self.sec - (day * 86400) as f64) / 3600.0).floor() as u32;
|
||||
format!("{}d+{}h", day, hour)
|
||||
}
|
||||
TimeScale::Day => {
|
||||
let day = (self.sec / 86400.0).floor() as u32;
|
||||
format!("{}d", day)
|
||||
}
|
||||
TimeScale::WeekDay => {
|
||||
let week = (self.sec / 604800.0).floor() as u32;
|
||||
let day = ((self.sec - (week * 604800) as f64) / 86400.0).floor() as u32;
|
||||
format!("{}w+{}d", week, day)
|
||||
}
|
||||
TimeScale::Week => {
|
||||
let week = (self.sec / 604800.0).floor() as u32;
|
||||
format!("{}w", week)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn cmp_dyn(&self, other: &dyn Column) -> Ordering {
|
||||
other
|
||||
.as_any()
|
||||
.downcast_ref::<TimeMSValue>()
|
||||
.map(|o| match self.min.cmp(&o.min) {
|
||||
Ordering::Equal => self.sec.partial_cmp(&o.sec).unwrap_or(Ordering::Equal),
|
||||
ord => ord,
|
||||
})
|
||||
.downcast_ref::<TimeValue>()
|
||||
.map(|o| self.sec.partial_cmp(&o.sec).unwrap_or(Ordering::Equal))
|
||||
.unwrap_or(Ordering::Equal)
|
||||
}
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
@@ -383,18 +413,12 @@ fn s(pid: u32, _stat: Stat) -> Box<dyn Column> {
|
||||
fn time_plus(pid: u32, _stat: Stat) -> Box<dyn Column> {
|
||||
let binding = sysinfo().read().unwrap();
|
||||
let Some(proc) = binding.process(Pid::from_u32(pid)) else {
|
||||
return TimeMSValue::new_boxed(0, 0.0);
|
||||
return TimeValue::new_boxed(0.0);
|
||||
};
|
||||
|
||||
let (min, sec) = {
|
||||
let total = proc.accumulated_cpu_time();
|
||||
let minute = total / (60 * 1000);
|
||||
let second = (total % (60 * 1000)) as f64 / 1000.0;
|
||||
let second = proc.accumulated_cpu_time() as f64 / 1000.0;
|
||||
|
||||
(minute, second)
|
||||
};
|
||||
|
||||
TimeMSValue::new_boxed(min, sec)
|
||||
TimeValue::new_boxed(second)
|
||||
}
|
||||
|
||||
fn mem(pid: u32, _stat: Stat) -> Box<dyn Column> {
|
||||
|
||||
@@ -233,7 +233,7 @@ fn collect(settings: &Settings, fields: &[String], tui_stat: &TuiStat) -> Vec<Ve
|
||||
.into_iter()
|
||||
.map(|it| {
|
||||
it.into_iter()
|
||||
.map(|c| c.as_string(tui_stat.show_zeros))
|
||||
.map(|c| c.as_string(tui_stat))
|
||||
.collect()
|
||||
})
|
||||
.collect()
|
||||
|
||||
@@ -84,6 +84,19 @@ pub fn handle_input(
|
||||
|
||||
should_update.store(true, Ordering::Relaxed);
|
||||
}
|
||||
Event::Key(KeyEvent {
|
||||
code: KeyCode::Char('e'),
|
||||
modifiers: KeyModifiers::CONTROL,
|
||||
..
|
||||
}) => {
|
||||
{
|
||||
let mut stat = tui_stat.write().unwrap();
|
||||
stat.time_scale = stat.time_scale.next();
|
||||
}
|
||||
|
||||
data.write().unwrap().1 = ProcList::new(settings, &tui_stat.read().unwrap());
|
||||
should_update.store(true, Ordering::Relaxed);
|
||||
}
|
||||
char!('I') => {
|
||||
{
|
||||
let mut stat = tui_stat.write().unwrap();
|
||||
|
||||
@@ -32,6 +32,7 @@ pub(crate) struct TuiStat {
|
||||
pub show_zeros: bool,
|
||||
pub irix_mode: bool,
|
||||
pub width_increment: Option<usize>, // None means auto
|
||||
pub time_scale: TimeScale,
|
||||
|
||||
pub filter: Option<crate::Filter>,
|
||||
}
|
||||
@@ -69,7 +70,8 @@ impl TuiStat {
|
||||
show_coordinates: false,
|
||||
show_zeros: true,
|
||||
irix_mode: true,
|
||||
width_increment: None,
|
||||
width_increment: Some(0), // fixed
|
||||
time_scale: TimeScale::default(),
|
||||
|
||||
filter: None,
|
||||
}
|
||||
@@ -123,7 +125,6 @@ impl CpuValueMode {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
#[derive(Debug, Default, PartialEq)]
|
||||
pub enum MemoryGraphMode {
|
||||
#[default]
|
||||
@@ -143,3 +144,29 @@ impl MemoryGraphMode {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, PartialEq)]
|
||||
pub enum TimeScale {
|
||||
#[default]
|
||||
MinSecondCent, // 00:00.00
|
||||
MinSecond, // 00:00
|
||||
HourMin, // 0,00
|
||||
DayHour, // 0d+0h
|
||||
Day, // 0d
|
||||
WeekDay, // 0w+0d
|
||||
Week, // 0w
|
||||
}
|
||||
|
||||
impl TimeScale {
|
||||
pub fn next(&self) -> TimeScale {
|
||||
match self {
|
||||
TimeScale::MinSecondCent => TimeScale::MinSecond,
|
||||
TimeScale::MinSecond => TimeScale::HourMin,
|
||||
TimeScale::HourMin => TimeScale::DayHour,
|
||||
TimeScale::DayHour => TimeScale::Day,
|
||||
TimeScale::Day => TimeScale::WeekDay,
|
||||
TimeScale::WeekDay => TimeScale::Week,
|
||||
TimeScale::Week => TimeScale::MinSecondCent,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user