Skip to main content

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}