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
@@ -4,30 +4,90 @@
4
4
  # SPDX-License-Identifier: AGPL-3.0-or-later
5
5
 
6
6
  module RatatuiRuby
7
- # Defines constraints for layout sections or table columns.
7
+ # Defines the sizing rule for a layout section.
8
8
  #
9
- # [type] The type of constraint (:length, :percentage, :min).
10
- # [value] The numeric value associated with the constraint.
9
+ # Flexible layouts need rules. You can't just place widgets at absolute coordinates; they must adapt to changing terminal sizes.
10
+ #
11
+ # This class defines the rules of engagement. It tells the layout engine exactly how much space a section requires relative to others.
12
+ #
13
+ # Mix and match fixed lengths, percentages, ratios, and minimums. Build layouts that breathe.
14
+ #
15
+ # === Examples
16
+ #
17
+ # Constraint.length(5) # Exactly 5 cells
18
+ # Constraint.percentage(50) # Half the available space
19
+ # Constraint.min(10) # At least 10 cells, maybe more
20
+ # Constraint.fill(1) # Fill remaining space (weight 1)
11
21
  class Constraint < Data.define(:type, :value)
12
- # Creates a length constraint (fixed number of cells).
22
+ ##
23
+ # :attr_reader: type
24
+ # The type of constraint.
25
+ #
26
+ # <tt>:length</tt>, <tt>:percentage</tt>, <tt>:min</tt>, <tt>:max</tt>, <tt>:fill</tt>, or <tt>:ratio</tt>.
27
+
28
+ ##
29
+ # :attr_reader: value
30
+ # The numeric value (or array for ratio) associated with the rule.
31
+
32
+ # Requests a fixed size.
33
+ #
34
+ # Constraint.length(10) # 10 characters wide/high
13
35
  #
14
- # [v] The length value in cells.
36
+ # [v] Number of cells (Integer).
15
37
  def self.length(v)
16
- new(type: :length, value: v)
38
+ new(type: :length, value: Integer(v))
17
39
  end
18
40
 
19
- # Creates a percentage constraint (portion of available space).
41
+ # Requests a percentage of available space.
42
+ #
43
+ # Constraint.percentage(25) # 25% of the area
20
44
  #
21
- # [v] The percentage value (0-100).
45
+ # [v] Percentage 0-100 (Integer).
22
46
  def self.percentage(v)
23
- new(type: :percentage, value: v)
47
+ new(type: :percentage, value: Integer(v))
24
48
  end
25
49
 
26
- # Creates a minimum size constraint.
50
+ # Enforces a minimum size.
27
51
  #
28
- # [v] The minimum number of cells.
52
+ # Constraint.min(5) # At least 5 cells
53
+ #
54
+ # This section will grow if space permits, but never shrink below +v+.
55
+ #
56
+ # [v] Minimum cells (Integer).
29
57
  def self.min(v)
30
- new(type: :min, value: v)
58
+ new(type: :min, value: Integer(v))
59
+ end
60
+
61
+ # Enforces a maximum size.
62
+ #
63
+ # Constraint.max(10) # At most 10 cells
64
+ #
65
+ # [v] Maximum cells (Integer).
66
+ def self.max(v)
67
+ new(type: :max, value: Integer(v))
68
+ end
69
+
70
+ # Fills remaining space proportionally.
71
+ #
72
+ # Constraint.fill(1) # Equal share
73
+ # Constraint.fill(2) # Double share
74
+ #
75
+ # Fill constraints distribute any space left after satisfying strict rules.
76
+ # They behave like flex-grow. A fill(2) takes twice as much space as a fill(1).
77
+ #
78
+ # [v] Proportional weight (Integer, default: 1).
79
+ def self.fill(v = 1)
80
+ new(type: :fill, value: Integer(v))
81
+ end
82
+
83
+ # Requests a specific ratio of the total space.
84
+ #
85
+ # Constraint.ratio(1, 3) # 1/3rd of the area
86
+ #
87
+ # [numerator] Top part of fraction (Integer).
88
+ # [denominator] Bottom part of fraction (Integer).
89
+ def self.ratio(numerator, denominator)
90
+ new(type: :ratio, value: [Integer(numerator), Integer(denominator)])
31
91
  end
32
92
  end
33
93
  end
@@ -4,14 +4,32 @@
4
4
  # SPDX-License-Identifier: AGPL-3.0-or-later
5
5
 
