ratatui_ruby 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. checksums.yaml +4 -4
  2. data/.builds/ruby-3.2.yml +1 -1
  3. data/.builds/ruby-3.3.yml +1 -1
  4. data/.builds/ruby-3.4.yml +1 -1
  5. data/.builds/ruby-4.0.0.yml +1 -1
  6. data/AGENTS.md +4 -4
  7. data/CHANGELOG.md +35 -0
  8. data/README.md +26 -1
  9. data/doc/application_architecture.md +16 -16
  10. data/doc/application_testing.md +1 -1
  11. data/doc/contributors/architectural_overhaul/chat_conversations.md +4952 -0
  12. data/doc/contributors/architectural_overhaul/implementation_plan.md +60 -0
  13. data/doc/contributors/architectural_overhaul/task.md +37 -0
  14. data/doc/contributors/design/ruby_frontend.md +277 -81
  15. data/doc/contributors/design/rust_backend.md +349 -55
  16. data/doc/contributors/developing_examples.md +5 -5
  17. data/doc/contributors/index.md +7 -5
  18. data/doc/contributors/v1.0.0_blockers.md +1729 -0
  19. data/doc/index.md +11 -6
  20. data/doc/interactive_design.md +2 -2
  21. data/doc/quickstart.md +66 -97
  22. data/doc/v0.7.0_migration.md +236 -0
  23. data/doc/why.md +93 -0
  24. data/examples/app_all_events/README.md +6 -4
  25. data/examples/app_all_events/app.rb +1 -1
  26. data/examples/app_all_events/model/app_model.rb +1 -1
  27. data/examples/app_all_events/model/msg.rb +1 -1
  28. data/examples/app_all_events/update.rb +1 -1
  29. data/examples/app_all_events/view/app_view.rb +1 -1
  30. data/examples/app_all_events/view/controls_view.rb +1 -1
  31. data/examples/app_all_events/view/counts_view.rb +1 -1
  32. data/examples/app_all_events/view/live_view.rb +1 -1
  33. data/examples/app_all_events/view/log_view.rb +1 -1
  34. data/examples/app_color_picker/README.md +7 -5
  35. data/examples/app_color_picker/app.rb +1 -1
  36. data/examples/app_login_form/README.md +2 -0
  37. data/examples/app_stateful_interaction/README.md +2 -0
  38. data/examples/app_stateful_interaction/app.rb +1 -1
  39. data/examples/verify_quickstart_dsl/README.md +4 -3
  40. data/examples/verify_quickstart_dsl/app.rb +1 -1
  41. data/examples/verify_quickstart_layout/README.md +1 -1
  42. data/examples/verify_quickstart_lifecycle/README.md +3 -3
  43. data/examples/verify_quickstart_lifecycle/app.rb +2 -2
  44. data/examples/verify_readme_usage/README.md +1 -1
  45. data/examples/widget_barchart_demo/README.md +2 -1
  46. data/examples/widget_block_demo/README.md +2 -0
  47. data/examples/widget_box_demo/README.md +3 -3
  48. data/examples/widget_calendar_demo/README.md +3 -3
  49. data/examples/widget_calendar_demo/app.rb +5 -1
  50. data/examples/widget_canvas_demo/README.md +3 -3
  51. data/examples/widget_cell_demo/README.md +3 -3
  52. data/examples/widget_center_demo/README.md +3 -3
  53. data/examples/widget_chart_demo/README.md +3 -3
  54. data/examples/widget_gauge_demo/README.md +3 -3
  55. data/examples/widget_layout_split/README.md +3 -3
  56. data/examples/widget_line_gauge_demo/README.md +3 -3
  57. data/examples/widget_list_demo/README.md +3 -3
  58. data/examples/widget_map_demo/README.md +3 -3
  59. data/examples/widget_map_demo/app.rb +2 -2
  60. data/examples/widget_overlay_demo/README.md +36 -0
  61. data/examples/widget_popup_demo/README.md +3 -3
  62. data/examples/widget_ratatui_logo_demo/README.md +3 -3
  63. data/examples/widget_ratatui_logo_demo/app.rb +1 -1
  64. data/examples/widget_ratatui_mascot_demo/README.md +3 -3
  65. data/examples/widget_rect/README.md +3 -3
  66. data/examples/widget_render/README.md +3 -3
  67. data/examples/widget_render/app.rb +3 -3
  68. data/examples/widget_rich_text/README.md +3 -3
  69. data/examples/widget_scroll_text/README.md +3 -3
  70. data/examples/widget_scrollbar_demo/README.md +3 -3
  71. data/examples/widget_sparkline_demo/README.md +3 -3
  72. data/examples/widget_style_colors/README.md +3 -3
  73. data/examples/widget_table_demo/README.md +3 -3
  74. data/examples/widget_table_demo/app.rb +19 -4
  75. data/examples/widget_tabs_demo/README.md +3 -3
  76. data/examples/widget_text_width/README.md +3 -3
  77. data/examples/widget_text_width/app.rb +8 -1
  78. data/ext/ratatui_ruby/Cargo.lock +1 -1
  79. data/ext/ratatui_ruby/Cargo.toml +1 -1
  80. data/ext/ratatui_ruby/src/frame.rs +6 -5
  81. data/ext/ratatui_ruby/src/lib.rs +3 -2
  82. data/ext/ratatui_ruby/src/rendering.rs +22 -21
  83. data/ext/ratatui_ruby/src/text.rs +12 -3
  84. data/ext/ratatui_ruby/src/widgets/canvas.rs +5 -5
  85. data/ext/ratatui_ruby/src/widgets/table.rs +81 -36
  86. data/lib/ratatui_ruby/buffer/cell.rb +168 -0
  87. data/lib/ratatui_ruby/buffer.rb +15 -0
  88. data/lib/ratatui_ruby/frame.rb +8 -8
  89. data/lib/ratatui_ruby/layout/constraint.rb +95 -0
  90. data/lib/ratatui_ruby/layout/layout.rb +106 -0
  91. data/lib/ratatui_ruby/layout/rect.rb +118 -0
  92. data/lib/ratatui_ruby/layout.rb +19 -0
  93. data/lib/ratatui_ruby/list_state.rb +2 -2
  94. data/lib/ratatui_ruby/schema/layout.rb +1 -1
  95. data/lib/ratatui_ruby/schema/row.rb +66 -0
  96. data/lib/ratatui_ruby/schema/table.rb +10 -10
  97. data/lib/ratatui_ruby/schema/text.rb +27 -2
  98. data/lib/ratatui_ruby/style/style.rb +81 -0
  99. data/lib/ratatui_ruby/style.rb +15 -0
  100. data/lib/ratatui_ruby/table_state.rb +1 -1
  101. data/lib/ratatui_ruby/test_helper/snapshot.rb +24 -0
  102. data/lib/ratatui_ruby/test_helper/style_assertions.rb +1 -1
  103. data/lib/ratatui_ruby/tui/buffer_factories.rb +20 -0
  104. data/lib/ratatui_ruby/tui/canvas_factories.rb +44 -0
  105. data/lib/ratatui_ruby/tui/core.rb +38 -0
  106. data/lib/ratatui_ruby/tui/layout_factories.rb +74 -0
  107. data/lib/ratatui_ruby/tui/state_factories.rb +33 -0
  108. data/lib/ratatui_ruby/tui/style_factories.rb +20 -0
  109. data/lib/ratatui_ruby/tui/text_factories.rb +44 -0
  110. data/lib/ratatui_ruby/tui/widget_factories.rb +195 -0
  111. data/lib/ratatui_ruby/tui.rb +75 -0
  112. data/lib/ratatui_ruby/version.rb +1 -1
  113. data/lib/ratatui_ruby/widgets/bar_chart/bar.rb +47 -0
  114. data/lib/ratatui_ruby/widgets/bar_chart/bar_group.rb +25 -0
  115. data/lib/ratatui_ruby/widgets/bar_chart.rb +239 -0
  116. data/lib/ratatui_ruby/widgets/block.rb +192 -0
  117. data/lib/ratatui_ruby/widgets/calendar.rb +84 -0
  118. data/lib/ratatui_ruby/widgets/canvas.rb +231 -0
  119. data/lib/ratatui_ruby/widgets/cell.rb +47 -0
  120. data/lib/ratatui_ruby/widgets/center.rb +59 -0
  121. data/lib/ratatui_ruby/widgets/chart.rb +185 -0
  122. data/lib/ratatui_ruby/widgets/clear.rb +54 -0
  123. data/lib/ratatui_ruby/widgets/cursor.rb +42 -0
  124. data/lib/ratatui_ruby/widgets/gauge.rb +72 -0
  125. data/lib/ratatui_ruby/widgets/line_gauge.rb +80 -0
  126. data/lib/ratatui_ruby/widgets/list.rb +127 -0
  127. data/lib/ratatui_ruby/widgets/list_item.rb +43 -0
  128. data/lib/ratatui_ruby/widgets/overlay.rb +43 -0
  129. data/lib/ratatui_ruby/widgets/paragraph.rb +99 -0
  130. data/lib/ratatui_ruby/widgets/ratatui_logo.rb +31 -0
  131. data/lib/ratatui_ruby/widgets/ratatui_mascot.rb +36 -0
  132. data/lib/ratatui_ruby/widgets/row.rb +68 -0
  133. data/lib/ratatui_ruby/widgets/scrollbar.rb +143 -0
  134. data/lib/ratatui_ruby/widgets/shape/label.rb +68 -0
  135. data/lib/ratatui_ruby/widgets/sparkline.rb +134 -0
  136. data/lib/ratatui_ruby/widgets/table.rb +141 -0
  137. data/lib/ratatui_ruby/widgets/tabs.rb +85 -0
  138. data/lib/ratatui_ruby/widgets.rb +40 -0
  139. data/lib/ratatui_ruby.rb +23 -39
  140. data/sig/examples/app_all_events/view.rbs +1 -1
  141. data/sig/examples/app_all_events/view_state.rbs +1 -1
  142. data/sig/ratatui_ruby/schema/row.rbs +22 -0
  143. data/sig/ratatui_ruby/schema/table.rbs +1 -1
  144. data/sig/ratatui_ruby/schema/text.rbs +1 -0
  145. data/sig/ratatui_ruby/session.rbs +29 -49
  146. data/sig/ratatui_ruby/tui/buffer_factories.rbs +10 -0
  147. data/sig/ratatui_ruby/tui/canvas_factories.rbs +14 -0
  148. data/sig/ratatui_ruby/tui/core.rbs +14 -0
  149. data/sig/ratatui_ruby/tui/layout_factories.rbs +19 -0
  150. data/sig/ratatui_ruby/tui/state_factories.rbs +12 -0
  151. data/sig/ratatui_ruby/tui/style_factories.rbs +10 -0
  152. data/sig/ratatui_ruby/tui/text_factories.rbs +14 -0
  153. data/sig/ratatui_ruby/tui/widget_factories.rbs +39 -0
  154. data/sig/ratatui_ruby/tui.rbs +19 -0
  155. data/tasks/autodoc.rake +1 -35
  156. data/tasks/sourcehut.rake +4 -1
  157. metadata +62 -15
  158. data/doc/contributors/dwim_dx.md +0 -366
  159. data/doc/contributors/examples_audit/p1_high.md +0 -21
  160. data/doc/contributors/examples_audit/p2_moderate.md +0 -81
  161. data/doc/contributors/examples_audit.md +0 -41
  162. data/doc/images/app_analytics.png +0 -0
  163. data/doc/images/app_custom_widget.png +0 -0
  164. data/doc/images/app_mouse_events.png +0 -0
  165. data/doc/images/widget_table_flex.png +0 -0
  166. data/lib/ratatui_ruby/session/autodoc.rb +0 -482
  167. data/lib/ratatui_ruby/session.rb +0 -178
  168. data/tasks/autodoc/inventory.rb +0 -63
  169. data/tasks/autodoc/notice.rb +0 -26
  170. data/tasks/autodoc/rbs.rb +0 -38
  171. data/tasks/autodoc/rdoc.rb +0 -45
