vfa_tui/ui/widgets/
output.rs1use ratatui::{
2 layout::Rect,
3 style::{Color, Style},
4 text::{Line, Span},
5 widgets::{Block, Borders, Paragraph, Wrap},
6 Frame,
7};
8
9use crate::subprocess::stream::OutputStream;
10
11use super::super::theme::Theme;
12
13#[derive(Debug, Clone)]
15pub struct OutputLine {
16 pub content: String,
17 pub stream: OutputStream,
18}
19
20pub fn render_output(
23 lines: &[OutputLine],
24 title: &str,
25 area: Rect,
26 frame: &mut Frame,
27 theme: &Theme,
28) {
29 render_output_scrolled(lines, title, area, frame, 0, theme);
30}
31
32pub fn render_output_scrolled(
35 lines: &[OutputLine],
36 title: &str,
37 area: Rect,
38 frame: &mut Frame,
39 scroll: u16,
40 theme: &Theme,
41) {
42 let display_lines: Vec<Line> = lines
43 .iter()
44 .map(|line| {
45 let style = if theme.no_color {
46 Style::default()
47 } else {
48 match line.stream {
49 OutputStream::Stdout => Style::default().fg(Color::White),
50 OutputStream::Stderr => Style::default().fg(Color::Red),
51 }
52 };
53 Line::from(vec![Span::styled(line.content.clone(), style)])
54 })
55 .collect();
56
57 let paragraph = Paragraph::new(display_lines)
58 .block(
59 Block::default()
60 .borders(Borders::ALL)
61 .title(title.to_string())
62 .border_style(theme.border_style()),
63 )
64 .wrap(Wrap { trim: false })
65 .scroll((scroll, 0));
66
67 frame.render_widget(paragraph, area);
68}