use ratatui::layout::Rect;
pub fn centered_rect(width: u16, height: u16, area: Rect) -> Rect {
let width = width.min(area.width);
let height = height.min(area.height);
Rect {
x: area.x + (area.width - width) / 2,
y: area.y + (area.height - height) / 2,
width,
height,
}
}
pub fn fit(wanted: u16, min: u16, max: u16) -> u16 {
wanted.max(min).min(max)
}
pub fn centered_fraction(
area: Rect,
numerator: u16,
denominator: u16,
min_width: u16,
min_height: u16,
) -> Rect {
let width =
fit(area.width * numerator / denominator, min_width, area.width);
let height = fit(
area.height * numerator / denominator,
min_height,
area.height,
);
centered_rect(width, height, area)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn centers_within_the_area() {
let area = Rect::new(0, 0, 100, 40);
let rect = centered_rect(40, 10, area);
assert_eq!(rect, Rect::new(30, 15, 40, 10));
}
#[test]
fn clamps_to_the_area_when_larger() {
let area = Rect::new(4, 6, 20, 8);
let rect = centered_rect(200, 200, area);
assert_eq!(rect, Rect::new(4, 6, 20, 8));
}
#[test]
fn fit_prefers_the_minimum_but_the_maximum_wins() {
assert_eq!(fit(10, 5, 20), 10); assert_eq!(fit(2, 5, 20), 5); assert_eq!(fit(30, 5, 20), 20); assert_eq!(fit(10, 28, 20), 20);
}
#[test]
fn centered_fraction_survives_an_area_below_its_minimum() {
let area = Rect::new(0, 0, 10, 3);
let rect = centered_fraction(area, 9, 10, 28, 5);
assert_eq!(rect, area);
}
}