@@ -20,21 +20,21 @@ module RatatuiRuby
20
20
  # Run the interactive demo from the terminal:
21
21
  #
22
22
  # ruby examples/widget_table_flex/app.rb
23
- class Table < Data.define(:header, :rows, :widths, :highlight_style, :highlight_symbol, :highlight_spacing, :column_highlight_style, :cell_highlight_style, :selected_row, :selected_column, :offset, :block, :footer, :flex, :style, :column_spacing)
23
+ class Table < Data.define(:header, :rows, :widths, :row_highlight_style, :highlight_symbol, :highlight_spacing, :column_highlight_style, :cell_highlight_style, :selected_row, :selected_column, :offset, :block, :footer, :flex, :style, :column_spacing)
24
24
  ##
25
25
  # :attr_reader: header
26
- # Header row content (Array of Strings).
26
+ # Header row content (Array of Strings, Text::Spans, Text::Lines, or Paragraphs).
27
27
 
28
28
  ##
29
29
  # :attr_reader: rows
30
- # Data rows (Array of Arrays of Strings).
30
+ # Data rows (Array of Arrays). Each cell can be String, Text::Span, Text::Line, Paragraph, or Cell.
31
31
 
32
32
  ##
33
33
  # :attr_reader: widths
34
34
  # Column width constraints (Array of Constraint).
