Skip to main content

md_tui/boxes/
searchbox.rs

1use ratatui::{
2    buffer::Buffer,
3    layout::Rect,
4    widgets::{Block, Borders, Paragraph, Widget, Wrap},
5};
6
7#[derive(Debug, Clone)]
8pub struct SearchBox {
9    pub text: String,
10    pub cursor: usize,
11    height: u16,
12    width: u16,
13    x: u16,
14    y: u16,
15}
16
17impl SearchBox {
18    #[must_use]
19    pub fn new() -> Self {
20        Self {
21            text: String::new(),
22            cursor: 0,
23            height: 2,
24            width: 20,
25            x: 0,
26            y: 0,
27        }
28    }
29
30    pub fn insert(&mut self, c: char) {
31        self.text.push(c);
32        self.cursor += 1;
33    }
34
35    pub fn delete(&mut self) {
36        if self.cursor > 0 {
37            self.text.remove(self.cursor - 1);
38            self.cursor -= 1;
39        }
40    }
41
42    pub fn clear(&mut self) {
43        self.text.clear();
44        self.cursor = 0;
45    }
46
47    #[must_use]
48    pub fn dimensions(&self) -> (u16, u16) {
49        (self.height, self.width)
50    }
51
52    pub fn consume(&mut self) -> String {
53        let text = self.text.clone();
54        self.clear();
55        text
56    }
57
58    #[must_use]
59    pub fn content_str(&self) -> &str {
60        &self.text
61    }
62
63    #[must_use]
64    pub fn content(&self) -> Option<&str> {
65        if self.text.is_empty() {
66            None
67        } else {
68            Some(&self.text)
69        }
70    }
71
72    pub fn set_position(&mut self, x: u16, y: u16) {
73        self.x = x;
74        self.y = y;
75    }
76
77    pub fn set_width(&mut self, width: u16) {
78        self.width = width;
79    }
80
81    #[must_use]
82    pub fn x(&self) -> u16 {
83        self.x
84    }
85
86    #[must_use]
87    pub fn y(&self) -> u16 {
88        self.y
89    }
90}
91
92impl Default for SearchBox {
93    fn default() -> Self {
94        Self::new()
95    }
96}
97
98impl Widget for SearchBox {
99    fn render(self, area: Rect, buf: &mut Buffer) {
100        let paragraph = Paragraph::new(self.text)
101            .block(Block::default().borders(Borders::BOTTOM))
102            .wrap(Wrap { trim: true });
103        paragraph.render(area, buf);
104    }
105}