ratatui_ruby 0.4.0 → 0.6.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 (441) 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 +98 -176
  7. data/CHANGELOG.md +80 -6
  8. data/README.md +19 -7
  9. data/REUSE.toml +15 -0
  10. data/doc/application_architecture.md +179 -45
  11. data/doc/application_testing.md +80 -32
  12. data/doc/contributors/design/ruby_frontend.md +48 -8
  13. data/doc/contributors/design/rust_backend.md +1 -0
  14. data/doc/contributors/developing_examples.md +191 -48
  15. data/doc/contributors/documentation_style.md +7 -0
  16. data/doc/contributors/examples_audit/p1_high.md +21 -0
  17. data/doc/contributors/examples_audit/p2_moderate.md +81 -0
  18. data/doc/contributors/examples_audit.md +41 -0
  19. data/doc/contributors/index.md +2 -0
  20. data/doc/event_handling.md +21 -7
  21. data/doc/images/app_all_events.png +0 -0
  22. data/doc/images/app_color_picker.png +0 -0
  23. data/doc/images/app_login_form.png +0 -0
  24. data/doc/images/app_stateful_interaction.png +0 -0
  25. data/doc/images/verify_quickstart_dsl.png +0 -0
  26. data/doc/images/verify_quickstart_layout.png +0 -0
  27. data/doc/images/verify_quickstart_lifecycle.png +0 -0
  28. data/doc/images/verify_readme_usage.png +0 -0
  29. data/doc/images/widget_barchart_demo.png +0 -0
  30. data/doc/images/widget_block_demo.png +0 -0
  31. data/doc/images/widget_box_demo.png +0 -0
  32. data/doc/images/widget_calendar_demo.png +0 -0
  33. data/doc/images/widget_canvas_demo.png +0 -0
  34. data/doc/images/widget_cell_demo.png +0 -0
  35. data/doc/images/widget_center_demo.png +0 -0
  36. data/doc/images/widget_chart_demo.png +0 -0
  37. data/doc/images/widget_gauge_demo.png +0 -0
  38. data/doc/images/widget_layout_split.png +0 -0
  39. data/doc/images/widget_line_gauge_demo.png +0 -0
  40. data/doc/images/widget_list_demo.png +0 -0
  41. data/doc/images/widget_overlay_demo.png +0 -0
  42. data/doc/images/widget_ratatui_logo_demo.png +0 -0
  43. data/doc/images/widget_ratatui_mascot_demo.png +0 -0
  44. data/doc/images/widget_render.png +0 -0
  45. data/doc/images/widget_rich_text.png +0 -0
  46. data/doc/images/widget_scroll_text.png +0 -0
  47. data/doc/images/widget_scrollbar_demo.png +0 -0
  48. data/doc/images/widget_sparkline_demo.png +0 -0
  49. data/doc/images/widget_style_colors.png +0 -0
  50. data/doc/images/widget_table_demo.png +0 -0
  51. data/doc/images/widget_table_flex.png +0 -0
  52. data/doc/images/widget_tabs_demo.png +0 -0
  53. data/doc/images/widget_text_width.png +0 -0
  54. data/doc/interactive_design.md +25 -30
  55. data/doc/quickstart.md +150 -130
  56. data/doc/terminal_limitations.md +92 -0
  57. data/examples/app_all_events/README.md +99 -0
  58. data/examples/app_all_events/app.rb +96 -0
  59. data/examples/app_all_events/model/app_model.rb +157 -0
  60. data/examples/app_all_events/model/event_color_cycle.rb +41 -0
  61. data/examples/app_all_events/model/event_entry.rb +92 -0
  62. data/examples/app_all_events/model/msg.rb +37 -0
  63. data/examples/app_all_events/model/timestamp.rb +54 -0
  64. data/examples/app_all_events/update.rb +73 -0
  65. data/examples/app_all_events/view/app_view.rb +78 -0
  66. data/examples/app_all_events/view/controls_view.rb +52 -0
  67. data/examples/app_all_events/view/counts_view.rb +59 -0
  68. data/examples/app_all_events/view/live_view.rb +70 -0
  69. data/examples/app_all_events/view/log_view.rb +55 -0
  70. data/examples/app_all_events/view.rb +7 -0
  71. data/examples/app_color_picker/README.md +134 -0
  72. data/examples/app_color_picker/app.rb +74 -0
  73. data/examples/app_color_picker/clipboard.rb +84 -0
  74. data/examples/app_color_picker/color.rb +191 -0
  75. data/examples/app_color_picker/controls.rb +90 -0
  76. data/examples/app_color_picker/copy_dialog.rb +166 -0
  77. data/examples/app_color_picker/export_pane.rb +126 -0
  78. data/examples/app_color_picker/harmony.rb +56 -0
  79. data/examples/app_color_picker/input.rb +174 -0
  80. data/examples/app_color_picker/main_container.rb +178 -0
  81. data/examples/app_color_picker/palette.rb +109 -0
  82. data/examples/app_login_form/README.md +47 -0
  83. data/examples/{login_form → app_login_form}/app.rb +38 -42
  84. data/examples/app_stateful_interaction/README.md +31 -0
  85. data/examples/app_stateful_interaction/app.rb +272 -0
  86. data/examples/timeout_demo.rb +43 -0
  87. data/examples/verify_quickstart_dsl/README.md +48 -0
  88. data/examples/{quickstart_dsl → verify_quickstart_dsl}/app.rb +17 -6
  89. data/examples/verify_quickstart_layout/README.md +71 -0
  90. data/examples/verify_quickstart_layout/app.rb +71 -0
  91. data/examples/verify_quickstart_lifecycle/README.md +56 -0
  92. data/examples/verify_quickstart_lifecycle/app.rb +54 -0
  93. data/examples/verify_readme_usage/README.md +43 -0
  94. data/examples/verify_readme_usage/app.rb +40 -0
  95. data/examples/widget_barchart_demo/README.md +49 -0
  96. data/examples/widget_barchart_demo/app.rb +238 -0
  97. data/examples/widget_block_demo/README.md +34 -0
  98. data/examples/widget_block_demo/app.rb +256 -0
  99. data/examples/widget_box_demo/README.md +45 -0
  100. data/examples/{box_demo → widget_box_demo}/app.rb +99 -65
  101. data/examples/widget_calendar_demo/README.md +39 -0
  102. data/examples/widget_calendar_demo/app.rb +109 -0
  103. data/examples/widget_canvas_demo/README.md +27 -0
  104. data/examples/widget_canvas_demo/app.rb +123 -0
  105. data/examples/widget_cell_demo/README.md +36 -0
  106. data/examples/widget_cell_demo/app.rb +111 -0
  107. data/examples/widget_center_demo/README.md +29 -0
  108. data/examples/widget_center_demo/app.rb +116 -0
  109. data/examples/widget_chart_demo/README.md +41 -0
  110. data/examples/widget_chart_demo/app.rb +218 -0
  111. data/examples/widget_gauge_demo/README.md +41 -0
  112. data/examples/widget_gauge_demo/app.rb +212 -0
  113. data/examples/widget_layout_split/README.md +44 -0
  114. data/examples/widget_layout_split/app.rb +246 -0
  115. data/examples/widget_line_gauge_demo/README.md +41 -0
  116. data/examples/widget_line_gauge_demo/app.rb +217 -0
  117. data/examples/widget_list_demo/README.md +49 -0
  118. data/examples/widget_list_demo/app.rb +366 -0
  119. data/examples/widget_map_demo/README.md +39 -0
  120. data/examples/{map_demo → widget_map_demo}/app.rb +24 -21
  121. data/examples/widget_overlay_demo/app.rb +248 -0
  122. data/examples/widget_popup_demo/README.md +36 -0
  123. data/examples/widget_popup_demo/app.rb +104 -0
  124. data/examples/widget_ratatui_logo_demo/README.md +34 -0
  125. data/examples/widget_ratatui_logo_demo/app.rb +103 -0
  126. data/examples/widget_ratatui_mascot_demo/README.md +34 -0
  127. data/examples/widget_ratatui_mascot_demo/app.rb +93 -0
  128. data/examples/widget_rect/README.md +38 -0
  129. data/examples/widget_rect/app.rb +205 -0
  130. data/examples/widget_render/README.md +37 -0
  131. data/examples/widget_render/app.rb +184 -0
  132. data/examples/widget_rich_text/README.md +35 -0
  133. data/examples/widget_rich_text/app.rb +166 -0
  134. data/examples/widget_scroll_text/README.md +37 -0
  135. data/examples/widget_scroll_text/app.rb +107 -0
  136. data/examples/widget_scrollbar_demo/README.md +37 -0
  137. data/examples/widget_scrollbar_demo/app.rb +153 -0
  138. data/examples/widget_sparkline_demo/README.md +42 -0
  139. data/examples/widget_sparkline_demo/app.rb +275 -0
  140. data/examples/widget_style_colors/README.md +34 -0
  141. data/examples/widget_style_colors/app.rb +19 -21
  142. data/examples/widget_table_demo/README.md +48 -0
  143. data/examples/widget_table_demo/app.rb +239 -0
  144. data/examples/widget_tabs_demo/README.md +41 -0
  145. data/examples/widget_tabs_demo/app.rb +181 -0
  146. data/examples/widget_text_width/README.md +35 -0
  147. data/examples/widget_text_width/app.rb +106 -0
  148. data/ext/ratatui_ruby/Cargo.lock +11 -4
  149. data/ext/ratatui_ruby/Cargo.toml +2 -1
  150. data/ext/ratatui_ruby/src/events.rs +359 -62
  151. data/ext/ratatui_ruby/src/frame.rs +227 -0
  152. data/ext/ratatui_ruby/src/lib.rs +110 -27
  153. data/ext/ratatui_ruby/src/rendering.rs +8 -4
  154. data/ext/ratatui_ruby/src/string_width.rs +101 -0
  155. data/ext/ratatui_ruby/src/style.rs +138 -57
  156. data/ext/ratatui_ruby/src/terminal.rs +42 -22
  157. data/ext/ratatui_ruby/src/text.rs +14 -7
  158. data/ext/ratatui_ruby/src/widgets/barchart.rs +74 -54
  159. data/ext/ratatui_ruby/src/widgets/block.rs +7 -6
  160. data/ext/ratatui_ruby/src/widgets/canvas.rs +21 -3
  161. data/ext/ratatui_ruby/src/widgets/chart.rs +20 -10
  162. data/ext/ratatui_ruby/src/widgets/gauge.rs +9 -2
  163. data/ext/ratatui_ruby/src/widgets/layout.rs +9 -4
  164. data/ext/ratatui_ruby/src/widgets/line_gauge.rs +9 -2
  165. data/ext/ratatui_ruby/src/widgets/list.rs +211 -12
  166. data/ext/ratatui_ruby/src/widgets/list_state.rs +137 -0
  167. data/ext/ratatui_ruby/src/widgets/mod.rs +3 -0
  168. data/ext/ratatui_ruby/src/widgets/overlay.rs +2 -1
  169. data/ext/ratatui_ruby/src/widgets/paragraph.rs +1 -1
  170. data/ext/ratatui_ruby/src/widgets/ratatui_logo.rs +19 -8
  171. data/ext/ratatui_ruby/src/widgets/ratatui_mascot.rs +17 -10
  172. data/ext/ratatui_ruby/src/widgets/scrollbar.rs +97 -3
  173. data/ext/ratatui_ruby/src/widgets/scrollbar_state.rs +169 -0
  174. data/ext/ratatui_ruby/src/widgets/sparkline.rs +14 -11
  175. data/ext/ratatui_ruby/src/widgets/table.rs +121 -5
  176. data/ext/ratatui_ruby/src/widgets/table_state.rs +121 -0
  177. data/ext/ratatui_ruby/src/widgets/tabs.rs +11 -11
  178. data/lib/ratatui_ruby/cell.rb +7 -7
  179. data/lib/ratatui_ruby/event/key/character.rb +35 -0
  180. data/lib/ratatui_ruby/event/key/media.rb +44 -0
  181. data/lib/ratatui_ruby/event/key/modifier.rb +95 -0
  182. data/lib/ratatui_ruby/event/key/navigation.rb +55 -0
  183. data/lib/ratatui_ruby/event/key/system.rb +45 -0
  184. data/lib/ratatui_ruby/event/key.rb +112 -52
  185. data/lib/ratatui_ruby/event/mouse.rb +3 -3
  186. data/lib/ratatui_ruby/event/none.rb +43 -0
  187. data/lib/ratatui_ruby/event/paste.rb +1 -1
  188. data/lib/ratatui_ruby/event.rb +56 -4
  189. data/lib/ratatui_ruby/frame.rb +183 -0
  190. data/lib/ratatui_ruby/list_state.rb +88 -0
  191. data/lib/ratatui_ruby/schema/bar_chart/bar.rb +13 -13
  192. data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +1 -5
  193. data/lib/ratatui_ruby/schema/bar_chart.rb +217 -217
  194. data/lib/ratatui_ruby/schema/block.rb +163 -168
  195. data/lib/ratatui_ruby/schema/calendar.rb +66 -67
  196. data/lib/ratatui_ruby/schema/canvas.rb +63 -63
  197. data/lib/ratatui_ruby/schema/center.rb +46 -46
  198. data/lib/ratatui_ruby/schema/chart.rb +135 -143
  199. data/lib/ratatui_ruby/schema/clear.rb +42 -42
  200. data/lib/ratatui_ruby/schema/constraint.rb +76 -76
  201. data/lib/ratatui_ruby/schema/cursor.rb +30 -25
  202. data/lib/ratatui_ruby/schema/gauge.rb +54 -52
  203. data/lib/ratatui_ruby/schema/layout.rb +87 -87
  204. data/lib/ratatui_ruby/schema/line_gauge.rb +62 -62
  205. data/lib/ratatui_ruby/schema/list.rb +103 -80
  206. data/lib/ratatui_ruby/schema/list_item.rb +41 -0
  207. data/lib/ratatui_ruby/schema/overlay.rb +31 -31
  208. data/lib/ratatui_ruby/schema/paragraph.rb +80 -80
  209. data/lib/ratatui_ruby/schema/ratatui_logo.rb +10 -6
  210. data/lib/ratatui_ruby/schema/ratatui_mascot.rb +10 -5
  211. data/lib/ratatui_ruby/schema/rect.rb +99 -56
  212. data/lib/ratatui_ruby/schema/scrollbar.rb +119 -119
  213. data/lib/ratatui_ruby/schema/shape/label.rb +1 -1
  214. data/lib/ratatui_ruby/schema/sparkline.rb +111 -110
  215. data/lib/ratatui_ruby/schema/style.rb +66 -46
  216. data/lib/ratatui_ruby/schema/table.rb +126 -115
  217. data/lib/ratatui_ruby/schema/tabs.rb +66 -67
  218. data/lib/ratatui_ruby/schema/text.rb +69 -1
  219. data/lib/ratatui_ruby/scrollbar_state.rb +112 -0
  220. data/lib/ratatui_ruby/session/autodoc.rb +482 -0
  221. data/lib/ratatui_ruby/session.rb +55 -23
  222. data/lib/ratatui_ruby/table_state.rb +90 -0
  223. data/lib/ratatui_ruby/test_helper/event_injection.rb +169 -0
  224. data/lib/ratatui_ruby/test_helper/snapshot.rb +390 -0
  225. data/lib/ratatui_ruby/test_helper/style_assertions.rb +351 -0
  226. data/lib/ratatui_ruby/test_helper/terminal.rb +127 -0
  227. data/lib/ratatui_ruby/test_helper/test_doubles.rb +68 -0
  228. data/lib/ratatui_ruby/test_helper.rb +66 -193
  229. data/lib/ratatui_ruby/version.rb +1 -1
  230. data/lib/ratatui_ruby.rb +100 -51
  231. data/{examples/sparkline_demo → sig/examples/app_all_events}/app.rbs +3 -2
  232. data/sig/examples/app_all_events/model/event_entry.rbs +16 -0
  233. data/sig/examples/app_all_events/model/events.rbs +15 -0
  234. data/sig/examples/app_all_events/model/timestamp.rbs +11 -0
  235. data/sig/examples/app_all_events/view/app_view.rbs +8 -0
  236. data/sig/examples/app_all_events/view/controls_view.rbs +6 -0
  237. data/sig/examples/app_all_events/view/counts_view.rbs +6 -0
  238. data/sig/examples/app_all_events/view/live_view.rbs +6 -0
  239. data/sig/examples/app_all_events/view/log_view.rbs +6 -0
  240. data/sig/examples/app_all_events/view.rbs +8 -0
  241. data/sig/examples/app_all_events/view_state.rbs +15 -0
  242. data/{examples/list_demo → sig/examples/app_color_picker}/app.rbs +2 -2
  243. data/sig/examples/app_login_form/app.rbs +11 -0
  244. data/sig/examples/app_stateful_interaction/app.rbs +33 -0
  245. data/sig/examples/verify_quickstart_dsl/app.rbs +11 -0
  246. data/sig/examples/verify_quickstart_lifecycle/app.rbs +11 -0
  247. data/sig/examples/verify_readme_usage/app.rbs +11 -0
  248. data/sig/examples/widget_block_demo/app.rbs +32 -0
  249. data/sig/examples/widget_box_demo/app.rbs +11 -0
  250. data/sig/examples/widget_calendar_demo/app.rbs +11 -0
  251. data/sig/examples/widget_cell_demo/app.rbs +11 -0
  252. data/sig/examples/widget_chart_demo/app.rbs +11 -0
  253. data/{examples/gauge_demo → sig/examples/widget_gauge_demo}/app.rbs +4 -0
  254. data/sig/examples/widget_layout_split/app.rbs +10 -0
  255. data/sig/examples/widget_line_gauge_demo/app.rbs +11 -0
  256. data/sig/examples/widget_list_demo/app.rbs +12 -0
  257. data/sig/examples/widget_map_demo/app.rbs +11 -0
  258. data/sig/examples/widget_popup_demo/app.rbs +11 -0
  259. data/sig/examples/widget_ratatui_logo_demo/app.rbs +11 -0
  260. data/sig/examples/widget_ratatui_mascot_demo/app.rbs +11 -0
  261. data/sig/examples/widget_rect/app.rbs +12 -0
  262. data/sig/examples/widget_render/app.rbs +10 -0
  263. data/sig/examples/widget_rich_text/app.rbs +11 -0
  264. data/sig/examples/widget_scroll_text/app.rbs +11 -0
  265. data/sig/examples/widget_scrollbar_demo/app.rbs +11 -0
  266. data/sig/examples/widget_sparkline_demo/app.rbs +10 -0
  267. data/{examples → sig/examples}/widget_style_colors/app.rbs +1 -1
  268. data/sig/examples/widget_table_demo/app.rbs +11 -0
  269. data/sig/examples/widget_text_width/app.rbs +10 -0
  270. data/sig/ratatui_ruby/event.rbs +11 -1
  271. data/sig/ratatui_ruby/frame.rbs +11 -0
  272. data/sig/ratatui_ruby/list_state.rbs +13 -0
  273. data/sig/ratatui_ruby/ratatui_ruby.rbs +5 -4
  274. data/sig/ratatui_ruby/schema/bar_chart/bar.rbs +3 -3
  275. data/sig/ratatui_ruby/schema/draw.rbs +4 -0
  276. data/sig/ratatui_ruby/schema/gauge.rbs +2 -2
  277. data/sig/ratatui_ruby/schema/layout.rbs +1 -1
  278. data/sig/ratatui_ruby/schema/line_gauge.rbs +2 -2
  279. data/sig/ratatui_ruby/schema/list.rbs +4 -2
  280. data/sig/ratatui_ruby/schema/list_item.rbs +10 -0
  281. data/sig/ratatui_ruby/schema/rect.rbs +3 -0
  282. data/sig/ratatui_ruby/schema/style.rbs +3 -3
  283. data/sig/ratatui_ruby/schema/table.rbs +3 -1
  284. data/sig/ratatui_ruby/schema/text.rbs +8 -6
  285. data/sig/ratatui_ruby/scrollbar_state.rbs +18 -0
  286. data/sig/ratatui_ruby/session.rbs +107 -0
  287. data/sig/ratatui_ruby/table_state.rbs +15 -0
  288. data/sig/ratatui_ruby/test_helper/event_injection.rbs +16 -0
  289. data/sig/ratatui_ruby/test_helper/snapshot.rbs +12 -0
  290. data/sig/ratatui_ruby/test_helper/style_assertions.rbs +64 -0
  291. data/sig/ratatui_ruby/test_helper/terminal.rbs +14 -0
  292. data/sig/ratatui_ruby/test_helper/test_doubles.rbs +22 -0
  293. data/sig/ratatui_ruby/test_helper.rbs +5 -4
  294. data/tasks/autodoc/examples.rb +79 -0
  295. data/tasks/autodoc/inventory.rb +63 -0
  296. data/tasks/autodoc/member.rb +56 -0
  297. data/tasks/autodoc/name.rb +19 -0
  298. data/tasks/autodoc/notice.rb +26 -0
  299. data/tasks/autodoc/rbs.rb +38 -0
  300. data/tasks/autodoc/rdoc.rb +45 -0
  301. data/tasks/autodoc.rake +53 -0
  302. data/tasks/bump/changelog.rb +3 -3
  303. data/tasks/bump/history.rb +2 -2
  304. data/tasks/bump/links.rb +67 -0
  305. data/tasks/doc.rake +600 -6
  306. data/tasks/example_viewer.html.erb +172 -0
  307. data/tasks/lint.rake +8 -4
  308. data/tasks/resources/index.html.erb +6 -0
  309. data/tasks/sourcehut.rake +70 -30
  310. data/tasks/terminal_preview/app_screenshot.rb +14 -6
  311. data/tasks/terminal_preview/crash_report.rb +7 -9
  312. data/tasks/terminal_preview/launcher_script.rb +4 -6
  313. data/tasks/terminal_preview/preview_collection.rb +4 -6
  314. data/tasks/terminal_preview/safety_confirmation.rb +3 -5
  315. data/tasks/terminal_preview/saved_screenshot.rb +10 -11
  316. data/tasks/terminal_preview/terminal_window.rb +7 -9
  317. data/tasks/test.rake +1 -1
  318. data/tasks/website/index_page.rb +3 -3
  319. data/tasks/website/version.rb +10 -10
  320. data/tasks/website/version_menu.rb +10 -12
  321. data/tasks/website/versioned_documentation.rb +49 -17
  322. data/tasks/website/website.rb +6 -8
  323. data/tasks/website.rake +4 -4
  324. metadata +232 -127
  325. data/LICENSES/BSD-2-Clause.txt +0 -9
  326. data/doc/contributors/better_dx.md +0 -543
  327. data/doc/contributors/example_analysis.md +0 -82
  328. data/doc/images/all_events.png +0 -0
  329. data/doc/images/block_padding.png +0 -0
  330. data/doc/images/block_titles.png +0 -0
  331. data/doc/images/box_demo.png +0 -0
  332. data/doc/images/calendar_demo.png +0 -0
  333. data/doc/images/cell_demo.png +0 -0
  334. data/doc/images/chart_demo.png +0 -0
  335. data/doc/images/flex_layout.png +0 -0
  336. data/doc/images/gauge_demo.png +0 -0
  337. data/doc/images/line_gauge_demo.png +0 -0
  338. data/doc/images/list_demo.png +0 -0
  339. data/doc/images/list_styles.png +0 -0
  340. data/doc/images/login_form.png +0 -0
  341. data/doc/images/quickstart_dsl.png +0 -0
  342. data/doc/images/quickstart_lifecycle.png +0 -0
  343. data/doc/images/readme_usage.png +0 -0
  344. data/doc/images/rich_text.png +0 -0
  345. data/doc/images/scroll_text.png +0 -0
  346. data/doc/images/scrollbar_demo.png +0 -0
  347. data/doc/images/sparkline_demo.png +0 -0
  348. data/doc/images/table_flex.png +0 -0
  349. data/doc/images/table_select.png +0 -0
  350. data/examples/all_events/app.rb +0 -169
  351. data/examples/all_events/app.rbs +0 -7
  352. data/examples/all_events/test_app.rb +0 -139
  353. data/examples/analytics/app.rb +0 -258
  354. data/examples/analytics/app.rbs +0 -7
  355. data/examples/analytics/test_app.rb +0 -132
  356. data/examples/block_padding/app.rb +0 -63
  357. data/examples/block_padding/app.rbs +0 -7
  358. data/examples/block_padding/test_app.rb +0 -31
  359. data/examples/block_titles/app.rb +0 -61
  360. data/examples/block_titles/app.rbs +0 -7
  361. data/examples/block_titles/test_app.rb +0 -34
  362. data/examples/box_demo/app.rbs +0 -7
  363. data/examples/box_demo/test_app.rb +0 -88
  364. data/examples/calendar_demo/app.rb +0 -101
  365. data/examples/calendar_demo/app.rbs +0 -7
  366. data/examples/calendar_demo/test_app.rb +0 -108
  367. data/examples/cell_demo/app.rb +0 -108
  368. data/examples/cell_demo/app.rbs +0 -7
  369. data/examples/cell_demo/test_app.rb +0 -36
  370. data/examples/chart_demo/app.rb +0 -203
  371. data/examples/chart_demo/app.rbs +0 -7
  372. data/examples/chart_demo/test_app.rb +0 -102
  373. data/examples/custom_widget/app.rb +0 -51
  374. data/examples/custom_widget/app.rbs +0 -7
  375. data/examples/custom_widget/test_app.rb +0 -30
  376. data/examples/flex_layout/app.rb +0 -156
  377. data/examples/flex_layout/app.rbs +0 -7
  378. data/examples/flex_layout/test_app.rb +0 -65
  379. data/examples/gauge_demo/app.rb +0 -182
  380. data/examples/gauge_demo/test_app.rb +0 -120
  381. data/examples/hit_test/app.rb +0 -175
  382. data/examples/hit_test/app.rbs +0 -7
  383. data/examples/hit_test/test_app.rb +0 -102
  384. data/examples/line_gauge_demo/app.rb +0 -190
  385. data/examples/line_gauge_demo/app.rbs +0 -7
  386. data/examples/line_gauge_demo/test_app.rb +0 -129
  387. data/examples/list_demo/app.rb +0 -253
  388. data/examples/list_demo/test_app.rb +0 -237
  389. data/examples/list_styles/app.rb +0 -140
  390. data/examples/list_styles/app.rbs +0 -7
  391. data/examples/list_styles/test_app.rb +0 -157
  392. data/examples/login_form/app.rbs +0 -7
  393. data/examples/login_form/test_app.rb +0 -51
  394. data/examples/map_demo/app.rbs +0 -7
  395. data/examples/map_demo/test_app.rb +0 -149
  396. data/examples/mouse_events/app.rb +0 -97
  397. data/examples/mouse_events/app.rbs +0 -7
  398. data/examples/mouse_events/test_app.rb +0 -53
  399. data/examples/popup_demo/app.rb +0 -103
  400. data/examples/popup_demo/app.rbs +0 -7
  401. data/examples/popup_demo/test_app.rb +0 -54
  402. data/examples/quickstart_dsl/app.rbs +0 -7
  403. data/examples/quickstart_dsl/test_app.rb +0 -29
  404. data/examples/quickstart_lifecycle/app.rb +0 -39
  405. data/examples/quickstart_lifecycle/app.rbs +0 -7
  406. data/examples/quickstart_lifecycle/test_app.rb +0 -29
  407. data/examples/ratatui_logo_demo/app.rb +0 -79
  408. data/examples/ratatui_logo_demo/app.rbs +0 -7
  409. data/examples/ratatui_logo_demo/test_app.rb +0 -51
  410. data/examples/ratatui_mascot_demo/app.rb +0 -84
  411. data/examples/ratatui_mascot_demo/app.rbs +0 -7
  412. data/examples/ratatui_mascot_demo/test_app.rb +0 -47
  413. data/examples/readme_usage/app.rb +0 -29
  414. data/examples/readme_usage/app.rbs +0 -7
  415. data/examples/readme_usage/test_app.rb +0 -29
  416. data/examples/rich_text/app.rb +0 -141
  417. data/examples/rich_text/app.rbs +0 -7
  418. data/examples/rich_text/test_app.rb +0 -166
  419. data/examples/scroll_text/app.rb +0 -103
  420. data/examples/scroll_text/app.rbs +0 -7
  421. data/examples/scroll_text/test_app.rb +0 -110
  422. data/examples/scrollbar_demo/app.rb +0 -143
  423. data/examples/scrollbar_demo/app.rbs +0 -7
  424. data/examples/scrollbar_demo/test_app.rb +0 -77
  425. data/examples/sparkline_demo/app.rb +0 -240
  426. data/examples/sparkline_demo/test_app.rb +0 -107
  427. data/examples/table_flex/app.rb +0 -65
  428. data/examples/table_flex/app.rbs +0 -7
  429. data/examples/table_flex/test_app.rb +0 -36
  430. data/examples/table_select/app.rb +0 -198
  431. data/examples/table_select/app.rbs +0 -7
  432. data/examples/table_select/test_app.rb +0 -180
  433. data/examples/widget_style_colors/test_app.rb +0 -48
  434. data/tasks/bump/comparison_links.rb +0 -41
  435. /data/doc/images/{analytics.png → app_analytics.png} +0 -0
  436. /data/doc/images/{custom_widget.png → app_custom_widget.png} +0 -0
  437. /data/doc/images/{mouse_events.png → app_mouse_events.png} +0 -0
  438. /data/doc/images/{map_demo.png → widget_map_demo.png} +0 -0
  439. /data/doc/images/{popup_demo.png → widget_popup_demo.png} +0 -0
  440. /data/doc/images/{hit_test.png → widget_rect.png} +0 -0
  441. /data/{doc/images/ratatui_logo_demo.png → exe/.gitkeep} +0 -0