6
6
  module RatatuiRuby
7
- # Sets the terminal cursor position (ghost widget).
7
+ # Controls the terminal cursor position.
8
8
  #
9
- # [x] the x coordinate.
10
- # [y] the y coordinate.
9
+ # Interfaces are not just output; they require input. Users need a visual cue—a blinking block or line—to know where their keystrokes will appear.
10
+ #
11
+ # This widget renders a ghost. It does not draw a character but instructs the terminal to place the hardware cursor at specific coordinates.
12
+ #
13
+ # Use it for text editors, input fields, or command prompts.
14
+ #
15
+ # === Examples
16
+ #
17
+ # Cursor.new(x: 10, y: 5)
11
18
  class Cursor < Data.define(:x, :y)
19
+ ##
20
+ # :attr_reader: x
21
+ # X coordinate (column).
22
+
23
+ ##
24
+ # :attr_reader: y
25
+ # Y coordinate (row).
26
+
12
27
  # Creates a new Cursor.
13
28
  #
14
- # [x] the x coordinate.
15
- # [y] the y coordinate.
29
+ # [x] Integer.
30
+ # [y] Integer.
31
+ def initialize(x:, y:)
32
+ super(x: Integer(x), y: Integer(y))
33
+ end
16
34
  end
17
35
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ module RatatuiRuby
7
+ # Draw commands for custom widgets.
8
+ #
9
+ # Custom widgets return an array of Draw commands instead of writing directly to a buffer.
10
+ # This keeps all pointers safely inside Rust while Ruby works with pure data.
11
+ #
12
+ # === Example
13
+ #
14
+ # class MyWidget
15
+ # def render(area)
16
+ # [
17
+ # RatatuiRuby::Draw.string(area.x, area.y, "Hello", {fg: :red}),
18
+ # RatatuiRuby::Draw.cell(area.x + 6, area.y, RatatuiRuby::Cell.char("!"))
19
+ # ]
20
+ # end
21
+ # end
22
+ module Draw
23
+ # Command to draw a string at the given coordinates.
24
+ #
25
+ # [x] X coordinate (absolute).
26
+ # [y] Y coordinate (absolute).
27
+ # [string] The text to draw.
28
+ # [style] Style hash or Style object.
29
+ StringCmd = Data.define(:x, :y, :string, :style)
30
+
31
+ # Command to draw a cell at the given coordinates.
32
+ #
33
+ # [x] X coordinate (absolute).
34
+ # [y] Y coordinate (absolute).
35
+ # [cell] The Cell to draw.
36
+ CellCmd = Data.define(:x, :y, :cell)
37
+
38
+ # Creates a string draw command.
39
+ #
40
+ # [x] X coordinate (Integer, duck-typed via +to_int+).
41
+ # [y] Y coordinate (Integer, duck-typed via +to_int+).
42
+ # [string] Text to draw.
43
+ # [style] Optional style (Hash or Style).
44
+ def self.string(x, y, string, style = {}) = StringCmd.new(x: Integer(x), y: Integer(y), string:, style:)
45
+
46
+ # Creates a cell draw command.
47
+ #
48
+ # [x] X coordinate (Integer, duck-typed via +to_int+).
49
+ # [y] Y coordinate (Integer, duck-typed via +to_int+).
50
+ # [cell] Cell to draw.
51
+ def self.cell(x, y, cell) = CellCmd.new(x: Integer(x), y: Integer(y), cell:)
52
+ end
53
+ end
@@ -4,21 +4,65 @@
4
4
  # SPDX-License-Identifier: AGPL-3.0-or-later
5
5
 
6
6
  module RatatuiRuby
7
- # A widget that displays a progress bar.
7
+ # Displays a standard progress bar.
8
8
  #
