Module: Marvi::Renderer::Curses::TabBar
- Defined in:
- lib/marvi/renderer/curses/tab_bar.rb
Overview
Pure layout computation for the tab bar so it can be tested without a terminal. Tabs are packed greedily left to right and wrap to a new row when the screen width is exceeded, producing a multi-row bar.
Defined Under Namespace
Classes: Item
Class Method Summary collapse
- .item_at(items, y, x) ⇒ Object
-
.item_for_click(items, y, x) ⇒ Object
Resolve a click including the margin row directly below the bar, which is attributed to the tab above it — a taller click target.
- .layout(labels, screen_width) ⇒ Object
- .rows(items) ⇒ Object
- .truncate_to_width(text, max_width) ⇒ Object
Class Method Details
.item_at(items, y, x) ⇒ Object
41 42 43 |
# File 'lib/marvi/renderer/curses/tab_bar.rb', line 41 def item_at(items, y, x) items.find { |item| item.contains?(y, x) } end |
.item_for_click(items, y, x) ⇒ Object
Resolve a click including the margin row directly below the bar, which is attributed to the tab above it — a taller click target.
47 48 49 |
# File 'lib/marvi/renderer/curses/tab_bar.rb', line 47 def item_for_click(items, y, x) item_at(items, y, x) || ((y == rows(items)) ? item_at(items, y - 1, x) : nil) end |
.layout(labels, screen_width) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/marvi/renderer/curses/tab_bar.rb', line 20 def layout(labels, screen_width) screen_width = [screen_width, 1].max row = 0 col = 0 labels.each_with_index.map do |label, index| text = truncate_to_width(" #{label} ", screen_width) width = Unicode::DisplayWidth.of(text) if col.positive? && col + width > screen_width row += 1 col = 0 end item = Item.new(index: index, text: text, row: row, col: col, width: width) col += width item end end |
.rows(items) ⇒ Object
37 38 39 |
# File 'lib/marvi/renderer/curses/tab_bar.rb', line 37 def rows(items) items.empty? ? 0 : items.last.row + 1 end |
.truncate_to_width(text, max_width) ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/marvi/renderer/curses/tab_bar.rb', line 51 def truncate_to_width(text, max_width) return text if Unicode::DisplayWidth.of(text) <= max_width result = +"" width = 0 text.each_char do |ch| ch_width = Unicode::DisplayWidth.of(ch) break if width + ch_width > max_width result << ch width += ch_width end result end |