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
@@ -0,0 +1,201 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
5
+ # SPDX-License-Identifier: AGPL-3.0-or-later
6
+
7
+ $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
8
+ require "bundler/setup"
9
+ require "ratatui_ruby"
10
+
11
+ # Sample process data
12
+ PROCESSES = [
13
+ { pid: 1234, name: "ruby", cpu: 15.2 },
14
+ { pid: 5678, name: "postgres", cpu: 8.7 },
15
+ { pid: 9012, name: "nginx", cpu: 3.1 },
16
+ { pid: 3456, name: "redis", cpu: 12.4 },
17
+ { pid: 7890, name: "sidekiq", cpu: 22.8 },
18
+ { pid: 2345, name: "webpack", cpu: 45.3 },
19
+ { pid: 6789, name: "node", cpu: 18.9 },
20
+ ].freeze
21
+
22
+ class AppTableSelect
23
+ attr_reader :selected_index, :selected_col, :current_style_index, :column_spacing, :highlight_spacing, :column_highlight_style, :cell_highlight_style
24
+
25
+ HIGHLIGHT_SPACINGS = [
26
+ { name: "When Selected", spacing: :when_selected },
27
+ { name: "Always", spacing: :always },
28
+ { name: "Never", spacing: :never },
29
+ ].freeze
30
+
31
+ def initialize
32
+ @selected_index = 1
33
+ @selected_col = 1
34
+ @current_style_index = 0
35
+ @column_spacing = 1
36
+ @highlight_spacing_index = 0
37
+ @show_column_highlight = true
38
+ @show_cell_highlight = true
39
+ end
40
+
41
+ def run
42
+ RatatuiRuby.run do |tui|
43
+ @tui = tui
44
+ setup_styles
45
+ loop do
46
+ @tui.draw do |frame|
47
+ render(frame)
48
+ end
49
+ break if handle_input == :quit
50
+ end
51
+ end
52
+ end
53
+
54
+ private def setup_styles
55
+ @styles = [
56
+ { name: "Cyan", style: @tui.style(fg: :cyan) },
57
+ { name: "Red", style: @tui.style(fg: :red) },
58
+ { name: "Green", style: @tui.style(fg: :green) },
59
+ { name: "Blue on White", style: @tui.style(fg: :blue, bg: :white) },
60
+ { name: "Magenta", style: @tui.style(fg: :magenta, modifiers: [:bold]) },
61
+ ]
62
+ @column_highlight_style = @tui.style(fg: :magenta)
63
+ @cell_highlight_style = @tui.style(fg: :white, bg: :red, modifiers: [:bold])
64
+ @hotkey_style = @tui.style(modifiers: [:bold, :underlined])
65
+ end
66
+
67
+ private def render(frame)
68
+ # Create table rows from process data
69
+ rows = PROCESSES.map { |p| [p[:pid].to_s, p[:name], "#{p[:cpu]}%"] }
70
+
71
+ # Define column widths
72
+ widths = [
73
+ @tui.constraint_length(8),
74
+ @tui.constraint_length(15),
75
+ @tui.constraint_length(10),
76
+ ]
77
+
78
+ # Create highlight style (yellow text)
79
+ highlight_style = @tui.style(fg: :yellow)
80
+
81
+ current_style_entry = @styles[@current_style_index]
82
+ current_spacing_entry = HIGHLIGHT_SPACINGS[@highlight_spacing_index]
83
+ selection_label = @selected_index.nil? ? "none" : @selected_index.to_s
84
+
85
+ # Main table
86
+ table = @tui.table(
87
+ header: ["PID", "Name", "CPU"],
88
+ rows:,
89
+ widths:,
90
+ selected_row: @selected_index,
91
+ selected_column: @selected_col,
92
+ highlight_style:,
93
+ highlight_symbol: "> ",
94
+ highlight_spacing: current_spacing_entry[:spacing],
95
+ column_highlight_style: @show_column_highlight ? @column_highlight_style : nil,
96
+ cell_highlight_style: @show_cell_highlight ? @cell_highlight_style : nil,
97
+ style: current_style_entry[:style],
98
+ column_spacing: @column_spacing,
99
+ block: @tui.block(
100
+ title: "Processes",
101
+ borders: :all
102
+ ),
103
+ footer: ["Total: #{PROCESSES.length}", "Total CPU: #{PROCESSES.sum { |p| p[:cpu] }}%", ""]
104
+ )
105
+
106
+ # Bottom control panel
107
+ control_panel = @tui.block(
108
+ title: "Controls",
109
+ borders: [:all],
110
+ children: [
111
+ @tui.paragraph(
112
+ text: [
113
+ # Line 1: Navigation
114
+ @tui.text_line(spans: [
115
+ @tui.text_span(content: "↑/↓", style: @hotkey_style),
116
+ @tui.text_span(content: ": Nav Row "),
117
+ @tui.text_span(content: "←/→", style: @hotkey_style),
118
+ @tui.text_span(content: ": Nav Col "),
119
+ @tui.text_span(content: "x", style: @hotkey_style),
120
+ @tui.text_span(content: ": Toggle Row (#{selection_label}) "),
121
+ @tui.text_span(content: "q", style: @hotkey_style),
122
+ @tui.text_span(content: ": Quit"),
123
+ ]),
124
+ # Line 2: Table Controls
125
+ @tui.text_line(spans: [
126
+ @tui.text_span(content: "s", style: @hotkey_style),
127
+ @tui.text_span(content: ": Style (#{current_style_entry[:name]}) "),
128
+ @tui.text_span(content: "p", style: @hotkey_style),
129
+ @tui.text_span(content: ": Spacing (#{current_spacing_entry[:name]}) "),
130
+ ]),
131
+ # Line 3: More Controls
132
+ @tui.text_line(spans: [
133
+ @tui.text_span(content: ": Col Space (#{@column_spacing}) "),
134
+ @tui.text_span(content: "c", style: @hotkey_style),
135
+ @tui.text_span(content: ": Col Highlight (#{@show_column_highlight ? 'On' : 'Off'}) "),
136
+ @tui.text_span(content: "z", style: @hotkey_style),
137
+ @tui.text_span(content: ": Cell Highlight (#{@show_cell_highlight ? 'On' : 'Off'})"),
138
+ ]),
139
+ ]
140
+ ),
141
+ ]
142
+ )
143
+
144
+ # Layout
145
+ layout = @tui.layout_split(
146
+ frame.area,
147
+ direction: :vertical,
148
+ constraints: [
149
+ @tui.constraint_fill(1),
150
+ @tui.constraint_length(5),
151
+ ]
152
+ )
153
+
154
+ frame.render_widget(table, layout[0])
155
+ frame.render_widget(control_panel, layout[1])
156
+ end
157
+
158
+ private def handle_input
159
+ event = @tui.poll_event
160
+
161
+ case event
162
+ in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
163
+ :quit
164
+ in type: :key, code: "down" | "j"
165
+ @selected_index = ((@selected_index || -1) + 1) % PROCESSES.length
166
+ in type: :key, code: "up" | "k"
167
+ @selected_index = (@selected_index || 0) - 1
168
+ @selected_index = PROCESSES.length - 1 if @selected_index.negative?
169
+ in type: :key, code: "right" | "l"
170
+ @selected_col = ((@selected_col || -1) + 1) % 3 # 3 columns
171
+ in type: :key, code: "left" | "h"
172
+ # 'h' is already used for highlight spacing, but let's override it or ignore vim keys for left/right?
173
+ # Actually 'h' is used for spacing in this demo. Let's just use arrows for cols.
174
+ # Or map 'h' to left if user meant vim keys.
175
+ # The demo uses 'h' for "Spacing". Let's change Spacing key to 'p' (property/padding?) or something else.
176
+ # Or just stick to arrows for columns to avoid conflict.
177
+ @selected_col = (@selected_col || 0) - 1
178
+ @selected_col = 2 if @selected_col.negative?
179
+ in type: :key, code: "s"
180
+ @current_style_index = (@current_style_index + 1) % @styles.length
181
+ in type: :key, code: "+"
182
+ @column_spacing += 1
183
+ in type: :key, code: "-"
184
+ @column_spacing = [@column_spacing - 1, 0].max
185
+ in type: :key, code: "p"
186
+ @highlight_spacing_index = (@highlight_spacing_index + 1) % HIGHLIGHT_SPACINGS.length
187
+ in type: :key, code: "x"
188
+ @selected_index = @selected_index.nil? ? 0 : nil
189
+ in type: :key, code: "c"
190
+ @show_column_highlight = !@show_column_highlight
191
+ in type: :key, code: "z"
192
+ @show_cell_highlight = !@show_cell_highlight
193
+ else
194
+ nil
195
+ end
196
+ end
197
+ end
198
+
199
+ if __FILE__ == $0
200
+ AppTableSelect.new.run
201
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
7
+
8
+ require "ratatui_ruby"
9
+
10
+ class VerifyQuickstartDsl
11
+ def run
12
+ # 1. Initialize the terminal, start the run loop, and ensure the terminal is restored.
13
+ RatatuiRuby.run do |tui|
14
+ loop do
15
+ # 2. Create your UI with methods instead of classes.
16
+ view = tui.paragraph(
17
+ text: "Hello, Ratatui! Press 'q' to quit.",
18
+ alignment: :center,
19
+ block: tui.block(
20
+ title: "My Ruby TUI App",
21
+ title_alignment: :center,
22
+ borders: [:all],
23
+ border_color: "cyan",
24
+ style: { fg: "white" }
25
+ )
26
+ )
27
+
28
+ # 3. Use RatatuiRuby methods, too.
29
+ tui.draw do |frame|
30
+ frame.render_widget(view, frame.area)
31
+ end
32
+
33
+ # 4. Poll for events with pattern matching
34
+ case tui.poll_event
35
+ in { type: :key, code: "q" }
36
+ break
37
+ else
38
+ # Ignore other events
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ VerifyQuickstartDsl.new.run if __FILE__ == $PROGRAM_NAME
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
7
+
8
+ require "ratatui_ruby"
9
+
10
+ class VerifyQuickstartLayout
11
+ def run
12
+ RatatuiRuby.run do |tui|
13
+ loop do
14
+ tui.draw do |frame|
15
+ # 1. Split the screen
16
+ top, bottom = tui.layout_split(
17
+ frame.area,
18
+ direction: :vertical,
19
+ constraints: [
20
+ tui.constraint_percentage(75),
21
+ tui.constraint_percentage(25),
22
+ ]
23
+ )
24
+
25
+ # 2. Render Top Widget
26
+ frame.render_widget(
27
+ tui.paragraph(
28
+ text: "Hello, Ratatui!",
29
+ alignment: :center,
30
+ block: tui.block(title: "Content", borders: [:all], border_color: "cyan")
31
+ ),
32
+ top
33
+ )
34
+
35
+ # 3. Render Bottom Widget with Styled Text
36
+ # We use a Line of Spans to style specific characters
37
+ text_line = tui.text_line(
38
+ spans: [
39
+ tui.text_span(content: "Press '"),
40
+ tui.text_span(
41
+ content: "q",
42
+ style: tui.style(modifiers: [:bold, :underlined])
43
+ ),
44
+ tui.text_span(content: "' to quit."),
45
+ ],
46
+ alignment: :center
47
+ )
48
+
49
+ frame.render_widget(
50
+ tui.paragraph(
51
+ text: text_line,
52
+ block: tui.block(title: "Controls", borders: [:all])
53
+ ),
54
+ bottom
55
+ )
56
+ end
57
+
58
+ case tui.poll_event
59
+ in { type: :key, code: "q" }
60
+ break
61
+ else
62
+ # Ignore other events
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ VerifyQuickstartLayout.new.run if __FILE__ == $PROGRAM_NAME
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
7
+
8
+ require "ratatui_ruby"
9
+
10
+ class VerifyQuickstartLifecycle
11
+ def run
12
+ # 1. Initialize the terminal
13
+ RatatuiRuby.init_terminal
14
+
15
+ begin
16
+ # The Main Loop
17
+ loop do
18
+ # 2. Create your UI (Immediate Mode)
19
+ # We define a Paragraph widget inside a Block with a title and borders.
20
+ view = RatatuiRuby::Paragraph.new(
21
+ text: "Hello, Ratatui! Press 'q' to quit.",
22
+ alignment: :center,
23
+ block: RatatuiRuby::Block.new(
24
+ title: "My Ruby TUI App",
25
+ title_alignment: :center,
26
+ borders: [:all],
27
+ border_color: "cyan",
28
+ style: { fg: "white" }
29
+ )
30
+ )
31
+
32
+ # 3. Draw the UI
33
+ RatatuiRuby.draw do |frame|
34
+ frame.render_widget(view, frame.area)
35
+ end
36
+
37
+ # 4. Poll for events
38
+ event = RatatuiRuby.poll_event
39
+ break if event.key? && event.code == "q"
40
+ end
41
+ ensure
42
+ # 5. Restore the terminal to its original state
43
+ RatatuiRuby.restore_terminal
44
+ end
45
+ end
46
+ end
47
+
48
+ VerifyQuickstartLifecycle.new.run if __FILE__ == $PROGRAM_NAME
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
7
+
8
+ require "ratatui_ruby"
9
+ class VerifyReadmeUsage
10
+ def run
11
+ RatatuiRuby.run do |tui|
12
+ loop do
13
+ tui.draw do |frame|
14
+ frame.render_widget(
15
+ tui.paragraph(
16
+ text: "Hello, Ratatui! Press 'q' to quit.",
17
+ alignment: :center,
18
+ block: tui.block(
19
+ title: "My Ruby TUI App",
20
+ borders: [:all],
21
+ border_color: "cyan"
22
+ )
23
+ ),
24
+ frame.area
25
+ )
26
+ end
27
+ event = tui.poll_event
28
+ break if event == "q" || event == :ctrl_c
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ VerifyReadmeUsage.new.run if __FILE__ == $PROGRAM_NAME
@@ -0,0 +1,238 @@
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 categorical data visualization with interactive attribute cycling.
10
+ #
11
+ # Raw tables of numbers are hard to scan. Comparing magnitudes requires mental arithmetic, which slows down decision-making.
12
+ #
13
+ # This demo showcases the <tt>BarChart</tt> widget. It provides an interactive playground where you can cycle through different data formats, styles, and orientations in real-time.
14
+ #
15
+ # Use it to understand how to visualize and compare discrete datasets effectively.
16
+ #
17
+ # === Example
18
+ #
19
+ # Run the demo from the terminal:
20
+ #
21
+ # ruby examples/widget_barchart_demo/app.rb
22
+ #
23
+ # rdoc-image:/doc/images/widget_barchart_demo.png
24
+ class WidgetBarchartDemo
25
+ def initialize
26
+ @data_index = 0
27
+ @styles = nil # Initialized in run
28
+ @style_index = 0
29
+ @label_style_index = 0
30
+ @value_style_index = 0
31
+ @bar_sets = [
32
+ { name: "Default", set: nil },
33
+ { name: "Numbers (Short)", set: { 8 => "8", 7 => "7", 6 => "6", 5 => "5", 4 => "4", 3 => "3", 2 => "2", 1 => "1", 0 => "0" } },
34
+ { name: "Letters (Long)", set: { full: "H", seven_eighths: "G", three_quarters: "F", five_eighths: "E", half: "D", three_eighths: "C", one_quarter: "B", one_eighth: "A", empty: " " } },
35
+ { name: "ASCII (Heights)", set: [" ", "_", ".", "-", "=", "+", "*", "#", "@"] },
36
+ ]
37
+ @bar_set_index = 0
38
+ @direction = :vertical
39
+ @bar_width = 8
40
+ @bar_gap = 1
41
+ @group_gap = 0
42
+ @height_mode = :full
43
+ @hotkey_style = nil
44
+ end
45
+
46
+ def run
47
+ RatatuiRuby.run do |tui|
48
+ @tui = tui
49
+ init_styles
50
+
51
+ loop do
52
+ render
53
+ break if handle_input == :quit
54
+ end
55
+ end
56
+ end
57
+
58
+ private def init_styles
59
+ @styles = [
60
+ { name: "Green", style: @tui.style(fg: :green) },
61
+ { name: "Blue", style: @tui.style(fg: :blue) },
62
+ { name: "Red", style: @tui.style(fg: :red) },
63
+ { name: "Cyan", style: @tui.style(fg: :cyan) },
64
+ { name: "Yellow Bold", style: @tui.style(fg: :yellow, modifiers: [:bold]) },
65
+ { name: "Reversed", style: @tui.style(modifiers: [:reversed]) },
66
+ ]
67
+ @hotkey_style = @tui.style(modifiers: [:bold, :underlined])
68
+ end
69
+
70
+ private def current_data
71
+ case @data_index
72
+ when 0 # Simple Hash
73
+ {
74
+ "Q1" => 50,
75
+ "Q2" => 80,
76
+ "Q3" => 45,
77
+ "Q4" => 60,
78
+ "Q1'" => 55,
79
+ "Q2'" => 85,
80
+ "Q3'" => 50,
81
+ "Q4'" => 65,
82
+ }
83
+ when 1 # Array with styles
84
+ [
85
+ ["Mon", 120],
86
+ ["Tue", 150],
87
+ ["Wed", 130],
88
+ ["Thu", 160],
89
+ ["Fri", 140],
90
+ ["Sat", 110, @tui.style(fg: :red)],
91
+ ["Sun", 100, @tui.style(fg: :red)],
92
+ ]
93
+ when 2 # Groups
94
+ [
95
+ @tui.bar_chart_bar_group(label: "2024", bars: [
96
+ @tui.bar_chart_bar(value: 40, label: "Q1"),
97
+ @tui.bar_chart_bar(value: 45, label: "Q2"),
98
+ @tui.bar_chart_bar(value: 50, label: "Q3"),
99
+ @tui.bar_chart_bar(value: 55, label: "Q4"),
100
+ ]),
101
+ @tui.bar_chart_bar_group(label: "2025", bars: [
102
+ @tui.bar_chart_bar(value: 60, label: "Q1", style: @tui.style(fg: :yellow)),
103
+ @tui.bar_chart_bar(value: 65, label: "Q2", style: @tui.style(fg: :yellow)),
104
+ @tui.bar_chart_bar(value: 70, label: "Q3", style: @tui.style(fg: :yellow)),
105
+ @tui.bar_chart_bar(value: 75, label: "Q4", style: @tui.style(fg: :yellow)),
106
+ ]),
107
+ ]
108
+ end
109
+ end
110
+
111
+ private def data_name
112
+ ["Simple Hash", "Styled Array", "Groups"][@data_index]
113
+ end
114
+
115
+ private def render
116
+ @tui.draw do |frame|
117
+ chart_area, controls_area = @tui.layout_split(
118
+ frame.area,
119
+ direction: :vertical,
120
+ constraints: [
121
+ @tui.constraint_fill(1),
122
+ @tui.constraint_length(6),
123
+ ]
124
+ )
125
+
126
+ # Handle Mini Mode
127
+ effective_chart_area = if @height_mode == :mini
128
+ mini_area, = @tui.layout_split(
129
+ chart_area,
130
+ direction: :vertical,
131
+ constraints: [
132
+ @tui.constraint_length(3),
133
+ @tui.constraint_fill(1),
134
+ ]
135
+ )
136
+ mini_area
137
+ else
138
+ chart_area
139
+ end
140
+
141
+ bar_chart = @tui.bar_chart(
142
+ data: current_data,
143
+ bar_width: @bar_width,
144
+ style: @styles[@style_index][:style],
145
+ bar_gap: @bar_gap,
146
+ group_gap: @group_gap,
147
+ direction: @direction,
148
+ label_style: @styles[@label_style_index][:style],
149
+ value_style: @styles[@value_style_index][:style],
150
+ bar_set: @bar_sets[@bar_set_index][:set],
151
+ block: @tui.block(
152
+ title: "BarChart Demo: #{data_name}",
153
+ borders: [:all]
154
+ )
155
+ )
156
+ frame.render_widget(bar_chart, effective_chart_area)
157
+
158
+ render_controls(frame, controls_area)
159
+ end
160
+ end
161
+
162
+ private def render_controls(frame, area)
163
+ controls = @tui.block(
164
+ title: "Controls",
165
+ borders: [:all],
166
+ children: [
167
+ @tui.paragraph(
168
+ text: [
169
+ @tui.text_line(spans: [
170
+ @tui.text_span(content: "d", style: @hotkey_style),
171
+ @tui.text_span(content: ": Data (#{data_name}) "),
172
+ @tui.text_span(content: "v", style: @hotkey_style),
173
+ @tui.text_span(content: ": Direction (#{@direction}) "),
174
+ @tui.text_span(content: "q", style: @hotkey_style),
175
+ @tui.text_span(content: ": Quit"),
176
+ ]),
177
+ @tui.text_line(spans: [
178
+ @tui.text_span(content: "w", style: @hotkey_style),
179
+ @tui.text_span(content: ": Width (#{@bar_width}) "),
180
+ @tui.text_span(content: "a", style: @hotkey_style),
181
+ @tui.text_span(content: ": Gap (#{@bar_gap}) "),
182
+ @tui.text_span(content: "g", style: @hotkey_style),
183
+ @tui.text_span(content: ": Group Gap (#{@group_gap})"),
184
+ ]),
185
+ @tui.text_line(spans: [
186
+ @tui.text_span(content: "s", style: @hotkey_style),
187
+ @tui.text_span(content: ": Style (#{@styles[@style_index][:name]}) "),
188
+ @tui.text_span(content: "x", style: @hotkey_style),
189
+ @tui.text_span(content: ": Label (#{@styles[@label_style_index][:name]}) "),
190
+ @tui.text_span(content: "z", style: @hotkey_style),
191
+ @tui.text_span(content: ": Value (#{@styles[@value_style_index][:name]}) "),
192
+ ]),
193
+ @tui.text_line(spans: [
194
+ @tui.text_span(content: "b", style: @hotkey_style),
195
+ @tui.text_span(content: ": Set (#{@bar_sets[@bar_set_index][:name]}) "),
196
+ @tui.text_span(content: "m", style: @hotkey_style),
197
+ @tui.text_span(content: ": Mode (#{(@height_mode == :full) ? 'Full' : 'Mini'})"),
198
+ ]),
199
+ ]
200
+ ),
201
+ ]
202
+ )
203
+ frame.render_widget(controls, area)
204
+ end
205
+
206
+ private def handle_input
207
+ case @tui.poll_event
208
+ in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
209
+ :quit
210
+ in type: :key, code: "d"
211
+ @data_index = (@data_index + 1) % 3
212
+ in type: :key, code: "v"
213
+ @direction = (@direction == :vertical) ? :horizontal : :vertical
214
+ # Adjust width default based on direction for better UX, though user can manually adjust 'w'
215
+ @bar_width = (@direction == :vertical) ? 8 : 1
216
+ in type: :key, code: "w"
217
+ @bar_width = (@bar_width % 10) + 1
218
+ in type: :key, code: "a"
219
+ @bar_gap = (@bar_gap + 1) % 5
220
+ in type: :key, code: "g"
221
+ @group_gap = (@group_gap + 1) % 5
222
+ in type: :key, code: "s"
223
+ @style_index = (@style_index + 1) % @styles.size
224
+ in type: :key, code: "x"
225
+ @label_style_index = (@label_style_index + 1) % @styles.size
226
+ in type: :key, code: "z"
227
+ @value_style_index = (@value_style_index + 1) % @styles.size
228
+ in type: :key, code: "b"
229
+ @bar_set_index = (@bar_set_index + 1) % @bar_sets.size
230
+ in type: :key, code: "m"
231
+ @height_mode = (@height_mode == :full) ? :mini : :full
232
+ else
233
+ # Ignore
234
+ end
235
+ end
236
+ end
237
+
238
+ WidgetBarchartDemo.new.run if __FILE__ == $0