top: tui impl X

This commit is contained in:
Bluemangoo
2025-10-06 16:40:21 +08:00
parent de50df2f35
commit 8ec2f941ce
3 changed files with 65 additions and 5 deletions
+32
View File
@@ -23,6 +23,7 @@ pub(crate) enum InputEvent {
NumaNode,
FilterUser,
FilterEUser,
WidthIncrement,
}
macro_rules! char {
@@ -138,6 +139,14 @@ pub fn handle_input(
should_update.store(true, Ordering::Relaxed);
}
char!('X') => {
let mut stat = tui_stat.write().unwrap();
stat.input_label = "width incr is 0, change to (0 default, -1 auto) ".into();
stat.input_value.clear();
stat.input_mode = InputMode::Input(InputEvent::WidthIncrement);
should_update.store(true, Ordering::Relaxed);
}
char!('x') => {
let mut stat = tui_stat.write().unwrap();
stat.highlight_sorted = !stat.highlight_sorted;
@@ -383,5 +392,28 @@ fn handle_input_value(
stat.reset_input();
should_update.store(true, Ordering::Relaxed);
}
InputEvent::WidthIncrement => {
let input_value = { tui_stat.read().unwrap().input_value.parse::<isize>() };
if input_value.is_err() || input_value.as_ref().is_ok_and(|v| *v < -1) {
let is_empty = { tui_stat.read().unwrap().input_value.trim().is_empty() };
let mut stat = tui_stat.write().unwrap();
stat.reset_input();
if !is_empty {
stat.input_message = Some(" Unacceptable integer ".into());
}
should_update.store(true, Ordering::Relaxed);
return;
}
let input_value = input_value.unwrap();
let mut stat = tui_stat.write().unwrap();
stat.width_increment = if input_value == -1 {
None
} else {
Some(input_value as usize)
};
stat.reset_input();
should_update.store(true, Ordering::Relaxed);
}
}
}
+31 -5
View File
@@ -8,6 +8,7 @@ mod input;
pub mod stat;
pub use input::*;
use std::borrow::Cow;
use crate::header::{format_memory, Header};
use crate::tui::color::TuiColor;
@@ -409,9 +410,26 @@ impl<'a> Tui<'a> {
.iter()
.position(|f| f == sorter)
.unwrap_or(0);
let user_width = {
if let Some(width) = self.stat.width_increment {
10 + width
} else if let Some(user_column_nth) =
self.proc_list.fields.iter().position(|f| f == "USER")
{
let users: Vec<&String> = self
.proc_list
.collected
.iter()
.map(|item| &item[user_column_nth])
.collect();
users.iter().map(|u| u.len()).max().unwrap_or_default() + 1
} else {
10
}
};
let build_constraint = |field: &str| match field {
"PID" => Constraint::Length(7),
"USER" => Constraint::Length(10),
"USER" => Constraint::Length(user_width as u16),
"PR" => Constraint::Length(4),
"NI" => Constraint::Length(4),
"VIRT" => Constraint::Length(8),
@@ -452,12 +470,20 @@ impl<'a> Tui<'a> {
.map(|(n, c)| {
let c = if column_coordinates.2 > 0 {
if c.len() < column_coordinates.2 {
""
// handle offset
Cow::Borrowed("")
} else {
&c[column_coordinates.2..]
Cow::Borrowed(&c[column_coordinates.2..])
}
} else if let Constraint::Length(length) = &constraints[n] {
// truncate if too long
if c.len() > *length as usize {
Cow::Owned(format!("{}+", &c[0..*length as usize - 2]))
} else {
Cow::Borrowed(c.as_str())
}
} else {
c
Cow::Borrowed(c.as_str())
};
if highlight_sorted && n == highlight_column {
Cell::from(Span::styled(
@@ -477,7 +503,7 @@ impl<'a> Tui<'a> {
let mut state = TableState::default().with_offset(list_coordinates.0);
let table = Table::new(rows, constraints).header(header);
let table = Table::new(rows, constraints.clone()).header(header);
StatefulWidget::render(table, area, buf, &mut state);
}
}
+2
View File
@@ -31,6 +31,7 @@ pub(crate) struct TuiStat {
pub show_coordinates: bool,
pub show_zeros: bool,
pub irix_mode: bool,
pub width_increment: Option<usize>, // None means auto
pub filter: Option<crate::Filter>,
}
@@ -68,6 +69,7 @@ impl TuiStat {
show_coordinates: false,
show_zeros: true,
irix_mode: true,
width_increment: None,
filter: None,
}