9
- # [ratio] A value between 0.0 and 1.0 representing the progress.
10
- # [label] An optional string to display on the gauge.
11
- # [style] The Style object to apply to the gauge.
12
- # [block] An optional Block widget to wrap the gauge.
13
- class Gauge < Data.define(:ratio, :label, :style, :block)
9
+ # Long-running tasks create anxiety. Users need to know that the system is working and how much is left to do.
10
+ #
11
+ # This widget visualizes completion. It fills a bar based on a percentage.
12
+ #
13
+ # Use it for downloads, installations, or processing jobs.
14
+ #
15
+ # {rdoc-image:/doc/images/widget_gauge_demo.png}[link:/examples/widget_gauge_demo/app_rb.html]
16
+ #
17
+ # === Example
18
+ #
19
+ # Run the interactive demo from the terminal:
20
+ #
21
+ # ruby examples/widget_gauge_demo/app.rb
22
+ class Gauge < Data.define(:ratio, :label, :style, :gauge_style, :block, :use_unicode)
23
+ ##
24
+ # :attr_reader: ratio
25
+ # Progress ratio from 0.0 to 1.0.
26
+
27
+ ##
28
+ # :attr_reader: label
29
+ # Text label to display (optional).
30
+ #
31
+ # If nil, it often displays the percentage automatically depending on renderer logic,
32
+ # but explicit labels are preferred.
33
+
34
+ ##
35
+ # :attr_reader: style
36
+ # Base style applied to the entire gauge background (optional).
37
+
38
+ ##
39
+ # :attr_reader: gauge_style
40
+ # Style applied specifically to the filled bar portion (optional).
41
+
42
+ ##
43
+ # :attr_reader: block
44
+ # Optional wrapping block.
45
+
46
+ ##
47
+ # :attr_reader: use_unicode
48
+ # Whether to use Unicode block characters (true) or ASCII characters (false).
49
+ # Default is false (ASCII) to be conservative, though Ratatui defaults to true.
50
+
14
51
  # Creates a new Gauge.
15
52
  #
16
- # [ratio] A value between 0.0 and 1.0 representing the progress.
17
- # [label] An optional string to display on the gauge.
18
- # [style] The Style object to apply to the gauge.
19
- # [block] An optional Block widget to wrap the gauge.
20
- def initialize(ratio: 0.0, label: nil, style: Style.default, block: nil)
21
- super
53
+ # [ratio] Float (0.0 - 1.0).
54
+ # [percent] Integer (0 - 100), alternative to ratio.
55
+ # [label] String (optional).
56
+ # [style] Style object for the background (optional).
57
+ # [gauge_style] Style object for the filled bar (optional).
58
+ # [block] Block widget (optional).
59
+ # [use_unicode] Boolean (default: true).
60
+ def initialize(ratio: nil, percent: nil, label: nil, style: nil, gauge_style: nil, block: nil, use_unicode: true)
61
+ if percent
62
+ ratio = Float(percent) / 100.0
63
+ end
64
+ ratio = Float(ratio || 0.0)
65
+ super(ratio:, label:, style:, gauge_style:, block:, use_unicode:)
22
66
  end
23
67
  end
24
68
  end
@@ -4,19 +4,101 @@
4
4
  # SPDX-License-Identifier: AGPL-3.0-or-later
5
5
 
6
6
  module RatatuiRuby
7
- # A widget that splits an area into multiple sections based on constraints.
7
+ # Divides an area into smaller chunks.
8
8
  #
9
- # [direction] The direction of the layout (:vertical or :horizontal).
10
- # [constraints] An array of Constraint objects defining the size of each section.
11
- # [children] An array of widgets to render within each section.
12
- class Layout < Data.define(:direction, :constraints, :children)
9
+ # Terminal screens vary in size. Hardcoded positions break when the window resizes. You need a way to organize space dynamically.
10
+ #
11
+ # This class manages geometry. It splits a given area into multiple sections based on a list of constraints.
12
+ #
13
+ # Use layouts to build responsive grids. Stack sections vertically for a sidebar-main structure. Partition them horizontally for headers and footers. Let the layout engine do the math.
14
+ #
15
+ # {rdoc-image:/doc/images/widget_layout_split.png}[link:/examples/widget_layout_split/app_rb.html]
16
+ #
17
+ # === Example
18
+ #
19
+ # Run the interactive demo from the terminal:
20
+ #
21
+ # ruby examples/widget_layout_split/app.rb
22
+ class Layout < Data.define(:direction, :constraints, :children, :flex)
23
+ ##
24
+ # :attr_reader: direction
25
+ # Direction of the split.
26
+ #
27
+ # Either <tt>:vertical</tt> (top to bottom) or <tt>:horizontal</tt> (left to right).
28
+ #
29
+ # layout.direction # => :vertical
30
+
31
+ ##
32
+ # :attr_reader: constraints
33
+ # Array of rules defining section sizes.
34
+ #
35
+ # See RatatuiRuby::Constraint.
36
+
37
+ ##
38
+ # :attr_reader: children
39
+ # Widgets to render in each section (optional).
40
+ #
41
+ # If provided, `children[i]` is rendered into the area defined by `constraints[i]`.
42
+
43
+ ##
44
+ # :attr_reader: flex
45
+ # Strategy for distributing extra space.
46
+ #
47
+ # One of <tt>:legacy</tt>, <tt>:start</tt>, <tt>:center</tt>, <tt>:end</tt>, <tt>:space_between</tt>, <tt>:space_around</tt>.
48
+
49
+ # :nodoc:
50
+ FLEX_MODES = %i[legacy start center end space_between space_around space_evenly].freeze
51
+
13
52
  # Creates a new Layout.
