scrin 0.1.80

A terminal UI toolkit with panes, widgets, overlays, animations, and Aisling-powered effects/loaders.
Documentation
use crate::core::buffer::Buffer;
use crate::core::color::Color;
use crate::core::rect::Rect;
use crate::widgets::Widget;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Clear {
    pub bg: Option<Color>,
}

impl Clear {
    pub const fn new() -> Self {
        Self { bg: None }
    }

    pub const fn with_bg(bg: Color) -> Self {
        Self { bg: Some(bg) }
    }
}

impl Default for Clear {
    fn default() -> Self {
        Self::new()
    }
}

impl Widget for Clear {
    fn render(&self, buffer: &mut Buffer, area: Rect) {
        buffer.fill(area, ' ', Color::WHITE, self.bg);
    }
}

pub fn centered_rect(percent_x: u16, percent_y: u16, area: Rect) -> Rect {
    let width = area.width.saturating_mul(percent_x.min(100)) / 100;
    let height = area.height.saturating_mul(percent_y.min(100)) / 100;
    let x = area.x + area.width.saturating_sub(width) / 2;
    let y = area.y + area.height.saturating_sub(height) / 2;
    Rect::new(x, y, width, height)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn clear_overwrites_area() {
        let mut buffer = Buffer::new(6, 3);
        buffer.fill(Rect::new(0, 0, 6, 3), 'X', Color::rgb(1, 2, 3), None);
        Clear::with_bg(Color::rgb(4, 5, 6)).render(&mut buffer, Rect::new(1, 1, 3, 1));
        assert_eq!(buffer.get(1, 1).unwrap().ch, ' ');
        assert_eq!(buffer.get(1, 1).unwrap().bg, Some(Color::rgb(4, 5, 6)));
        assert_eq!(buffer.get(0, 1).unwrap().ch, 'X');
    }

    #[test]
    fn centered_rect_uses_percentages() {
        assert_eq!(
            centered_rect(50, 50, Rect::new(0, 0, 100, 40)),
            Rect::new(25, 10, 50, 20)
        );
    }
}