rat_widget/
hover.rs

1use ratatui::buffer::Buffer;
2use ratatui::layout::{Position, Rect};
3use ratatui::widgets::StatefulWidget;
4
5/// Render a hover.
6///
7/// The state contains a buffer which can be used to render the hover
8/// wherever needed.
9///
10/// At the very end of rendering the Hover widget itself is rendered
11/// and uses the stored buffer.
12///
13/// **unstable**
14#[derive(Debug, Default)]
15pub struct Hover {}
16
17#[derive(Debug, Default)]
18pub struct HoverState {
19    pub hover_buf: Option<Buffer>,
20}
21
22impl Hover {
23    pub fn new() -> Self {
24        Self::default()
25    }
26}
27
28impl StatefulWidget for Hover {
29    type State = HoverState;
30
31    fn render(self, _area: Rect, buf: &mut Buffer, state: &mut Self::State) {
32        if let Some(hover_buf) = state.hover_buf.take() {
33            let buf_area = hover_buf.area;
34            for y in 0..buf_area.height {
35                for x in 0..buf_area.width {
36                    let pos = Position::new(buf_area.x + x, buf_area.y + y);
37                    let src_cell = hover_buf.cell(pos).expect("src-cell");
38                    let tgt_cell = buf.cell_mut(pos).expect("tgt_cell");
39                    *tgt_cell = src_cell.clone();
40                }
41            }
42        }
43    }
44}
45
46impl HoverState {
47    pub fn new() -> Self {
48        Self { hover_buf: None }
49    }
50
51    pub fn buffer_mut(&mut self, area: Rect) -> &mut Buffer {
52        self.hover_buf = match self.hover_buf.take() {
53            None => Some(Buffer::empty(area)),
54            Some(mut buf) => {
55                buf.resize(area);
56                Some(buf)
57            }
58        };
59        self.hover_buf.as_mut().expect("buffer")
60    }
61}