14
53
  #
15
- # [direction] The direction of the layout (:vertical or :horizontal).
16
- # [constraints] An array of Constraint objects defining the size of each section.
17
- # [children] An array of widgets to render within each section.
18
- def initialize(direction: :vertical, constraints: [], children: [])
54
+ # [direction]
55
+ # <tt>:vertical</tt> or <tt>:horizontal</tt> (default: <tt>:vertical</tt>).
56
+ # [constraints]
57
+ # list of Constraint objects.
58
+ # [children]
59
+ # List of widgets to render (optional).
60
+ # [flex]
61
+ # Flex mode for spacing (default: <tt>:legacy</tt>).
62
+ def initialize(direction: :vertical, constraints: [], children: [], flex: :legacy)
19
63
  super
20
64
  end
65
+
66
+ # Splits an area into multiple rectangles.
67
+ #
68
+ # This is a pure calculation helper for hit testing. It computes where
69
+ # widgets *would* be placed without actually rendering them.
70
+ #
71
+ # rects = Layout.split(
72
+ # area,
73
+ # direction: :horizontal,
74
+ # constraints: [Constraint.percentage(50), Constraint.percentage(50)]
75
+ # )
76
+ # left, right = rects
77
+ #
78
+ # [area]
79
+ # The area to split. Can be a <tt>Rect</tt> or a <tt>Hash</tt> containing <tt>:x</tt>, <tt>:y</tt>, <tt>:width</tt>, and <tt>:height</tt>.
80
+ # [direction]
81
+ # <tt>:vertical</tt> or <tt>:horizontal</tt> (default: <tt>:vertical</tt>).
82
+ # [constraints]
83
+ # Array of <tt>Constraint</tt> objects defining section sizes.
84
+ # [flex]
85
+ # Flex mode for spacing (default: <tt>:legacy</tt>).
86
+ #
87
+ # Returns an Array of <tt>Rect</tt> objects.
88
+ def self.split(area, direction: :vertical, constraints:, flex: :legacy)
89
+ # Duck-typing: If it lacks geometry methods but can be a Hash, convert it.
90
+ if !area.respond_to?(:x) && area.respond_to?(:to_h)
91
+ # Assume it's a Hash-like object with :x, :y, etc.
92
+ hash = area.to_h
93
+ area = Rect.new(
94
+ x: hash.fetch(:x, 0),
95
+ y: hash.fetch(:y, 0),
96
+ width: hash.fetch(:width, 0),
97
+ height: hash.fetch(:height, 0)
98
+ )
99
+ end
100
+ raw_rects = _split(area, direction, constraints, flex)
101
+ raw_rects.map { |r| Rect.new(x: r[:x], y: r[:y], width: r[:width], height: r[:height]) }
102
+ end
21
103
  end
22
104
  end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ module RatatuiRuby
