use retroglyph_core::{Backend, Rect, Style, Terminal};
use super::{Panel, Widget};
use crate::layout::centered_rect;
#[derive(Clone, Copy, Debug)]
pub struct Modal<'a> {
width: u16,
height: u16,
title: Option<&'a str>,
border_style: Style,
fill_style: Style,
}
impl<'a> Modal<'a> {
#[must_use]
pub fn new(width: u16, height: u16) -> Self {
Self {
width,
height,
title: None,
border_style: Style::new(),
fill_style: Style::new(),
}
}
#[must_use]
pub const fn title(mut self, title: &'a str) -> Self {
self.title = Some(title);
self
}
#[must_use]
pub const fn border_style(mut self, style: Style) -> Self {
self.border_style = style;
self
}
#[must_use]
pub const fn fill_style(mut self, style: Style) -> Self {
self.fill_style = style;
self
}
pub fn render<B: Backend>(self, screen: Rect, term: &mut Terminal<B>) -> Rect {
let rect = centered_rect(screen, self.width, self.height);
let mut panel = Panel::new()
.border_style(self.border_style)
.fill_style(self.fill_style);
if let Some(title) = self.title {
panel = panel.title(title);
}
panel.render(rect, term);
Rect::new(
rect.left() + 1,
rect.top() + 1,
rect.width().saturating_sub(2),
rect.height().saturating_sub(2),
)
}
}
#[cfg(test)]
mod tests {
use retroglyph_core::Headless;
use super::*;
#[test]
fn centers_the_box_and_returns_the_inner_content_rect() {
let screen = Rect::new(0, 0, 20, 10);
let mut term = Terminal::new(Headless::new(20, 10));
let inner = Modal::new(10, 4).render(screen, &mut term);
assert_eq!(inner, Rect::new(6, 4, 8, 2));
assert_eq!(term.grid().get(5, 3).glyph(), '┌');
assert_eq!(term.grid().get(14, 3).glyph(), '┐');
}
#[test]
fn draws_only_the_box_leaving_the_rest_of_the_screen_untouched() {
let screen = Rect::new(0, 0, 20, 10);
let mut term = Terminal::new(Headless::new(20, 10));
Modal::new(10, 4).render(screen, &mut term);
assert_eq!(term.grid().get(0, 0).glyph(), ' ');
}
}