ratatui_ruby 0.3.1 → 0.5.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 (350) hide show
  1. checksums.yaml +4 -4
  2. data/.builds/ruby-3.2.yml +14 -12
  3. data/.builds/ruby-3.3.yml +14 -12
  4. data/.builds/ruby-3.4.yml +14 -12
  5. data/.builds/ruby-4.0.0.yml +14 -12
  6. data/AGENTS.md +89 -132
  7. data/CHANGELOG.md +223 -1
  8. data/README.md +23 -16
  9. data/REUSE.toml +20 -0
  10. data/doc/application_architecture.md +176 -0
  11. data/doc/application_testing.md +17 -10
  12. data/doc/contributors/design/ruby_frontend.md +11 -7
  13. data/doc/contributors/developing_examples.md +261 -0
  14. data/doc/contributors/documentation_style.md +104 -0
  15. data/doc/contributors/dwim_dx.md +366 -0
  16. data/doc/contributors/index.md +2 -0
  17. data/doc/custom.css +14 -0
  18. data/doc/event_handling.md +125 -0
  19. data/doc/images/app_all_events.png +0 -0
  20. data/doc/images/app_analytics.png +0 -0
  21. data/doc/images/app_color_picker.png +0 -0
  22. data/doc/images/app_custom_widget.png +0 -0
  23. data/doc/images/app_login_form.png +0 -0
  24. data/doc/images/app_map_demo.png +0 -0
  25. data/doc/images/app_mouse_events.png +0 -0
  26. data/doc/images/app_table_select.png +0 -0
  27. data/doc/images/verify_quickstart_dsl.png +0 -0
  28. data/doc/images/verify_quickstart_layout.png +0 -0
  29. data/doc/images/verify_quickstart_lifecycle.png +0 -0
  30. data/doc/images/verify_readme_usage.png +0 -0
  31. data/doc/images/widget_barchart_demo.png +0 -0
  32. data/doc/images/widget_block_padding.png +0 -0
  33. data/doc/images/widget_block_titles.png +0 -0
  34. data/doc/images/widget_box_demo.png +0 -0
  35. data/doc/images/widget_calendar_demo.png +0 -0
  36. data/doc/images/widget_cell_demo.png +0 -0
  37. data/doc/images/widget_chart_demo.png +0 -0
  38. data/doc/images/widget_gauge_demo.png +0 -0
  39. data/doc/images/widget_layout_split.png +0 -0
  40. data/doc/images/widget_line_gauge_demo.png +0 -0
  41. data/doc/images/widget_list_demo.png +0 -0
  42. data/doc/images/widget_list_styles.png +0 -0
  43. data/doc/images/widget_popup_demo.png +0 -0
  44. data/doc/images/widget_ratatui_logo_demo.png +0 -0
  45. data/doc/images/widget_ratatui_mascot_demo.png +0 -0
  46. data/doc/images/widget_rect.png +0 -0
  47. data/doc/images/widget_render.png +0 -0
  48. data/doc/images/widget_rich_text.png +0 -0
  49. data/doc/images/widget_scroll_text.png +0 -0
  50. data/doc/images/widget_scrollbar_demo.png +0 -0
  51. data/doc/images/widget_sparkline_demo.png +0 -0
  52. data/doc/images/widget_style_colors.png +0 -0
  53. data/doc/images/widget_table_flex.png +0 -0
  54. data/doc/images/widget_tabs_demo.png +0 -0
  55. data/doc/index.md +1 -0
  56. data/doc/interactive_design.md +116 -0
  57. data/doc/quickstart.md +186 -84
  58. data/examples/app_all_events/README.md +81 -0
  59. data/examples/app_all_events/app.rb +93 -0
  60. data/examples/app_all_events/model/event_color_cycle.rb +41 -0
  61. data/examples/app_all_events/model/event_entry.rb +75 -0
  62. data/examples/app_all_events/model/events.rb +180 -0
  63. data/examples/app_all_events/model/highlight.rb +57 -0
  64. data/examples/app_all_events/model/timestamp.rb +54 -0
  65. data/examples/app_all_events/test/snapshots/after_focus_lost.txt +24 -0
  66. data/examples/app_all_events/test/snapshots/after_focus_regained.txt +24 -0
  67. data/examples/app_all_events/test/snapshots/after_horizontal_resize.txt +24 -0
  68. data/examples/app_all_events/test/snapshots/after_key_a.txt +24 -0
  69. data/examples/app_all_events/test/snapshots/after_key_ctrl_x.txt +24 -0
  70. data/examples/app_all_events/test/snapshots/after_mouse_click.txt +24 -0
  71. data/examples/app_all_events/test/snapshots/after_mouse_drag.txt +24 -0
  72. data/examples/app_all_events/test/snapshots/after_multiple_events.txt +24 -0
  73. data/examples/app_all_events/test/snapshots/after_paste.txt +24 -0
  74. data/examples/app_all_events/test/snapshots/after_resize.txt +24 -0
  75. data/examples/app_all_events/test/snapshots/after_right_click.txt +24 -0
  76. data/examples/app_all_events/test/snapshots/after_vertical_resize.txt +24 -0
  77. data/examples/app_all_events/test/snapshots/initial_state.txt +24 -0
  78. data/examples/app_all_events/view/app_view.rb +78 -0
  79. data/examples/app_all_events/view/controls_view.rb +50 -0
  80. data/examples/app_all_events/view/counts_view.rb +55 -0
  81. data/examples/app_all_events/view/live_view.rb +69 -0
  82. data/examples/app_all_events/view/log_view.rb +60 -0
  83. data/{lib/ratatui_ruby/output.rb → examples/app_all_events/view.rb} +1 -1
  84. data/examples/app_all_events/view_state.rb +42 -0
  85. data/examples/app_color_picker/README.md +94 -0
  86. data/examples/app_color_picker/app.rb +112 -0
  87. data/examples/app_color_picker/clipboard.rb +84 -0
  88. data/examples/app_color_picker/color.rb +191 -0
  89. data/examples/app_color_picker/copy_dialog.rb +170 -0
  90. data/examples/app_color_picker/harmony.rb +56 -0
  91. data/examples/app_color_picker/input.rb +142 -0
  92. data/examples/app_color_picker/palette.rb +80 -0
  93. data/examples/app_color_picker/scene.rb +201 -0
  94. data/examples/app_login_form/app.rb +108 -0
  95. data/examples/app_map_demo/app.rb +93 -0
  96. data/examples/app_table_select/app.rb +201 -0
  97. data/examples/verify_quickstart_dsl/app.rb +45 -0
  98. data/examples/verify_quickstart_layout/app.rb +69 -0
  99. data/examples/verify_quickstart_lifecycle/app.rb +48 -0
  100. data/examples/verify_readme_usage/app.rb +34 -0
  101. data/examples/widget_barchart_demo/app.rb +238 -0
  102. data/examples/widget_block_padding/app.rb +67 -0
  103. data/examples/widget_block_titles/app.rb +69 -0
  104. data/examples/widget_box_demo/app.rb +250 -0
  105. data/examples/widget_calendar_demo/app.rb +109 -0
  106. data/examples/widget_cell_demo/app.rb +104 -0
  107. data/examples/widget_chart_demo/app.rb +213 -0
  108. data/examples/widget_gauge_demo/app.rb +212 -0
  109. data/examples/widget_layout_split/app.rb +246 -0
  110. data/examples/widget_line_gauge_demo/app.rb +217 -0
  111. data/examples/widget_list_demo/app.rb +382 -0
  112. data/examples/widget_list_styles/app.rb +141 -0
  113. data/examples/widget_popup_demo/app.rb +104 -0
  114. data/examples/widget_ratatui_logo_demo/app.rb +103 -0
  115. data/examples/widget_ratatui_mascot_demo/app.rb +93 -0
  116. data/examples/widget_rect/app.rb +205 -0
  117. data/examples/widget_render/app.rb +184 -0
  118. data/examples/widget_rich_text/app.rb +137 -0
  119. data/examples/widget_scroll_text/app.rb +108 -0
  120. data/examples/widget_scrollbar_demo/app.rb +153 -0
  121. data/examples/widget_sparkline_demo/app.rb +274 -0
  122. data/examples/widget_style_colors/app.rb +102 -0
  123. data/examples/widget_table_flex/app.rb +95 -0
  124. data/examples/widget_tabs_demo/app.rb +167 -0
  125. data/ext/ratatui_ruby/Cargo.lock +889 -115
  126. data/ext/ratatui_ruby/Cargo.toml +4 -3
  127. data/ext/ratatui_ruby/clippy.toml +7 -0
  128. data/ext/ratatui_ruby/extconf.rb +7 -0
  129. data/ext/ratatui_ruby/src/events.rs +293 -219
  130. data/ext/ratatui_ruby/src/frame.rs +115 -0
  131. data/ext/ratatui_ruby/src/lib.rs +105 -24
  132. data/ext/ratatui_ruby/src/rendering.rs +94 -10
  133. data/ext/ratatui_ruby/src/style.rs +357 -93
  134. data/ext/ratatui_ruby/src/terminal.rs +121 -31
  135. data/ext/ratatui_ruby/src/text.rs +178 -0
  136. data/ext/ratatui_ruby/src/widgets/barchart.rs +99 -24
  137. data/ext/ratatui_ruby/src/widgets/block.rs +32 -3
  138. data/ext/ratatui_ruby/src/widgets/calendar.rs +45 -44
  139. data/ext/ratatui_ruby/src/widgets/canvas.rs +44 -9
  140. data/ext/ratatui_ruby/src/widgets/chart.rs +79 -27
  141. data/ext/ratatui_ruby/src/widgets/clear.rs +3 -1
  142. data/ext/ratatui_ruby/src/widgets/gauge.rs +11 -4
  143. data/ext/ratatui_ruby/src/widgets/layout.rs +223 -15
  144. data/ext/ratatui_ruby/src/widgets/line_gauge.rs +92 -0
  145. data/ext/ratatui_ruby/src/widgets/list.rs +114 -11
  146. data/ext/ratatui_ruby/src/widgets/mod.rs +3 -0
  147. data/ext/ratatui_ruby/src/widgets/overlay.rs +4 -2
  148. data/ext/ratatui_ruby/src/widgets/paragraph.rs +35 -13
  149. data/ext/ratatui_ruby/src/widgets/ratatui_logo.rs +40 -0
  150. data/ext/ratatui_ruby/src/widgets/ratatui_mascot.rs +51 -0
  151. data/ext/ratatui_ruby/src/widgets/scrollbar.rs +61 -7
  152. data/ext/ratatui_ruby/src/widgets/sparkline.rs +73 -6
  153. data/ext/ratatui_ruby/src/widgets/table.rs +177 -64
  154. data/ext/ratatui_ruby/src/widgets/tabs.rs +105 -5
  155. data/lib/ratatui_ruby/cell.rb +166 -0
  156. data/lib/ratatui_ruby/event/focus_gained.rb +49 -0
  157. data/lib/ratatui_ruby/event/focus_lost.rb +50 -0
  158. data/lib/ratatui_ruby/event/key.rb +211 -0
  159. data/lib/ratatui_ruby/event/mouse.rb +124 -0
  160. data/lib/ratatui_ruby/event/none.rb +43 -0
  161. data/lib/ratatui_ruby/event/paste.rb +71 -0
  162. data/lib/ratatui_ruby/event/resize.rb +80 -0
  163. data/lib/ratatui_ruby/event.rb +131 -0
  164. data/lib/ratatui_ruby/frame.rb +87 -0
  165. data/lib/ratatui_ruby/schema/bar_chart/bar.rb +45 -0
  166. data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +23 -0
  167. data/lib/ratatui_ruby/schema/bar_chart.rb +226 -17
  168. data/lib/ratatui_ruby/schema/block.rb +178 -11
  169. data/lib/ratatui_ruby/schema/calendar.rb +70 -14
  170. data/lib/ratatui_ruby/schema/canvas.rb +213 -46
  171. data/lib/ratatui_ruby/schema/center.rb +46 -8
  172. data/lib/ratatui_ruby/schema/chart.rb +134 -32
  173. data/lib/ratatui_ruby/schema/clear.rb +22 -53
  174. data/lib/ratatui_ruby/schema/constraint.rb +72 -12
  175. data/lib/ratatui_ruby/schema/cursor.rb +23 -5
  176. data/lib/ratatui_ruby/schema/draw.rb +53 -0
  177. data/lib/ratatui_ruby/schema/gauge.rb +56 -12
  178. data/lib/ratatui_ruby/schema/layout.rb +91 -9
  179. data/lib/ratatui_ruby/schema/line_gauge.rb +78 -0
  180. data/lib/ratatui_ruby/schema/list.rb +92 -16
  181. data/lib/ratatui_ruby/schema/overlay.rb +29 -3
  182. data/lib/ratatui_ruby/schema/paragraph.rb +82 -25
  183. data/lib/ratatui_ruby/schema/ratatui_logo.rb +29 -0
  184. data/lib/ratatui_ruby/schema/ratatui_mascot.rb +34 -0
  185. data/lib/ratatui_ruby/schema/rect.rb +59 -10
  186. data/lib/ratatui_ruby/schema/scrollbar.rb +127 -19
  187. data/lib/ratatui_ruby/schema/shape/label.rb +66 -0
  188. data/lib/ratatui_ruby/schema/sparkline.rb +120 -12
  189. data/lib/ratatui_ruby/schema/style.rb +39 -11
  190. data/lib/ratatui_ruby/schema/table.rb +109 -18
  191. data/lib/ratatui_ruby/schema/tabs.rb +71 -10
  192. data/lib/ratatui_ruby/schema/text.rb +90 -0
  193. data/lib/ratatui_ruby/session/autodoc.rb +417 -0
  194. data/lib/ratatui_ruby/session.rb +163 -0
  195. data/lib/ratatui_ruby/test_helper.rb +322 -13
  196. data/lib/ratatui_ruby/version.rb +1 -1
  197. data/lib/ratatui_ruby.rb +184 -38
  198. data/sig/examples/app_all_events/app.rbs +11 -0
  199. data/sig/examples/app_all_events/model/event_entry.rbs +16 -0
  200. data/sig/examples/app_all_events/model/events.rbs +15 -0
  201. data/sig/examples/app_all_events/model/timestamp.rbs +11 -0
  202. data/sig/examples/app_all_events/view/app_view.rbs +8 -0
  203. data/sig/examples/app_all_events/view/controls_view.rbs +6 -0
  204. data/sig/examples/app_all_events/view/counts_view.rbs +6 -0
  205. data/sig/examples/app_all_events/view/live_view.rbs +6 -0
  206. data/sig/examples/app_all_events/view/log_view.rbs +6 -0
  207. data/sig/examples/app_all_events/view.rbs +8 -0
  208. data/sig/examples/app_all_events/view_state.rbs +15 -0
  209. data/sig/examples/app_color_picker/app.rbs +12 -0
  210. data/sig/examples/app_login_form/app.rbs +11 -0
  211. data/sig/examples/app_map_demo/app.rbs +11 -0
  212. data/sig/examples/app_table_select/app.rbs +11 -0
  213. data/sig/examples/verify_quickstart_dsl/app.rbs +11 -0
  214. data/sig/examples/verify_quickstart_lifecycle/app.rbs +11 -0
  215. data/sig/examples/verify_readme_usage/app.rbs +11 -0
  216. data/sig/examples/widget_block_padding/app.rbs +11 -0
  217. data/sig/examples/widget_block_titles/app.rbs +11 -0
  218. data/sig/examples/widget_box_demo/app.rbs +11 -0
  219. data/sig/examples/widget_calendar_demo/app.rbs +11 -0
  220. data/sig/examples/widget_cell_demo/app.rbs +11 -0
  221. data/sig/examples/widget_chart_demo/app.rbs +11 -0
  222. data/sig/examples/widget_gauge_demo/app.rbs +11 -0
  223. data/sig/examples/widget_layout_split/app.rbs +10 -0
  224. data/sig/examples/widget_line_gauge_demo/app.rbs +11 -0
  225. data/sig/examples/widget_list_demo/app.rbs +12 -0
  226. data/sig/examples/widget_list_styles/app.rbs +11 -0
  227. data/sig/examples/widget_popup_demo/app.rbs +11 -0
  228. data/sig/examples/widget_ratatui_logo_demo/app.rbs +11 -0
  229. data/sig/examples/widget_ratatui_mascot_demo/app.rbs +11 -0
  230. data/sig/examples/widget_rect/app.rbs +12 -0
  231. data/sig/examples/widget_render/app.rbs +10 -0
  232. data/sig/examples/widget_rich_text/app.rbs +11 -0
  233. data/sig/examples/widget_scroll_text/app.rbs +11 -0
  234. data/sig/examples/widget_scrollbar_demo/app.rbs +11 -0
  235. data/sig/examples/widget_sparkline_demo/app.rbs +10 -0
  236. data/sig/examples/widget_style_colors/app.rbs +14 -0
  237. data/sig/examples/widget_table_flex/app.rbs +11 -0
  238. data/sig/ratatui_ruby/event.rbs +69 -0
  239. data/sig/ratatui_ruby/frame.rbs +9 -0
  240. data/sig/ratatui_ruby/ratatui_ruby.rbs +5 -3
  241. data/sig/ratatui_ruby/schema/bar_chart/bar.rbs +16 -0
  242. data/sig/ratatui_ruby/schema/bar_chart/bar_group.rbs +13 -0
  243. data/sig/ratatui_ruby/schema/bar_chart.rbs +20 -2
  244. data/sig/ratatui_ruby/schema/block.rbs +5 -4
  245. data/sig/ratatui_ruby/schema/calendar.rbs +6 -2
  246. data/sig/ratatui_ruby/schema/canvas.rbs +52 -39
  247. data/sig/ratatui_ruby/schema/center.rbs +3 -3
  248. data/sig/ratatui_ruby/schema/chart.rbs +8 -5
  249. data/sig/ratatui_ruby/schema/constraint.rbs +8 -5
  250. data/sig/ratatui_ruby/schema/cursor.rbs +1 -1
  251. data/sig/ratatui_ruby/schema/draw.rbs +27 -0
  252. data/sig/ratatui_ruby/schema/gauge.rbs +4 -2
  253. data/sig/ratatui_ruby/schema/layout.rbs +11 -1
  254. data/sig/ratatui_ruby/schema/line_gauge.rbs +16 -0
  255. data/sig/ratatui_ruby/schema/list.rbs +5 -1
  256. data/sig/ratatui_ruby/schema/paragraph.rbs +4 -1
  257. data/sig/ratatui_ruby/schema/ratatui_logo.rbs +8 -0
  258. data/sig/ratatui_ruby/{buffer.rbs → schema/ratatui_mascot.rbs} +4 -3
  259. data/sig/ratatui_ruby/schema/rect.rbs +2 -1
  260. data/sig/ratatui_ruby/schema/scrollbar.rbs +18 -2
  261. data/sig/ratatui_ruby/schema/sparkline.rbs +6 -2
  262. data/sig/ratatui_ruby/schema/table.rbs +8 -1
  263. data/sig/ratatui_ruby/schema/tabs.rbs +5 -1
  264. data/sig/ratatui_ruby/schema/text.rbs +22 -0
  265. data/sig/ratatui_ruby/session.rbs +94 -0
  266. data/tasks/autodoc/inventory.rb +61 -0
  267. data/tasks/autodoc/member.rb +56 -0
  268. data/tasks/autodoc/name.rb +19 -0
  269. data/tasks/autodoc/notice.rb +26 -0
  270. data/tasks/autodoc/rbs.rb +38 -0
  271. data/tasks/autodoc/rdoc.rb +45 -0
  272. data/tasks/autodoc.rake +47 -0
  273. data/tasks/bump/history.rb +2 -2
  274. data/tasks/doc.rake +600 -6
  275. data/tasks/example_viewer.html.erb +172 -0
  276. data/tasks/lint.rake +8 -4
  277. data/tasks/resources/build.yml.erb +13 -11
  278. data/tasks/resources/index.html.erb +6 -0
  279. data/tasks/sourcehut.rake +4 -4
  280. data/tasks/terminal_preview/app_screenshot.rb +33 -0
  281. data/tasks/terminal_preview/crash_report.rb +52 -0
  282. data/tasks/terminal_preview/example_app.rb +25 -0
  283. data/tasks/terminal_preview/launcher_script.rb +46 -0
  284. data/tasks/terminal_preview/preview_collection.rb +58 -0
  285. data/tasks/terminal_preview/preview_timing.rb +22 -0
  286. data/tasks/terminal_preview/safety_confirmation.rb +56 -0
  287. data/tasks/terminal_preview/saved_screenshot.rb +53 -0
  288. data/tasks/terminal_preview/system_appearance.rb +11 -0
  289. data/tasks/terminal_preview/terminal_window.rb +136 -0
  290. data/tasks/terminal_preview/window_id.rb +14 -0
  291. data/tasks/terminal_preview.rake +28 -0
  292. data/tasks/test.rake +2 -2
  293. data/tasks/website/index_page.rb +3 -3
  294. data/tasks/website/version.rb +10 -10
  295. data/tasks/website/version_menu.rb +10 -12
  296. data/tasks/website/versioned_documentation.rb +49 -17
  297. data/tasks/website/website.rb +6 -8
  298. data/tasks/website.rake +4 -4
  299. metadata +206 -54
  300. data/LICENSES/BSD-2-Clause.txt +0 -9
  301. data/doc/images/examples-analytics.rb.png +0 -0
  302. data/doc/images/examples-box_demo.rb.png +0 -0
  303. data/doc/images/examples-calendar_demo.rb.png +0 -0
  304. data/doc/images/examples-chart_demo.rb.png +0 -0
  305. data/doc/images/examples-custom_widget.rb.png +0 -0
  306. data/doc/images/examples-dashboard.rb.png +0 -0
  307. data/doc/images/examples-list_styles.rb.png +0 -0
  308. data/doc/images/examples-login_form.rb.png +0 -0
  309. data/doc/images/examples-map_demo.rb.png +0 -0
  310. data/doc/images/examples-mouse_events.rb.png +0 -0
  311. data/doc/images/examples-popup_demo.rb.gif +0 -0
  312. data/doc/images/examples-quickstart_lifecycle.rb.png +0 -0
  313. data/doc/images/examples-scroll_text.rb.png +0 -0
  314. data/doc/images/examples-scrollbar_demo.rb.png +0 -0
  315. data/doc/images/examples-stock_ticker.rb.png +0 -0
  316. data/doc/images/examples-system_monitor.rb.png +0 -0
  317. data/doc/images/examples-table_select.rb.png +0 -0
  318. data/examples/analytics.rb +0 -88
  319. data/examples/box_demo.rb +0 -71
  320. data/examples/calendar_demo.rb +0 -55
  321. data/examples/chart_demo.rb +0 -84
  322. data/examples/custom_widget.rb +0 -43
  323. data/examples/dashboard.rb +0 -72
  324. data/examples/list_styles.rb +0 -66
  325. data/examples/login_form.rb +0 -115
  326. data/examples/map_demo.rb +0 -58
  327. data/examples/mouse_events.rb +0 -95
  328. data/examples/popup_demo.rb +0 -105
  329. data/examples/quickstart_dsl.rb +0 -30
  330. data/examples/quickstart_lifecycle.rb +0 -40
  331. data/examples/readme_usage.rb +0 -21
  332. data/examples/scroll_text.rb +0 -74
  333. data/examples/scrollbar_demo.rb +0 -75
  334. data/examples/stock_ticker.rb +0 -93
  335. data/examples/system_monitor.rb +0 -94
  336. data/examples/table_select.rb +0 -70
  337. data/examples/test_analytics.rb +0 -65
  338. data/examples/test_box_demo.rb +0 -38
  339. data/examples/test_calendar_demo.rb +0 -66
  340. data/examples/test_dashboard.rb +0 -38
  341. data/examples/test_list_styles.rb +0 -61
  342. data/examples/test_login_form.rb +0 -63
  343. data/examples/test_map_demo.rb +0 -100
  344. data/examples/test_popup_demo.rb +0 -62
  345. data/examples/test_scroll_text.rb +0 -130
  346. data/examples/test_stock_ticker.rb +0 -39
  347. data/examples/test_system_monitor.rb +0 -40
  348. data/examples/test_table_select.rb +0 -37
  349. data/ext/ratatui_ruby/src/buffer.rs +0 -54
  350. data/lib/ratatui_ruby/dsl.rb +0 -64