7
+ # Displays a compact, single-line progress bar.
8
+ #
9
+ # Screen space is precious. Standard block gauges are bulky and consume multiple rows.
10
+ #
11
+ # This widget compresses the feedback. It draws a progress bar using line characters, fitting perfectly into tight layouts or lists.
12
+ #
13
+ # Use it when you need to show status without stealing focus or space.
14
+ #
15
+ # {rdoc-image:/doc/images/widget_line_gauge_demo.png}[link:/examples/widget_line_gauge_demo/app_rb.html]
16
+ #
17
+ # === Example
18
+ #
19
+ # Run the interactive demo from the terminal:
20
+ #
21
+ # ruby examples/widget_line_gauge_demo/app.rb
22
+ class LineGauge < Data.define(:ratio, :label, :style, :filled_style, :unfilled_style, :block, :filled_symbol, :unfilled_symbol)
23
+ ##
24
+ # :attr_reader: ratio
25
+ # Progress ratio from 0.0 to 1.0.
26
+
27
+ ##
28
+ # :attr_reader: label
29
+ # Optional label.
30
+
31
+ ##
32
+ # :attr_reader: style
33
+ # Base style applied to the entire gauge.
34
+
35
+ ##
36
+ # :attr_reader: filled_style
37
+ # Style for the completed portion.
38
+
39
+ ##
40
+ # :attr_reader: unfilled_style
41
+ # Style for the remainder.
42
+
43
+ ##
44
+ # :attr_reader: block
45
+ # Optional wrapping block.
46
+
47
+ ##
48
+ # :attr_reader: filled_symbol
49
+ # Character for filled segments.
50
+
51
+ ##
52
+ # :attr_reader: unfilled_symbol
53
+ # Character for empty segments.
54
+
55
+ # Creates a new LineGauge.
56
+ #
57
+ # [ratio] Float (0.0 - 1.0).
58
+ # [label] String (optional).
59
+ # [style] Style (optional, base style for the gauge).
60
+ # [filled_style] Style.
61
+ # [unfilled_style] Style.
62
+ # [block] Block.
63
+ # [filled_symbol] String (default: <tt>"█"</tt>).
64
+ # [unfilled_symbol] String (default: <tt>"░"</tt>).
65
+ def initialize(ratio: 0.0, label: nil, style: nil, filled_style: nil, unfilled_style: nil, block: nil, filled_symbol: "█", unfilled_symbol: "░")
66
+ super(
67
+ ratio: Float(ratio),
68
+ label:,
69
+ style:,
70
+ filled_style:,
71
+ unfilled_style:,
72
+ block:,
73
+ filled_symbol:,
74
+ unfilled_symbol:
75
+ )
76
+ end
77
+ end
78
+ end
@@ -4,25 +4,101 @@
4
4
  # SPDX-License-Identifier: AGPL-3.0-or-later
5
5
 
6
6
  module RatatuiRuby
7
- # A widget that displays a list of selectable items.
7
+ # Displays a selectable list of items.
8
8
  #
9
- # [items] An array of strings to display in the list.
10
- # [selected_index] The index of the currently selected item, or nil if none.
11
- # [style] The base style for all items.
12
- # [highlight_style] The style for the selected item.
13
- # [highlight_symbol] The symbol to display in front of the selected item.
14
- # [block] An optional Block widget to wrap the list.
15
- class List < Data.define(:items, :selected_index, :style, :highlight_style, :highlight_symbol, :block)
9
+ # Users need to choose from options. Menus, file explorers, and selectors are everywhere.
10
+ # Implementing navigation, highlighting, and scrolling state from scratch is tedious.
11
+ #
12
+ # This widget manages the list. It renders the items. It highlights the selection. It handles the scrolling window.
13
+ #
14
+ # Use it to build main menus, navigation sidebars, or logs.
15
+ #
16
+ # {rdoc-image:/doc/images/widget_list_demo.png}[link:/examples/widget_list_demo/app_rb.html]
17
+ #
18
+ # === Examples
19
+ #
20
+ # # Basic List
21
+ # List.new(items: ["Item 1", "Item 2"])
22
+ #
23
+ # # Navigation Menu
24
+ # List.new(
25
+ # items: ["New Game", "Load Game", "Options", "Quit"],
26
+ # selected_index: 0,
27
+ # highlight_style: Style.new(bg: :blue),
28
+ # highlight_symbol: ">> "
29
+ # )
30
+ class List < Data.define(:items, :selected_index, :style, :highlight_style, :highlight_symbol, :repeat_highlight_symbol, :highlight_spacing, :direction, :scroll_padding, :block)
31
+ ##
32
+ # :attr_reader: items
33
+ # The items to display (Array of Strings).
34
+
35
+ ##
36
+ # :attr_reader: selected_index
37
+ # Index of the active selection (Integer or nil).
38
+
39
+ ##
40
+ # :attr_reader: style
41
+ # Base style for unselected items.
42
+
43
+ ##
44
+ # :attr_reader: highlight_style
45
+ # Style for the selected item.
46
+
47
+ ##
48
+ # :attr_reader: highlight_symbol
49
+ # Symbol drawn before the selected item.
50
+
51
+ ##
52
+ # :attr_reader: repeat_highlight_symbol
53
+ # Whether to repeat the highlight symbol for each line of the selected item.
54
+
55
+ ##
56
+ # :attr_reader: highlight_spacing
57
+ # When to show the highlight symbol column.
58
+ #
59
+ # <tt>:always</tt>, <tt>:when_selected</tt>, or <tt>:never</tt>.
60
+
61
+ ##
62
+ # :attr_reader: direction
63
+ # Render direction.
64
+ #
65
+ # <tt>:top_to_bottom</tt> or <tt>:bottom_to_top</tt>.
66
+
67
+ ##
68
+ # :attr_reader: scroll_padding
69
+ # Number of items to keep visible above/below the selected item when scrolling (Integer or nil).
70
+
71
+ ##
72
+ # :attr_reader: block
73
+ # Optional wrapping block.
74
+
16
75
  # Creates a new List.
