ratatui_ruby 1.3.0 → 1.3.3

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 (301) hide show
  1. checksums.yaml +4 -4
  2. data/ext/ratatui_ruby/Cargo.lock +2 -1
  3. data/ext/ratatui_ruby/Cargo.toml +2 -1
  4. data/ext/ratatui_ruby/src/color.rs +1 -1
  5. data/ext/ratatui_ruby/src/errors.rs +1 -1
  6. data/ext/ratatui_ruby/src/events.rs +158 -19
  7. data/ext/ratatui_ruby/src/frame.rs +1 -1
  8. data/ext/ratatui_ruby/src/lib.rs +1 -1
  9. data/ext/ratatui_ruby/src/lib_header.rs +1 -1
  10. data/ext/ratatui_ruby/src/rendering.rs +1 -1
  11. data/ext/ratatui_ruby/src/string_width.rs +1 -1
  12. data/ext/ratatui_ruby/src/style.rs +1 -1
  13. data/ext/ratatui_ruby/src/terminal/capabilities.rs +1 -1
  14. data/ext/ratatui_ruby/src/terminal/init.rs +1 -1
  15. data/ext/ratatui_ruby/src/terminal/mod.rs +1 -1
  16. data/ext/ratatui_ruby/src/terminal/mutations.rs +1 -1
  17. data/ext/ratatui_ruby/src/terminal/queries.rs +1 -1
  18. data/ext/ratatui_ruby/src/terminal/query.rs +1 -1
  19. data/ext/ratatui_ruby/src/terminal/storage.rs +1 -1
  20. data/ext/ratatui_ruby/src/terminal/wrapper.rs +1 -1
  21. data/ext/ratatui_ruby/src/text.rs +1 -1
  22. data/ext/ratatui_ruby/src/widgets/barchart.rs +1 -1
  23. data/ext/ratatui_ruby/src/widgets/block.rs +1 -1
  24. data/ext/ratatui_ruby/src/widgets/calendar.rs +1 -1
  25. data/ext/ratatui_ruby/src/widgets/canvas.rs +1 -1
  26. data/ext/ratatui_ruby/src/widgets/center.rs +1 -1
  27. data/ext/ratatui_ruby/src/widgets/chart.rs +1 -1
  28. data/ext/ratatui_ruby/src/widgets/clear.rs +1 -1
  29. data/ext/ratatui_ruby/src/widgets/cursor.rs +1 -1
  30. data/ext/ratatui_ruby/src/widgets/gauge.rs +1 -1
  31. data/ext/ratatui_ruby/src/widgets/layout.rs +1 -1
  32. data/ext/ratatui_ruby/src/widgets/line_gauge.rs +1 -1
  33. data/ext/ratatui_ruby/src/widgets/list.rs +1 -1
  34. data/ext/ratatui_ruby/src/widgets/list_state.rs +1 -1
  35. data/ext/ratatui_ruby/src/widgets/mod.rs +1 -1
  36. data/ext/ratatui_ruby/src/widgets/overlay.rs +1 -1
  37. data/ext/ratatui_ruby/src/widgets/paragraph.rs +1 -1
  38. data/ext/ratatui_ruby/src/widgets/ratatui_logo.rs +1 -1
  39. data/ext/ratatui_ruby/src/widgets/ratatui_mascot.rs +1 -1
  40. data/ext/ratatui_ruby/src/widgets/scrollbar.rs +1 -1
  41. data/ext/ratatui_ruby/src/widgets/scrollbar_state.rs +1 -1
  42. data/ext/ratatui_ruby/src/widgets/sparkline.rs +1 -1
  43. data/ext/ratatui_ruby/src/widgets/table.rs +1 -1
  44. data/ext/ratatui_ruby/src/widgets/table_state.rs +1 -1
  45. data/ext/ratatui_ruby/src/widgets/tabs.rs +1 -1
  46. data/lib/ratatui_ruby/version.rb +1 -1
  47. metadata +1 -255
  48. data/.builds/ruby-3.2.yml +0 -54
  49. data/.builds/ruby-3.3.yml +0 -54
  50. data/.builds/ruby-3.4.yml +0 -54
  51. data/.builds/ruby-4.0.0.yml +0 -54
  52. data/.pre-commit-config.yaml +0 -16
  53. data/.rubocop.yml +0 -10
  54. data/AGENTS.md +0 -147
  55. data/CHANGELOG.md +0 -771
  56. data/README.md +0 -187
  57. data/README.rdoc +0 -302
  58. data/Rakefile +0 -11
  59. data/Steepfile +0 -50
  60. data/doc/concepts/application_architecture.md +0 -321
  61. data/doc/concepts/application_testing.md +0 -193
  62. data/doc/concepts/async.md +0 -190
  63. data/doc/concepts/custom_widgets.md +0 -247
  64. data/doc/concepts/debugging.md +0 -401
  65. data/doc/concepts/event_handling.md +0 -162
  66. data/doc/concepts/interactive_design.md +0 -146
  67. data/doc/contributors/auditing/parity.md +0 -239
  68. data/doc/contributors/design/ruby_frontend.md +0 -448
  69. data/doc/contributors/design/rust_backend.md +0 -434
  70. data/doc/contributors/design.md +0 -11
  71. data/doc/contributors/developing_examples.md +0 -400
  72. data/doc/contributors/documentation_style.md +0 -121
  73. data/doc/contributors/index.md +0 -21
  74. data/doc/contributors/releasing.md +0 -215
  75. data/doc/contributors/todo/align/api_completeness_audit-finished.md +0 -381
  76. data/doc/contributors/todo/align/api_completeness_audit-unfinished.md +0 -200
  77. data/doc/contributors/todo/align/term.md +0 -351
  78. data/doc/contributors/todo/align/terminal.md +0 -647
  79. data/doc/contributors/todo/future_work.md +0 -169
  80. data/doc/contributors/upstream_requests/paragraph_span_rects.md +0 -259
  81. data/doc/contributors/upstream_requests/tab_rects.md +0 -173
  82. data/doc/contributors/upstream_requests/title_rects.md +0 -132
  83. data/doc/custom.css +0 -22
  84. data/doc/getting_started/quickstart.md +0 -291
  85. data/doc/getting_started/why.md +0 -93
  86. data/doc/images/app_all_events.png +0 -0
  87. data/doc/images/app_cli_rich_moments.gif +0 -0
  88. data/doc/images/app_color_picker.png +0 -0
  89. data/doc/images/app_debugging_showcase.gif +0 -0
  90. data/doc/images/app_debugging_showcase.png +0 -0
  91. data/doc/images/app_external_editor.gif +0 -0
  92. data/doc/images/app_login_form.png +0 -0
  93. data/doc/images/app_stateful_interaction.png +0 -0
  94. data/doc/images/verify_quickstart_dsl.png +0 -0
  95. data/doc/images/verify_quickstart_layout.png +0 -0
  96. data/doc/images/verify_quickstart_lifecycle.png +0 -0
  97. data/doc/images/verify_readme_usage.png +0 -0
  98. data/doc/images/widget_barchart.png +0 -0
  99. data/doc/images/widget_block.png +0 -0
  100. data/doc/images/widget_box.png +0 -0
  101. data/doc/images/widget_calendar.png +0 -0
  102. data/doc/images/widget_canvas.png +0 -0
  103. data/doc/images/widget_cell.png +0 -0
  104. data/doc/images/widget_center.png +0 -0
  105. data/doc/images/widget_chart.png +0 -0
  106. data/doc/images/widget_gauge.png +0 -0
  107. data/doc/images/widget_layout_split.png +0 -0
  108. data/doc/images/widget_line_gauge.png +0 -0
  109. data/doc/images/widget_list.png +0 -0
  110. data/doc/images/widget_map.png +0 -0
  111. data/doc/images/widget_overlay.png +0 -0
  112. data/doc/images/widget_popup.png +0 -0
  113. data/doc/images/widget_ratatui_logo.png +0 -0
  114. data/doc/images/widget_ratatui_mascot.png +0 -0
  115. data/doc/images/widget_rect.png +0 -0
  116. data/doc/images/widget_render.png +0 -0
  117. data/doc/images/widget_rich_text.png +0 -0
  118. data/doc/images/widget_scroll_text.png +0 -0
  119. data/doc/images/widget_scrollbar.png +0 -0
  120. data/doc/images/widget_sparkline.png +0 -0
  121. data/doc/images/widget_style_colors.png +0 -0
  122. data/doc/images/widget_table.png +0 -0
  123. data/doc/images/widget_tabs.png +0 -0
  124. data/doc/images/widget_text_width.png +0 -0
  125. data/doc/index.md +0 -34
  126. data/doc/troubleshooting/async.md +0 -4
  127. data/doc/troubleshooting/terminal_limitations.md +0 -131
  128. data/doc/troubleshooting/tui_output.md +0 -197
  129. data/examples/app_all_events/README.md +0 -114
  130. data/examples/app_all_events/app.rb +0 -98
  131. data/examples/app_all_events/model/app_model.rb +0 -159
  132. data/examples/app_all_events/model/event_color_cycle.rb +0 -43
  133. data/examples/app_all_events/model/event_entry.rb +0 -94
  134. data/examples/app_all_events/model/msg.rb +0 -39
  135. data/examples/app_all_events/model/timestamp.rb +0 -56
  136. data/examples/app_all_events/update.rb +0 -75
  137. data/examples/app_all_events/view/app_view.rb +0 -80
  138. data/examples/app_all_events/view/controls_view.rb +0 -54
  139. data/examples/app_all_events/view/counts_view.rb +0 -61
  140. data/examples/app_all_events/view/live_view.rb +0 -72
  141. data/examples/app_all_events/view/log_view.rb +0 -57
  142. data/examples/app_all_events/view.rb +0 -9
  143. data/examples/app_cli_rich_moments/README.md +0 -81
  144. data/examples/app_cli_rich_moments/app.rb +0 -189
  145. data/examples/app_color_picker/README.md +0 -156
  146. data/examples/app_color_picker/app.rb +0 -76
  147. data/examples/app_color_picker/clipboard.rb +0 -86
  148. data/examples/app_color_picker/color.rb +0 -193
  149. data/examples/app_color_picker/controls.rb +0 -92
  150. data/examples/app_color_picker/copy_dialog.rb +0 -168
  151. data/examples/app_color_picker/export_pane.rb +0 -128
  152. data/examples/app_color_picker/harmony.rb +0 -58
  153. data/examples/app_color_picker/input.rb +0 -176
  154. data/examples/app_color_picker/main_container.rb +0 -180
  155. data/examples/app_color_picker/palette.rb +0 -111
  156. data/examples/app_debugging_showcase/README.md +0 -119
  157. data/examples/app_debugging_showcase/app.rb +0 -318
  158. data/examples/app_external_editor/README.md +0 -62
  159. data/examples/app_external_editor/app.rb +0 -344
  160. data/examples/app_login_form/README.md +0 -58
  161. data/examples/app_login_form/app.rb +0 -109
  162. data/examples/app_stateful_interaction/README.md +0 -35
  163. data/examples/app_stateful_interaction/app.rb +0 -328
  164. data/examples/timeout_demo.rb +0 -45
  165. data/examples/verify_quickstart_dsl/README.md +0 -55
  166. data/examples/verify_quickstart_dsl/app.rb +0 -49
  167. data/examples/verify_quickstart_layout/README.md +0 -77
  168. data/examples/verify_quickstart_layout/app.rb +0 -73
  169. data/examples/verify_quickstart_lifecycle/README.md +0 -68
  170. data/examples/verify_quickstart_lifecycle/app.rb +0 -62
  171. data/examples/verify_readme_usage/README.md +0 -49
  172. data/examples/verify_readme_usage/app.rb +0 -42
  173. data/examples/verify_website_managed/README.md +0 -48
  174. data/examples/verify_website_managed/app.rb +0 -36
  175. data/examples/verify_website_menu/README.md +0 -60
  176. data/examples/verify_website_menu/app.rb +0 -84
  177. data/examples/verify_website_spinner/README.md +0 -44
  178. data/examples/verify_website_spinner/app.rb +0 -34
  179. data/examples/widget_barchart/README.md +0 -58
  180. data/examples/widget_barchart/app.rb +0 -240
  181. data/examples/widget_block/README.md +0 -44
  182. data/examples/widget_block/app.rb +0 -258
  183. data/examples/widget_box/README.md +0 -54
  184. data/examples/widget_box/app.rb +0 -255
  185. data/examples/widget_calendar/README.md +0 -48
  186. data/examples/widget_calendar/app.rb +0 -115
  187. data/examples/widget_canvas/README.md +0 -31
  188. data/examples/widget_canvas/app.rb +0 -130
  189. data/examples/widget_cell/README.md +0 -45
  190. data/examples/widget_cell/app.rb +0 -112
  191. data/examples/widget_center/README.md +0 -33
  192. data/examples/widget_center/app.rb +0 -118
  193. data/examples/widget_chart/README.md +0 -50
  194. data/examples/widget_chart/app.rb +0 -220
  195. data/examples/widget_gauge/README.md +0 -50
  196. data/examples/widget_gauge/app.rb +0 -229
  197. data/examples/widget_layout_split/README.md +0 -53
  198. data/examples/widget_layout_split/app.rb +0 -260
  199. data/examples/widget_line_gauge/README.md +0 -50
  200. data/examples/widget_line_gauge/app.rb +0 -219
  201. data/examples/widget_list/README.md +0 -58
  202. data/examples/widget_list/app.rb +0 -382
  203. data/examples/widget_map/README.md +0 -48
  204. data/examples/widget_map/app.rb +0 -95
  205. data/examples/widget_overlay/README.md +0 -45
  206. data/examples/widget_overlay/app.rb +0 -250
  207. data/examples/widget_popup/README.md +0 -45
  208. data/examples/widget_popup/app.rb +0 -106
  209. data/examples/widget_ratatui_logo/README.md +0 -43
  210. data/examples/widget_ratatui_logo/app.rb +0 -104
  211. data/examples/widget_ratatui_mascot/README.md +0 -43
  212. data/examples/widget_ratatui_mascot/app.rb +0 -95
  213. data/examples/widget_rect/README.md +0 -53
  214. data/examples/widget_rect/app.rb +0 -222
  215. data/examples/widget_render/README.md +0 -46
  216. data/examples/widget_render/app.rb +0 -186
  217. data/examples/widget_render/app.rbs +0 -41
  218. data/examples/widget_rich_text/README.md +0 -44
  219. data/examples/widget_rich_text/app.rb +0 -193
  220. data/examples/widget_scroll_text/README.md +0 -46
  221. data/examples/widget_scroll_text/app.rb +0 -109
  222. data/examples/widget_scrollbar/README.md +0 -46
  223. data/examples/widget_scrollbar/app.rb +0 -155
  224. data/examples/widget_sparkline/README.md +0 -51
  225. data/examples/widget_sparkline/app.rb +0 -277
  226. data/examples/widget_style_colors/README.md +0 -43
  227. data/examples/widget_style_colors/app.rb +0 -83
  228. data/examples/widget_table/README.md +0 -57
  229. data/examples/widget_table/app.rb +0 -285
  230. data/examples/widget_tabs/README.md +0 -50
  231. data/examples/widget_tabs/app.rb +0 -183
  232. data/examples/widget_text_width/README.md +0 -44
  233. data/examples/widget_text_width/app.rb +0 -117
  234. data/migrate_to_buffer.rb +0 -145
  235. data/mise.toml +0 -8
  236. data/tasks/autodoc/examples.rb +0 -87
  237. data/tasks/autodoc/member.rb +0 -58
  238. data/tasks/autodoc/name.rb +0 -21
  239. data/tasks/autodoc.rake +0 -21
  240. data/tasks/bump/bump_workflow.rb +0 -49
  241. data/tasks/bump/cargo_lockfile.rb +0 -21
  242. data/tasks/bump/changelog.rb +0 -104
  243. data/tasks/bump/header.rb +0 -32
  244. data/tasks/bump/history.rb +0 -32
  245. data/tasks/bump/links.rb +0 -69
  246. data/tasks/bump/manifest.rb +0 -33
  247. data/tasks/bump/patch_release.rb +0 -19
  248. data/tasks/bump/release_branch.rb +0 -17
  249. data/tasks/bump/release_from_trunk.rb +0 -49
  250. data/tasks/bump/repository.rb +0 -54
  251. data/tasks/bump/ruby_gem.rb +0 -29
  252. data/tasks/bump/sem_ver.rb +0 -44
  253. data/tasks/bump/unreleased_section.rb +0 -73
  254. data/tasks/bump.rake +0 -61
  255. data/tasks/doc/documentation.rb +0 -59
  256. data/tasks/doc/link/file_url.rb +0 -30
  257. data/tasks/doc/link/relative_path.rb +0 -61
  258. data/tasks/doc/link/web_url.rb +0 -55
  259. data/tasks/doc/link.rb +0 -52
  260. data/tasks/doc/link_audit.rb +0 -116
  261. data/tasks/doc/problem.rb +0 -40
  262. data/tasks/doc/source_file.rb +0 -93
  263. data/tasks/doc.rake +0 -905
  264. data/tasks/example_viewer.html.erb +0 -172
  265. data/tasks/extension.rake +0 -14
  266. data/tasks/license/headers_md.rb +0 -223
  267. data/tasks/license/headers_rb.rb +0 -210
  268. data/tasks/license/license_utils.rb +0 -130
  269. data/tasks/license/snippets_md.rb +0 -315
  270. data/tasks/license/snippets_rdoc.rb +0 -150
  271. data/tasks/license.rake +0 -91
  272. data/tasks/lint.rake +0 -170
  273. data/tasks/rbs_predicates/predicate_catalog.rb +0 -52
  274. data/tasks/rbs_predicates/predicate_tests.rb +0 -124
  275. data/tasks/rbs_predicates/rbs_signature.rb +0 -63
  276. data/tasks/rbs_predicates.rake +0 -31
  277. data/tasks/rdoc_config.rb +0 -29
  278. data/tasks/resources/build.yml.erb +0 -60
  279. data/tasks/resources/index.html.erb +0 -141
  280. data/tasks/resources/rubies.yml +0 -7
  281. data/tasks/sourcehut.rake +0 -122
  282. data/tasks/steep.rake +0 -11
  283. data/tasks/terminal_preview/app_screenshot.rb +0 -45
  284. data/tasks/terminal_preview/crash_report.rb +0 -54
  285. data/tasks/terminal_preview/example_app.rb +0 -27
  286. data/tasks/terminal_preview/launcher_script.rb +0 -48
  287. data/tasks/terminal_preview/preview_collection.rb +0 -60
  288. data/tasks/terminal_preview/preview_timing.rb +0 -24
  289. data/tasks/terminal_preview/safety_confirmation.rb +0 -58
  290. data/tasks/terminal_preview/saved_screenshot.rb +0 -56
  291. data/tasks/terminal_preview/system_appearance.rb +0 -13
  292. data/tasks/terminal_preview/terminal_window.rb +0 -138
  293. data/tasks/terminal_preview/window_id.rb +0 -16
  294. data/tasks/terminal_preview.rake +0 -30
  295. data/tasks/test.rake +0 -36
  296. data/tasks/website/index_page.rb +0 -30
  297. data/tasks/website/version.rb +0 -122
  298. data/tasks/website/version_menu.rb +0 -68
  299. data/tasks/website/versioned_documentation.rb +0 -83
  300. data/tasks/website/website.rb +0 -53
  301. data/tasks/website.rake +0 -28
