feat: add Rect::outer() (#1929)

Fixes: https://github.com/ratatui/ratatui/issues/211
This commit is contained in:
Josh McKinney 2025-06-25 21:56:15 -07:00 committed by GitHub
parent 9f9ec332b0
commit 0c3872f1c5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -155,6 +155,34 @@ impl Rect {
}
}
/// Returns a new `Rect` outside the current one, with the given margin applied on each side.
///
/// If the margin causes the `Rect`'s bounds to outsdie the range of a `u16`, the `Rect` will
/// be truncated to keep the bounds within `u16`. This will cause the size of the `Rect` to
/// change.
///
/// The generated `Rect` may not fit inside the buffer or containing area, so it consider
/// constraining the resulting `Rect` with [`Rect::clamp`] before using it.
#[must_use = "method returns the modified value"]
pub const fn outer(self, margin: Margin) -> Self {
let x = self.x.saturating_sub(margin.horizontal);
let y = self.y.saturating_sub(margin.vertical);
let width = self
.right()
.saturating_add(margin.horizontal)
.saturating_sub(x);
let height = self
.bottom()
.saturating_add(margin.vertical)
.saturating_sub(y);
Self {
x,
y,
width,
height,
}
}
/// Moves the `Rect` without modifying its size.
///
/// Moves the `Rect` according to the given offset without modifying its [`width`](Rect::width)
@ -511,6 +539,27 @@ mod tests {
);
}
#[test]
fn outer() {
// enough space to grow on all sides
assert_eq!(
Rect::new(100, 200, 10, 20).outer(Margin::new(20, 30)),
Rect::new(80, 170, 50, 80)
);
// left / top saturation should truncate the size (10 less on left / top)
assert_eq!(
Rect::new(10, 20, 10, 20).outer(Margin::new(20, 30)),
Rect::new(0, 0, 40, 70),
);
// right / bottom saturation should truncate the size (10 less on bottom / right)
assert_eq!(
Rect::new(u16::MAX - 20, u16::MAX - 40, 10, 20).outer(Margin::new(20, 30)),
Rect::new(u16::MAX - 40, u16::MAX - 70, 40, 70),
);
}
#[test]
fn offset() {
assert_eq!(