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        title_color: Option<Color>,
25        border_color: Option<Color>,
26        message_color: Option<Color>,
27    ) -> Self {
28        Self {
29            title,
30            message,
31            width,
32            padding: 2,
33            title_color: title_color.unwrap_or(Color::White), // Default to White if not provided
34            border_color: border_color.unwrap_or(Color::Blue),
35            message_color: message_color.unwrap_or(Color::Reset),
36        }
37    }
38
39    pub fn with_padding(mut self, padding: usize) -> Self {
40        self.padding = padding;
41        self
42    }
43
44    pub fn render(&self) -> Result<(), Box<dyn std::error::Error>> {
45        let mut stdout = stdout();
46        let total_width = self.width + 2 * self.padding + 2;
47
48        execute!(stdout, cursor::MoveToColumn(0))?;
49        execute!(stdout, Clear(ClearType::UntilNewLine))?;
50
51        execute!(
52            stdout,
53            PrintStyledContent(
54                format!("{: <width$}", self.title, width = total_width as usize)
55                    .with(self.title_color)
56            )
57        )?;
58        execute!(stdout, Print("\n"))?;
59
60        execute!(stdout, PrintStyledContent("┌".with(self.border_color)))?;
61        for _ in 0..total_width - 2 {
62            execute!(stdout, PrintStyledContent("─".with(self.border_color)))?;
63        }
64        execute!(stdout, PrintStyledContent("┐\n".with(self.border_color)))?;
65
66        let wrapped_message = fill(&self.message, self.width);
67        for line in wrapped_message.lines() {
68            execute!(stdout, PrintStyledContent("│".with(self.border_color)))?;
69            for _ in 0..self.padding {
70                execute!(stdout, Print(" "))?;
71            }
72            execute!(stdout, PrintStyledContent(line.with(self.message_color)))?;
73            for _ in 0..self.padding + (self.width - line.len()) {
74                execute!(stdout, Print(" "))?;
75            }
76            execute!(stdout, PrintStyledContent("│\n".with(self.border_color)))?;
77        }
78
79        execute!(stdout, PrintStyledContent("└".with(self.border_color)))?;
80        for _ in 0..total_width - 2 {
81            execute!(stdout, PrintStyledContent("─".with(self.border_color)))?;
82        }
83        execute!(stdout, PrintStyledContent("┘\n".with(self.border_color)))?;
84
85        stdout.flush()?;
86
87        Ok(())
88    }
89}