Class: TuiTui::Rect
- Inherits:
-
Data
- Object
- Data
- TuiTui::Rect
- Defined in:
- lib/tui_tui/rect.rb
Overview
A 1-origin screen rectangle with pure layout helpers.
Instance Attribute Summary collapse
-
#col ⇒ Object
readonly
Returns the value of attribute col.
-
#cols ⇒ Object
readonly
Returns the value of attribute cols.
-
#row ⇒ Object
readonly
Returns the value of attribute row.
-
#rows ⇒ Object
readonly
Returns the value of attribute rows.
Class Method Summary collapse
- .centered(within, cols:, rows:) ⇒ Object
-
.of(size) ⇒ Object
The Rect covering a whole screen: row/col 1 over anything with Size-compatible
rows/cols(a Size or a RenderContext).
Instance Method Summary collapse
-
#hit?(mouse) ⇒ Boolean
Whether a MouseEvent's cell falls inside this rectangle.
-
#include?(r, c) ⇒ Boolean
Whether a 1-origin cell (row, col) falls inside this rectangle.
- #shift_right(by) ⇒ Object
-
#split_cols(*constraints) ⇒ Object
Same as split_rows, but left to right over the columns.
-
#split_gutter(width = 1) ⇒ Object
Carve
widthcolumns off the right edge for a scrollbar gutter. - #split_h(top_rows) ⇒ Object
-
#split_ratio(ratio, min: 0, gutter: 0) ⇒ Object
Split into [left, right] by
ratioof the width. -
#split_rows(*constraints) ⇒ Object
Split into stacked Rects, top to bottom, one per constraint: an Integer is a fixed number of rows, a Float a fraction of the whole (
(rows * f).round), and :rest shares whatever the fixed and fractional segments leave over (several :rest split it evenly, leading ones taking the indivisible remainder). - #split_v(left_cols) ⇒ Object
Instance Attribute Details
#col ⇒ Object (readonly)
Returns the value of attribute col
5 6 7 |
# File 'lib/tui_tui/rect.rb', line 5 def col @col end |
#cols ⇒ Object (readonly)
Returns the value of attribute cols
5 6 7 |
# File 'lib/tui_tui/rect.rb', line 5 def cols @cols end |
#row ⇒ Object (readonly)
Returns the value of attribute row
5 6 7 |
# File 'lib/tui_tui/rect.rb', line 5 def row @row end |
#rows ⇒ Object (readonly)
Returns the value of attribute rows
5 6 7 |
# File 'lib/tui_tui/rect.rb', line 5 def rows @rows end |
Class Method Details
.centered(within, cols:, rows:) ⇒ Object
6 7 8 9 10 11 12 13 |
# File 'lib/tui_tui/rect.rb', line 6 def self.centered(within, cols:, rows:) new( row: [((within.rows - rows) / 2) + 1, 1].max, col: [((within.cols - cols) / 2) + 1, 1].max, rows: rows, cols: cols ) end |
.of(size) ⇒ Object
The Rect covering a whole screen: row/col 1 over anything with
Size-compatible rows / cols (a Size or a RenderContext).
17 18 19 |
# File 'lib/tui_tui/rect.rb', line 17 def self.of(size) new(row: 1, col: 1, rows: size.rows, cols: size.cols) end |
Instance Method Details
#hit?(mouse) ⇒ Boolean
Whether a MouseEvent's cell falls inside this rectangle.
81 |
# File 'lib/tui_tui/rect.rb', line 81 def hit?(mouse) = include?(mouse.row, mouse.col) |
#include?(r, c) ⇒ Boolean
Whether a 1-origin cell (row, col) falls inside this rectangle.
76 77 78 |
# File 'lib/tui_tui/rect.rb', line 76 def include?(r, c) r.between?(row, row + rows - 1) && c.between?(col, col + cols - 1) end |
#shift_right(by) ⇒ Object
71 72 73 |
# File 'lib/tui_tui/rect.rb', line 71 def shift_right(by) Rect.new(row: row, col: col + by, rows: rows, cols: cols - by) end |
#split_cols(*constraints) ⇒ Object
Same as split_rows, but left to right over the columns.
62 63 64 65 66 67 68 69 |
# File 'lib/tui_tui/rect.rb', line 62 def split_cols(*constraints) left = col resolve_segments(constraints, cols).map do |size| segment = Rect.new(row: row, col: left, rows: rows, cols: size) left += size segment end end |
#split_gutter(width = 1) ⇒ Object
Carve width columns off the right edge for a scrollbar gutter. Returns
[body, gutter]; gutter is nil when the rect is too narrow to spare them.
85 86 87 88 89 |
# File 'lib/tui_tui/rect.rb', line 85 def split_gutter(width = 1) return [self, nil] if cols <= width [with(cols: cols - width), Rect.new(row: row, col: col + cols - width, rows: rows, cols: width)] end |
#split_h(top_rows) ⇒ Object
21 22 23 24 25 |
# File 'lib/tui_tui/rect.rb', line 21 def split_h(top_rows) top = Rect.new(row: row, col: col, rows: top_rows, cols: cols) bottom = Rect.new(row: row + top_rows, col: col, rows: rows - top_rows, cols: cols) [top, bottom] end |
#split_ratio(ratio, min: 0, gutter: 0) ⇒ Object
Split into [left, right] by ratio of the width
34 35 36 37 38 39 40 |
# File 'lib/tui_tui/rect.rb', line 34 def split_ratio(ratio, min: 0, gutter: 0) lo = min hi = cols - min - gutter left_cols = hi < lo ? cols / 2 : (cols * ratio).round.clamp(lo, hi) left, right = split_v(left_cols) [left, right.shift_right(gutter)] end |
#split_rows(*constraints) ⇒ Object
Split into stacked Rects, top to bottom, one per constraint:
an Integer is a fixed number of rows, a Float a fraction of the whole
((rows * f).round), and :rest shares whatever the fixed and fractional
segments leave over (several :rest split it evenly, leading ones taking
the indivisible remainder). Sizes resolve front to back, each clamped to
what is still left, so an undersized rect squashes trailing segments to
0 rather than raising — the same live-and-let-live rule as split_ratio.
Without a :rest, leftover space stays unassigned (no implicit stretch).
Every constraint yields a Rect (possibly 0-sized), so destructuring is
stable: header, body, status = rect.split_rows(2, :rest, 2).
52 53 54 55 56 57 58 59 |
# File 'lib/tui_tui/rect.rb', line 52 def split_rows(*constraints) top = row resolve_segments(constraints, rows).map do |size| segment = Rect.new(row: top, col: col, rows: size, cols: cols) top += size segment end end |