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
@@ -0,0 +1,212 @@
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 completion visualization with interactive attribute cycling.
10
+ #
11
+ # Long-running tasks create anxiety. Users need to know that the system is working and how much is left to do.
12
+ #
13
+ # This demo showcases the <tt>Gauge</tt> widget. It provides an interactive playground where you can cycle through different ratios, colors, and label templates in real-time.
14
+ #
15
+ # Use it to understand how to communicate progress and task status in your terminal interface.
16
+ #
17
+ # === Example
18
+ #
19
+ # Run the demo from the terminal:
20
+ #
21
+ # ruby examples/widget_gauge_demo/app.rb
22
+ #
23
+ # rdoc-image:/doc/images/widget_gauge_demo.png
24
+ class WidgetGaugeDemo
25
+ def initialize
26
+ @ratio = 0.65
27
+ @ratios = [0.0, 0.25, 0.5, 0.65, 0.8, 0.95, 1.0]
28
+ @ratio_index = 3
29
+
30
+ @gauge_colors = [
31
+ { name: "Green", color: :green },
32
+ { name: "Yellow", color: :yellow },
33
+ { name: "Red", color: :red },
34
+ { name: "Cyan", color: :cyan },
35
+ { name: "Blue", color: :blue },
36
+ ]
37
+ @gauge_color_index = 0
38
+
39
+ @bg_styles = nil # Initialized in run when @tui is available
40
+ @bg_style_index = 1
41
+
42
+ @use_unicode_options = [true, false]
43
+ @use_unicode_index = 0
44
+
45
+ @label_modes = [
46
+ { name: "Percentage", template: -> (ratio) { "#{(ratio * 100).to_i}%" } },
47
+ { name: "Ratio (decimal)", template: -> (ratio) { format("%.2f", ratio) } },
48
+ { name: "Progress", template: -> (ratio) { "Progress: #{(ratio * 100).to_i}%" } },
49
+ { name: "None", template: -> (_ratio) { nil } },
50
+ ]
51
+ @label_mode_index = 0
52
+ @hotkey_style = nil # Initialized in run when @tui is available
53
+ end
54
+
55
+ def run
56
+ RatatuiRuby.run do |tui|
57
+ @tui = tui
58
+
59
+ # Initialize styles using tui helpers
60
+ @bg_styles = [
61
+ { name: "None", style: nil },
62
+ { name: "Dark Gray BG", style: tui.style(fg: :dark_gray) },
63
+ { name: "White on Black", style: tui.style(fg: :white, bg: :black) },
64
+ { name: "Bold White", style: tui.style(fg: :white, modifiers: [:bold]) },
65
+ ]
66
+ @hotkey_style = tui.style(modifiers: [:bold, :underlined])
67
+
68
+ loop do
69
+ render
70
+ break if handle_input == :quit
71
+ end
72
+ end
73
+ end
74
+
75
+ private def render
76
+ @ratio = @ratios[@ratio_index]
77
+ gauge_color = @gauge_colors[@gauge_color_index][:color]
78
+ bg_style = @bg_styles[@bg_style_index][:style]
79
+ use_unicode = @use_unicode_options[@use_unicode_index]
80
+ label_template = @label_modes[@label_mode_index][:template]
81
+
82
+ gauge_style = @tui.style(fg: gauge_color)
83
+ label = label_template.call(@ratio)
84
+
85
+ @tui.draw do |frame|
86
+ # Split into main content and control panel
87
+ main_area, controls_area = @tui.layout_split(
88
+ frame.area,
89
+ direction: :vertical,
90
+ constraints: [
91
+ @tui.constraint_fill(1),
92
+ @tui.constraint_length(6),
93
+ ]
94
+ )
95
+
96
+ # Split main area into title, gauges, and spacer
97
+ title_area, gauge1_area, gauge2_area, gauge3_area, spacer_area = @tui.layout_split(
98
+ main_area,
99
+ direction: :vertical,
100
+ constraints: [
101
+ @tui.constraint_length(1),
102
+ @tui.constraint_fill(1),
103
+ @tui.constraint_fill(1),
104
+ @tui.constraint_fill(1),
105
+ @tui.constraint_length(1),
106
+ ]
107
+ )
108
+
109
+ # Render title
110
+ title = @tui.paragraph(
111
+ text: "Gauge Widget Demo",
112
+ style: @tui.style(modifiers: [:bold])
113
+ )
114
+ frame.render_widget(title, title_area)
115
+
116
+ # Gauge 1: Main interactive gauge
117
+ gauge1 = @tui.gauge(
118
+ ratio: @ratio,
119
+ label:,
120
+ style: bg_style,
121
+ gauge_style:,
122
+ use_unicode:,
123
+ block: @tui.block(title: "Interactive Gauge")
124
+ )
125
+ frame.render_widget(gauge1, gauge1_area)
126
+
127
+ # Gauge 2: Inverse ratio for comparison
128
+ gauge2 = @tui.gauge(
129
+ ratio: 1.0 - @ratio,
130
+ label: label_template.call(1.0 - @ratio),
131
+ style: bg_style,
132
+ gauge_style:,
133
+ use_unicode:,
134
+ block: @tui.block(title: "Inverse (1.0 - ratio)")
135
+ )
136
+ frame.render_widget(gauge2, gauge2_area)
137
+
138
+ # Gauge 3: Fixed at different stages
139
+ gauge3 = @tui.gauge(
140
+ ratio: [@ratio, 0.5].max,
141
+ label: "Min 50%",
142
+ style: @tui.style(fg: :dark_gray),
143
+ gauge_style: @tui.style(fg: :magenta),
144
+ use_unicode:,
145
+ block: @tui.block(title: "Min Threshold (Magenta)")
146
+ )
147
+ frame.render_widget(gauge3, gauge3_area)
148
+
149
+ # Render empty spacer
150
+ spacer = @tui.paragraph(text: "")
151
+ frame.render_widget(spacer, spacer_area)
152
+
153
+ # Bottom controls panel
154
+ controls = @tui.block(
155
+ title: "Controls",
156
+ borders: [:all],
157
+ children: [
158
+ @tui.paragraph(
159
+ text: [
160
+ # Navigation & General
161
+ @tui.text_line(spans: [
162
+ @tui.text_span(content: "←/→", style: @hotkey_style),
163
+ @tui.text_span(content: ": Adjust Ratio (#{format('%.2f', @ratio)}) "),
164
+ @tui.text_span(content: "q", style: @hotkey_style),
165
+ @tui.text_span(content: ": Quit"),
166
+ ]),
167
+ # Styling
168
+ @tui.text_line(spans: [
169
+ @tui.text_span(content: "g", style: @hotkey_style),
170
+ @tui.text_span(content: ": Color (#{@gauge_colors[@gauge_color_index][:name]}) "),
171
+ @tui.text_span(content: "b", style: @hotkey_style),
172
+ @tui.text_span(content: ": Background (#{@bg_styles[@bg_style_index][:name]})"),
173
+ ]),
174
+ # Options
175
+ @tui.text_line(spans: [
176
+ @tui.text_span(content: "u", style: @hotkey_style),
177
+ @tui.text_span(content: ": Unicode (#{use_unicode ? 'On' : 'Off'}) "),
178
+ @tui.text_span(content: "l", style: @hotkey_style),
179
+ @tui.text_span(content: ": Label (#{@label_modes[@label_mode_index][:name]})"),
180
+ ]),
181
+ ]
182
+ ),
183
+ ]
184
+ )
185
+ frame.render_widget(controls, controls_area)
186
+ end
187
+ end
188
+
189
+ private def handle_input
190
+ case @tui.poll_event
191
+ in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
192
+ :quit
193
+ in type: :key, code: "right"
194
+ @ratio_index = (@ratio_index + 1) % @ratios.length
195
+ in type: :key, code: "left"
196
+ @ratio_index = (@ratio_index - 1) % @ratios.length
197
+ in type: :key, code: "g"
198
+ @gauge_color_index = (@gauge_color_index + 1) % @gauge_colors.length
199
+ in type: :key, code: "b"
200
+ @bg_style_index = (@bg_style_index + 1) % @bg_styles.length
201
+ in type: :key, code: "u"
202
+ @use_unicode_index = (@use_unicode_index + 1) % @use_unicode_options.length
203
+ in type: :key, code: "l"
204
+ @label_mode_index = (@label_mode_index + 1) % @label_modes.length
205
+ else
206
+ # Ignore other events
207
+ nil
208
+ end
209
+ end
210
+ end
211
+
212
+ WidgetGaugeDemo.new.run if __FILE__ == $PROGRAM_NAME
@@ -0,0 +1,44 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
+ SPDX-License-Identifier: CC-BY-SA-4.0
4
+ -->
5
+
6
+ # Layout Split Example
7
+
8
+ Demonstrates dynamic geometry management with constraints and flex modes.
9
+
10
+ Terminal screens vary in size. Hardcoded layouts break. `Layout.split` manages space dynamically, ensuring your interface adapts to any window dimension.
11
+
12
+ ## Features Demonstrated
13
+
14
+ - **Constraints**:
15
+ - `Fill(n)`: Takes available space proportional to `n`.
16
+ - `Length(n)`: Fixed number of cells.
17
+ - `Percentage(n)`: Percentage of the parent area.
18
+ - `Min(n)`: At least `n` cells.
19
+ - `Ratio(x, y)`: `x/y` of the parent area.
20
+ - **Flex Modes**: Controlling how extra space is distributed (`Start`, `End`, `Center`, `SpaceBetween`, etc.).
21
+ - **Direction**: Splitting Vertically vs Horizontally.
22
+
23
+ ## Hotkeys
24
+
25
+ - **d**: Toggle Direction (`direction`)
26
+ - **f**: Cycle Flex Mode (`flex`)
27
+ - **c**: Cycle Constraint Set (`constraints`)
28
+ - **q**: Quit
29
+
30
+ ## Usage
31
+
32
+ ```bash
33
+ ruby examples/widget_layout_split/app.rb
34
+ ```
35
+
36
+ ## Learning Outcomes
37
+
38
+ Use this example if you need to...
39
+ - Build responsive dashboards.
40
+ - Create 3-column layouts where the middle content fills remaining space.
41
+ - Center a modal dialog on the screen.
42
+ - Distribute buttons evenly across a control bar.
43
+
44
+ ![Demo](/doc/images/widget_layout_split.png)
@@ -0,0 +1,246 @@
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 dynamic geometry management with interactive cycling.
10
+ #
11
+ # Terminal screens vary in size. Hardcoded positions break when the window resizes. You need a way to organize space dynamically.
12
+ #
13
+ # This demo showcases the <tt>Layout.split</tt> mechanism. It provides an interactive playground where you can toggle directions, all seven flex modes, and various constraint types (Fill, Length, Percentage, Min, Ratio) in real-time.
14
+ #
15
+ # Use it to understand how to build responsive, fluid terminal interfaces that adapt to any window dimensions.
16
+ #
17
+ # === Example
18
+ #
19
+ # Run the demo from the terminal:
20
+ #
21
+ # ruby examples/widget_layout_split/app.rb
22
+ #
23
+ # rdoc-image:/doc/images/widget_layout_split.png
24
+ class WidgetLayoutSplit
25
+ DIRECTIONS = [
26
+ { name: "Vertical", value: :vertical },
27
+ { name: "Horizontal", value: :horizontal },
28
+ ].freeze
29
+
30
+ FLEX_MODES = [
31
+ { name: "Legacy", value: :legacy },
32
+ { name: "Start", value: :start },
33
+ { name: "Center", value: :center },
34
+ { name: "End", value: :end },
35
+ { name: "Space Between", value: :space_between },
36
+ { name: "Space Around", value: :space_around },
37
+ { name: "Space Evenly", value: :space_evenly },
38
+ ].freeze
39
+
40
+ BLOCK_COLORS = %i[red green blue].freeze
41
+
42
+ def initialize
43
+ @direction_index = 0
44
+ @flex_index = 0
45
+ @constraint_index = 0
46
+ @hotkey_style = nil
47
+ end
48
+
49
+ def run
50
+ RatatuiRuby.run do |tui|
51
+ @tui = tui
52
+ @hotkey_style = tui.style(modifiers: [:bold, :underlined])
53
+ @constraint_demos = build_constraint_demos
54
+
55
+ loop do
56
+ render
57
+ break if handle_input == :quit
58
+ end
59
+ end
60
+ end
61
+
62
+ private def build_constraint_demos
63
+ [
64
+ {
65
+ name: "Fill (1:2:1)",
66
+ constraints: -> (dir) {
67
+ [
68
+ @tui.constraint_fill(1),
69
+ @tui.constraint_fill(2),
70
+ @tui.constraint_fill(1),
71
+ ]
72
+ },
73
+ },
74
+ {
75
+ name: "Length (10/15/10)",
76
+ constraints: -> (dir) {
77
+ [
78
+ @tui.constraint_length(10),
79
+ @tui.constraint_length(15),
80
+ @tui.constraint_length(10),
81
+ ]
82
+ },
83
+ },
84
+ {
85
+ name: "Percentage (25/50/25)",
86
+ constraints: -> (dir) {
87
+ [
88
+ @tui.constraint_percentage(25),
89
+ @tui.constraint_percentage(50),
90
+ @tui.constraint_percentage(25),
91
+ ]
92
+ },
93
+ },
94
+ {
95
+ name: "Min (5/10/5)",
96
+ constraints: -> (dir) {
97
+ [
98
+ @tui.constraint_min(5),
99
+ @tui.constraint_min(10),
100
+ @tui.constraint_min(5),
101
+ ]
102
+ },
103
+ },
104
+ {
105
+ name: "Ratio (1:4, 2:4, 1:4)",
106
+ constraints: -> (dir) {
107
+ [
108
+ @tui.constraint_ratio(1, 4),
109
+ @tui.constraint_ratio(2, 4),
110
+ @tui.constraint_ratio(1, 4),
111
+ ]
112
+ },
113
+ },
114
+ {
115
+ name: -> (dir) { (dir == :vertical) ? "Mixed (Len 3, Fill, Pct 25)" : "Mixed (Len 20, Fill, Pct 25)" },
116
+ constraints: -> (dir) {
117
+ fixed = (dir == :vertical) ? 3 : 20
118
+ [
119
+ @tui.constraint_length(fixed),
120
+ @tui.constraint_fill(1),
121
+ @tui.constraint_percentage(25),
122
+ ]
123
+ },
124
+ },
125
+ ]
126
+ end
127
+
128
+ private def current_direction
129
+ DIRECTIONS[@direction_index][:value]
130
+ end
131
+
132
+ private def current_flex
133
+ FLEX_MODES[@flex_index][:value]
134
+ end
135
+
136
+ private def current_constraints
137
+ demo = @constraint_demos[@constraint_index]
138
+ demo[:constraints].call(current_direction)
139
+ end
140
+
141
+ private def current_constraint_name
142
+ demo = @constraint_demos[@constraint_index]
143
+ name = demo[:name]
144
+ name.respond_to?(:call) ? name.call(current_direction) : name
145
+ end
146
+
147
+ private def render
148
+ @tui.draw do |frame|
149
+ # Split into main content and control panel
150
+ main_area, controls_area = @tui.layout_split(
151
+ frame.area,
152
+ direction: :vertical,
153
+ constraints: [
154
+ @tui.constraint_fill(1),
155
+ @tui.constraint_length(6),
156
+ ]
157
+ )
158
+
159
+ render_demo_area(frame, main_area)
160
+ render_controls(frame, controls_area)
161
+ end
162
+ end
163
+
164
+ private def render_demo_area(frame, area)
165
+ # Split demo area into title and content
166
+ title_area, content_area = @tui.layout_split(
167
+ area,
168
+ direction: :vertical,
169
+ constraints: [
170
+ @tui.constraint_length(1),
171
+ @tui.constraint_fill(1),
172
+ ]
173
+ )
174
+
175
+ # Render title
176
+ title = @tui.paragraph(
177
+ text: "Layout.split Demo",
178
+ style: @tui.style(modifiers: [:bold])
179
+ )
180
+ frame.render_widget(title, title_area)
181
+
182
+ # Apply current layout settings to 3 colored blocks
183
+ block_areas = @tui.layout_split(
184
+ content_area,
185
+ direction: current_direction,
186
+ flex: current_flex,
187
+ constraints: current_constraints
188
+ )
189
+
190
+ block_areas.each_with_index do |block_area, i|
191
+ block = @tui.block(
192
+ title: "Block #{i + 1}",
193
+ borders: [:all],
194
+ border_color: BLOCK_COLORS[i % BLOCK_COLORS.length]
195
+ )
196
+ frame.render_widget(block, block_area)
197
+ end
198
+ end
199
+
200
+ private def render_controls(frame, area)
201
+ controls = @tui.block(
202
+ title: "Controls",
203
+ borders: [:all],
204
+ children: [
205
+ @tui.paragraph(
206
+ text: [
207
+ # Row 1: Direction and Flex
208
+ @tui.text_line(spans: [
209
+ @tui.text_span(content: "d", style: @hotkey_style),
210
+ @tui.text_span(content: ": Direction (#{DIRECTIONS[@direction_index][:name]}) "),
211
+ @tui.text_span(content: "f", style: @hotkey_style),
212
+ @tui.text_span(content: ": Flex (#{FLEX_MODES[@flex_index][:name]})"),
213
+ ]),
214
+ @tui.text_line(spans: [
215
+ @tui.text_span(content: "c", style: @hotkey_style),
216
+ @tui.text_span(content: ": Constraints (#{current_constraint_name})"),
217
+ ]),
218
+ # Row 3: Quit
219
+ @tui.text_line(spans: [
220
+ @tui.text_span(content: "q", style: @hotkey_style),
221
+ @tui.text_span(content: ": Quit"),
222
+ ]),
223
+ ]
224
+ ),
225
+ ]
226
+ )
227
+ frame.render_widget(controls, area)
228
+ end
229
+
230
+ private def handle_input
231
+ case @tui.poll_event
232
+ in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
233
+ :quit
234
+ in type: :key, code: "d"
235
+ @direction_index = (@direction_index + 1) % DIRECTIONS.length
236
+ in type: :key, code: "f"
237
+ @flex_index = (@flex_index + 1) % FLEX_MODES.length
238
+ in type: :key, code: "c"
239
+ @constraint_index = (@constraint_index + 1) % @constraint_demos.length
240
+ else
241
+ nil
242
+ end
243
+ end
244
+ end
245
+
246
+ WidgetLayoutSplit.new.run if __FILE__ == $PROGRAM_NAME
@@ -0,0 +1,41 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
+ SPDX-License-Identifier: CC-BY-SA-4.0
4
+ -->
5
+
6
+ # Line Gauge Widget Example
7
+
8
+ Demonstrates compact progress bars for constrained spaces.
9
+
10
+ Standard block gauges take up vertical space. Sometimes you only have one line to show status. The `LineGauge` provides a compact, high-density progress indicator.
11
+
12
+ ## Features Demonstrated
13
+
14
+ - **Compact Rendering**: Visualizing progress in a single character height.
15
+ - **Custom Symbols**: Replacing the standard line with Blocks, Shades, Dashes, or ASCII characters.
16
+ - **Styling**: Independent styling for the filled (progress) and unfilled (track) portions.
17
+
18
+ ## Hotkeys
19
+
20
+ - **Arrows (←/→)**: Adjust Ratio (`ratio`)
21
+ - **f**: Cycle Filled Symbol (`filled_symbol`)
22
+ - **u**: Cycle Unfilled Symbol (`unfilled_symbol`)
23
+ - **c**: Cycle Filled Color (`filled_style`)
24
+ - **x**: Cycle Unfilled Color (`unfilled_style`)
25
+ - **b**: Cycle Base Style (`style`)
26
+ - **q**: Cycle Quit
27
+
28
+ ## Usage
29
+
30
+ ```bash
31
+ ruby examples/widget_line_gauge_demo/app.rb
32
+ ```
33
+
34
+ ## Learning Outcomes
35
+
36
+ Use this example if you need to...
37
+ - Add a progress bar to a list item or table row.
38
+ - Create a status line at the bottom of the screen.
39
+ - Show multiple metrics (CPU, RAM, Net) in a compact list.
40
+
41
+ ![Demo](/doc/images/widget_line_gauge_demo.png)