ratatui_ruby 0.4.0 → 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 (351) 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 +87 -171
  7. data/CHANGELOG.md +38 -1
  8. data/README.md +8 -3
  9. data/REUSE.toml +20 -0
  10. data/doc/application_architecture.md +105 -45
  11. data/doc/application_testing.md +5 -3
  12. data/doc/contributors/design/ruby_frontend.md +9 -5
  13. data/doc/contributors/developing_examples.md +76 -18
  14. data/doc/contributors/documentation_style.md +7 -0
  15. data/doc/contributors/index.md +2 -0
  16. data/doc/event_handling.md +10 -4
  17. data/doc/images/app_all_events.png +0 -0
  18. data/doc/images/app_color_picker.png +0 -0
  19. data/doc/images/verify_readme_usage.png +0 -0
  20. data/doc/images/widget_barchart_demo.png +0 -0
  21. data/doc/images/widget_block_padding.png +0 -0
  22. data/doc/images/widget_block_titles.png +0 -0
  23. data/doc/images/widget_box_demo.png +0 -0
  24. data/doc/images/widget_calendar_demo.png +0 -0
  25. data/doc/images/widget_cell_demo.png +0 -0
  26. data/doc/images/widget_chart_demo.png +0 -0
  27. data/doc/images/widget_gauge_demo.png +0 -0
  28. data/doc/images/widget_layout_split.png +0 -0
  29. data/doc/images/widget_line_gauge_demo.png +0 -0
  30. data/doc/images/widget_list_demo.png +0 -0
  31. data/doc/images/widget_ratatui_logo_demo.png +0 -0
  32. data/doc/images/widget_ratatui_mascot_demo.png +0 -0
  33. data/doc/images/widget_render.png +0 -0
  34. data/doc/images/widget_scrollbar_demo.png +0 -0
  35. data/doc/images/widget_sparkline_demo.png +0 -0
  36. data/doc/images/widget_style_colors.png +0 -0
  37. data/doc/images/widget_table_flex.png +0 -0
  38. data/doc/images/widget_tabs_demo.png +0 -0
  39. data/doc/interactive_design.md +25 -30
  40. data/doc/quickstart.md +147 -120
  41. data/examples/app_all_events/README.md +81 -0
  42. data/examples/app_all_events/app.rb +93 -0
  43. data/examples/app_all_events/model/event_color_cycle.rb +41 -0
  44. data/examples/app_all_events/model/event_entry.rb +75 -0
  45. data/examples/app_all_events/model/events.rb +180 -0
  46. data/examples/app_all_events/model/highlight.rb +57 -0
  47. data/examples/app_all_events/model/timestamp.rb +54 -0
  48. data/examples/app_all_events/test/snapshots/after_focus_lost.txt +24 -0
  49. data/examples/app_all_events/test/snapshots/after_focus_regained.txt +24 -0
  50. data/examples/app_all_events/test/snapshots/after_horizontal_resize.txt +24 -0
  51. data/examples/app_all_events/test/snapshots/after_key_a.txt +24 -0
  52. data/examples/app_all_events/test/snapshots/after_key_ctrl_x.txt +24 -0
  53. data/examples/app_all_events/test/snapshots/after_mouse_click.txt +24 -0
  54. data/examples/app_all_events/test/snapshots/after_mouse_drag.txt +24 -0
  55. data/examples/app_all_events/test/snapshots/after_multiple_events.txt +24 -0
  56. data/examples/app_all_events/test/snapshots/after_paste.txt +24 -0
  57. data/examples/app_all_events/test/snapshots/after_resize.txt +24 -0
  58. data/examples/app_all_events/test/snapshots/after_right_click.txt +24 -0
  59. data/examples/app_all_events/test/snapshots/after_vertical_resize.txt +24 -0
  60. data/examples/app_all_events/test/snapshots/initial_state.txt +24 -0
  61. data/examples/app_all_events/view/app_view.rb +78 -0
  62. data/examples/app_all_events/view/controls_view.rb +50 -0
  63. data/examples/app_all_events/view/counts_view.rb +55 -0
  64. data/examples/app_all_events/view/live_view.rb +69 -0
  65. data/examples/app_all_events/view/log_view.rb +60 -0
  66. data/examples/app_all_events/view.rb +7 -0
  67. data/examples/app_all_events/view_state.rb +42 -0
  68. data/examples/app_color_picker/README.md +94 -0
  69. data/examples/app_color_picker/app.rb +112 -0
  70. data/examples/app_color_picker/clipboard.rb +84 -0
  71. data/examples/app_color_picker/color.rb +191 -0
  72. data/examples/app_color_picker/copy_dialog.rb +170 -0
  73. data/examples/app_color_picker/harmony.rb +56 -0
  74. data/examples/app_color_picker/input.rb +142 -0
  75. data/examples/app_color_picker/palette.rb +80 -0
  76. data/examples/app_color_picker/scene.rb +201 -0
  77. data/examples/{login_form → app_login_form}/app.rb +39 -42
  78. data/examples/{map_demo → app_map_demo}/app.rb +24 -21
  79. data/examples/{table_select → app_table_select}/app.rb +68 -65
  80. data/examples/{quickstart_dsl → verify_quickstart_dsl}/app.rb +15 -6
  81. data/examples/verify_quickstart_layout/app.rb +69 -0
  82. data/examples/{quickstart_lifecycle → verify_quickstart_lifecycle}/app.rb +19 -10
  83. data/examples/verify_readme_usage/app.rb +34 -0
  84. data/examples/widget_barchart_demo/app.rb +238 -0
  85. data/examples/{block_padding → widget_block_padding}/app.rb +17 -13
  86. data/examples/{block_titles → widget_block_titles}/app.rb +25 -17
  87. data/examples/{box_demo → widget_box_demo}/app.rb +99 -65
  88. data/examples/widget_calendar_demo/app.rb +109 -0
  89. data/examples/widget_cell_demo/app.rb +104 -0
  90. data/examples/widget_chart_demo/app.rb +213 -0
  91. data/examples/widget_gauge_demo/app.rb +212 -0
  92. data/examples/widget_layout_split/app.rb +246 -0
  93. data/examples/widget_line_gauge_demo/app.rb +217 -0
  94. data/examples/widget_list_demo/app.rb +382 -0
  95. data/examples/widget_list_styles/app.rb +141 -0
  96. data/examples/widget_popup_demo/app.rb +104 -0
  97. data/examples/widget_ratatui_logo_demo/app.rb +103 -0
  98. data/examples/widget_ratatui_mascot_demo/app.rb +93 -0
  99. data/examples/widget_rect/app.rb +205 -0
  100. data/examples/widget_render/app.rb +184 -0
  101. data/examples/widget_rich_text/app.rb +137 -0
  102. data/examples/widget_scroll_text/app.rb +108 -0
  103. data/examples/widget_scrollbar_demo/app.rb +153 -0
  104. data/examples/widget_sparkline_demo/app.rb +274 -0
  105. data/examples/widget_style_colors/app.rb +19 -21
  106. data/examples/widget_table_flex/app.rb +95 -0
  107. data/examples/widget_tabs_demo/app.rb +167 -0
  108. data/ext/ratatui_ruby/Cargo.lock +1 -1
  109. data/ext/ratatui_ruby/Cargo.toml +1 -1
  110. data/ext/ratatui_ruby/src/events.rs +121 -36
  111. data/ext/ratatui_ruby/src/frame.rs +115 -0
  112. data/ext/ratatui_ruby/src/lib.rs +79 -26
  113. data/ext/ratatui_ruby/src/rendering.rs +8 -4
  114. data/ext/ratatui_ruby/src/style.rs +138 -57
  115. data/ext/ratatui_ruby/src/terminal.rs +5 -9
  116. data/ext/ratatui_ruby/src/text.rs +13 -6
  117. data/ext/ratatui_ruby/src/widgets/barchart.rs +56 -54
  118. data/ext/ratatui_ruby/src/widgets/block.rs +7 -6
  119. data/ext/ratatui_ruby/src/widgets/canvas.rs +21 -3
  120. data/ext/ratatui_ruby/src/widgets/chart.rs +20 -10
  121. data/ext/ratatui_ruby/src/widgets/layout.rs +9 -4
  122. data/ext/ratatui_ruby/src/widgets/list.rs +32 -9
  123. data/ext/ratatui_ruby/src/widgets/overlay.rs +2 -1
  124. data/ext/ratatui_ruby/src/widgets/paragraph.rs +1 -1
  125. data/ext/ratatui_ruby/src/widgets/ratatui_logo.rs +19 -8
  126. data/ext/ratatui_ruby/src/widgets/ratatui_mascot.rs +17 -10
  127. data/ext/ratatui_ruby/src/widgets/scrollbar.rs +4 -2
  128. data/ext/ratatui_ruby/src/widgets/sparkline.rs +14 -11
  129. data/ext/ratatui_ruby/src/widgets/table.rs +8 -4
  130. data/ext/ratatui_ruby/src/widgets/tabs.rs +11 -11
  131. data/lib/ratatui_ruby/cell.rb +3 -3
  132. data/lib/ratatui_ruby/event/key.rb +1 -1
  133. data/lib/ratatui_ruby/event/none.rb +43 -0
  134. data/lib/ratatui_ruby/event.rb +56 -4
  135. data/lib/ratatui_ruby/frame.rb +87 -0
  136. data/lib/ratatui_ruby/schema/bar_chart/bar.rb +11 -11
  137. data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +1 -5
  138. data/lib/ratatui_ruby/schema/bar_chart.rb +217 -217
  139. data/lib/ratatui_ruby/schema/block.rb +163 -168
  140. data/lib/ratatui_ruby/schema/calendar.rb +66 -67
  141. data/lib/ratatui_ruby/schema/canvas.rb +63 -63
  142. data/lib/ratatui_ruby/schema/center.rb +46 -46
  143. data/lib/ratatui_ruby/schema/chart.rb +135 -143
  144. data/lib/ratatui_ruby/schema/clear.rb +42 -42
  145. data/lib/ratatui_ruby/schema/constraint.rb +76 -76
  146. data/lib/ratatui_ruby/schema/cursor.rb +25 -25
  147. data/lib/ratatui_ruby/schema/gauge.rb +53 -53
  148. data/lib/ratatui_ruby/schema/layout.rb +87 -87
  149. data/lib/ratatui_ruby/schema/line_gauge.rb +62 -62
  150. data/lib/ratatui_ruby/schema/list.rb +86 -84
  151. data/lib/ratatui_ruby/schema/overlay.rb +31 -31
  152. data/lib/ratatui_ruby/schema/paragraph.rb +80 -80
  153. data/lib/ratatui_ruby/schema/ratatui_logo.rb +10 -6
  154. data/lib/ratatui_ruby/schema/ratatui_mascot.rb +10 -5
  155. data/lib/ratatui_ruby/schema/rect.rb +60 -60
  156. data/lib/ratatui_ruby/schema/scrollbar.rb +119 -119
  157. data/lib/ratatui_ruby/schema/shape/label.rb +1 -1
  158. data/lib/ratatui_ruby/schema/sparkline.rb +111 -110
  159. data/lib/ratatui_ruby/schema/style.rb +46 -46
  160. data/lib/ratatui_ruby/schema/table.rb +112 -119
  161. data/lib/ratatui_ruby/schema/tabs.rb +66 -67
  162. data/lib/ratatui_ruby/session/autodoc.rb +417 -0
  163. data/lib/ratatui_ruby/session.rb +40 -23
  164. data/lib/ratatui_ruby/test_helper.rb +185 -19
  165. data/lib/ratatui_ruby/version.rb +1 -1
  166. data/lib/ratatui_ruby.rb +65 -39
  167. data/{examples/sparkline_demo → sig/examples/app_all_events}/app.rbs +3 -2
  168. data/sig/examples/app_all_events/model/event_entry.rbs +16 -0
  169. data/sig/examples/app_all_events/model/events.rbs +15 -0
  170. data/sig/examples/app_all_events/model/timestamp.rbs +11 -0
  171. data/sig/examples/app_all_events/view/app_view.rbs +8 -0
  172. data/sig/examples/app_all_events/view/controls_view.rbs +6 -0
  173. data/sig/examples/app_all_events/view/counts_view.rbs +6 -0
  174. data/sig/examples/app_all_events/view/live_view.rbs +6 -0
  175. data/sig/examples/app_all_events/view/log_view.rbs +6 -0
  176. data/sig/examples/app_all_events/view.rbs +8 -0
  177. data/sig/examples/app_all_events/view_state.rbs +15 -0
  178. data/{examples/list_demo → sig/examples/app_color_picker}/app.rbs +2 -2
  179. data/sig/examples/app_login_form/app.rbs +11 -0
  180. data/sig/examples/app_map_demo/app.rbs +11 -0
  181. data/sig/examples/app_table_select/app.rbs +11 -0
  182. data/sig/examples/verify_quickstart_dsl/app.rbs +11 -0
  183. data/sig/examples/verify_quickstart_lifecycle/app.rbs +11 -0
  184. data/sig/examples/verify_readme_usage/app.rbs +11 -0
  185. data/sig/examples/widget_block_padding/app.rbs +11 -0
  186. data/sig/examples/widget_block_titles/app.rbs +11 -0
  187. data/sig/examples/widget_box_demo/app.rbs +11 -0
  188. data/sig/examples/widget_calendar_demo/app.rbs +11 -0
  189. data/sig/examples/widget_cell_demo/app.rbs +11 -0
  190. data/sig/examples/widget_chart_demo/app.rbs +11 -0
  191. data/{examples/gauge_demo → sig/examples/widget_gauge_demo}/app.rbs +4 -0
  192. data/sig/examples/widget_layout_split/app.rbs +10 -0
  193. data/sig/examples/widget_line_gauge_demo/app.rbs +11 -0
  194. data/sig/examples/widget_list_demo/app.rbs +12 -0
  195. data/sig/examples/widget_list_styles/app.rbs +11 -0
  196. data/sig/examples/widget_popup_demo/app.rbs +11 -0
  197. data/sig/examples/widget_ratatui_logo_demo/app.rbs +11 -0
  198. data/sig/examples/widget_ratatui_mascot_demo/app.rbs +11 -0
  199. data/sig/examples/widget_rect/app.rbs +12 -0
  200. data/sig/examples/widget_render/app.rbs +10 -0
  201. data/sig/examples/widget_rich_text/app.rbs +11 -0
  202. data/sig/examples/widget_scroll_text/app.rbs +11 -0
  203. data/sig/examples/widget_scrollbar_demo/app.rbs +11 -0
  204. data/sig/examples/widget_sparkline_demo/app.rbs +10 -0
  205. data/{examples → sig/examples}/widget_style_colors/app.rbs +1 -1
  206. data/sig/examples/widget_table_flex/app.rbs +11 -0
  207. data/sig/ratatui_ruby/frame.rbs +9 -0
  208. data/sig/ratatui_ruby/ratatui_ruby.rbs +3 -2
  209. data/sig/ratatui_ruby/schema/draw.rbs +4 -0
  210. data/sig/ratatui_ruby/schema/layout.rbs +1 -1
  211. data/sig/ratatui_ruby/session.rbs +94 -0
  212. data/tasks/autodoc/inventory.rb +61 -0
  213. data/tasks/autodoc/member.rb +56 -0
  214. data/tasks/autodoc/name.rb +19 -0
  215. data/tasks/autodoc/notice.rb +26 -0
  216. data/tasks/autodoc/rbs.rb +38 -0
  217. data/tasks/autodoc/rdoc.rb +45 -0
  218. data/tasks/autodoc.rake +47 -0
  219. data/tasks/bump/history.rb +2 -2
  220. data/tasks/doc.rake +600 -6
  221. data/tasks/example_viewer.html.erb +172 -0
  222. data/tasks/lint.rake +8 -4
  223. data/tasks/resources/index.html.erb +6 -0
  224. data/tasks/sourcehut.rake +4 -4
  225. data/tasks/terminal_preview/app_screenshot.rb +1 -3
  226. data/tasks/terminal_preview/crash_report.rb +7 -9
  227. data/tasks/terminal_preview/launcher_script.rb +4 -6
  228. data/tasks/terminal_preview/preview_collection.rb +4 -6
  229. data/tasks/terminal_preview/safety_confirmation.rb +3 -5
  230. data/tasks/terminal_preview/saved_screenshot.rb +7 -9
  231. data/tasks/terminal_preview/terminal_window.rb +7 -9
  232. data/tasks/test.rake +1 -1
  233. data/tasks/website/index_page.rb +3 -3
  234. data/tasks/website/version.rb +10 -10
  235. data/tasks/website/version_menu.rb +10 -12
  236. data/tasks/website/versioned_documentation.rb +49 -17
  237. data/tasks/website/website.rb +6 -8
  238. data/tasks/website.rake +4 -4
  239. metadata +156 -125
  240. data/LICENSES/BSD-2-Clause.txt +0 -9
  241. data/doc/contributors/better_dx.md +0 -543
  242. data/doc/contributors/example_analysis.md +0 -82
  243. data/doc/images/all_events.png +0 -0
  244. data/doc/images/block_padding.png +0 -0
  245. data/doc/images/block_titles.png +0 -0
  246. data/doc/images/box_demo.png +0 -0
  247. data/doc/images/calendar_demo.png +0 -0
  248. data/doc/images/cell_demo.png +0 -0
  249. data/doc/images/chart_demo.png +0 -0
  250. data/doc/images/flex_layout.png +0 -0
  251. data/doc/images/gauge_demo.png +0 -0
  252. data/doc/images/line_gauge_demo.png +0 -0
  253. data/doc/images/list_demo.png +0 -0
  254. data/doc/images/readme_usage.png +0 -0
  255. data/doc/images/scrollbar_demo.png +0 -0
  256. data/doc/images/sparkline_demo.png +0 -0
  257. data/doc/images/table_flex.png +0 -0
  258. data/examples/all_events/app.rb +0 -169
  259. data/examples/all_events/app.rbs +0 -7
  260. data/examples/all_events/test_app.rb +0 -139
  261. data/examples/analytics/app.rb +0 -258
  262. data/examples/analytics/app.rbs +0 -7
  263. data/examples/analytics/test_app.rb +0 -132
  264. data/examples/block_padding/app.rbs +0 -7
  265. data/examples/block_padding/test_app.rb +0 -31
  266. data/examples/block_titles/app.rbs +0 -7
  267. data/examples/block_titles/test_app.rb +0 -34
  268. data/examples/box_demo/app.rbs +0 -7
  269. data/examples/box_demo/test_app.rb +0 -88
  270. data/examples/calendar_demo/app.rb +0 -101
  271. data/examples/calendar_demo/app.rbs +0 -7
  272. data/examples/calendar_demo/test_app.rb +0 -108
  273. data/examples/cell_demo/app.rb +0 -108
  274. data/examples/cell_demo/app.rbs +0 -7
  275. data/examples/cell_demo/test_app.rb +0 -36
  276. data/examples/chart_demo/app.rb +0 -203
  277. data/examples/chart_demo/app.rbs +0 -7
  278. data/examples/chart_demo/test_app.rb +0 -102
  279. data/examples/custom_widget/app.rb +0 -51
  280. data/examples/custom_widget/app.rbs +0 -7
  281. data/examples/custom_widget/test_app.rb +0 -30
  282. data/examples/flex_layout/app.rb +0 -156
  283. data/examples/flex_layout/app.rbs +0 -7
  284. data/examples/flex_layout/test_app.rb +0 -65
  285. data/examples/gauge_demo/app.rb +0 -182
  286. data/examples/gauge_demo/test_app.rb +0 -120
  287. data/examples/hit_test/app.rb +0 -175
  288. data/examples/hit_test/app.rbs +0 -7
  289. data/examples/hit_test/test_app.rb +0 -102
  290. data/examples/line_gauge_demo/app.rb +0 -190
  291. data/examples/line_gauge_demo/app.rbs +0 -7
  292. data/examples/line_gauge_demo/test_app.rb +0 -129
  293. data/examples/list_demo/app.rb +0 -253
  294. data/examples/list_demo/test_app.rb +0 -237
  295. data/examples/list_styles/app.rb +0 -140
  296. data/examples/list_styles/app.rbs +0 -7
  297. data/examples/list_styles/test_app.rb +0 -157
  298. data/examples/login_form/app.rbs +0 -7
  299. data/examples/login_form/test_app.rb +0 -51
  300. data/examples/map_demo/app.rbs +0 -7
  301. data/examples/map_demo/test_app.rb +0 -149
  302. data/examples/mouse_events/app.rb +0 -97
  303. data/examples/mouse_events/app.rbs +0 -7
  304. data/examples/mouse_events/test_app.rb +0 -53
  305. data/examples/popup_demo/app.rb +0 -103
  306. data/examples/popup_demo/app.rbs +0 -7
  307. data/examples/popup_demo/test_app.rb +0 -54
  308. data/examples/quickstart_dsl/app.rbs +0 -7
  309. data/examples/quickstart_dsl/test_app.rb +0 -29
  310. data/examples/quickstart_lifecycle/app.rbs +0 -7
  311. data/examples/quickstart_lifecycle/test_app.rb +0 -29
  312. data/examples/ratatui_logo_demo/app.rb +0 -79
  313. data/examples/ratatui_logo_demo/app.rbs +0 -7
  314. data/examples/ratatui_logo_demo/test_app.rb +0 -51
  315. data/examples/ratatui_mascot_demo/app.rb +0 -84
  316. data/examples/ratatui_mascot_demo/app.rbs +0 -7
  317. data/examples/ratatui_mascot_demo/test_app.rb +0 -47
  318. data/examples/readme_usage/app.rb +0 -29
  319. data/examples/readme_usage/app.rbs +0 -7
  320. data/examples/readme_usage/test_app.rb +0 -29
  321. data/examples/rich_text/app.rb +0 -141
  322. data/examples/rich_text/app.rbs +0 -7
  323. data/examples/rich_text/test_app.rb +0 -166
  324. data/examples/scroll_text/app.rb +0 -103
  325. data/examples/scroll_text/app.rbs +0 -7
  326. data/examples/scroll_text/test_app.rb +0 -110
  327. data/examples/scrollbar_demo/app.rb +0 -143
  328. data/examples/scrollbar_demo/app.rbs +0 -7
  329. data/examples/scrollbar_demo/test_app.rb +0 -77
  330. data/examples/sparkline_demo/app.rb +0 -240
  331. data/examples/sparkline_demo/test_app.rb +0 -107
  332. data/examples/table_flex/app.rb +0 -65
  333. data/examples/table_flex/app.rbs +0 -7
  334. data/examples/table_flex/test_app.rb +0 -36
  335. data/examples/table_select/app.rbs +0 -7
  336. data/examples/table_select/test_app.rb +0 -180
  337. data/examples/widget_style_colors/test_app.rb +0 -48
  338. /data/doc/images/{analytics.png → app_analytics.png} +0 -0
  339. /data/doc/images/{custom_widget.png → app_custom_widget.png} +0 -0
  340. /data/doc/images/{login_form.png → app_login_form.png} +0 -0
  341. /data/doc/images/{map_demo.png → app_map_demo.png} +0 -0
  342. /data/doc/images/{mouse_events.png → app_mouse_events.png} +0 -0
  343. /data/doc/images/{table_select.png → app_table_select.png} +0 -0
  344. /data/doc/images/{quickstart_dsl.png → verify_quickstart_dsl.png} +0 -0
  345. /data/doc/images/{ratatui_logo_demo.png → verify_quickstart_layout.png} +0 -0
  346. /data/doc/images/{quickstart_lifecycle.png → verify_quickstart_lifecycle.png} +0 -0
  347. /data/doc/images/{list_styles.png → widget_list_styles.png} +0 -0
  348. /data/doc/images/{popup_demo.png → widget_popup_demo.png} +0 -0
  349. /data/doc/images/{hit_test.png → widget_rect.png} +0 -0
  350. /data/doc/images/{rich_text.png → widget_rich_text.png} +0 -0
  351. /data/doc/images/{scroll_text.png → widget_scroll_text.png} +0 -0
