diff options
Diffstat (limited to 'src/ui.rs')
-rw-r--r-- | src/ui.rs | 131 |
1 files changed, 83 insertions, 48 deletions
@@ -1,4 +1,8 @@ -use crate::registers::RegistersData; +use crate::{ + cli::Args, + registers::RegistersData, + trace::{trace, trace_kill, trace_next}, +}; use crossterm::{ event::{self, Event, KeyCode}, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, @@ -8,19 +12,95 @@ use nix::unistd::Pid; use ratatui::{prelude::*, widgets::*}; use std::io::{self, stdout}; -struct UI { +pub struct UI { height: usize, max_lines: usize, scroll: usize, + lines: Vec<RegistersData>, } impl UI { - fn new() -> UI { + pub fn new() -> UI { UI { height: 0, max_lines: 0, scroll: 0, + lines: vec![], + } + } + + pub fn add_line(&mut self, registers: RegistersData) { + self.lines.push(registers); + self.max_lines = self.lines.len() + 1; + } + + pub fn get_paragraph(&self, pid: Pid) -> Paragraph { + let lines: Vec<Line> = self.lines.iter().map(|x| x.output_ui()).collect(); + let paragraph = Paragraph::new(lines) + .block( + Block::default() + .border_style(Style::default().fg(Color::Yellow)) + .title(format!("[{pid}]")) + .title( + block::Title::from(format!( + "[lines {}-{}]", + self.scroll, + self.scroll + self.height + )) + .position(block::Position::Bottom) + .alignment(Alignment::Right), + ) + .borders(Borders::ALL), + ) + .scroll((self.scroll as u16, 0)); + + paragraph + } + + pub fn start(&mut self, pid: Pid, args: &Args) -> anyhow::Result<()> { + enable_raw_mode()?; + stdout().execute(EnterAlternateScreen)?; + let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?; + + let mut have_to_print = true; + let mut have_to_trace = !args.command.is_some(); + let mut should_quit = false; + + let lines = trace(pid, &args, args.command.is_some())?; + if lines.len() > 1 { + for line in lines { + self.add_line(line); + } + } + while !should_quit { + if have_to_trace { + if let Some(reg) = trace_next(pid)? { + have_to_print ^= true; + if have_to_print { + self.add_line(reg); + } + } else { + have_to_trace = false; + } + } + + self.height = terminal.get_frame().size().height as usize; + terminal.draw(|frame| { + let size = frame.size(); + + frame.render_widget(self.get_paragraph(pid), size); + })?; + + should_quit = handle_events(self)?; } + + // FIXME: avoid this kill without Rust errors + let _ = trace_kill(pid); + + disable_raw_mode()?; + stdout().execute(LeaveAlternateScreen)?; + + Ok(()) } } @@ -55,48 +135,3 @@ fn handle_events(ui: &mut UI) -> io::Result<bool> { } Ok(false) } - -pub fn run_tui(pid: Pid, registers: &Vec<RegistersData>) -> anyhow::Result<()> { - enable_raw_mode()?; - stdout().execute(EnterAlternateScreen)?; - let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?; - - let mut ui = UI::new(); - ui.max_lines = registers.len() + 1; - - let mut should_quit = false; - while !should_quit { - ui.height = terminal.get_frame().size().height as usize; - terminal.draw(move |frame| { - let size = frame.size(); - let lines: Vec<Line> = registers.iter().map(|x| x.output_ui()).collect(); - - frame.render_widget( - Paragraph::new(lines) - .block( - Block::default() - .border_style(Style::default().fg(Color::Yellow)) - .title(format!("[{pid}]")) - .title( - block::Title::from(format!( - "[lines {}-{}]", - ui.scroll, - ui.scroll + ui.height - )) - .position(block::Position::Bottom) - .alignment(Alignment::Right), - ) - .borders(Borders::ALL), - ) - .scroll((ui.scroll as u16, 0)), - size, - ); - })?; - should_quit = handle_events(&mut ui)?; - } - - disable_raw_mode()?; - stdout().execute(LeaveAlternateScreen)?; - - Ok(()) -} |