17
76
  #
18
- # [items] An array of strings to display in the list.
19
- # [selected_index] The index of the currently selected item, or nil if none.
20
- # [style] The base style for all items.
21
- # [highlight_style] The style for the selected item.
22
- # [highlight_symbol] The symbol to display in front of the selected item.
23
- # [block] An optional Block widget to wrap the list.
24
- def initialize(items: [], selected_index: nil, style: nil, highlight_style: nil, highlight_symbol: "> ", block: nil)
25
- super
77
+ # Integer parameters accept any object responding to +to_int+ or +to_i+ (duck-typed).
78
+ #
79
+ # [items] Array of Strings.
80
+ # [selected_index] Numeric (nullable, coerced to Integer).
81
+ # [style] Style object.
82
+ # [highlight_style] Style object.
83
+ # [highlight_symbol] String (default: <tt>"> "</tt>).
84
+ # [repeat_highlight_symbol] Boolean (default: <tt>false</tt>).
85
+ # [highlight_spacing] Symbol (default: <tt>:when_selected</tt>).
86
+ # [direction] Symbol (default: <tt>:top_to_bottom</tt>).
87
+ # [scroll_padding] Numeric (nullable, coerced to Integer, default: <tt>nil</tt>).
88
+ # [block] Block (optional).
89
+ def initialize(items: [], selected_index: nil, style: nil, highlight_style: nil, highlight_symbol: "> ", repeat_highlight_symbol: false, highlight_spacing: :when_selected, direction: :top_to_bottom, scroll_padding: nil, block: nil)
90
+ super(
91
+ items:,
92
+ selected_index: selected_index.nil? ? nil : Integer(selected_index),
93
+ style:,
94
+ highlight_style:,
95
+ highlight_symbol:,
96
+ repeat_highlight_symbol:,
97
+ highlight_spacing:,
98
+ direction:,
99
+ scroll_padding: scroll_padding.nil? ? nil : Integer(scroll_padding),
100
+ block:
101
+ )
26
102
  end
27
103
  end
28
104
  end
@@ -4,12 +4,38 @@
4
4
  # SPDX-License-Identifier: AGPL-3.0-or-later
5
5
 
6
6
  module RatatuiRuby
7
- # Renders children on top of each other (Painter's Algorithm).
7
+ # Stacks widgets on top of each other.
8
8
  #
9
- # [layers] Array of Widgets.
9
+ # Terminal interfaces are 2D grids, but complex UIs require depth. You need to float modals over text,
10
+ # or place a status bar on top of a map.
11
+ #
12
+ # This widget manages the Z-axis. It renders a list of widgets sequentially into the same area.
13
+ # Later widgets draw over earlier ones (Painter's Algorithm).
14
+ #
15
+ # Use overlays to compose complex scenes. Combine backgrounds, main content, and floating elements.
16
+ #
17
+ # === Examples
18
+ #
19
+ # Overlay.new(
20
+ # layers: [
21
+ # BackgroundMap.new,
22
+ # StatusBar.new, # Draws over map
23
+ # ModalDialog.new # Draws over everything
24
+ # ]
25
+ # )
10
26
  class Overlay < Data.define(:layers)
27
+ ##
28
+ # :attr_reader: layers
29
+ # The stack of widgets to render.
30
+ #
31
+ # Rendered from index 0 to N. Index N is the top-most layer.
32
+
11
33
  # Creates a new Overlay.
12
34
  #
13
- # [layers] Array of Widgets.
35
+ # [layers]
36
+ # Array of widgets.
37
+ def initialize(layers: [])
38
+ super
39
+ end
14
40
  end
15
41
  end