35
35
 
36
36
  ##
37
- # :attr_reader: highlight_style
37
+ # :attr_reader: row_highlight_style
38
38
  # Style for the selected row.
39
39
 
40
40
  ##
@@ -83,7 +83,7 @@ module RatatuiRuby
83
83
 
84
84
  ##
85
85
  # :attr_reader: footer
86
- # Footer row content (Array of Strings).
86
+ # Footer row content (Array of Strings, Text::Spans, Text::Lines, or Paragraphs).
87
87
 
88
88
  ##
89
89
  # :attr_reader: flex
@@ -99,10 +99,10 @@ module RatatuiRuby
99
99
 
100
100
  # Creates a new Table.
101
101
  #
102
- # [header] Array of strings/paragraphs.
103
- # [rows] 2D Array of strings/paragraphs.
102
+ # [header] Array of strings, Text::Spans, Text::Lines, or paragraphs.
103
+ # [rows] 2D Array where each cell is String, Text::Span, Text::Line, Paragraph, or Cell.
104
104
  # [widths] Array of Constraints.
105
- # [highlight_style] Style object.
105
+ # [row_highlight_style] Style object.
106
106
  # [highlight_symbol] String.
107
107
  # [highlight_spacing] Symbol (optional, default: <tt>:when_selected</tt>).
