slt/rect.rs
1//! Axis-aligned rectangle type used throughout SLT for layout regions,
2//! clipping bounds, and hit-test areas.
3
4/// An axis-aligned rectangle with `u32` coordinates.
5///
6/// Uses `u32` rather than `u16` to avoid overflow bugs that affect other TUI
7/// libraries on large terminals. All coordinates are in terminal columns and
8/// rows, with `(0, 0)` at the top-left.
9///
10/// Note: [`Rect::right`] and [`Rect::bottom`] return **exclusive** bounds
11/// (one past the last column/row), consistent with Rust range conventions.
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
13pub struct Rect {
14 /// Left edge column, inclusive.
15 pub x: u32,
16 /// Top edge row, inclusive.
17 pub y: u32,
18 /// Width in terminal columns.
19 pub width: u32,
20 /// Height in terminal rows.
21 pub height: u32,
22}
23
24impl Rect {
25 /// Create a new rectangle from position and size.
26 #[inline]
27 pub const fn new(x: u32, y: u32, width: u32, height: u32) -> Self {
28 Self {
29 x,
30 y,
31 width,
32 height,
33 }
34 }
35
36 /// Total area in cells (`width * height`).
37 #[inline]
38 pub const fn area(&self) -> u32 {
39 self.width * self.height
40 }
41
42 /// Exclusive right edge (`x + width`).
43 ///
44 /// This is one column past the last column in the rectangle.
45 #[inline]
46 pub const fn right(&self) -> u32 {
47 self.x + self.width
48 }
49
50 /// Exclusive bottom edge (`y + height`).
51 ///
52 /// This is one row past the last row in the rectangle.
53 #[inline]
54 pub const fn bottom(&self) -> u32 {
55 self.y + self.height
56 }
57
58 /// Returns `true` if the rectangle has zero area (width or height is zero).
59 #[inline]
60 pub const fn is_empty(&self) -> bool {
61 self.width == 0 || self.height == 0
62 }
63}