@@ -4,70 +4,70 @@
4
4
  # SPDX-License-Identifier: AGPL-3.0-or-later
5
5
 
6
6
  module RatatuiRuby
7
- # Defines a rectangular area in the terminal grid.
8
- #
9
- # Geometry management involves passing groups of four integers (`x, y, width, height`) repeatedly.
10
- # This is verbose and prone to parameter mismatch errors.
11
- #
12
- # This class encapsulates the geometry. It provides a standard primitive for passing area definitions
13
- # between layout engines and rendering functions.
14
- #
15
- # Use it when manual positioning is required or when querying layout results.
16
- #
17
- # === Examples
18
- #
19
- # area = Rect.new(x: 0, y: 0, width: 80, height: 24)
20
- # puts area.width # => 80
21
- class Rect < Data.define(:x, :y, :width, :height)
22
- ##
23
- # :attr_reader: x
24
- # X coordinate (column) of the top-left corner (Integer, coerced via +to_int+ or +to_i+).
7
+ # Defines a rectangular area in the terminal grid.
8
+ #
9
+ # Geometry management involves passing groups of four integers (`x, y, width, height`) repeatedly.
10
+ # This is verbose and prone to parameter mismatch errors.
11
+ #
12
+ # This class encapsulates the geometry. It provides a standard primitive for passing area definitions
13
+ # between layout engines and rendering functions.
14
+ #
15
+ # Use it when manual positioning is required or when querying layout results.
16
+ #
17
+ # === Examples
18
+ #
19
+ # area = Rect.new(x: 0, y: 0, width: 80, height: 24)
20
+ # puts area.width # => 80
21
+ class Rect < Data.define(:x, :y, :width, :height)
22
+ ##
23
+ # :attr_reader: x
24
+ # X coordinate (column) of the top-left corner (Integer, coerced via +to_int+ or +to_i+).
25
25
 
