diff --git a/src/renderer/disk.rs b/src/renderer/disk.rs index 755fade..ec26f69 100644 --- a/src/renderer/disk.rs +++ b/src/renderer/disk.rs @@ -11,7 +11,7 @@ use byte_unit::{Byte, Unit}; use ratatui::layout::{Constraint, Direction, Layout, Rect}; use ratatui::style::{Color, Style}; use ratatui::text::{Line, Span}; -use ratatui::widgets::{Block, Borders, List, ListItem, Paragraph, Sparkline}; +use ratatui::widgets::{Block, Borders, List, ListItem, ListState, Paragraph, Sparkline}; use ratatui::Frame; use std::borrow::Cow; @@ -21,7 +21,7 @@ pub fn render_disk( f: &mut Frame<'_>, view: View, border_style: Style, - file_system_index: &usize, + fs_list_state: &mut ListState, file_system_display: &FileSystemDisplay, ) { let (disk_layout, view) = split_left_right_pane("Disk", layout, f, view, border_style); @@ -31,45 +31,34 @@ pub fn render_disk( .constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref()) .split(disk_layout[1]); + let file_system_index = fs_list_state.selected().unwrap_or(0); if *file_system_display == FileSystemDisplay::Activity { - disk_activity_histogram(app, f, view, &area, file_system_index); + disk_activity_histogram(app, f, view, &area, &file_system_index); } else { - disk_usage(app, f, view, &area, file_system_index); + disk_usage(app, f, view, &area, &file_system_index); } let mut disk_list: Vec<_> = app.disks.values().collect(); disk_list.sort_by(|a, b| b.mount_point.cmp(&a.mount_point)); let disks: Vec<_> = disk_list .iter() - .enumerate() - .map(|(i, d)| { + .map(|d| { let style = if d.get_perc_free_space() < 10.0 { max_style() } else { ok_style() }; - if *file_system_index == i { - Span::styled( - Cow::Owned(format!( - "→{:3.0}%: {}", - d.get_perc_free_space(), - d.mount_point.display() - )), - style, - ) - } else { - Span::styled( - Cow::Owned(format!( - " {:3.0}%: {}", - d.get_perc_free_space(), - d.mount_point.display() - )), - style, - ) - } + Span::styled( + Cow::Owned(format!( + " {:3.0}%: {}", + d.get_perc_free_space(), + d.mount_point.display() + )), + style, + ) }) .map(ListItem::new) .collect(); - List::new(disks) + let disks_list = List::new(disks) .block( Block::default() .title(Span::styled( @@ -79,7 +68,8 @@ pub fn render_disk( .borders(Borders::ALL) .border_style(border_style), ) - .render(f, disk_layout[0]); + .highlight_symbol("→"); + f.render_stateful_widget(disks_list, disk_layout[0], fs_list_state); } fn disk_activity_histogram( app: &CPUTimeApp, diff --git a/src/renderer/graphics.rs b/src/renderer/graphics.rs index d437981..5c01d17 100644 --- a/src/renderer/graphics.rs +++ b/src/renderer/graphics.rs @@ -11,7 +11,7 @@ use byte_unit::{Byte, Unit}; use ratatui::layout::{Constraint, Direction, Layout, Rect}; use ratatui::style::{Color, Style}; use ratatui::text::{Line, Span}; -use ratatui::widgets::{Block, Borders, List, ListItem, Sparkline}; +use ratatui::widgets::{Block, Borders, List, ListItem, ListState, Sparkline}; use ratatui::Frame; use std::borrow::Cow; @@ -20,7 +20,7 @@ pub fn render_graphics( layout: Rect, f: &mut Frame<'_>, view: View, - gfx_device_index: &usize, + gfx_list_state: &mut ListState, border_style: Style, ) { Block::default() @@ -47,7 +47,7 @@ pub fn render_graphics( ..view }; - let gd = &app.gfx_devices[*gfx_device_index]; + let gd = &app.gfx_devices[gfx_list_state.selected().unwrap_or(0)]; let h_gpu = match app .histogram_map .get_zoomed(&HistogramKind::GpuUse(gd.uuid.clone()), &view) @@ -156,30 +156,26 @@ pub fn render_graphics( let devices: Vec<_> = app .gfx_devices .iter() - .enumerate() - .map(|(i, d)| { - let indicator = if i == *gfx_device_index { "→" } else { " " }; + .map(|d| { let style = if d.gpu_utilization > 90 { max_style() } else { ok_style() }; Span::styled( - Cow::Owned(format!( - "{}{:3.0}%: {}", - indicator, d.gpu_utilization, d.name - )), + Cow::Owned(format!(" {:3.0}%: {}", d.gpu_utilization, d.name)), style, ) }) .map(ListItem::new) .collect(); - List::new(devices) + let devices_list = List::new(devices) .block( Block::default() .title(Span::styled("Graphics Devices", border_style)) .borders(Borders::ALL) .border_style(border_style), ) - .render(f, gfx_layout[0]); + .highlight_symbol("→"); + f.render_stateful_widget(devices_list, gfx_layout[0], gfx_list_state); } diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index 4301280..62db1fb 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -34,7 +34,7 @@ use std::time::{Duration, Instant}; use ratatui::layout::{Constraint, Direction, Layout, Rect}; use ratatui::style::{Color, Style}; -use ratatui::widgets::{Block, Borders}; +use ratatui::widgets::{Block, Borders, ListState}; use ratatui::Frame; const PROCESS_SELECTION_GRACE: Duration = Duration::from_millis(2000); @@ -186,7 +186,9 @@ pub struct TerminalRenderer<'a> { process_table_row_start: usize, process_table_height: u16, gfx_device_index: usize, + gfx_list_state: ListState, file_system_index: usize, + fs_list_state: ListState, file_system_display: FileSystemDisplay, /// Index in the vector below is "order" on the screen starting from the top /// (usually CPU) while value is the section it belongs to and its current height (as %). @@ -253,7 +255,9 @@ impl TerminalRenderer<'_> { process_table_row_start: 0, process_table_height: 0, gfx_device_index: 0, + gfx_list_state: ListState::default(), file_system_index: 0, + fs_list_state: ListState::default(), file_system_display: FileSystemDisplay::Activity, section_geometry: section_geometry.clone(), zoom_factor: 1, @@ -402,23 +406,29 @@ impl TerminalRenderer<'_> { Section::Network => { network::render_net(&self.app, v_section, f, view, border_style) } - Section::Disk => disk::render_disk( - &self.app, - v_section, - f, - view, - border_style, - &self.file_system_index, - &self.file_system_display, - ), - Section::Graphics => graphics::render_graphics( - &self.app, - v_section, - f, - view, - &self.gfx_device_index, - border_style, - ), + Section::Disk => { + self.fs_list_state.select(Some(self.file_system_index)); + disk::render_disk( + &self.app, + v_section, + f, + view, + border_style, + &mut self.fs_list_state, + &self.file_system_display, + ) + } + Section::Graphics => { + self.gfx_list_state.select(Some(self.gfx_device_index)); + graphics::render_graphics( + &self.app, + v_section, + f, + view, + &mut self.gfx_list_state, + border_style, + ) + } Section::Process => { if let Some(p) = self.app.selected_process.as_ref() { process::render_process(