108
108
  # [column_highlight_style] Style object.
@@ -115,12 +115,12 @@ module RatatuiRuby
115
115
  # [flex] Symbol (optional, default: <tt>:legacy</tt>).
116
116
  # [style] Style object or Hash (optional).
117
117
  # [column_spacing] Integer (optional, default: 1).
118
- def initialize(header: nil, rows: [], widths: [], highlight_style: nil, highlight_symbol: "> ", highlight_spacing: :when_selected, column_highlight_style: nil, cell_highlight_style: nil, selected_row: nil, selected_column: nil, offset: nil, block: nil, footer: nil, flex: :legacy, style: nil, column_spacing: 1)
118
+ def initialize(header: nil, rows: [], widths: [], row_highlight_style: nil, highlight_symbol: "> ", highlight_spacing: :when_selected, column_highlight_style: nil, cell_highlight_style: nil, selected_row: nil, selected_column: nil, offset: nil, block: nil, footer: nil, flex: :legacy, style: nil, column_spacing: 1)
119
119
  super(
120
120
  header:,
121
121
  rows:,
122
122
  widths:,
123
- highlight_style:,
123
+ row_highlight_style:,
124
124
  highlight_symbol:,
125
125
  highlight_spacing:,
126
126
  column_highlight_style:,
@@ -94,7 +94,7 @@ module RatatuiRuby
94
94
  # Text::Span.styled("kerrick", Style.new(fg: :blue))
95
95
  # ]
96
96
  # )
97
- class Line < Data.define(:spans, :alignment)
97
+ class Line < Data.define(:spans, :alignment, :style)
98
98
  ##
99
99
  # :attr_reader: spans
100
100
  # Array of Span objects.
@@ -105,11 +105,18 @@ module RatatuiRuby
105
105
  #
106
106
  # <tt>:left</tt>, <tt>:center</tt>, or <tt>:right</tt>.
107
107
 
108
+ ##
109
+ # :attr_reader: style
110
+ # Line-level style applied to all spans.
111
+ #
112
+ # A Style object that sets colors/modifiers for the entire line.
113
+
108
114
  # Creates a new Line.
109
115
  #
110
116
  # [spans] Array of Span objects (or Strings).
111
117
  # [alignment] Symbol (optional).
112
- def initialize(spans: [], alignment: nil)
118
+ # [style] Style object (optional).
119
+ def initialize(spans: [], alignment: nil, style: nil)
113
120
  super
114
121
  end
115
122
 
@@ -119,6 +126,24 @@ module RatatuiRuby
119
126
  def self.from_string(content, alignment: nil)
120
127
  new(spans: [Span.new(content:, style: nil)], alignment:)
121
128
  end
129
+
130
+ # Calculates the display width of this line in terminal cells.
131
+ #
132
+ # Sums the widths of all span contents using the same unicode-aware
133
+ # algorithm as Text.width. Useful for layout calculations.
134
+ #
135
+ # === Examples
136
+ #
137
+ # line = Text::Line.new(spans: [
138
+ # Text::Span.new(content: "Hello "),
139
+ # Text::Span.new(content: "世界")
140
+ # ])
141
+ # line.width # => 10 (6 ASCII + 4 CJK)
142
+ #
143
+ # Returns: Integer (number of terminal cells)
144
+ def width
145
+ RatatuiRuby::Text.width(spans.map { |s| s.content.to_s }.join)
146
+ end
122
147
  end
123
148
 
124
149
  ##
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ module RatatuiRuby
7
+ module Style
8
+ # Defines colors and text modifiers.
9
+ #
10
+ # The terminal is traditionally monochrome, but efficient interfaces use color to convey meaning.
11
+ # Red for errors. Green for success. Bold for headers.
12
+ #
13
+ # This value object encapsulates those choices. It applies foreground and background colors. It adds effects like italics or blinking.
14
+ #
15
+ # Use it to theme your application or highlight critical data.
16
+ #
17
+ # === Examples
18
+ #
19
+ # # Standard colors
20
+ # Style::Style.new(fg: :red, bg: :white, modifiers: [:bold])
21
+ #
22
+ # # Hex colors
23
+ # Style::Style.new(fg: "#ff00ff")
24
+ #
25
+ # === Supported Colors
26
+ #
27
+ # ==== Integer
28
+ # Represents an indexed color from the Xterm 256-color palette (0-255).
29
+ # * <tt>0</tt>–<tt>15</tt>: Standard and bright ANSI colors.
30
+ # * <tt>16</tt>–<tt>231</tt>: {6x6x6 Color Cube}[https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit].
31
+ # * <tt>232</tt>–<tt>255</tt>: Grayscale ramp.
32
+ #
33
+ # ==== Symbol
34
+ # Represents a named color from the standard ANSI palette. Supported values:
35
+ # * <tt>:black</tt>, <tt>:red</tt>, <tt>:green</tt>, <tt>:yellow</tt>,
36
+ # <tt>:blue</tt>, <tt>:magenta</tt>, <tt>:cyan</tt>, <tt>:gray</tt>
37
+ # * <tt>:dark_gray</tt>, <tt>:light_red</tt>, <tt>:light_green</tt>,
38
+ # <tt>:light_yellow</tt>, <tt>:light_blue</tt>, <tt>:light_magenta</tt>,
39
+ # <tt>:light_cyan</tt>, <tt>:white</tt>
40
+ #
41
+ # ==== String
42
+ # Represents a specific RGB color using a Hex code (<tt>"#RRGGBB"</tt>).
43
+ # Requires a terminal emulator with "True Color" (24-bit color) support.
44
+ class Style < Data.define(:fg, :bg, :modifiers)
45
+ ##
46
+ # :attr_reader: fg
47
+ # Foreground color.
48
+ #
49
+ # Symbol (<tt>:red</tt>), Hex String (<tt>"#ffffff"</tt>), or Integer (0-255).
50
+
51
+ ##
52
+ # :attr_reader: bg
53
+ # Background color.
54
+ #
55
+ # Symbol (<tt>:black</tt>), Hex String (<tt>"#000000"</tt>), or Integer (0-255).
56
+
57
+ ##
58
+ # :attr_reader: modifiers
59
+ # Text effects.
60
+ #
61
+ # Array of symbols: <tt>:bold</tt>, <tt>:dim</tt>, <tt>:italic</tt>, <tt>:underlined</tt>,
62
+ # <tt>:slow_blink</tt>, <tt>:rapid_blink</tt>, <tt>:reversed</tt>, <tt>:hidden</tt>, <tt>:crossed_out</tt>.
63
+
64
+ # Creates a new Style.
65
+ #
66
+ # [fg] Color (Symbol/String/Integer).
67
+ # [bg] Color (Symbol/String/Integer).
68
+ # [modifiers] Array of Symbols.
69
+ def initialize(fg: nil, bg: nil, modifiers: [])
70
+ super
71
+ end
72
+
73
+ # Returns an empty style.
74
+ #
75
+ # Use this as a baseline to prevent style inheritance issues or when no styling is required.
76
+ def self.default
77
+ new
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ module RatatuiRuby
7
+ # Styling primitives for colors and text effects.
8
+ #
9
+ # This module mirrors +ratatui::style+ and contains:
10
+ # - {Style} — Colors and modifiers
11
+ module Style
12
+ end
13
+ end
14
+
15
+ require_relative "style/style"
@@ -18,7 +18,7 @@ module RatatuiRuby
18
18
  # @table_state.select_column(0) # Select first column
19
19
  #
20
20
  # RatatuiRuby.draw do |frame|
21
- # table = RatatuiRuby::Table.new(rows: [...], widths: [...])
21
+ # table = RatatuiRuby::Widgets::Table.new(rows: [...], widths: [...])
22
22
  # frame.render_stateful_widget(table, frame.area, @table_state)
23
23
  # end
24
24
  #
@@ -252,6 +252,30 @@ module RatatuiRuby
252
252
  end
253
253
  end
254
254
 
255
+ ##
256
+ # Returns the current buffer content as an ANSI-encoded string.
257
+ #
258
+ # The rich snapshot assertion captures styled output. Sometimes you need the raw ANSI
259
+ # string for debugging, custom assertions, or programmatic inspection.
260
+ #
261
+ # This method renders the buffer with escape codes for colors and modifiers.
262
+ # You can `cat` the output to see exactly what the terminal would display.
263
+ #
264
+ # === Example
265
+ #
266
+ # with_test_terminal(80, 25) do
267
+ # RatatuiRuby.run do |tui|
268
+ # tui.draw tui.paragraph(text: "Hello", block: tui.block(title: "Test"))
269
+ # break
270
+ # end
271
+ # ansi_output = render_rich_buffer
272
+ # puts ansi_output # Shows styled output with escape codes
273
+ # end
274
+ #
275
+ def render_rich_buffer
276
+ _render_buffer_with_ansi
277
+ end
278
+
255
279
  private def _render_buffer_with_ansi
256
280
  RatatuiRuby.get_buffer_content # Ensure buffer is fresh if needed
257
281
 
@@ -86,7 +86,7 @@ module RatatuiRuby
86
86
  #
87
87
  # === Examples
88
88
  #
89
- # header = RatatuiRuby::Rect.new(x: 0, y: 0, width: 80, height: 1)
89
+ # header = RatatuiRuby::Layout::Rect.new(x: 0, y: 0, width: 80, height: 1)
90
90
  # assert_area_style(header, bg: :blue, modifiers: [:bold])
91
91
  #
92
92
  # assert_area_style({ x: 0, y: 0, w: 10, h: 1 }, fg: :red)
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ module RatatuiRuby
7
+ class TUI
8
+ # Buffer inspection factory methods for Session.
9
+ #
10
+ # Provides convenient access to Buffer::Cell for testing
11
+ # and buffer inspection purposes.
12
+ module BufferFactories
13
+ # Creates a Buffer::Cell (for testing).
14
+ # @return [Buffer::Cell]
15
+ def cell(...)
16
+ Buffer::Cell.new(...)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ module RatatuiRuby
7
+ class TUI
8
+ # Canvas shape factory methods for Session.
9
+ #
10
+ # Provides convenient access to Widgets::Shape::* classes
11
+ # for creating custom drawings on Canvas widgets.
12
+ module CanvasFactories
13
+ # Creates a map shape for Canvas.
14
+ # @return [Widgets::Shape::Map]
15
+ def shape_map(...)
16
+ Widgets::Shape::Map.new(...)
17
+ end
18
+
19
+ # Creates a line shape for Canvas.
20
+ # @return [Widgets::Shape::Line]
21
+ def shape_line(...)
22
+ Widgets::Shape::Line.new(...)
23
+ end
24
+
25
+ # Creates a point (single pixel) shape for Canvas.
26
+ # @return [Widgets::Shape::Point]
27
+ def shape_point(...)
28
+ Widgets::Shape::Point.new(...)
29
+ end
30
+
31
+ # Creates a circle shape for Canvas.
32
+ # @return [Widgets::Shape::Circle]
33
+ def shape_circle(...)
34
+ Widgets::Shape::Circle.new(...)
35
+ end
36
+
37
+ # Creates a rectangle shape for Canvas.
38
+ # @return [Widgets::Shape::Rectangle]
39
+ def shape_rectangle(...)
40
+ Widgets::Shape::Rectangle.new(...)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ module RatatuiRuby
7
+ class TUI
8
+ # Core terminal methods delegated to RatatuiRuby module.
9
+ #
10
+ # These are the fundamental operations for the render loop:
11
+ # drawing UI, polling events, and inspecting the buffer.
12
+ module Core
13
+ # Draws the given UI node tree to the terminal.
14
+ # @see RatatuiRuby.draw
15
+ def draw(tree = nil, &)
16
+ RatatuiRuby.draw(tree, &)
17
+ end
18
+
19
+ # Checks for user input.
20
+ # @see RatatuiRuby.poll_event
21
+ def poll_event(timeout: 0.016)
22
+ RatatuiRuby.poll_event(timeout:)
23
+ end
24
+
25
+ # Inspects the terminal buffer at specific coordinates.
26
+ # @see RatatuiRuby.get_cell_at
27
+ def get_cell_at(x, y)
28
+ RatatuiRuby.get_cell_at(x, y)
29
+ end
30
+
31
+ # Creates a Draw::CellCmd for placing a cell at coordinates.
32
+ # @return [Draw::CellCmd]
33
+ def draw_cell(x, y, cell)
34
+ Draw.cell(x, y, cell)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ module RatatuiRuby
7
+ class TUI
8
+ # Layout factory methods for Session.
9
+ #
10
+ # Provides convenient access to Layout::Rect, Layout::Constraint,
11
+ # and Layout::Layout without fully qualifying the class names.
12
+ module LayoutFactories
13
+ # Creates a Layout::Rect.
14
+ # @return [Layout::Rect]
15
+ def rect(...)
16
+ Layout::Rect.new(...)
17
+ end
18
+
19
+ # Creates a Layout::Constraint.
20
+ # @return [Layout::Constraint]
21
+ def constraint(...)
22
+ Layout::Constraint.new(...)
23
+ end
24
+
25
+ # Creates a Layout::Constraint.length.
26
+ # @return [Layout::Constraint]
27
+ def constraint_length(n)
28
+ Layout::Constraint.length(n)
29
+ end
30
+
31
+ # Creates a Layout::Constraint.percentage.
32
+ # @return [Layout::Constraint]
33
+ def constraint_percentage(n)
34
+ Layout::Constraint.percentage(n)
35
+ end
36
+
37
+ # Creates a Layout::Constraint.min.
38
+ # @return [Layout::Constraint]
39
+ def constraint_min(n)
40
+ Layout::Constraint.min(n)
41
+ end
42
+
43
+ # Creates a Layout::Constraint.max.
44
+ # @return [Layout::Constraint]
45
+ def constraint_max(n)
46
+ Layout::Constraint.max(n)
47
+ end
48
+
49
+ # Creates a Layout::Constraint.fill.
50
+ # @return [Layout::Constraint]
51
+ def constraint_fill(n = 1)
52
+ Layout::Constraint.fill(n)
53
+ end
54
+
55
+ # Creates a Layout::Constraint.ratio.
56
+ # @return [Layout::Constraint]
57
+ def constraint_ratio(numerator, denominator)
58
+ Layout::Constraint.ratio(numerator, denominator)
59
+ end
60
+
61
+ # Creates a Layout::Layout.
62
+ # @return [Layout::Layout]
63
+ def layout(...)
64
+ Layout::Layout.new(...)
65
+ end
66
+
67
+ # Splits an area using Layout::Layout.split.
68
+ # @return [Array<Layout::Rect>]
69
+ def layout_split(area, direction: :vertical, constraints:, flex: :legacy)
70
+ Layout::Layout.split(area, direction:, constraints:, flex:)
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ module RatatuiRuby
7
+ class TUI
8
+ # State object factory methods for Session.
9
+ #
10
+ # Provides convenient access to stateful widget state objects
11
+ # (ListState, TableState, ScrollbarState) without fully
12
+ # qualifying the class names.
13
+ module StateFactories
14
+ # Creates a ListState.
15
+ # @return [ListState]
16
+ def list_state(...)
17
+ ListState.new(...)
18
+ end
19
+
20
+ # Creates a TableState.
21
+ # @return [TableState]
22
+ def table_state(...)
23
+ TableState.new(...)
24
+ end
25
+
26
+ # Creates a ScrollbarState.
27
+ # @return [ScrollbarState]
28
+ def scrollbar_state(...)
29
+ ScrollbarState.new(...)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ module RatatuiRuby
7
+ class TUI
8
+ # Style factory methods for Session.
9
+ #
10
+ # Provides convenient access to Style::Style without fully
11
+ # qualifying the class name.
12
+ module StyleFactories
13
+ # Creates a Style::Style.
14
+ # @return [Style::Style]
15
+ def style(...)
16
+ Style::Style.new(...)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ module RatatuiRuby
7
+ class TUI
8
+ # Text factory methods for Session.
9
+ #
10
+ # Provides convenient access to Text::Span and Text::Line
11
+ # without fully qualifying the class names.
12
+ module TextFactories
13
+ # Creates a Text::Span.
14
+ # @return [Text::Span]
15
+ def text_span(...)
16
+ Text::Span.new(...)
17
+ end
18
+
19
+ # Creates a Text::Span (alias).
20
+ # @return [Text::Span]
21
+ def span(...)
22
+ Text::Span.new(...)
23
+ end
24
+
25
+ # Creates a Text::Line.
26
+ # @return [Text::Line]
27
+ def text_line(...)
28
+ Text::Line.new(...)
29
+ end
30
+
31
+ # Creates a Text::Line (alias).
32
+ # @return [Text::Line]
33
+ def line(...)
34
+ Text::Line.new(...)
35
+ end
36
+
37
+ # Calculates the display width of a string.
38
+ # @return [Integer]
39
+ def text_width(string)
40
+ Text.width(string)
41
+ end
42
+ end
43
+ end
44
+ end