26
- ##
27
- # :attr_reader: y
28
- # Y coordinate (row) of the top-left corner (Integer, coerced via +to_int+ or +to_i+).
26
+ ##
27
+ # :attr_reader: y
28
+ # Y coordinate (row) of the top-left corner (Integer, coerced via +to_int+ or +to_i+).
29
29
 
30
- ##
31
- # :attr_reader: width
32
- # Width in characters (Integer, coerced via +to_int+ or +to_i+).
30
+ ##
31
+ # :attr_reader: width
32
+ # Width in characters (Integer, coerced via +to_int+ or +to_i+).
33
33
 
34
- ##
35
- # :attr_reader: height
36
- # Height in characters (Integer, coerced via +to_int+ or +to_i+).
34
+ ##
35
+ # :attr_reader: height
36
+ # Height in characters (Integer, coerced via +to_int+ or +to_i+).
37
37
 
38
- # Creates a new Rect.
39
- #
40
- # All parameters accept any object responding to +to_int+ or +to_i+ (duck-typed).
41
- #
42
- # [x] Column index (Numeric).
43
- # [y] Row index (Numeric).
44
- # [width] Width in columns (Numeric).
45
- # [height] Height in rows (Numeric).
46
- def initialize(x: 0, y: 0, width: 0, height: 0)
47
- super(
48
- x: Integer(x),
49
- y: Integer(y),
50
- width: Integer(width),
51
- height: Integer(height)
52
- )
53
- end
38
+ # Creates a new Rect.
39
+ #
40
+ # All parameters accept any object responding to +to_int+ or +to_i+ (duck-typed).
41
+ #
42
+ # [x] Column index (Numeric).
43
+ # [y] Row index (Numeric).
44
+ # [width] Width in columns (Numeric).
45
+ # [height] Height in rows (Numeric).
46
+ def initialize(x: 0, y: 0, width: 0, height: 0)
47
+ super(
48
+ x: Integer(x),
49
+ y: Integer(y),
50
+ width: Integer(width),
51
+ height: Integer(height)
52
+ )
53
+ end
54
54
 
