1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//!
//! Clears an area with a Style and a fill char.
//!
//! There is Buffer::set_style() to fill an area with a style.
//! What is missing is the ability to overwrite the text-content too.
//!
use ratatui::buffer::Buffer;
use ratatui::layout::Rect;
use ratatui::style::Style;
use ratatui::widgets::{Widget, WidgetRef};

/// Fill the area with a grapheme and a style.
/// Useful when overwriting an already rendered buffer
/// for overlays or windows.
#[derive(Debug)]
pub struct Fill<'a> {
    c: &'a str,
    style: Style,
}

impl<'a> Default for Fill<'a> {
    fn default() -> Self {
        Self {
            c: " ",
            style: Default::default(),
        }
    }
}

impl<'a> Fill<'a> {
    pub fn new() -> Self {
        Self::default()
    }

    /// Sets the fill char as one graphem.
    pub fn fill_char(mut self, c: &'a str) -> Self {
        self.c = c;
        self
    }

    /// Set the fill style.
    pub fn style(mut self, style: Style) -> Self {
        self.style = style;
        self
    }
}

impl<'a> WidgetRef for Fill<'a> {
    fn render_ref(&self, area: Rect, buf: &mut Buffer) {
        render_ref(self, area, buf);
    }
}

impl<'a> Widget for Fill<'a> {
    fn render(self, area: Rect, buf: &mut Buffer)
    where
        Self: Sized,
    {
        render_ref(&self, area, buf);
    }
}

fn render_ref(widget: &Fill<'_>, area: Rect, buf: &mut Buffer) {
    let area = buf.area.intersection(area);
    for y in area.top()..area.bottom() {
        for x in area.left()..area.right() {
            let cell = buf.get_mut(x, y);
            cell.set_symbol(widget.c);
            cell.set_style(widget.style);
        }
    }
}