term_kit/
infobox.rs

1use crossterm::{
2    cursor, execute,
3    style::{Color, Print, PrintStyledContent, Stylize},
4    terminal::{Clear, ClearType},
5};
6use std::io::{stdout, Write};
7use textwrap::fill;
8
9pub struct InfoBox {
10    pub title: String,
11    pub message: String,
12    pub width: usize,
13    pub padding: usize,
14    pub title_color: Color,
15    pub border_color: Color,
16    pub message_color: Color,
17}
18
19impl InfoBox {
20    pub fn new(
21        title: String,
22        message: String,
23        width: usize,
24        padding: Option<usize>,
25        title_color: Option<Color>,
26        border_color: Option<Color>,
27        message_color: Option<Color>,
28    ) -> Self {
29        Self {
30            title,
31            message,
32            width,
33            padding: padding.unwrap_or(2),
34            title_color: title_color.unwrap_or(Color::White), // Default to White if not provided
35            border_color: border_color.unwrap_or(Color::Blue),
36            message_color: message_color.unwrap_or(Color::Reset),
37        }
38    }
39
40    pub fn render(&self) -> Result<(), Box<dyn std::error::Error>> {
41        let mut stdout = stdout();
42        let total_width = self.width + 2 * self.padding + 2;
43
44        execute!(stdout, cursor::MoveToColumn(0))?;
45        execute!(stdout, Clear(ClearType::UntilNewLine))?;
46
47        execute!(
48            stdout,
49            PrintStyledContent(
50                format!("{: <width$}", self.title, width = total_width as usize)
51                    .with(self.title_color)
52            )
53        )?;
54        execute!(stdout, Print("\n"))?;
55
56        execute!(stdout, PrintStyledContent("┌".with(self.border_color)))?;
57        for _ in 0..total_width - 2 {
58            execute!(stdout, PrintStyledContent("─".with(self.border_color)))?;
59        }
60        execute!(stdout, PrintStyledContent("┐\n".with(self.border_color)))?;
61
62        let wrapped_message = fill(&self.message, self.width);
63        for line in wrapped_message.lines() {
64            execute!(stdout, PrintStyledContent("│".with(self.border_color)))?;
65            for _ in 0..self.padding {
66                execute!(stdout, Print(" "))?;
67            }
68            execute!(stdout, PrintStyledContent(line.with(self.message_color)))?;
69            for _ in 0..self.padding + (self.width - line.len()) {
70                execute!(stdout, Print(" "))?;
71            }
72            execute!(stdout, PrintStyledContent("│\n".with(self.border_color)))?;
73        }
74
75        execute!(stdout, PrintStyledContent("└".with(self.border_color)))?;
76        for _ in 0..total_width - 2 {
77            execute!(stdout, PrintStyledContent("─".with(self.border_color)))?;
78        }
79        execute!(stdout, PrintStyledContent("┘\n".with(self.border_color)))?;
80
81        stdout.flush()?;
82
83        Ok(())
84    }
85}