55
- # Tests whether a point is inside this rectangle.
56
- #
57
- # Essential for hit testing mouse clicks against layout regions.
58
- #
59
- # area = Rect.new(x: 10, y: 5, width: 20, height: 10)
60
- # area.contains?(15, 8) # => true
61
- # area.contains?(5, 8) # => false
62
- #
63
- # [px]
64
- # X coordinate to test (column).
65
- # [py]
66
- # Y coordinate to test (row).
67
- #
68
- # Returns true if the point (px, py) is within the rectangle bounds.
69
- def contains?(px, py)
70
- px >= x && px < x + width && py >= y && py < y + height
71
- end
55
+ # Tests whether a point is inside this rectangle.
56
+ #
57
+ # Essential for hit testing mouse clicks against layout regions.
58
+ #
59
+ # area = Rect.new(x: 10, y: 5, width: 20, height: 10)
60
+ # area.contains?(15, 8) # => true
61
+ # area.contains?(5, 8) # => false
62
+ #
63
+ # [px]
64
+ # X coordinate to test (column).
65
+ # [py]
66
+ # Y coordinate to test (row).
67
+ #
68
+ # Returns true if the point (px, py) is within the rectangle bounds.
69
+ def contains?(px, py)
70
+ px >= x && px < x + width && py >= y && py < y + height
72
71
  end