@@ -1,112 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- #--
4
- # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: MIT-0
6
- #++
7
-
8
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
9
- require "ratatui_ruby"
10
-
11
- # A custom widget that fills its area with a checkered pattern using Cell objects.
12
- class CheckeredBackground
13
- def initialize(tui)
14
- @tui = tui
15
- end
16
-
17
- def render(area)
18
- cell = @tui.cell(char: "░", fg: :dark_gray)
19
- commands = []
20
- area.height.times do |y|
21
- area.width.times do |x|
22
- # Checkerboard logic
23
- if (x + y).even?
24
- # Use a dim cell for the background pattern
25
- commands << @tui.draw_cell(area.x + x, area.y + y, cell)
26
- end
27
- end
28
- end
29
- commands
30
- end
31
- end
32
-
33
- class WidgetCell
34
- def run
35
- RatatuiRuby.run do |tui|
36
- @tui = tui
37
- # Define some reusable cells for our table
38
- ok_cell = @tui.cell(char: "OK", fg: :green)
39
- fail_cell = @tui.cell(char: "FAIL", fg: :red, modifiers: ["bold"])
40
- pending_cell = @tui.cell(char: "...", fg: :yellow, modifiers: ["dim"])
41
-
42
- # A mix of Strings and Cells in rows
43
- rows = [
44
- ["Database", ok_cell],
45
- ["Cache", ok_cell],
46
- ["Worker", fail_cell],
47
- ["Analytics", pending_cell],
48
- ["Web Server", @tui.cell(char: "RESTARTING", fg: :blue, modifiers: ["rapid_blink"])],
49
- ]
50
-
51
- table = @tui.table(
52
- header: ["Service", @tui.cell(char: "Status", modifiers: ["underlined"])],
53
- rows:,
54
- widths: [
55
- @tui.constraint_percentage(70),
56
- @tui.constraint_percentage(30),
57
- ],
58
- block: @tui.block(title: "System Status", borders: :all),
59
- column_spacing: 1
60
- )
61
-
62
- # Main loop
63
- loop do
64
- @tui.draw do |frame|
65
- # Create a layout that holds both widgets
66
- # We use a vertical layout:
67
- # Top: Custom CheckeredBackground with specific height
68
- # Bottom: Table using remaining space
69
- top_area, bottom_area = @tui.layout_split(
70
- frame.area,
71
- direction: :vertical,
72
- constraints: [
73
- @tui.constraint_length(10), # Top section
74
- @tui.constraint_min(0), # Bottom section
75
- ]
76
- )
77
-
78
- # Top Child: An Overlay of Paragraph on top of CheckeredBackground
79
- overlay = @tui.overlay(
80
- layers: [
81
- CheckeredBackground.new(@tui),
82
- @tui.center(
83
- width_percent: 50,
84
- height_percent: 50,
85
- child: @tui.paragraph(
86
- text: "Custom Widget\n(CheckeredBackground)",
87
- alignment: :center,
88
- block: @tui.block(borders: :all, title: "Overlay")
89
- )
90
- ),
91
- ]
92
- )
93
- frame.render_widget(overlay, top_area)
94
-
95
- # Bottom Child: The Table
96
- frame.render_widget(table, bottom_area)
97
- end
98
-
99
- case @tui.poll_event
100
- in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
101
- break
102
- else
103
- nil
104
- end
105
- end
106
- end
107
- end
108
- end
109
-
110
- if __FILE__ == $0
111
- WidgetCell.new.run
112
- end
@@ -1,33 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
- SPDX-License-Identifier: CC-BY-SA-4.0
4
- -->
5
- # Center Example
6
-
7
- [![widget_center](../../doc/images/widget_center.png)](app.rb)
8
-
9
- <!--
10
- SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
11
- SPDX-License-Identifier: CC-BY-SA-4.0
12
- -->
13
-
14
- This example demonstrates the `Center` widget, which positions a child widget in the center of the available area.
15
-
16
- ## Key Concepts
17
-
18
- - **Centering**: The widget automatically calculates the necessary padding to center its child.
19
- - **Sizing**: You can control the size of the centered area using `width_percent` and `height_percent`.
20
- - **Composition**: The `Center` widget wraps another widget (the child), making it easy to compose layouts.
21
-
22
- ## Controls
23
-
24
- | Key | Action |
25
- | --- | --- |
26
- | `←` / `→` | Decrease / Increase width percentage |
27
- | `↑` / `↓` | Increase / Decrease height percentage |
28
- | `q` | Quit |
29
-
30
- ## Screenshot
31
- ## Source Code
32
-
33
- - [app.rb](app.rb)
@@ -1,118 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- #--
4
- # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: MIT-0
6
- #++
7
-
8
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
9
- require "ratatui_ruby"
10
-
11
- # Center Widget
12
- # Demonstrates how to center content horizontally and vertically
13
- # with adjustable width/height percentages.
14
- class WidgetCenter
15
- def initialize
16
- @width_percent = 50
17
- @height_percent = 50
18
- end
19
-
20
- def run
21
- RatatuiRuby.run do |tui|
22
- @tui = tui
23
- loop do
24
- render
25
- break if handle_input == :quit
26
- end
27
- end
28
- end
29
-
30
- private def render
31
- @tui.draw do |frame|
32
- layout = @tui.layout_split(
33
- frame.area,
34
- direction: :vertical,
35
- constraints: [
36
- @tui.constraint_fill(1),
37
- @tui.constraint_length(3),
38
- ]
39
- )
40
-
41
- # 1. Main Area
42
- # Background block frames the centered content
43
- bg_block = @tui.block(
44
- title: "Center Widget",
45
- borders: [:all],
46
- style: @tui.style(fg: :gray)
47
- )
48
- frame.render_widget(bg_block, layout[0])
49
-
50
- # 2. Centered Content
51
- # The content itself is just a block with some text
52
- content = @tui.paragraph(
53
- text: [
54
- @tui.text_line(
55
- spans: [
56
- @tui.text_span(content: "Centered Area", style: @tui.style(modifiers: [:bold])),
57
- ],
58
- alignment: :center
59
- ),
60
- @tui.text_line(spans: []),
61
- @tui.text_line(spans: [@tui.text_span(content: "Width: #{@width_percent}%", style: @tui.style(fg: :cyan))], alignment: :center),
62
- @tui.text_line(spans: [@tui.text_span(content: "Height: #{@height_percent}%", style: @tui.style(fg: :magenta))], alignment: :center),
63
- ],
64
- block: @tui.block(
65
- title: "Child Widget",
66
- borders: [:all],
67
- style: @tui.style(fg: :white)
68
- ),
69
- alignment: :center
70
- )
71
-
72
- # Create the Center widget
73
- center_widget = @tui.center(
74
- child: content,
75
- width_percent: @width_percent,
76
- height_percent: @height_percent
77
- )
78
-
79
- # Render center widget into the main layout area
80
- frame.render_widget(center_widget, layout[0])
81
-
82
- # 3. Controls
83
- control_text = @tui.paragraph(
84
- text: [
85
- @tui.text_line(spans: [
86
- @tui.text_span(content: "←/→", style: @tui.style(modifiers: [:bold, :underlined])),
87
- @tui.text_span(content: ": Width "),
88
- @tui.text_span(content: "↑/↓", style: @tui.style(modifiers: [:bold, :underlined])),
89
- @tui.text_span(content: ": Height "),
90
- @tui.text_span(content: "q", style: @tui.style(modifiers: [:bold, :underlined])),
91
- @tui.text_span(content: ": Quit"),
92
- ]),
93
- ],
94
- block: @tui.block(borders: [:top], style: @tui.style(bg: :black))
95
- )
96
- frame.render_widget(control_text, layout[1])
97
- end
98
- end
99
-
100
- def handle_input
101
- case @tui.poll_event
102
- in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
103
- :quit
104
- in { type: :key, code: "left" }
105
- @width_percent = [@width_percent - 5, 5].max
106
- in { type: :key, code: "right" }
107
- @width_percent = [@width_percent + 5, 100].min
108
- in { type: :key, code: "up" }
109
- @height_percent = [@height_percent + 5, 100].min
110
- in { type: :key, code: "down" }
111
- @height_percent = [@height_percent - 5, 5].max
112
- else
113
- # Ignore other events
114
- end
115
- end
116
- end
117
-
118
- WidgetCenter.new.run if __FILE__ == $0
@@ -1,50 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
- SPDX-License-Identifier: CC-BY-SA-4.0
4
- -->
5
-
6
- # Chart (Dataset, Axis) Example
7
-
8
- [![widget_chart](../../doc/images/widget_chart.png)](app.rb)
9
-
10
- Demonstrates Cartesian plotting with interactive styling and configuration.
11
-
12
- Trends and patterns are invisible in raw logs. Charts visualize X/Y datasets to reveal the story behind the data.
13
-
14
- ## Features Demonstrated
15
-
16
- - **Dataset Types**: Line charts and Scatter plots.
17
- - **Markers**: Braille patterns, dots, blocks, and bars.
18
- - **Axis Configuration**: Controlling labels, bounds, and alignment (Left/Center/Right).
19
- - **Legend**: Positioning the legend in any of the four corners or hiding it based on constraints.
20
-
21
- ## Hotkeys
22
-
23
- - **m**: Cycle Marker Type (`marker`)
24
- - **s**: Cycle Dataset Style (`style`)
25
- - **x**: Cycle X-Axis Alignment (`labels_alignment`)
26
- - **y**: Cycle Y-Axis Alignment (`labels_alignment`)
27
- - **l**: Cycle Legend Position (`legend_position`)
28
- - **q**: Quit
29
-
30
- ## Usage
31
-
32
- <!-- SPDX-SnippetBegin -->
33
- <!--
34
- SPDX-FileCopyrightText: 2026 Kerrick Long
35
- SPDX-License-Identifier: MIT-0
36
- -->
37
- ```bash
38
- ruby examples/widget_chart/app.rb
39
- ```
40
- <!-- SPDX-SnippetEnd -->
41
-
42
- ## Learning Outcomes
43
-
44
- Use this example if you need to...
45
-
46
- - Plot real-time data monitoring (CPU history, request latency).
47
- - Visualize mathematical functions.
48
- - Compare multiple datasets on the same axis.
49
-
50
- [Read the source code →](app.rb)
@@ -1,220 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- #--
4
- # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: MIT-0
6
- #++
7
-
8
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
9
- require "ratatui_ruby"
10
-
11
- # Demonstrates Cartesian plotting attributes with interactive cycling.
12
- #
13
- # Trends and patterns are invisible in raw logs. You need to see the shape of the data to understand the story it tells.
14
- #
15
- # This demo showcases the <tt>Chart</tt> widget. It provides an interactive playground where you can toggle marker types, axis alignments, and legend positions in real-time.
16
- #
17
- # Use it to understand how to visualize complex X/Y datasets and trends efficiently.
18
- #
19
- # === Example
20
- #
21
- # Run the demo from the terminal:
22
- #
23
- # ruby examples/widget_chart/app.rb
24
- #
25
- # rdoc-image:/doc/images/widget_chart.png
26
- class WidgetChart
27
- MARKERS = [
28
- { name: "Dot (·)", marker: :dot },
29
- { name: "Braille", marker: :braille },
30
- { name: "Block (█)", marker: :block },
31
- { name: "Bar", marker: :bar },
32
- ].freeze
33
-
34
- X_ALIGNMENTS = [
35
- { name: "Left", alignment: :left },
36
- { name: "Center", alignment: :center },
37
- { name: "Right", alignment: :right },
38
- ].freeze
39
-
40
- Y_ALIGNMENTS = [
41
- { name: "Left", alignment: :left },
42
- { name: "Center", alignment: :center },
43
- { name: "Right", alignment: :right },
44
- ].freeze
45
-
46
- LEGEND_POSITIONS = [
47
- { name: "Top Right", position: :top_right },
48
- { name: "Top Left", position: :top_left },
49
- { name: "Bottom Right", position: :bottom_right },
50
- { name: "Bottom Left", position: :bottom_left },
51
- ].freeze
52
-
53
- def run
54
- RatatuiRuby.run do |tui|
55
- @tui = tui
56
- init_styles
57
-
58
- # Support seeded random for deterministic testing
59
- # Set RATA_SEED=42 for reproducible scatter plot data
60
- seed = ENV.fetch("RATA_SEED", nil)
61
- @rng = seed ? Random.new(seed.to_i) : Random.new
62
-
63
- @marker_index = 0
64
- @dataset_style_index = 0
65
- @x_alignment_index = 1
66
- @y_alignment_index = 2
67
- @legend_position_index = 0
68
-
69
- loop do
70
- render
71
- break if handle_input == :quit
72
- sleep 0.05
73
- end
74
- end
75
- end
76
-
77
- private def init_styles
78
- @hotkey_style = @tui.style(modifiers: [:bold, :underlined])
79
- @dataset_styles = [
80
- { name: "Yellow", style: @tui.style(fg: :yellow) },
81
- { name: "Green", style: @tui.style(fg: :green) },
82
- { name: "Cyan", style: @tui.style(fg: :cyan) },
83
- { name: "Red", style: @tui.style(fg: :red) },
84
- { name: "Magenta", style: @tui.style(fg: :magenta) },
85
- { name: "Bold Blue", style: @tui.style(fg: :blue, modifiers: [:bold]) },
86
- { name: "Dim White", style: @tui.style(fg: :white, modifiers: [:dim]) },
87
- { name: "Italic Green", style: @tui.style(fg: :green, modifiers: [:italic]) },
88
- { name: "Alert (Red/White/Bar)", style: @tui.style(fg: :white, bg: :red, modifiers: [:bold]) },
89
- ]
90
- end
91
-
92
- private def render
93
- # Static sample data: sine wave with wider range for better visibility
94
- line_data = (0..50).map do |i|
95
- x = i / 5.0
96
- [x, Math.sin(x)]
97
- end
98
-
99
- # Scatter: Random points (deterministic when RATA_SEED is set)
100
- scatter_data = (0..20).map do |_|
101
- [@rng.rand(0.0..10.0), @rng.rand(-1.0..1.0)]
102
- end
103
-
104
- style = @dataset_styles[@dataset_style_index][:style]
105
- # Ensure the second dataset has a different style
106
- scatter_style = @dataset_styles[(@dataset_style_index + 2) % @dataset_styles.length][:style]
107
-
108
- datasets = [
109
- @tui.dataset(
110
- name: "Line",
111
- data: line_data,
112
- style:,
113
- marker: (style.modifiers.include?(:bold) && style.bg) ? :bar : MARKERS[@marker_index][:marker],
114
- graph_type: :line
115
- ),
116
- @tui.dataset(
117
- name: "Scatter",
118
- data: scatter_data,
119
- style: scatter_style,
120
- marker: (scatter_style.modifiers.include?(:bold) && scatter_style.bg) ? :bar : MARKERS[@marker_index][:marker],
121
- graph_type: :scatter
122
- ),
123
- ]
124
-
125
- chart = @tui.chart(
126
- datasets:,
127
- x_axis: @tui.axis(
128
- title: "Time",
129
- bounds: [0.0, 10.0],
130
- labels: %w[0 5 10],
131
- style: @tui.style(fg: :yellow),
132
- labels_alignment: X_ALIGNMENTS[@x_alignment_index][:alignment]
133
- ),
134
- y_axis: @tui.axis(
135
- title: "Amplitude",
136
- bounds: [-1.0, 1.0],
137
- labels: %w[-1 0 1],
138
- style: @tui.style(fg: :cyan),
139
- labels_alignment: Y_ALIGNMENTS[@y_alignment_index][:alignment]
140
- ),
141
- block: @tui.block(
142
- title: "Chart Widget",
143
- borders: [:all]
144
- ),
145
- legend_position: LEGEND_POSITIONS[@legend_position_index][:position],
146
- hidden_legend_constraints: [
147
- @tui.constraint_min(20),
148
- @tui.constraint_min(10),
149
- ]
150
- )
151
-
152
- controls = @tui.block(
153
- title: "Controls",
154
- borders: [:all],
155
- children: [
156
- @tui.paragraph(
157
- text: [
158
- # Line 1: Markers & Colors
159
- @tui.text_line(spans: [
160
- @tui.text_span(content: "m", style: @hotkey_style),
161
- @tui.text_span(content: ": Marker (#{MARKERS[@marker_index][:name]}) "),
162
- @tui.text_span(content: "s", style: @hotkey_style),
163
- @tui.text_span(content: ": Style (#{@dataset_styles[@dataset_style_index][:name]})"),
164
- ]),
165
- # Line 2: Axis alignments
166
- @tui.text_line(spans: [
167
- @tui.text_span(content: "x", style: @hotkey_style),
168
- @tui.text_span(content: ": X Align (#{X_ALIGNMENTS[@x_alignment_index][:name]}) "),
169
- @tui.text_span(content: "y", style: @hotkey_style),
170
- @tui.text_span(content: ": Y Align (#{Y_ALIGNMENTS[@y_alignment_index][:name]}) "),
171
- @tui.text_span(content: "l", style: @hotkey_style),
172
- @tui.text_span(content: ": Legend (#{LEGEND_POSITIONS[@legend_position_index][:name]})"),
173
- ]),
174
- # Line 3: Quit
175
- @tui.text_line(spans: [
176
- @tui.text_span(content: "q", style: @hotkey_style),
177
- @tui.text_span(content: ": Quit"),
178
- ]),
179
- ]
180
- ),
181
- ]
182
- )
183
-
184
- @tui.draw do |frame|
185
- chart_area, controls_area = @tui.layout_split(
186
- frame.area,
187
- direction: :vertical,
188
- constraints: [
189
- @tui.constraint_fill(1),
190
- @tui.constraint_length(5),
191
- ]
192
- )
193
- frame.render_widget(chart, chart_area)
194
- frame.render_widget(controls, controls_area)
195
- end
196
- end
197
-
198
- private def handle_input
199
- event = @tui.poll_event
200
-
201
- case event
202
- in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
203
- :quit
204
- in type: :key, code: "m"
205
- @marker_index = (@marker_index + 1) % MARKERS.length
206
- in type: :key, code: "s"
207
- @dataset_style_index = (@dataset_style_index + 1) % @dataset_styles.length
208
- in type: :key, code: "x"
209
- @x_alignment_index = (@x_alignment_index + 1) % X_ALIGNMENTS.length
210
- in type: :key, code: "y"
211
- @y_alignment_index = (@y_alignment_index + 1) % Y_ALIGNMENTS.length
212
- in type: :key, code: "l"
213
- @legend_position_index = (@legend_position_index + 1) % LEGEND_POSITIONS.length
214
- else
215
- nil
216
- end
217
- end
218
- end
219
-
220
- WidgetChart.new.run if __FILE__ == $PROGRAM_NAME
@@ -1,50 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
- SPDX-License-Identifier: CC-BY-SA-4.0
4
- -->
5
-
6
- # Gauge Widget Example
7
-
8
- [![widget_gauge](../../doc/images/widget_gauge.png)](app.rb)
9
-
10
- Demonstrates progress bars with interactive configuration.
11
-
12
- Long-running tasks create anxiety. Users need to know the system is working. Gauges provide visual feedback on completion status.
13
-
14
- ## Features Demonstrated
15
-
16
- - **Progress styles**: standard block characters or Unicode bars.
17
- - **Labels**: Customizing the text overlay (Percentage, Ratio, etc.).
18
- - **Styling**: Independent control of the filled gauge color and the background track.
19
- - **Thresholds**: Implementing multi-colored gauges based on values.
20
-
21
- ## Hotkeys
22
-
23
- - **Arrows (←/→)**: Adjust Ratio (`ratio`)
24
- - **g**: Cycle Gauge Color (`gauge_style`)
25
- - **b**: Cycle Background Style (`style`)
26
- - **u**: Toggle Unicode Mode (`use_unicode`)
27
- - **l**: Cycle Label Mode (`label`)
28
- - **q**: Quit
29
-
30
- ## Usage
31
-
32
- <!-- SPDX-SnippetBegin -->
33
- <!--
34
- SPDX-FileCopyrightText: 2026 Kerrick Long
35
- SPDX-License-Identifier: MIT-0
36
- -->
37
- ```bash
38
- ruby examples/widget_gauge/app.rb
39
- ```
40
- <!-- SPDX-SnippetEnd -->
41
-
42
- ## Learning Outcomes
43
-
44
- Use this example if you need to...
45
-
46
- - Show download or upload progress.
47
- - Visualize resource quotas (disk space, memory usage).
48
- - Create "health bars" or status indicators.
49
-
50
- [Read the source code →](app.rb)