@@ -1,84 +0,0 @@
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
- $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
7
- require "ratatui_ruby"
8
-
9
- # Chart Demo
10
- # Demonstrates Scatter and Line datasets in a single Chart.
11
- class ChartDemoApp
12
- def run
13
- RatatuiRuby.init_terminal
14
- begin
15
- loop do
16
- render
17
- break if handle_input == :quit
18
- sleep 0.1
19
- end
20
- ensure
21
- RatatuiRuby.restore_terminal
22
- end
23
- end
24
-
25
- def render
26
- # Scatter data: Random points
27
- scatter_data = Array.new(20) { [rand(0.0..10.0), rand(-1.0..1.0)] }
28
-
29
- # Line data: Sine wave
30
- line_data = (0..100).map do |i|
31
- x = i / 10.0
32
- [x, Math.sin(x)]
33
- end
34
-
35
- datasets = [
36
- RatatuiRuby::Dataset.new(
37
- name: "Scatter",
38
- data: scatter_data,
39
- color: "red",
40
- marker: :dot,
41
- graph_type: :scatter,
42
- ),
43
- RatatuiRuby::Dataset.new(
44
- name: "Line",
45
- data: line_data,
46
- color: "green",
47
- marker: :braille,
48
- graph_type: :line,
49
- ),
50
- ]
51
-
52
- chart = RatatuiRuby::Chart.new(
53
- datasets:,
54
- x_axis: RatatuiRuby::Axis.new(
55
- title: "Time",
56
- bounds: [0.0, 10.0],
57
- labels: %w[0 5 10],
58
- style: RatatuiRuby::Style.new(fg: :yellow),
59
- ),
60
- y_axis: RatatuiRuby::Axis.new(
61
- title: "Amplitude",
62
- bounds: [-1.0, 1.0],
63
- labels: %w[-1 0 1],
64
- style: RatatuiRuby::Style.new(fg: :cyan),
65
- ),
66
- block: RatatuiRuby::Block.new(
67
- title: "Chart Demo (Q to quit)",
68
- borders: [:all],
69
- ),
70
- )
71
-
72
- RatatuiRuby.draw(chart)
73
- end
74
-
75
- def handle_input
76
- event = RatatuiRuby.poll_event
77
- return nil unless event
78
-
79
- return :quit if event[:type] == :key && event[:code] == "q"
80
- nil
81
- end
82
- end
83
-
84
- ChartDemoApp.new.run if __FILE__ == $PROGRAM_NAME
@@ -1,43 +0,0 @@
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
- $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
7
- require "ratatui_ruby"
8
-
9
- # A custom widget that draws a diagonal line.
10
- class DiagonalWidget
11
- def render(area, buffer)
12
- # Draw a diagonal line within the area
13
- (0..10).each do |i|
14
- next if area.x + i >= area.x + area.width || area.y + i >= area.y + area.height
15
-
16
- buffer.set_string(
17
- area.x + i,
18
- area.y + i,
19
- "\\",
20
- RatatuiRuby::Style.new(fg: :red, modifiers: [:bold])
21
- )
22
- end
23
- end
24
- end
25
-
26
- RatatuiRuby.main_loop do |tui|
27
- tui.draw(
28
- RatatuiRuby::Layout.new(
29
- direction: :vertical,
30
- constraints: [
31
- RatatuiRuby::Constraint.percentage(50),
32
- RatatuiRuby::Constraint.percentage(50),
33
- ],
34
- children: [
35
- RatatuiRuby::Paragraph.new(text: "Above custom widget"),
36
- DiagonalWidget.new,
37
- ]
38
- )
39
- )
40
-
41
- event = RatatuiRuby.poll_event
42
- break if event && event[:type] == :key && event[:code] == "q"
43
- end
@@ -1,72 +0,0 @@
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
- $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
7
- require "ratatui_ruby"
8
-
9
- include RatatuiRuby
10
-
11
- class DashboardApp
12
- include RatatuiRuby
13
-
14
- def initialize
15
- @items = ["Item 1", "Item 2", "Item 3", "Item 4", "Item 5"]
16
- @selected_index = 0
17
- end
18
-
19
- def run
20
- RatatuiRuby.init_terminal
21
- begin
22
- loop do
23
- render
24
- break if handle_input == :quit
25
- end
26
- ensure
27
- RatatuiRuby.restore_terminal
28
- end
29
- end
30
-
31
- def render
32
- selected_item = @items[@selected_index]
33
-
34
- sidebar = List.new(
35
- items: @items,
36
- selected_index: @selected_index,
37
- block: Block.new(title: "Files", borders: [:all])
38
- )
39
-
40
- main_content = Paragraph.new(
41
- text: "You selected: #{selected_item}",
42
- block: Block.new(title: "Content", borders: [:all])
43
- )
44
-
45
- layout = Layout.new(
46
- direction: :horizontal,
47
- constraints: [
48
- Constraint.percentage(30),
49
- Constraint.min(0),
50
- ],
51
- children: [sidebar, main_content]
52
- )
53
-
54
- RatatuiRuby.draw(layout)
55
- end
56
-
57
- def handle_input
58
- event = RatatuiRuby.poll_event
59
- if event
60
- case event[:code]
61
- when "q", "esc"
62
- :quit
63
- when "up"
64
- @selected_index = (@selected_index - 1) % @items.length
65
- when "down"
66
- @selected_index = (@selected_index + 1) % @items.length
67
- end
68
- end
69
- end
70
- end
71
-
72
- DashboardApp.new.run if __FILE__ == $0
@@ -1,66 +0,0 @@
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
- $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
7
- require "ratatui_ruby"
8
-
9
- # Styled List Example
10
- # Demonstrates advanced styling options for the List widget.
11
- class ListStylesApp
12
- attr_reader :selected_index
13
-
14
- def initialize
15
- @items = ["Item 1", "Item 2", "Item 3"]
16
- @selected_index = 0
17
- end
18
-
19
- def run
20
- RatatuiRuby.init_terminal
21
- begin
22
- loop do
23
- render
24
- break if handle_input == :quit
25
- sleep 0.05
26
- end
27
- ensure
28
- RatatuiRuby.restore_terminal
29
- end
30
- end
31
-
32
- def render
33
- RatatuiRuby.draw(
34
- RatatuiRuby::List.new(
35
- items: @items,
36
- selected_index: @selected_index,
37
- style: RatatuiRuby::Style.new(fg: :white, bg: :black),
38
- highlight_style: RatatuiRuby::Style.new(fg: :blue, bg: :white, modifiers: [:bold]),
39
- highlight_symbol: ">> ",
40
- block: RatatuiRuby::Block.new(
41
- title: "Styled List (Up/Down to move, Q to quit)",
42
- borders: [:all]
43
- )
44
- )
45
- )
46
- end
47
-
48
- def handle_input
49
- event = RatatuiRuby.poll_event
50
- return nil unless event
51
-
52
- if event[:type] == :key
53
- case event[:code]
54
- when "up"
55
- @selected_index = (@selected_index - 1) % @items.size
56
- when "down"
57
- @selected_index = (@selected_index + 1) % @items.size
58
- when "q"
59
- return :quit
60
- end
61
- end
62
- nil
63
- end
64
- end
65
-
66
- ListStylesApp.new.run if __FILE__ == $PROGRAM_NAME
@@ -1,115 +0,0 @@
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
- $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
7
- require "ratatui_ruby"
8
-
9
- class LoginFormApp
10
- PREFIX = "Enter Username: [ "
11
- SUFFIX = " ]"
12
-
13
- def initialize
14
- @username = ""
15
- @show_popup = false
16
- end
17
-
18
- def run
19
- RatatuiRuby.init_terminal
20
- begin
21
- loop do
22
- render
23
- break if handle_input == :quit
24
- end
25
- ensure
26
- RatatuiRuby.restore_terminal
27
- end
28
- end
29
-
30
- def render
31
- # 1. Base Layer Construction
32
- # We want a cursor relative to the paragraph.
33
- # So we wrap Paragraph and Cursor in an Overlay, and put that Overlay in a Center.
34
-
35
- # Calculate cursor position
36
- # Border takes 1 cell.
37
- # Cursor X = 1 (border) + PREFIX.length + username.length
38
- # Cursor Y = 1 (border + line 0)
39
- cursor_x = 1 + PREFIX.length + @username.length
40
- cursor_y = 1
41
-
42
- # The content of the base form
43
- form_content = RatatuiRuby::Overlay.new(layers: [
44
- RatatuiRuby::Paragraph.new(
45
- text: "#{PREFIX}#{@username}#{SUFFIX}",
46
- block: RatatuiRuby::Block.new(borders: :all, title: "Login Form"),
47
- align: :left
48
- ),
49
- RatatuiRuby::Cursor.new(x: cursor_x, y: cursor_y),
50
- ])
51
-
52
- # Center the form on screen
53
- base_layer = RatatuiRuby::Center.new(
54
- child: form_content,
55
- width_percent: 50,
56
- height_percent: 20
57
- )
58
-
59
- # 2. Popup Layer Construction
60
- final_view = if @show_popup
61
- popup_message = RatatuiRuby::Center.new(
62
- child: RatatuiRuby::Paragraph.new(
63
- text: "Login Successful!\nPress 'q' to quit.",
64
- style: RatatuiRuby::Style.new(fg: :green, bg: :black),
65
- block: RatatuiRuby::Block.new(borders: :all),
66
- align: :center,
67
- wrap: true
68
- ),
69
- width_percent: 30,
70
- height_percent: 20
71
- )
72
-
73
- # Render Base Layer (background) THEN Popup Layer
74
- RatatuiRuby::Overlay.new(layers: [base_layer, popup_message])
75
- else
76
- base_layer
77
- end
78
-
79
- # 3. Draw
80
- RatatuiRuby.draw(final_view)
81
- end
82
-
83
- def handle_input
84
- # 4. Event Handling
85
- event = RatatuiRuby.poll_event
86
- return unless event
87
-
88
- if event[:type] == :key
89
- if @show_popup
90
- # If popup is shown, any key (or specifically q) quits?
91
- # "The Center widget contains a Green Box saying 'Login Successful! Press q.'"
92
- if event[:code] == "q"
93
- :quit
94
- end
95
- else
96
- # Login Form Input
97
- case event[:code]
98
- when "enter"
99
- @show_popup = true
100
- when "backspace"
101
- @username.chop!
102
- when "esc"
103
- :quit
104
- else
105
- # Simple text input
106
- if event[:code].length == 1
107
- @username += event[:code]
108
- end
109
- end
110
- end
111
- end
112
- end
113
- end
114
-
115
- LoginFormApp.new.run if __FILE__ == $0
data/examples/map_demo.rb DELETED
@@ -1,58 +0,0 @@
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
- $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
7
- require "ratatui_ruby"
8
-
9
- # An example of the Canvas widget showing a world map and animated shapes.
10
- module MapDemo
11
- include RatatuiRuby
12
-
13
- # Returns a Canvas view for the map demo with the given circle radius.
14
- #
15
- # +radius+:: The radius of the animated circle.
16
- def self.view(radius)
17
- Canvas.new(
18
- shapes: [
19
- Map.new(color: :green, resolution: :high),
20
- Circle.new(x: 0.0, y: 0.0, radius:, color: :red),
21
- Line.new(x1: 0.0, y1: 0.0, x2: 50.0, y2: 25.0, color: :yellow),
22
- ],
23
- x_bounds: [-180.0, 180.0],
24
- y_bounds: [-90.0, 90.0],
25
- marker: :braille,
26
- block: Block.new(title: "World Map Canvas", borders: :all)
27
- )
28
- end
29
-
30
- # Runs the map demo loop.
31
- def self.run
32
- RatatuiRuby.init_terminal
33
- radius = 0.0
34
- direction = 1
35
-
36
- loop do
37
- # Animate the circle radius
38
- radius += 0.5 * direction
39
- if radius > 10.0 || radius < 0.0
40
- direction *= -1
41
- end
42
-
43
- # Define the view
44
- view = view(radius)
45
-
46
- RatatuiRuby.draw(view)
47
-
48
- event = RatatuiRuby.poll_event
49
- break if event && event[:type] == :key && event[:code] == "q"
50
-
51
- sleep 0.05
52
- end
53
- ensure
54
- RatatuiRuby.restore_terminal
55
- end
56
- end
57
-
58
- MapDemo.run if __FILE__ == $PROGRAM_NAME
@@ -1,95 +0,0 @@
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
- $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
7
- require "ratatui_ruby"
8
-
9
- class MouseEventsApp
10
- def initialize
11
- @message = "Waiting for Mouse... (q to quit)"
12
- @details = ""
13
- @color = "white"
14
- end
15
-
16
- def run
17
- RatatuiRuby.init_terminal
18
- begin
19
- loop do
20
- render
21
- break if handle_input == :quit
22
- end
23
- ensure
24
- RatatuiRuby.restore_terminal
25
- end
26
- end
27
-
28
- def render
29
- # Create a centered block with the mouse event details
30
- block = RatatuiRuby::Block.new(
31
- title: "Mouse Event Plumbing",
32
- borders: [:all],
33
- border_color: @color
34
- )
35
-
36
- content = RatatuiRuby::Paragraph.new(
37
- text: "#{@message}\n#{@details}",
38
- align: :center,
39
- block:
40
- )
41
-
42
- # Use a layout to center the content
43
- layout = RatatuiRuby::Layout.new(
44
- direction: :vertical,
45
- constraints: [
46
- RatatuiRuby::Constraint.percentage(25),
47
- RatatuiRuby::Constraint.percentage(50),
48
- RatatuiRuby::Constraint.percentage(25),
49
- ],
50
- children: [
51
- RatatuiRuby::Paragraph.new(text: ""),
52
- content,
53
- RatatuiRuby::Paragraph.new(text: ""),
54
- ]
55
- )
56
-
57
- RatatuiRuby.draw(layout)
58
- end
59
-
60
- def handle_input
61
- event = RatatuiRuby.poll_event
62
- return unless event
63
-
64
- if event[:type] == :key && event[:code] == "q"
65
- return :quit
66
- end
67
-
68
- if event[:type] == :mouse
69
- @color = "green"
70
- case event[:kind]
71
- when :down
72
- @message = "#{event[:button].to_s.capitalize} Click at [#{event[:x]}, #{event[:y]}]"
73
- @details = "Modifiers: #{event[:modifiers].join(', ')}"
74
- when :up
75
- @message = "#{event[:button].to_s.capitalize} Release at [#{event[:x]}, #{event[:y]}]"
76
- @details = "Modifiers: #{event[:modifiers].join(', ')}"
77
- when :drag
78
- @message = "Dragging #{event[:button].to_s.capitalize} Button at [#{event[:x]}, #{event[:y]}]"
79
- @details = "Modifiers: #{event[:modifiers].join(', ')}"
80
- when :moved
81
- @message = "Mouse Moved to [#{event[:x]}, #{event[:y]}]"
82
- @details = "Modifiers: #{event[:modifiers].join(', ')}"
83
- when :scroll_down
84
- @message = "Scrolled Down"
85
- @details = "Position: [#{event[:x]}, #{event[:y]}]"
86
- when :scroll_up
87
- @message = "Scrolled Up"
88
- @details = "Position: [#{event[:x]}, #{event[:y]}]"
89
- end
90
- end
91
- nil
92
- end
93
- end
94
-
95
- MouseEventsApp.new.run if __FILE__ == $0
@@ -1,105 +0,0 @@
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
- $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
7
- require "ratatui_ruby"
8
-
9
- # Popup Demo Example
10
- # Demonstrates the Clear widget for creating opaque popups.
11
-
12
- class PopupDemo
13
- def initialize
14
- @clear_enabled = false
15
- end
16
-
17
- def run
18
- RatatuiRuby.init_terminal
19
- begin
20
- loop do
21
- render
22
- break if handle_input == :quit
23
- sleep 0.05
24
- end
25
- ensure
26
- RatatuiRuby.restore_terminal
27
- end
28
- end
29
-
30
- def render
31
- # 1. Background: Loud Red Background
32
- # This demonstrates "Style Bleed" where the background color persists
33
- # unless explicitly cleared or overwritten.
34
- background = RatatuiRuby::Paragraph.new(
35
- text: "BACKGROUND RED " * 100,
36
- style: RatatuiRuby::Style.new(bg: :red, fg: :white),
37
- wrap: true
38
- )
39
-
40
- # 2. Popup Content: No specific background set (Style.default)
41
- # Without Clear, this will "inherit" the red background from underneath.
42
- popup_text = if @clear_enabled
43
- "✓ Clear is ENABLED\n\nResets background to default\n(Usually Black/Transparent)\n\nPress Space to toggle"
44
- else
45
- "✗ Clear is DISABLED\n\nStyle Bleed: Popup is RED!\n(Inherits background style)\n\nPress Space to toggle"
46
- end
47
-
48
- popup_content = RatatuiRuby::Paragraph.new(
49
- text: popup_text,
50
- align: :center,
51
- block: RatatuiRuby::Block.new(
52
- title: "Popup Demo (Press 'q' to quit)",
53
- borders: [:all]
54
- )
55
- )
56
-
57
- # Build the UI with or without Clear
58
- if @clear_enabled
59
- # With Clear: Resets the style in the popup area before rendering content
60
- ui = RatatuiRuby::Overlay.new(
61
- layers: [
62
- background,
63
- RatatuiRuby::Center.new(
64
- child: RatatuiRuby::Overlay.new(
65
- layers: [
66
- RatatuiRuby::Clear.new,
67
- popup_content
68
- ]
69
- ),
70
- width_percent: 60,
71
- height_percent: 50
72
- )
73
- ]
74
- )
75
- else
76
- # Without Clear: Background style (RED) bleeds through the popup
77
- ui = RatatuiRuby::Overlay.new(
78
- layers: [
79
- background,
80
- RatatuiRuby::Center.new(
81
- child: popup_content,
82
- width_percent: 60,
83
- height_percent: 50
84
- )
85
- ]
86
- )
87
- end
88
-
89
- RatatuiRuby.draw(ui)
90
- end
91
-
92
- def handle_input
93
- event = RatatuiRuby.poll_event
94
- if event
95
- case event[:code]
96
- when "q"
97
- :quit
98
- when " "
99
- @clear_enabled = !@clear_enabled
100
- end
101
- end
102
- end
103
- end
104
-
105
- PopupDemo.new.run if __FILE__ == $0
@@ -1,30 +0,0 @@
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
- $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
7
-
8
- require "ratatui_ruby"
9
-
10
- # 1. Initialize the terminal, start the main loop, and ensure the terminal is restored.
11
- RatatuiRuby.main_loop do |tui|
12
- # 2. Create your UI with methods instead of classes.
13
- view = tui.paragraph(
14
- text: "Hello, Ratatui! Press 'q' to quit.",
15
- align: :center,
16
- block: tui.block(
17
- title: "My Ruby TUI App",
18
- borders: [:all],
19
- border_color: "cyan"
20
- )
21
- )
22
-
23
- # 3. Use RatatuiRuby methods, too.
24
- tui.draw(view)
25
- event = tui.poll_event
26
-
27
- if event && event[:type] == :key && event[:code] == "q"
28
- break
29
- end
30
- end
@@ -1,40 +0,0 @@
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
- $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
7
-
8
- require "ratatui_ruby"
9
-
10
- # 1. Initialize the terminal
11
- RatatuiRuby.init_terminal
12
-
13
- begin
14
- # The Main Loop
15
- loop do
16
- # 2. Create your UI (Immediate Mode)
17
- # We define a Paragraph widget inside a Block with a title and borders.
18
- view = RatatuiRuby::Paragraph.new(
19
- text: "Hello, Ratatui! Press 'q' to quit.",
20
- align: :center,
21
- block: RatatuiRuby::Block.new(
22
- title: "My Ruby TUI App",
23
- borders: [:all],
24
- border_color: "cyan"
25
- )
26
- )
27
-
28
- # 3. Draw the UI
29
- RatatuiRuby.draw(view)
30
-
31
- # 4. Poll for events
32
- event = RatatuiRuby.poll_event
33
- if event && event[:type] == :key && event[:code] == "q"
34
- break
35
- end
36
- end
37
- ensure
38
- # 5. Restore the terminal to its original state
39
- RatatuiRuby.restore_terminal
40
- end