72
+ end
73
73
  end
@@ -4,138 +4,138 @@
4
4
  # SPDX-License-Identifier: AGPL-3.0-or-later
5
5
 
6
6
  module RatatuiRuby
7
- # Visualizes the scroll state of a viewport.
8
- #
9
- # Content overflows. Users get lost in long lists without landmarks. They need to know where they are and how much is left.
10
- #
11
- # This widget maps your context. It draws a track and a thumb, representing your current position relative to the total length.
12
- #
13
- # Overlay it on top of lists, paragraphs, or tables to provide spatial awareness.
14
- #
15
- # === Examples
16
- #
17
- # Scrollbar.new(
18
- # content_length: 100,
19
- # position: 25,
20
- # orientation: :vertical
21
- # )
22
- class Scrollbar < Data.define(
23
- :content_length,
24
- :position,
25
- :orientation,
26
- :thumb_symbol,
27
- :thumb_style,
28
- :track_symbol,
29
- :track_style,
30
- :begin_symbol,
31
- :begin_style,
32
- :end_symbol,
33
- :end_style,
34
- :style,
35
- :block
36
- )
37
- ##
38
- # :attr_reader: content_length
39
- # Total items or lines in the content.
7
+ # Visualizes the scroll state of a viewport.
8
+ #
9
+ # Content overflows. Users get lost in long lists without landmarks. They need to know where they are and how much is left.
10
+ #
11
+ # This widget maps your context. It draws a track and a thumb, representing your current position relative to the total length.
12
+ #
13
+ # Overlay it on top of lists, paragraphs, or tables to provide spatial awareness.
14
+ #
15
+ # {rdoc-image:/doc/images/widget_scrollbar_demo.png}[link:/examples/widget_scrollbar_demo/app_rb.html]
16
+ #
17
+ # === Example
18
+ #
19
+ # Run the interactive demo from the terminal:
20
+ #
21
+ # ruby examples/widget_scrollbar_demo/app.rb
22
+ class Scrollbar < Data.define(
23
+ :content_length,
24
+ :position,
25
+ :orientation,
26
+ :thumb_symbol,
27
+ :thumb_style,
28
+ :track_symbol,
29
+ :track_style,
30
+ :begin_symbol,
31
+ :begin_style,
32
+ :end_symbol,
33
+ :end_style,
34
+ :style,
35
+ :block
36
+ )
37
+ ##
38
+ # :attr_reader: content_length
39
+ # Total items or lines in the content.
40
40
 