@@ -1,7 +0,0 @@
1
- class HitTestApp
2
- # @public
3
- def self.new: () -> HitTestApp
4
-
5
- # @public
6
- def run: () -> void
7
- end
@@ -1,102 +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
- require "ratatui_ruby/test_helper"
9
- require "minitest/autorun"
10
- require_relative "app"
11
-
12
- class TestHitTestExample < Minitest::Test
13
- include RatatuiRuby::TestHelper
14
-
15
- def setup
16
- @app = HitTestApp.new
17
- end
18
-
19
- def test_initial_render_shows_both_panels
20
- with_test_terminal do
21
- inject_key(:q)
22
- @app.run
23
-
24
- content = buffer_content
25
- assert content.any? { |line| line.include?("Left Panel") }
26
- assert content.any? { |line| line.include?("Right Panel") }
27
- end
28
- end
29
-
30
- def test_left_panel_click
31
- with_test_terminal do
32
- # Click in left half at x=10, then quit
33
- inject_event(RatatuiRuby::Event::Mouse.new(kind: "down", button: "left", x: 10, y: 12))
34
- inject_key(:q)
35
-
36
- @app.run
37
-
38
- content = buffer_content
39
- # Check both status line and debug message
40
- assert content.any? { |line| line.include?("Last Click: left") }
41
- assert content.any? { |line| line.include?("Left Panel clicked") }
42
- end
43
- end
44
-
45
- def test_right_panel_click
46
- with_test_terminal do
47
- # Click in right half at x=50, then quit
48
- inject_event(RatatuiRuby::Event::Mouse.new(kind: "down", button: "left", x: 50, y: 12))
49
- inject_key(:q)
50
-
51
- @app.run
52
-
53
- content = buffer_content
54
- assert content.any? { |line| line.include?("Last Click: right") }
55
- assert content.any? { |line| line.include?("Right Panel clicked") }
56
- end
57
- end
58
-
59
- def test_ratio_change_decreases_left
60
- with_test_terminal do
61
- # Shrink left panel using left arrow
62
- inject_keys("left", :q)
63
- @app.run
64
-
65
- content = buffer_content
66
- assert content.any? { |line| line.include?("40%") }
67
- end
68
- end
69
-
70
- def test_ratio_change_increases_left
71
- with_test_terminal do
72
- # Expand left panel using right arrow
73
- inject_keys("right", :q)
74
- @app.run
75
-
76
- content = buffer_content
77
- assert content.any? { |line| line.include?("60%") }
78
- end
79
- end
80
-
81
- def test_ratio_minimum_boundary
82
- with_test_terminal do
83
- # Try to go below 10%
84
- inject_keys("left", "left", "left", "left", "left", :q)
85
- @app.run
86
-
87
- content = buffer_content
88
- assert content.any? { |line| line.include?("10%") }
89
- end
90
- end
91
-
92
- def test_ratio_maximum_boundary
93
- with_test_terminal do
94
- # Try to go above 90%
95
- inject_keys("right", "right", "right", "right", "right", "right", "right", "right", "right", :q)
96
- @app.run
97
-
98
- content = buffer_content
99
- assert content.any? { |line| line.include?("90%") }
100
- end
101
- end
102
- end
@@ -1,190 +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
- # Demonstrates LineGauge widget with interactive attribute cycling.
10
- class LineGaugeDemoApp
11
- def initialize
12
- @ratio = 0.5
13
- @ratios = [0.2, 0.35, 0.5, 0.65, 0.8, 0.95]
14
- @ratio_index = 2
15
-
16
- @filled_symbols = [
17
- { name: "█ (Block)", symbol: "█" },
18
- { name: "▓ (Dark Shade)", symbol: "▓" },
19
- { name: "▒ (Medium Shade)", symbol: "▒" },
20
- { name: "= (Equals)", symbol: "=" },
21
- { name: "# (Hash)", symbol: "#" }
22
- ]
23
- @filled_symbol_index = 0
24
-
25
- @unfilled_symbols = [
26
- { name: "░ (Light Shade)", symbol: "░" },
27
- { name: "· (Dot)", symbol: "·" },
28
- { name: "- (Dash)", symbol: "-" },
29
- { name: "~ (Tilde)", symbol: "~" }
30
- ]
31
- @unfilled_symbol_index = 0
32
-
33
- @filled_colors = [
34
- { name: "Red", color: :red },
35
- { name: "Yellow", color: :yellow },
36
- { name: "Green", color: :green },
37
- { name: "Cyan", color: :cyan },
38
- { name: "Blue", color: :blue }
39
- ]
40
- @filled_color_index = 2
41
-
42
- @unfilled_colors = [
43
- { name: "Default", color: nil },
44
- { name: "Dark Gray", color: :dark_gray },
45
- { name: "Gray", color: :gray }
46
- ]
47
- @unfilled_color_index = 1
48
-
49
- @base_styles = [
50
- { name: "None", style: nil },
51
- { name: "Bold White", style: RatatuiRuby::Style.new(fg: :white, modifiers: [:bold]) },
52
- { name: "White on Blue", style: RatatuiRuby::Style.new(fg: :white, bg: :blue) },
53
- { name: "Italic Cyan", style: RatatuiRuby::Style.new(fg: :cyan, modifiers: [:italic]) }
54
- ]
55
- @base_style_index = 0
56
- @hotkey_style = RatatuiRuby::Style.new(modifiers: [:bold, :underlined])
57
- end
58
-
59
- def run
60
- RatatuiRuby.run do
61
- loop do
62
- render
63
- break if handle_input == :quit
64
- sleep 0.05
65
- end
66
- end
67
- end
68
-
69
- private
70
-
71
- def render
72
- @ratio = @ratios[@ratio_index]
73
-
74
- filled_color = @filled_colors[@filled_color_index][:color]
75
- unfilled_color = @unfilled_colors[@unfilled_color_index][:color]
76
-
77
- filled_style = filled_color ? RatatuiRuby::Style.new(fg: filled_color) : RatatuiRuby::Style.new(fg: :white)
78
- unfilled_style = unfilled_color ? RatatuiRuby::Style.new(fg: unfilled_color) : RatatuiRuby::Style.new(fg: :dark_gray)
79
-
80
- layout = RatatuiRuby::Layout.new(
81
- direction: :vertical,
82
- constraints: [
83
- RatatuiRuby::Constraint.fill(1),
84
- RatatuiRuby::Constraint.length(5)
85
- ],
86
- children: [
87
- # Main content area
88
- RatatuiRuby::Layout.new(
89
- direction: :vertical,
90
- constraints: [
91
- RatatuiRuby::Constraint.length(1),
92
- RatatuiRuby::Constraint.length(4),
93
- RatatuiRuby::Constraint.length(4),
94
- RatatuiRuby::Constraint.fill(1)
95
- ],
96
- children: [
97
- RatatuiRuby::Paragraph.new(
98
- text: "LineGauge Widget Demo - Cycle attributes with hotkeys"
99
- ),
100
- # Example 1: Static gauge showing all features
101
- RatatuiRuby::LineGauge.new(
102
- ratio: @ratio,
103
- label: "#{(@ratio * 100).to_i}%",
104
- style: @base_styles[@base_style_index][:style],
105
- filled_style:,
106
- unfilled_style:,
107
- filled_symbol: @filled_symbols[@filled_symbol_index][:symbol],
108
- unfilled_symbol: @unfilled_symbols[@unfilled_symbol_index][:symbol],
109
- block: RatatuiRuby::Block.new(title: "Interactive Gauge")
110
- ),
111
- # Example 2: Inverted colors for contrast demonstration
112
- RatatuiRuby::LineGauge.new(
113
- ratio: 1.0 - @ratio,
114
- label: "#{((1.0 - @ratio) * 100).to_i}%",
115
- filled_style: RatatuiRuby::Style.new(fg: :black, bg: :yellow),
116
- unfilled_style: RatatuiRuby::Style.new(fg: :white, bg: :dark_gray),
117
- filled_symbol: @filled_symbols[@filled_symbol_index][:symbol],
118
- unfilled_symbol: @unfilled_symbols[@unfilled_symbol_index][:symbol],
119
- block: RatatuiRuby::Block.new(title: "Inverse (100% - ratio)")
120
- ),
121
- RatatuiRuby::Paragraph.new(text: "")
122
- ]
123
- ),
124
- # Bottom control panel
125
- RatatuiRuby::Block.new(
126
- title: "Controls",
127
- borders: [:all],
128
- children: [
129
- RatatuiRuby::Paragraph.new(
130
- text: [
131
- # Line 1: General
132
- RatatuiRuby::Text::Line.new(spans: [
133
- RatatuiRuby::Text::Span.new(content: "←/→", style: @hotkey_style),
134
- RatatuiRuby::Text::Span.new(content: ": Ratio (#{(@ratio * 100).to_i}%) "),
135
- RatatuiRuby::Text::Span.new(content: "b", style: @hotkey_style),
136
- RatatuiRuby::Text::Span.new(content: ": Base Style (#{@base_styles[@base_style_index][:name]}) "),
137
- RatatuiRuby::Text::Span.new(content: "q", style: @hotkey_style),
138
- RatatuiRuby::Text::Span.new(content: ": Quit")
139
- ]),
140
- # Line 2: Filled
141
- RatatuiRuby::Text::Line.new(spans: [
142
- RatatuiRuby::Text::Span.new(content: "f", style: @hotkey_style),
143
- RatatuiRuby::Text::Span.new(content: ": Filled Symbol (#{@filled_symbols[@filled_symbol_index][:name]}) "),
144
- RatatuiRuby::Text::Span.new(content: "c", style: @hotkey_style),
145
- RatatuiRuby::Text::Span.new(content: ": Filled Color (#{@filled_colors[@filled_color_index][:name]})")
146
- ]),
147
- # Line 3: Unfilled
148
- RatatuiRuby::Text::Line.new(spans: [
149
- RatatuiRuby::Text::Span.new(content: "u", style: @hotkey_style),
150
- RatatuiRuby::Text::Span.new(content: ": Unfilled Symbol (#{@unfilled_symbols[@unfilled_symbol_index][:name]}) "),
151
- RatatuiRuby::Text::Span.new(content: "x", style: @hotkey_style),
152
- RatatuiRuby::Text::Span.new(content: ": Unfilled Color (#{@unfilled_colors[@unfilled_color_index][:name]})")
153
- ])
154
- ]
155
- )
156
- ]
157
- )
158
- ]
159
- )
160
-
161
-
162
- RatatuiRuby.draw(layout)
163
- end
164
-
165
- def handle_input
166
- event = RatatuiRuby.poll_event
167
- return unless event
168
-
169
- case event
170
- in {type: :key, code: "q"} | {type: :key, code: "c", modifiers: ["ctrl"]}
171
- :quit
172
- in type: :key, code: "right"
173
- @ratio_index = (@ratio_index + 1) % @ratios.length
174
- in type: :key, code: "left"
175
- @ratio_index = (@ratio_index - 1) % @ratios.length
176
- in type: :key, code: "b"
177
- @base_style_index = (@base_style_index + 1) % @base_styles.length
178
- in type: :key, code: "f"
179
- @filled_symbol_index = (@filled_symbol_index + 1) % @filled_symbols.length
180
- in type: :key, code: "c"
181
- @filled_color_index = (@filled_color_index + 1) % @filled_colors.length
182
- in type: :key, code: "u"
183
- @unfilled_symbol_index = (@unfilled_symbol_index + 1) % @unfilled_symbols.length
184
- in type: :key, code: "x"
185
- @unfilled_color_index = (@unfilled_color_index + 1) % @unfilled_colors.length
186
- end
187
- end
188
- end
189
-
190
- LineGaugeDemoApp.new.run if __FILE__ == $PROGRAM_NAME
@@ -1,7 +0,0 @@
1
- class LineGaugeDemoApp
2
- # @public
3
- def self.new: () -> LineGaugeDemoApp
4
-
5
- # @public
6
- def run: () -> void
7
- end
@@ -1,129 +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
- require "ratatui_ruby/test_helper"
9
- require "minitest/autorun"
10
- require_relative "app"
11
-
12
- class TestLineGaugeDemo < Minitest::Test
13
- include RatatuiRuby::TestHelper
14
-
15
- def setup
16
- @app = LineGaugeDemoApp.new
17
- end
18
-
19
- def test_initial_render
20
- with_test_terminal do
21
- inject_key(:q)
22
- @app.run
23
-
24
- content = buffer_content.join("\n")
25
- assert_includes content, "LineGauge Widget Demo"
26
- assert_includes content, "Interactive Gauge"
27
- assert_includes content, "Inverse"
28
- assert_includes content, "←/→: Ratio"
29
- assert_includes content, "50%"
30
- end
31
- end
32
-
33
- def test_ratio_cycling_right
34
- with_test_terminal do
35
- inject_keys(:right, :right, :q)
36
- @app.run
37
-
38
- content = buffer_content.join("\n")
39
- # After 2 right presses: index 2 -> 3 -> 4 (80%)
40
- assert_includes content, "80%"
41
- end
42
- end
43
-
44
- def test_ratio_cycling_left
45
- with_test_terminal do
46
- inject_keys(:left, :q)
47
- @app.run
48
-
49
- content = buffer_content.join("\n")
50
- # After 1 left press: index 2 -> 1 (35%)
51
- assert_includes content, "35%"
52
- end
53
- end
54
-
55
- def test_filled_symbol_cycling
56
- with_test_terminal do
57
- inject_keys(:f, :q)
58
- @app.run
59
-
60
- content = buffer_content.join("\n")
61
- # Default filled_symbol_index is 0 (█), after press becomes 1 (▓)
62
- assert_includes content, "Dark Shade"
63
- end
64
- end
65
-
66
- def test_filled_color_cycling
67
- with_test_terminal do
68
- inject_keys(:c, :c, :q)
69
- @app.run
70
-
71
- content = buffer_content.join("\n")
72
- # Default is index 2 (Green), after 2 presses -> 4 (Blue)
73
- assert_includes content, "Blue"
74
- end
75
- end
76
-
77
- def test_unfilled_symbol_cycling
78
- with_test_terminal do
79
- inject_keys(:u, :q)
80
- @app.run
81
-
82
- content = buffer_content.join("\n")
83
- # Default is index 0 (Light Shade), after press becomes 1 (Dot)
84
- assert_includes content, "Dot"
85
- end
86
- end
87
-
88
- def test_unfilled_color_cycling
89
- with_test_terminal do
90
- inject_keys(:x, :q)
91
- @app.run
92
-
93
- content = buffer_content.join("\n")
94
- # Default is index 1 (Dark Gray), after press becomes 2 (Gray)
95
- assert_includes content, "Gray"
96
- end
97
- end
98
-
99
- def test_base_style_cycling
100
- with_test_terminal do
101
- inject_keys(:b, :q)
102
- @app.run
103
-
104
- content = buffer_content.join("\n")
105
- # Default is index 0 (None), after press becomes 1 (Bold White)
106
- assert_includes content, "Bold White"
107
- end
108
- end
109
-
110
- def test_quit_with_ctrl_c
111
- with_test_terminal do
112
- inject_key(:ctrl_c)
113
- @app.run
114
- # Success if returns without hanging
115
- end
116
- end
117
-
118
- def test_multiple_attribute_changes
119
- with_test_terminal do
120
- inject_keys(:right, :f, :c, :b, :q)
121
- @app.run
122
-
123
- content = buffer_content.join("\n")
124
- # Verify some of the changes took effect
125
- assert_includes content, "65%" # ratio changed
126
- assert_includes content, "Dark Shade" # filled_symbol changed
127
- end
128
- end
129
- end
@@ -1,253 +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
- # Demonstrates List widget with interactive attribute cycling.
10
- class ListDemoApp
11
- def initialize
12
- @selected_index = nil
13
-
14
- @item_sets = [
15
- {
16
- name: "Large List",
17
- items: (1..200).map { |i| "Item #{i}" }
18
- },
19
- {
20
- name: "Colors",
21
- items: [
22
- "Red", "Orange", "Yellow", "Green", "Cyan", "Blue", "Indigo", "Violet",
23
- "Scarlet", "Crimson", "Maroon", "Brown", "Tan", "Beige", "Khaki",
24
- "Gold", "Silver", "White", "Gray", "Black", "Pink", "Magenta",
25
- "Turquoise", "Teal", "Coral", "Salmon", "Peach", "Lavender", "Lilac",
26
- "Olive", "Lime", "Navy", "Charcoal", "Ivory", "Azure"
27
- ]
28
- },
29
- {
30
- name: "Fruits",
31
- items: [
32
- "Apple", "Apricot", "Avocado", "Banana", "Blueberry", "Blackberry",
33
- "Cherry", "Cranberry", "Cucumber", "Date", "Dragonfruit", "Elderberry",
34
- "Fig", "Grape", "Grapefruit", "Guava", "Honeydew", "Huckleberry",
35
- "Jackfruit", "Kiwi", "Kumquat", "Lemon", "Lime", "Lychee",
36
- "Mango", "Melon", "Mulberry", "Nectarine", "Olive", "Orange",
37
- "Papaya", "Passion Fruit", "Peach", "Pear", "Persimmon", "Pineapple",
38
- "Plum", "Pomegranate", "Prune", "Rambutan", "Raspberry", "Starfruit",
39
- "Strawberry", "Tangerine", "Watermelon", "Ugli Fruit"
40
- ]
41
- },
42
- {
43
- name: "Programming",
44
- items: [
45
- "Ruby", "Rust", "Python", "JavaScript", "Go", "C++", "C#", "Java",
46
- "Kotlin", "Swift", "Objective-C", "PHP", "TypeScript", "Perl", "Lua",
47
- "R", "Scala", "Haskell", "Elixir", "Clojure", "Groovy", "Closure",
48
- "VB.NET", "F#", "Erlang", "Lisp", "Scheme", "Prolog", "Fortran",
49
- "COBOL", "Pascal", "Delphi", "Ada", "Bash", "Sh", "Tcl",
50
- "Awk", "sed", "Vim Script", "PowerShell", "Batch", "Assembly",
51
- "Wasm", "WebAssembly", "Julia", "Matlab", "Octave", "BASIC"
52
- ]
53
- }
54
- ]
55
- @item_set_index = 0
56
-
57
- @highlight_styles = [
58
- { name: "Blue Bold", style: RatatuiRuby::Style.new(fg: :blue, modifiers: [:bold]) },
59
- { name: "Yellow on Black", style: RatatuiRuby::Style.new(fg: :yellow, bg: :black) },
60
- { name: "Green Italic", style: RatatuiRuby::Style.new(fg: :green, modifiers: [:italic]) },
61
- { name: "White Reversed", style: RatatuiRuby::Style.new(fg: :white, modifiers: [:reversed]) },
62
- { name: "Cyan Bold", style: RatatuiRuby::Style.new(fg: :cyan, modifiers: [:bold]) }
63
- ]
64
- @highlight_style_index = 0
65
-
66
- @highlight_symbols = [
67
- { name: ">> ", symbol: ">> " },
68
- { name: "▶ ", symbol: "▶ " },
69
- { name: "→ ", symbol: "→ " },
70
- { name: "• ", symbol: "• " },
71
- { name: "★ ", symbol: "★ " }
72
- ]
73
- @highlight_symbol_index = 0
74
-
75
- @directions = [
76
- { name: "Top to Bottom", direction: :top_to_bottom },
77
- { name: "Bottom to Top", direction: :bottom_to_top }
78
- ]
79
- @direction_index = 0
80
-
81
- @highlight_spacings = [
82
- { name: "When Selected", spacing: :when_selected },
83
- { name: "Always", spacing: :always },
84
- { name: "Never", spacing: :never }
85
- ]
86
- @highlight_spacing_index = 0
87
-
88
- @repeat_modes = [
89
- { name: "Off", repeat: false },
90
- { name: "On", repeat: true }
91
- ]
92
- @repeat_index = 0
93
-
94
- @base_styles = [
95
- { name: "None", style: nil },
96
- { name: "Dark Gray", style: RatatuiRuby::Style.new(fg: :dark_gray) },
97
- { name: "White on Black", style: RatatuiRuby::Style.new(fg: :white, bg: :black) }
98
- ]
99
- @base_style_index = 0
100
-
101
- @scroll_paddings = [
102
- { name: "None", padding: nil },
103
- { name: "1 item", padding: 1 },
104
- { name: "2 items", padding: 2 }
105
- ]
106
- @scroll_padding_index = 0
107
- end
108
-
109
- def run
110
- RatatuiRuby.run do
111
- loop do
112
- render
113
- break if handle_input == :quit
114
- sleep 0.05
115
- end
116
- end
117
- end
118
-
119
- private
120
-
121
- def render
122
- items = @item_sets[@item_set_index][:items]
123
- selection_label = @selected_index.nil? ? "none" : @selected_index.to_s
124
- direction_config = @directions[@direction_index]
125
- spacing_config = @highlight_spacings[@highlight_spacing_index]
126
- repeat_config = @repeat_modes[@repeat_index]
127
- highlight_style_config = @highlight_styles[@highlight_style_index]
128
- highlight_symbol_config = @highlight_symbols[@highlight_symbol_index]
129
- base_style_config = @base_styles[@base_style_index]
130
- scroll_padding_config = @scroll_paddings[@scroll_padding_index]
131
-
132
- # Main list area
133
- main_content = RatatuiRuby::Layout.new(
134
- direction: :vertical,
135
- constraints: [
136
- RatatuiRuby::Constraint.length(1),
137
- RatatuiRuby::Constraint.fill(1)
138
- ],
139
- children: [
140
- RatatuiRuby::Paragraph.new(
141
- text: "List Widget Demo - Interactive Attribute Cycling"
142
- ),
143
- RatatuiRuby::List.new(
144
- items:,
145
- selected_index: @selected_index,
146
- style: base_style_config[:style],
147
- highlight_style: highlight_style_config[:style],
148
- highlight_symbol: highlight_symbol_config[:symbol],
149
- repeat_highlight_symbol: repeat_config[:repeat],
150
- highlight_spacing: spacing_config[:spacing],
151
- direction: direction_config[:direction],
152
- scroll_padding: scroll_padding_config[:padding],
153
- block: RatatuiRuby::Block.new(
154
- title: "#{@item_sets[@item_set_index][:name]} (Selection: #{selection_label})",
155
- borders: [:all]
156
- )
157
- )
158
- ]
159
- )
160
-
161
- # Bottom control panel with full width
162
- hotkey_style = RatatuiRuby::Style.new(modifiers: [:bold, :underlined])
163
- control_panel = RatatuiRuby::Block.new(
164
- title: "Controls",
165
- borders: [:all],
166
- children: [
167
- RatatuiRuby::Paragraph.new(
168
- text: [
169
- RatatuiRuby::Text::Line.new(spans: [
170
- RatatuiRuby::Text::Span.new(content: "i", style: hotkey_style),
171
- RatatuiRuby::Text::Span.new(content: ": Items "),
172
- RatatuiRuby::Text::Span.new(content: "↑/↓", style: hotkey_style),
173
- RatatuiRuby::Text::Span.new(content: ": Navigate "),
174
- RatatuiRuby::Text::Span.new(content: "x", style: hotkey_style),
175
- RatatuiRuby::Text::Span.new(content: ": Select "),
176
- RatatuiRuby::Text::Span.new(content: "h", style: hotkey_style),
177
- RatatuiRuby::Text::Span.new(content: ": Highlight (#{highlight_style_config[:name]})")
178
- ]),
179
- RatatuiRuby::Text::Line.new(spans: [
180
- RatatuiRuby::Text::Span.new(content: "y", style: hotkey_style),
181
- RatatuiRuby::Text::Span.new(content: ": Symbol (#{highlight_symbol_config[:name]}) "),
182
- RatatuiRuby::Text::Span.new(content: "d", style: hotkey_style),
183
- RatatuiRuby::Text::Span.new(content: ": Direction (#{direction_config[:name]})")
184
- ]),
185
- RatatuiRuby::Text::Line.new(spans: [
186
- RatatuiRuby::Text::Span.new(content: "s", style: hotkey_style),
187
- RatatuiRuby::Text::Span.new(content: ": Spacing (#{spacing_config[:name]}) "),
188
- RatatuiRuby::Text::Span.new(content: "p", style: hotkey_style),
189
- RatatuiRuby::Text::Span.new(content: ": Scroll Padding (#{scroll_padding_config[:name]})")
190
- ]),
191
- RatatuiRuby::Text::Line.new(spans: [
192
- RatatuiRuby::Text::Span.new(content: "b", style: hotkey_style),
193
- RatatuiRuby::Text::Span.new(content: ": Base (#{base_style_config[:name]}) "),
194
- RatatuiRuby::Text::Span.new(content: "r", style: hotkey_style),
195
- RatatuiRuby::Text::Span.new(content: ": Repeat (#{repeat_config[:name]}) "),
196
- RatatuiRuby::Text::Span.new(content: "q", style: hotkey_style),
197
- RatatuiRuby::Text::Span.new(content: ": Quit")
198
- ])
199
- ]
200
- )
201
- ]
202
- )
203
-
204
- # Combine layouts vertically
205
- layout = RatatuiRuby::Layout.new(
206
- direction: :vertical,
207
- constraints: [
208
- RatatuiRuby::Constraint.fill(1),
209
- RatatuiRuby::Constraint.length(7)
210
- ],
211
- children: [main_content, control_panel]
212
- )
213
-
214
- RatatuiRuby.draw(layout)
215
- end
216
-
217
- def handle_input
218
- case RatatuiRuby.poll_event
219
- in {type: :key, code: "q"} | {type: :key, code: "c", modifiers: ["ctrl"]}
220
- :quit
221
- in type: :key, code: "i"
222
- @item_set_index = (@item_set_index + 1) % @item_sets.size
223
- @selected_index = nil
224
- in type: :key, code: "up"
225
- items = @item_sets[@item_set_index][:items]
226
- @selected_index = (@selected_index || 0) - 1
227
- @selected_index = items.size - 1 if @selected_index.negative?
228
- in type: :key, code: "down"
229
- items = @item_sets[@item_set_index][:items]
230
- @selected_index = ((@selected_index || -1) + 1) % items.size
231
- in type: :key, code: "x"
232
- @selected_index = @selected_index.nil? ? 0 : nil
233
- in type: :key, code: "h"
234
- @highlight_style_index = (@highlight_style_index + 1) % @highlight_styles.size
235
- in type: :key, code: "y"
236
- @highlight_symbol_index = (@highlight_symbol_index + 1) % @highlight_symbols.size
237
- in type: :key, code: "d"
238
- @direction_index = (@direction_index + 1) % @directions.size
239
- in type: :key, code: "s"
240
- @highlight_spacing_index = (@highlight_spacing_index + 1) % @highlight_spacings.size
241
- in type: :key, code: "b"
242
- @base_style_index = (@base_style_index + 1) % @base_styles.size
243
- in type: :key, code: "r"
244
- @repeat_index = (@repeat_index + 1) % @repeat_modes.size
245
- in type: :key, code: "p"
246
- @scroll_padding_index = (@scroll_padding_index + 1) % @scroll_paddings.size
247
- else
248
- nil
249
- end
250
- end
251
- end
252
-
253
- ListDemoApp.new.run if __FILE__ == $PROGRAM_NAME