41
- ##
42
- # :attr_reader: position
43
- # Current scroll offset (index).
44
- #
45
- # Maps to Ratatui's <tt>ScrollbarState::get_position()</tt> (new in 0.30.0).
41
+ ##
42
+ # :attr_reader: position
43
+ # Current scroll offset (index).
44
+ #
45
+ # Maps to Ratatui's <tt>ScrollbarState::get_position()</tt> (new in 0.30.0).
46
46
 
47
- ##
48
- # :attr_reader: orientation
49
- # Direction of the scrollbar.
50
- #
51
- # <tt>:vertical</tt> (default, alias for <tt>:vertical_right</tt>), <tt>:horizontal</tt> (alias for <tt>:horizontal_bottom</tt>),
52
- # <tt>:vertical_left</tt>, <tt>:vertical_right</tt>, <tt>:horizontal_top</tt>, or <tt>:horizontal_bottom</tt>.
47
+ ##
48
+ # :attr_reader: orientation
49
+ # Direction of the scrollbar.
50
+ #
51
+ # <tt>:vertical</tt> (default, alias for <tt>:vertical_right</tt>), <tt>:horizontal</tt> (alias for <tt>:horizontal_bottom</tt>),
52
+ # <tt>:vertical_left</tt>, <tt>:vertical_right</tt>, <tt>:horizontal_top</tt>, or <tt>:horizontal_bottom</tt>.
53
53
 
54
- ##
55
- # :attr_reader: thumb_symbol
56
- # Symbol used to represent the current position indicator.
54
+ ##
55
+ # :attr_reader: thumb_symbol
56
+ # Symbol used to represent the current position indicator.
57
57
 
58
- ##
59
- # :attr_reader: thumb_style
60
- # Style of the position indicator (thumb).
58
+ ##
59
+ # :attr_reader: thumb_style
60
+ # Style of the position indicator (thumb).
61
61
 
62
- ##
63
- # :attr_reader: track_symbol
64
- # Symbol used to represent the empty space of the scrollbar.
62
+ ##
63
+ # :attr_reader: track_symbol
64
+ # Symbol used to represent the empty space of the scrollbar.
65
65
 
66
- ##
67
- # :attr_reader: track_style
68
- # Style of the filled track area.
66
+ ##
67
+ # :attr_reader: track_style
68
+ # Style of the filled track area.
69
69
 
70
- ##
71
- # :attr_reader: begin_symbol
72
- # Symbol rendered at the start of the track (e.g., arrow).
70
+ ##
71
+ # :attr_reader: begin_symbol
72
+ # Symbol rendered at the start of the track (e.g., arrow).
73
73
 
74
- ##
75
- # :attr_reader: begin_style
76
- # Style of the start symbol.
74
+ ##
75
+ # :attr_reader: begin_style
76
+ # Style of the start symbol.
77
77
 
78
- ##
79
- # :attr_reader: end_symbol
80
- # Symbol rendered at the end of the track (e.g., arrow).
78
+ ##
79
+ # :attr_reader: end_symbol
80
+ # Symbol rendered at the end of the track (e.g., arrow).
81
81
 
82
- ##
83
- # :attr_reader: end_style
84
- # Style of the end symbol.
82
+ ##
83
+ # :attr_reader: end_style
84
+ # Style of the end symbol.
85
85
 
86
- ##
87
- # :attr_reader: style
88
- # Base style applied to the entire widget.
86
+ ##
87
+ # :attr_reader: style
88
+ # Base style applied to the entire widget.
89
89
 
90
- ##
91
- # :attr_reader: block
92
- # Optional wrapping block.
90
+ ##
91
+ # :attr_reader: block
92
+ # Optional wrapping block.
93
93
 
94
- # Creates a new Scrollbar.
95
- #
96
- # [content_length] Integer.
97
- # [position] Integer.
98
- # [orientation] Symbol (default: <tt>:vertical</tt>).
99
- # [thumb_symbol] String (default: <tt>"█"</tt>).
100
- # [thumb_style] Style (optional).
101
- # [track_symbol] String (optional).
102
- # [track_style] Style (optional).
103
- # [begin_symbol] String (optional).
104
- # [begin_style] Style (optional).
105
- # [end_symbol] String (optional).
106
- # [end_style] Style (optional).
107
- # [style] Style (optional).
108
- # [block] Block (optional).
109
- def initialize(
110
- content_length:,
111
- position:,
112
- orientation: :vertical,
113
- thumb_symbol: "█",
114
- thumb_style: nil,
115
- track_symbol: nil,
116
- track_style: nil,
117
- begin_symbol: nil,
118
- begin_style: nil,
119
- end_symbol: nil,
120
- end_style: nil,
121
- style: nil,
122
- block: nil
94
+ # Creates a new Scrollbar.
95
+ #
96
+ # [content_length] Integer.
97
+ # [position] Integer.
98
+ # [orientation] Symbol (default: <tt>:vertical</tt>).
99
+ # [thumb_symbol] String (default: <tt>"█"</tt>).
100
+ # [thumb_style] Style (optional).
101
+ # [track_symbol] String (optional).
102
+ # [track_style] Style (optional).
103
+ # [begin_symbol] String (optional).
104
+ # [begin_style] Style (optional).
105
+ # [end_symbol] String (optional).
106
+ # [end_style] Style (optional).
107
+ # [style] Style (optional).
108
+ # [block] Block (optional).
109
+ def initialize(
110
+ content_length:,
111
+ position:,
112
+ orientation: :vertical,
113
+ thumb_symbol: "█",
114
+ thumb_style: nil,
115
+ track_symbol: nil,
116
+ track_style: nil,
117
+ begin_symbol: nil,
118
+ begin_style: nil,
119
+ end_symbol: nil,
120
+ end_style: nil,
121
+ style: nil,
122
+ block: nil
123
+ )
124
+ super(
125
+ content_length: Integer(content_length),
126
+ position: Integer(position),
127
+ orientation:,
128
+ thumb_symbol:,
129
+ thumb_style:,
130
+ track_symbol:,
131
+ track_style:,
132
+ begin_symbol:,
133
+ begin_style:,
134
+ end_symbol:,
135
+ end_style:,
136
+ style:,
137
+ block:
123
138
  )
124
- super(
125
- content_length: Integer(content_length),
126
- position: Integer(position),
127
- orientation: orientation,
128
- thumb_symbol: thumb_symbol,
129
- thumb_style: thumb_style,
130
- track_symbol: track_symbol,
131
- track_style: track_style,
132
- begin_symbol: begin_symbol,
133
- begin_style: begin_style,
134
- end_symbol: end_symbol,
135
- end_style: end_style,
136
- style: style,
137
- block: block
138
- )
139
- end
140
139
  end
140
+ end
141
141
  end
@@ -59,7 +59,7 @@ module RatatuiRuby
59
59
  # [text] Text content (String or Text::Line).
60
60
  # [style] Style (optional).
61
61
  def initialize(x:, y:, text:, style: nil)
62
- super(x: Float(x), y: Float(y), text: text, style: style)
62
+ super(x: Float(x), y: Float(y), text:, style:)
63
63
  end
64
64
  end
65
65
  end
@@ -4,128 +4,129 @@
4
4
  # SPDX-License-Identifier: AGPL-3.0-or-later
5
5
 
6
6
  module RatatuiRuby
7
- # Displays high-density data in a compact row.
8
- #
9
- # Users need context. A single value ("90% CPU") tells you current status, but not the trend.
10
- # Full charts take up too much room.
11
- #
12
- # This widget solves the density problem. It condenses history into a single line of variable-height blocks.
13
- #
14
- # Use it in dashboards, headers, or list items to providing trending data at a glance.
15
- #
16
- # === Examples
17
- #
18
- # Sparkline.new(
19
- # data: [1, 4, 3, 8, 2, 9, 3, 2],
20
- # style: Style.new(fg: :yellow)
21
- # )
22
- class Sparkline < Data.define(:data, :max, :style, :block, :direction, :absent_value_symbol, :absent_value_style, :bar_set)
23
- ##
24
- # :attr_reader: data
25
- # Array of integer values to plot.
7
+ # Displays high-density data in a compact row.
8
+ #
9
+ # Users need context. A single value ("90% CPU") tells you current status, but not the trend.
10
+ # Full charts take up too much room.
11
+ #
12
+ # This widget solves the density problem. It condenses history into a single line of variable-height blocks.
13
+ #
14
+ # Use it in dashboards, headers, or list items to providing trending data at a glance.
15
+ #
16
+ # {rdoc-image:/doc/images/widget_sparkline_demo.png}[link:/examples/widget_sparkline_demo/app_rb.html]
17
+ #
18
+ # === Example
19
+ #
20
+ # Run the interactive demo from the terminal:
21
+ #
22
+ # ruby examples/widget_sparkline_demo/app.rb
23
+ class Sparkline < Data.define(:data, :max, :style, :block, :direction, :absent_value_symbol, :absent_value_style, :bar_set)
24
+ ##
25
+ # :attr_reader: data
26
+ # Array of integer values to plot.
26
27
 
27
- ##
28
- # :attr_reader: max
29
- # Maximum value for scaling (optional).
30
- #
31
- # If nil, derived from data max.
28
+ ##
29
+ # :attr_reader: max
30
+ # Maximum value for scaling (optional).
31
+ #
32
+ # If nil, derived from data max.
32
33
 
33
- ##
34
- # :attr_reader: style
35
- # Style for the bars.
34
+ ##
35
+ # :attr_reader: style
36
+ # Style for the bars.
36
37
 
37
- ##
38
- # :attr_reader: block
39
- # Optional wrapping block.
38
+ ##
39
+ # :attr_reader: block
40
+ # Optional wrapping block.
40
41
 
41
- ##
42
- # :attr_reader: direction
43
- # Direction to render data.
44
- #
45
- # Accepts +:left_to_right+ (default) or +:right_to_left+.
46
- # Use +:right_to_left+ when new data should appear on the left.
42
+ ##
43
+ # :attr_reader: direction
44
+ # Direction to render data.
45
+ #
46
+ # Accepts +:left_to_right+ (default) or +:right_to_left+.
47
+ # Use +:right_to_left+ when new data should appear on the left.
47
48
 
48
- ##
49
- # :attr_reader: absent_value_symbol
50
- # Character to render for absent (nil) values (optional).
51
- #
52
- # If nil, absent values are rendered with a space.
49
+ ##
50
+ # :attr_reader: absent_value_symbol
51
+ # Character to render for absent (nil) values (optional).
52
+ #
53
+ # If nil, absent values are rendered with a space.
53
54
 
54
- ##
55
- # :attr_reader: absent_value_style
56
- # Style for absent (nil) values (optional).
55
+ ##
56
+ # :attr_reader: absent_value_style
57
+ # Style for absent (nil) values (optional).
57
58
 
58
- ##
59
- # :attr_reader: bar_set
60
- # Custom characters for the bars (optional).
61
- #
62
- # A Hash with keys defining the characters for the bars.
63
- # Keys: <tt>:empty</tt>, <tt>:one_eighth</tt>, <tt>:one_quarter</tt>, <tt>:three_eighths</tt>, <tt>:half</tt>, <tt>:five_eighths</tt>, <tt>:three_quarters</tt>, <tt>:seven_eighths</tt>, <tt>:full</tt>.
64
- #
65
- # You can also use integers (0-8) as keys, where 0 is empty, 4 is half, and 8 is full.
66
- #
67
- # Alternatively, you can pass an Array of 9 strings, where index 0 is empty and index 8 is full.
68
- #
69
- # === Examples
70
- #
71
- # bar_set: {
72
- # empty: " ",
73
- # one_eighth: " ",
74
- # one_quarter: "▂",
75
- # three_eighths: "▃",
76
- # half: "▄",
77
- # five_eighths: "▅",
78
- # three_quarters: "▆",
79
- # seven_eighths: "▇",
80
- # full: "█"
81
- # }
82
- #
83
- # # Numeric keys (0-8)
84
- # bar_set: {
85
- # 0 => " ", 1 => " ", 2 => "▂", 3 => "▃", 4 => "▄", 5 => "▅", 6 => "▆", 7 => "▇", 8 => "█"
86
- # }
87
- #
88
- # # Array (9 items)
89
- # bar_set: [" ", " ", "▂", "▃", "▄", "▅", "▆", "▇", "█"]
59
+ ##
60
+ # :attr_reader: bar_set
61
+ # Custom characters for the bars (optional).
62
+ #
63
+ # A Hash with keys defining the characters for the bars.
64
+ # Keys: <tt>:empty</tt>, <tt>:one_eighth</tt>, <tt>:one_quarter</tt>, <tt>:three_eighths</tt>, <tt>:half</tt>, <tt>:five_eighths</tt>, <tt>:three_quarters</tt>, <tt>:seven_eighths</tt>, <tt>:full</tt>.
65
+ #
66
+ # You can also use integers (0-8) as keys, where 0 is empty, 4 is half, and 8 is full.
67
+ #
68
+ # Alternatively, you can pass an Array of 9 strings, where index 0 is empty and index 8 is full.
69
+ #
70
+ # === Examples
71
+ #
72
+ # bar_set: {
73
+ # empty: " ",
74
+ # one_eighth: " ",
75
+ # one_quarter: "▂",
76
+ # three_eighths: "▃",
77
+ # half: "▄",
78
+ # five_eighths: "▅",
79
+ # three_quarters: "▆",
80
+ # seven_eighths: "▇",
81
+ # full: "█"
82
+ # }
83
+ #
84
+ # # Numeric keys (0-8)
85
+ # bar_set: {
86
+ # 0 => " ", 1 => " ", 2 => "▂", 3 => "▃", 4 => "▄", 5 => "▅", 6 => "▆", 7 => "▇", 8 => "█"
87
+ # }
88
+ #
89
+ # # Array (9 items)
90
+ # bar_set: [" ", " ", "▂", "▃", "▄", "▅", "▆", "▇", "█"]
90
91
 
91
- BAR_KEYS = %i[empty one_eighth one_quarter three_eighths half five_eighths three_quarters seven_eighths full].freeze
92
+ BAR_KEYS = %i[empty one_eighth one_quarter three_eighths half five_eighths three_quarters seven_eighths full].freeze
92
93
 
93
- # Creates a new Sparkline widget.
94
- #
95
- # [data] Array of Integers or nil. nil marks an absent value (distinct from 0).
96
- # [max] Max value (optional).
97
- # [style] Style (optional).
98
- # [block] Block (optional).
99
- # [direction] +:left_to_right+ or +:right_to_left+ (default: +:left_to_right+).
100
- # [absent_value_symbol] Character for absent (nil) values (optional).
101
- # [absent_value_style] Style for absent (nil) values (optional).
102
- # [bar_set] Hash or Array of custom characters (optional).
103
- def initialize(data:, max: nil, style: nil, block: nil, direction: :left_to_right, absent_value_symbol: nil, absent_value_style: nil, bar_set: nil)
104
- if bar_set
105
- if bar_set.is_a?(Array) && bar_set.size == 9
106
- # Convert Array to Hash using BAR_KEYS order
107
- bar_set = BAR_KEYS.zip(bar_set).to_h
108
- else
109
- bar_set = bar_set.dup
110
- # Normalize numeric keys (0-8) to symbolic keys
111
- BAR_KEYS.each_with_index do |key, i|
112
- if val = bar_set.delete(i) || bar_set.delete(i.to_s)
113
- bar_set[key] = val
114
- end
94
+ # Creates a new Sparkline widget.
95
+ #
96
+ # [data] Array of Integers or nil. nil marks an absent value (distinct from 0).
97
+ # [max] Max value (optional).
98
+ # [style] Style (optional).
99
+ # [block] Block (optional).
100
+ # [direction] +:left_to_right+ or +:right_to_left+ (default: +:left_to_right+).
101
+ # [absent_value_symbol] Character for absent (nil) values (optional).
102
+ # [absent_value_style] Style for absent (nil) values (optional).
103
+ # [bar_set] Hash or Array of custom characters (optional).
104
+ def initialize(data:, max: nil, style: nil, block: nil, direction: :left_to_right, absent_value_symbol: nil, absent_value_style: nil, bar_set: nil)
105
+ if bar_set
106
+ if bar_set.is_a?(Array) && bar_set.size == 9
107
+ # Convert Array to Hash using BAR_KEYS order
108
+ bar_set = BAR_KEYS.zip(bar_set).to_h
109
+ else
110
+ bar_set = bar_set.dup
111
+ # Normalize numeric keys (0-8) to symbolic keys
112
+ BAR_KEYS.each_with_index do |key, i|
113
+ if (val = bar_set.delete(i) || bar_set.delete(i.to_s))
114
+ bar_set[key] = val
115
115
  end
116
116
  end
117
117
  end
118
- coerced_data = data.map { |v| v.nil? ? nil : Integer(v) }
119
- super(
120
- data: coerced_data,
121
- max: max.nil? ? nil : Integer(max),
122
- style: style,
123
- block: block,
124
- direction: direction,
125
- absent_value_symbol: absent_value_symbol,
126
- absent_value_style: absent_value_style,
127
- bar_set: bar_set
128
- )
129
118
  end
119
+ coerced_data = data.map { |v| v.nil? ? nil : Integer(v) }
120
+ super(
121
+ data: coerced_data,
122
+ max: max.nil? ? nil : Integer(max),
123
+ style:,
124
+ block:,
125
+ direction:,
126
+ absent_value_symbol:,
127
+ absent_value_style:,
128
+ bar_set:
129
+ )
130
130
  end
131
+ end
131
132
  end