ratatui_ruby 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (351) hide show
  1. checksums.yaml +4 -4
  2. data/.builds/ruby-3.2.yml +1 -1
  3. data/.builds/ruby-3.3.yml +1 -1
  4. data/.builds/ruby-3.4.yml +1 -1
  5. data/.builds/ruby-4.0.0.yml +1 -1
  6. data/AGENTS.md +87 -171
  7. data/CHANGELOG.md +38 -1
  8. data/README.md +8 -3
  9. data/REUSE.toml +20 -0
  10. data/doc/application_architecture.md +105 -45
  11. data/doc/application_testing.md +5 -3
  12. data/doc/contributors/design/ruby_frontend.md +9 -5
  13. data/doc/contributors/developing_examples.md +76 -18
  14. data/doc/contributors/documentation_style.md +7 -0
  15. data/doc/contributors/index.md +2 -0
  16. data/doc/event_handling.md +10 -4
  17. data/doc/images/app_all_events.png +0 -0
  18. data/doc/images/app_color_picker.png +0 -0
  19. data/doc/images/verify_readme_usage.png +0 -0
  20. data/doc/images/widget_barchart_demo.png +0 -0
  21. data/doc/images/widget_block_padding.png +0 -0
  22. data/doc/images/widget_block_titles.png +0 -0
  23. data/doc/images/widget_box_demo.png +0 -0
  24. data/doc/images/widget_calendar_demo.png +0 -0
  25. data/doc/images/widget_cell_demo.png +0 -0
  26. data/doc/images/widget_chart_demo.png +0 -0
  27. data/doc/images/widget_gauge_demo.png +0 -0
  28. data/doc/images/widget_layout_split.png +0 -0
  29. data/doc/images/widget_line_gauge_demo.png +0 -0
  30. data/doc/images/widget_list_demo.png +0 -0
  31. data/doc/images/widget_ratatui_logo_demo.png +0 -0
  32. data/doc/images/widget_ratatui_mascot_demo.png +0 -0
  33. data/doc/images/widget_render.png +0 -0
  34. data/doc/images/widget_scrollbar_demo.png +0 -0
  35. data/doc/images/widget_sparkline_demo.png +0 -0
  36. data/doc/images/widget_style_colors.png +0 -0
  37. data/doc/images/widget_table_flex.png +0 -0
  38. data/doc/images/widget_tabs_demo.png +0 -0
  39. data/doc/interactive_design.md +25 -30
  40. data/doc/quickstart.md +147 -120
  41. data/examples/app_all_events/README.md +81 -0
  42. data/examples/app_all_events/app.rb +93 -0
  43. data/examples/app_all_events/model/event_color_cycle.rb +41 -0
  44. data/examples/app_all_events/model/event_entry.rb +75 -0
  45. data/examples/app_all_events/model/events.rb +180 -0
  46. data/examples/app_all_events/model/highlight.rb +57 -0
  47. data/examples/app_all_events/model/timestamp.rb +54 -0
  48. data/examples/app_all_events/test/snapshots/after_focus_lost.txt +24 -0
  49. data/examples/app_all_events/test/snapshots/after_focus_regained.txt +24 -0
  50. data/examples/app_all_events/test/snapshots/after_horizontal_resize.txt +24 -0
  51. data/examples/app_all_events/test/snapshots/after_key_a.txt +24 -0
  52. data/examples/app_all_events/test/snapshots/after_key_ctrl_x.txt +24 -0
  53. data/examples/app_all_events/test/snapshots/after_mouse_click.txt +24 -0
  54. data/examples/app_all_events/test/snapshots/after_mouse_drag.txt +24 -0
  55. data/examples/app_all_events/test/snapshots/after_multiple_events.txt +24 -0
  56. data/examples/app_all_events/test/snapshots/after_paste.txt +24 -0
  57. data/examples/app_all_events/test/snapshots/after_resize.txt +24 -0
  58. data/examples/app_all_events/test/snapshots/after_right_click.txt +24 -0
  59. data/examples/app_all_events/test/snapshots/after_vertical_resize.txt +24 -0
  60. data/examples/app_all_events/test/snapshots/initial_state.txt +24 -0
  61. data/examples/app_all_events/view/app_view.rb +78 -0
  62. data/examples/app_all_events/view/controls_view.rb +50 -0
  63. data/examples/app_all_events/view/counts_view.rb +55 -0
  64. data/examples/app_all_events/view/live_view.rb +69 -0
  65. data/examples/app_all_events/view/log_view.rb +60 -0
  66. data/examples/app_all_events/view.rb +7 -0
  67. data/examples/app_all_events/view_state.rb +42 -0
  68. data/examples/app_color_picker/README.md +94 -0
  69. data/examples/app_color_picker/app.rb +112 -0
  70. data/examples/app_color_picker/clipboard.rb +84 -0
  71. data/examples/app_color_picker/color.rb +191 -0
  72. data/examples/app_color_picker/copy_dialog.rb +170 -0
  73. data/examples/app_color_picker/harmony.rb +56 -0
  74. data/examples/app_color_picker/input.rb +142 -0
  75. data/examples/app_color_picker/palette.rb +80 -0
  76. data/examples/app_color_picker/scene.rb +201 -0
  77. data/examples/{login_form → app_login_form}/app.rb +39 -42
  78. data/examples/{map_demo → app_map_demo}/app.rb +24 -21
  79. data/examples/{table_select → app_table_select}/app.rb +68 -65
  80. data/examples/{quickstart_dsl → verify_quickstart_dsl}/app.rb +15 -6
  81. data/examples/verify_quickstart_layout/app.rb +69 -0
  82. data/examples/{quickstart_lifecycle → verify_quickstart_lifecycle}/app.rb +19 -10
  83. data/examples/verify_readme_usage/app.rb +34 -0
  84. data/examples/widget_barchart_demo/app.rb +238 -0
  85. data/examples/{block_padding → widget_block_padding}/app.rb +17 -13
  86. data/examples/{block_titles → widget_block_titles}/app.rb +25 -17
  87. data/examples/{box_demo → widget_box_demo}/app.rb +99 -65
  88. data/examples/widget_calendar_demo/app.rb +109 -0
  89. data/examples/widget_cell_demo/app.rb +104 -0
  90. data/examples/widget_chart_demo/app.rb +213 -0
  91. data/examples/widget_gauge_demo/app.rb +212 -0
  92. data/examples/widget_layout_split/app.rb +246 -0
  93. data/examples/widget_line_gauge_demo/app.rb +217 -0
  94. data/examples/widget_list_demo/app.rb +382 -0
  95. data/examples/widget_list_styles/app.rb +141 -0
  96. data/examples/widget_popup_demo/app.rb +104 -0
  97. data/examples/widget_ratatui_logo_demo/app.rb +103 -0
  98. data/examples/widget_ratatui_mascot_demo/app.rb +93 -0
  99. data/examples/widget_rect/app.rb +205 -0
  100. data/examples/widget_render/app.rb +184 -0
  101. data/examples/widget_rich_text/app.rb +137 -0
  102. data/examples/widget_scroll_text/app.rb +108 -0
  103. data/examples/widget_scrollbar_demo/app.rb +153 -0
  104. data/examples/widget_sparkline_demo/app.rb +274 -0
  105. data/examples/widget_style_colors/app.rb +19 -21
  106. data/examples/widget_table_flex/app.rb +95 -0
  107. data/examples/widget_tabs_demo/app.rb +167 -0
  108. data/ext/ratatui_ruby/Cargo.lock +1 -1
  109. data/ext/ratatui_ruby/Cargo.toml +1 -1
  110. data/ext/ratatui_ruby/src/events.rs +121 -36
  111. data/ext/ratatui_ruby/src/frame.rs +115 -0
  112. data/ext/ratatui_ruby/src/lib.rs +79 -26
  113. data/ext/ratatui_ruby/src/rendering.rs +8 -4
  114. data/ext/ratatui_ruby/src/style.rs +138 -57
  115. data/ext/ratatui_ruby/src/terminal.rs +5 -9
  116. data/ext/ratatui_ruby/src/text.rs +13 -6
  117. data/ext/ratatui_ruby/src/widgets/barchart.rs +56 -54
  118. data/ext/ratatui_ruby/src/widgets/block.rs +7 -6
  119. data/ext/ratatui_ruby/src/widgets/canvas.rs +21 -3
  120. data/ext/ratatui_ruby/src/widgets/chart.rs +20 -10
  121. data/ext/ratatui_ruby/src/widgets/layout.rs +9 -4
  122. data/ext/ratatui_ruby/src/widgets/list.rs +32 -9
  123. data/ext/ratatui_ruby/src/widgets/overlay.rs +2 -1
  124. data/ext/ratatui_ruby/src/widgets/paragraph.rs +1 -1
  125. data/ext/ratatui_ruby/src/widgets/ratatui_logo.rs +19 -8
  126. data/ext/ratatui_ruby/src/widgets/ratatui_mascot.rs +17 -10
  127. data/ext/ratatui_ruby/src/widgets/scrollbar.rs +4 -2
  128. data/ext/ratatui_ruby/src/widgets/sparkline.rs +14 -11
  129. data/ext/ratatui_ruby/src/widgets/table.rs +8 -4
  130. data/ext/ratatui_ruby/src/widgets/tabs.rs +11 -11
  131. data/lib/ratatui_ruby/cell.rb +3 -3
  132. data/lib/ratatui_ruby/event/key.rb +1 -1
  133. data/lib/ratatui_ruby/event/none.rb +43 -0
  134. data/lib/ratatui_ruby/event.rb +56 -4
  135. data/lib/ratatui_ruby/frame.rb +87 -0
  136. data/lib/ratatui_ruby/schema/bar_chart/bar.rb +11 -11
  137. data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +1 -5
  138. data/lib/ratatui_ruby/schema/bar_chart.rb +217 -217
  139. data/lib/ratatui_ruby/schema/block.rb +163 -168
  140. data/lib/ratatui_ruby/schema/calendar.rb +66 -67
  141. data/lib/ratatui_ruby/schema/canvas.rb +63 -63
  142. data/lib/ratatui_ruby/schema/center.rb +46 -46
  143. data/lib/ratatui_ruby/schema/chart.rb +135 -143
  144. data/lib/ratatui_ruby/schema/clear.rb +42 -42
  145. data/lib/ratatui_ruby/schema/constraint.rb +76 -76
  146. data/lib/ratatui_ruby/schema/cursor.rb +25 -25
  147. data/lib/ratatui_ruby/schema/gauge.rb +53 -53
  148. data/lib/ratatui_ruby/schema/layout.rb +87 -87
  149. data/lib/ratatui_ruby/schema/line_gauge.rb +62 -62
  150. data/lib/ratatui_ruby/schema/list.rb +86 -84
  151. data/lib/ratatui_ruby/schema/overlay.rb +31 -31
  152. data/lib/ratatui_ruby/schema/paragraph.rb +80 -80
  153. data/lib/ratatui_ruby/schema/ratatui_logo.rb +10 -6
  154. data/lib/ratatui_ruby/schema/ratatui_mascot.rb +10 -5
  155. data/lib/ratatui_ruby/schema/rect.rb +60 -60
  156. data/lib/ratatui_ruby/schema/scrollbar.rb +119 -119
  157. data/lib/ratatui_ruby/schema/shape/label.rb +1 -1
  158. data/lib/ratatui_ruby/schema/sparkline.rb +111 -110
  159. data/lib/ratatui_ruby/schema/style.rb +46 -46
  160. data/lib/ratatui_ruby/schema/table.rb +112 -119
  161. data/lib/ratatui_ruby/schema/tabs.rb +66 -67
  162. data/lib/ratatui_ruby/session/autodoc.rb +417 -0
  163. data/lib/ratatui_ruby/session.rb +40 -23
  164. data/lib/ratatui_ruby/test_helper.rb +185 -19
  165. data/lib/ratatui_ruby/version.rb +1 -1
  166. data/lib/ratatui_ruby.rb +65 -39
  167. data/{examples/sparkline_demo → sig/examples/app_all_events}/app.rbs +3 -2
  168. data/sig/examples/app_all_events/model/event_entry.rbs +16 -0
  169. data/sig/examples/app_all_events/model/events.rbs +15 -0
  170. data/sig/examples/app_all_events/model/timestamp.rbs +11 -0
  171. data/sig/examples/app_all_events/view/app_view.rbs +8 -0
  172. data/sig/examples/app_all_events/view/controls_view.rbs +6 -0
  173. data/sig/examples/app_all_events/view/counts_view.rbs +6 -0
  174. data/sig/examples/app_all_events/view/live_view.rbs +6 -0
  175. data/sig/examples/app_all_events/view/log_view.rbs +6 -0
  176. data/sig/examples/app_all_events/view.rbs +8 -0
  177. data/sig/examples/app_all_events/view_state.rbs +15 -0
  178. data/{examples/list_demo → sig/examples/app_color_picker}/app.rbs +2 -2
  179. data/sig/examples/app_login_form/app.rbs +11 -0
  180. data/sig/examples/app_map_demo/app.rbs +11 -0
  181. data/sig/examples/app_table_select/app.rbs +11 -0
  182. data/sig/examples/verify_quickstart_dsl/app.rbs +11 -0
  183. data/sig/examples/verify_quickstart_lifecycle/app.rbs +11 -0
  184. data/sig/examples/verify_readme_usage/app.rbs +11 -0
  185. data/sig/examples/widget_block_padding/app.rbs +11 -0
  186. data/sig/examples/widget_block_titles/app.rbs +11 -0
  187. data/sig/examples/widget_box_demo/app.rbs +11 -0
  188. data/sig/examples/widget_calendar_demo/app.rbs +11 -0
  189. data/sig/examples/widget_cell_demo/app.rbs +11 -0
  190. data/sig/examples/widget_chart_demo/app.rbs +11 -0
  191. data/{examples/gauge_demo → sig/examples/widget_gauge_demo}/app.rbs +4 -0
  192. data/sig/examples/widget_layout_split/app.rbs +10 -0
  193. data/sig/examples/widget_line_gauge_demo/app.rbs +11 -0
  194. data/sig/examples/widget_list_demo/app.rbs +12 -0
  195. data/sig/examples/widget_list_styles/app.rbs +11 -0
  196. data/sig/examples/widget_popup_demo/app.rbs +11 -0
  197. data/sig/examples/widget_ratatui_logo_demo/app.rbs +11 -0
  198. data/sig/examples/widget_ratatui_mascot_demo/app.rbs +11 -0
  199. data/sig/examples/widget_rect/app.rbs +12 -0
  200. data/sig/examples/widget_render/app.rbs +10 -0
  201. data/sig/examples/widget_rich_text/app.rbs +11 -0
  202. data/sig/examples/widget_scroll_text/app.rbs +11 -0
  203. data/sig/examples/widget_scrollbar_demo/app.rbs +11 -0
  204. data/sig/examples/widget_sparkline_demo/app.rbs +10 -0
  205. data/{examples → sig/examples}/widget_style_colors/app.rbs +1 -1
  206. data/sig/examples/widget_table_flex/app.rbs +11 -0
  207. data/sig/ratatui_ruby/frame.rbs +9 -0
  208. data/sig/ratatui_ruby/ratatui_ruby.rbs +3 -2
  209. data/sig/ratatui_ruby/schema/draw.rbs +4 -0
  210. data/sig/ratatui_ruby/schema/layout.rbs +1 -1
  211. data/sig/ratatui_ruby/session.rbs +94 -0
  212. data/tasks/autodoc/inventory.rb +61 -0
  213. data/tasks/autodoc/member.rb +56 -0
  214. data/tasks/autodoc/name.rb +19 -0
  215. data/tasks/autodoc/notice.rb +26 -0
  216. data/tasks/autodoc/rbs.rb +38 -0
  217. data/tasks/autodoc/rdoc.rb +45 -0
  218. data/tasks/autodoc.rake +47 -0
  219. data/tasks/bump/history.rb +2 -2
  220. data/tasks/doc.rake +600 -6
  221. data/tasks/example_viewer.html.erb +172 -0
  222. data/tasks/lint.rake +8 -4
  223. data/tasks/resources/index.html.erb +6 -0
  224. data/tasks/sourcehut.rake +4 -4
  225. data/tasks/terminal_preview/app_screenshot.rb +1 -3
  226. data/tasks/terminal_preview/crash_report.rb +7 -9
  227. data/tasks/terminal_preview/launcher_script.rb +4 -6
  228. data/tasks/terminal_preview/preview_collection.rb +4 -6
  229. data/tasks/terminal_preview/safety_confirmation.rb +3 -5
  230. data/tasks/terminal_preview/saved_screenshot.rb +7 -9
  231. data/tasks/terminal_preview/terminal_window.rb +7 -9
  232. data/tasks/test.rake +1 -1
  233. data/tasks/website/index_page.rb +3 -3
  234. data/tasks/website/version.rb +10 -10
  235. data/tasks/website/version_menu.rb +10 -12
  236. data/tasks/website/versioned_documentation.rb +49 -17
  237. data/tasks/website/website.rb +6 -8
  238. data/tasks/website.rake +4 -4
  239. metadata +156 -125
  240. data/LICENSES/BSD-2-Clause.txt +0 -9
  241. data/doc/contributors/better_dx.md +0 -543
  242. data/doc/contributors/example_analysis.md +0 -82
  243. data/doc/images/all_events.png +0 -0
  244. data/doc/images/block_padding.png +0 -0
  245. data/doc/images/block_titles.png +0 -0
  246. data/doc/images/box_demo.png +0 -0
  247. data/doc/images/calendar_demo.png +0 -0
  248. data/doc/images/cell_demo.png +0 -0
  249. data/doc/images/chart_demo.png +0 -0
  250. data/doc/images/flex_layout.png +0 -0
  251. data/doc/images/gauge_demo.png +0 -0
  252. data/doc/images/line_gauge_demo.png +0 -0
  253. data/doc/images/list_demo.png +0 -0
  254. data/doc/images/readme_usage.png +0 -0
  255. data/doc/images/scrollbar_demo.png +0 -0
  256. data/doc/images/sparkline_demo.png +0 -0
  257. data/doc/images/table_flex.png +0 -0
  258. data/examples/all_events/app.rb +0 -169
  259. data/examples/all_events/app.rbs +0 -7
  260. data/examples/all_events/test_app.rb +0 -139
  261. data/examples/analytics/app.rb +0 -258
  262. data/examples/analytics/app.rbs +0 -7
  263. data/examples/analytics/test_app.rb +0 -132
  264. data/examples/block_padding/app.rbs +0 -7
  265. data/examples/block_padding/test_app.rb +0 -31
  266. data/examples/block_titles/app.rbs +0 -7
  267. data/examples/block_titles/test_app.rb +0 -34
  268. data/examples/box_demo/app.rbs +0 -7
  269. data/examples/box_demo/test_app.rb +0 -88
  270. data/examples/calendar_demo/app.rb +0 -101
  271. data/examples/calendar_demo/app.rbs +0 -7
  272. data/examples/calendar_demo/test_app.rb +0 -108
  273. data/examples/cell_demo/app.rb +0 -108
  274. data/examples/cell_demo/app.rbs +0 -7
  275. data/examples/cell_demo/test_app.rb +0 -36
  276. data/examples/chart_demo/app.rb +0 -203
  277. data/examples/chart_demo/app.rbs +0 -7
  278. data/examples/chart_demo/test_app.rb +0 -102
  279. data/examples/custom_widget/app.rb +0 -51
  280. data/examples/custom_widget/app.rbs +0 -7
  281. data/examples/custom_widget/test_app.rb +0 -30
  282. data/examples/flex_layout/app.rb +0 -156
  283. data/examples/flex_layout/app.rbs +0 -7
  284. data/examples/flex_layout/test_app.rb +0 -65
  285. data/examples/gauge_demo/app.rb +0 -182
  286. data/examples/gauge_demo/test_app.rb +0 -120
  287. data/examples/hit_test/app.rb +0 -175
  288. data/examples/hit_test/app.rbs +0 -7
  289. data/examples/hit_test/test_app.rb +0 -102
  290. data/examples/line_gauge_demo/app.rb +0 -190
  291. data/examples/line_gauge_demo/app.rbs +0 -7
  292. data/examples/line_gauge_demo/test_app.rb +0 -129
  293. data/examples/list_demo/app.rb +0 -253
  294. data/examples/list_demo/test_app.rb +0 -237
  295. data/examples/list_styles/app.rb +0 -140
  296. data/examples/list_styles/app.rbs +0 -7
  297. data/examples/list_styles/test_app.rb +0 -157
  298. data/examples/login_form/app.rbs +0 -7
  299. data/examples/login_form/test_app.rb +0 -51
  300. data/examples/map_demo/app.rbs +0 -7
  301. data/examples/map_demo/test_app.rb +0 -149
  302. data/examples/mouse_events/app.rb +0 -97
  303. data/examples/mouse_events/app.rbs +0 -7
  304. data/examples/mouse_events/test_app.rb +0 -53
  305. data/examples/popup_demo/app.rb +0 -103
  306. data/examples/popup_demo/app.rbs +0 -7
  307. data/examples/popup_demo/test_app.rb +0 -54
  308. data/examples/quickstart_dsl/app.rbs +0 -7
  309. data/examples/quickstart_dsl/test_app.rb +0 -29
  310. data/examples/quickstart_lifecycle/app.rbs +0 -7
  311. data/examples/quickstart_lifecycle/test_app.rb +0 -29
  312. data/examples/ratatui_logo_demo/app.rb +0 -79
  313. data/examples/ratatui_logo_demo/app.rbs +0 -7
  314. data/examples/ratatui_logo_demo/test_app.rb +0 -51
  315. data/examples/ratatui_mascot_demo/app.rb +0 -84
  316. data/examples/ratatui_mascot_demo/app.rbs +0 -7
  317. data/examples/ratatui_mascot_demo/test_app.rb +0 -47
  318. data/examples/readme_usage/app.rb +0 -29
  319. data/examples/readme_usage/app.rbs +0 -7
  320. data/examples/readme_usage/test_app.rb +0 -29
  321. data/examples/rich_text/app.rb +0 -141
  322. data/examples/rich_text/app.rbs +0 -7
  323. data/examples/rich_text/test_app.rb +0 -166
  324. data/examples/scroll_text/app.rb +0 -103
  325. data/examples/scroll_text/app.rbs +0 -7
  326. data/examples/scroll_text/test_app.rb +0 -110
  327. data/examples/scrollbar_demo/app.rb +0 -143
  328. data/examples/scrollbar_demo/app.rbs +0 -7
  329. data/examples/scrollbar_demo/test_app.rb +0 -77
  330. data/examples/sparkline_demo/app.rb +0 -240
  331. data/examples/sparkline_demo/test_app.rb +0 -107
  332. data/examples/table_flex/app.rb +0 -65
  333. data/examples/table_flex/app.rbs +0 -7
  334. data/examples/table_flex/test_app.rb +0 -36
  335. data/examples/table_select/app.rbs +0 -7
  336. data/examples/table_select/test_app.rb +0 -180
  337. data/examples/widget_style_colors/test_app.rb +0 -48
  338. /data/doc/images/{analytics.png → app_analytics.png} +0 -0
  339. /data/doc/images/{custom_widget.png → app_custom_widget.png} +0 -0
  340. /data/doc/images/{login_form.png → app_login_form.png} +0 -0
  341. /data/doc/images/{map_demo.png → app_map_demo.png} +0 -0
  342. /data/doc/images/{mouse_events.png → app_mouse_events.png} +0 -0
  343. /data/doc/images/{table_select.png → app_table_select.png} +0 -0
  344. /data/doc/images/{quickstart_dsl.png → verify_quickstart_dsl.png} +0 -0
  345. /data/doc/images/{ratatui_logo_demo.png → verify_quickstart_layout.png} +0 -0
  346. /data/doc/images/{quickstart_lifecycle.png → verify_quickstart_lifecycle.png} +0 -0
  347. /data/doc/images/{list_styles.png → widget_list_styles.png} +0 -0
  348. /data/doc/images/{popup_demo.png → widget_popup_demo.png} +0 -0
  349. /data/doc/images/{hit_test.png → widget_rect.png} +0 -0
  350. /data/doc/images/{rich_text.png → widget_rich_text.png} +0 -0
  351. /data/doc/images/{scroll_text.png → widget_scroll_text.png} +0 -0
@@ -0,0 +1,180 @@
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
+ require_relative "timestamp"
7
+ require_relative "event_color_cycle"
8
+ require_relative "event_entry"
9
+
10
+ # Manages the history and state of all application events.
11
+ #
12
+ # Applications need to track, count, and display event history for debugging and feedback.
13
+ # Direct management of event arrays and counters across the app leads to scattered state.
14
+ #
15
+ # This class centralizes event storage. It records new events, maintains counts, and manages temporary highlights.
16
+ #
17
+ # Use it to store key presses, mouse clicks, and window resizes for display in a log or counter.
18
+ #
19
+ # === Examples
20
+ #
21
+ # events = Events.new
22
+ # events.record(key_event)
23
+ # puts events.count(:key) #=> 1
24
+ #
25
+ # if events.lit?(:key)
26
+ # puts "Key event just happened!"
27
+ # end
28
+ class Events
29
+ # Duration in milliseconds for an event to remain highlighted in the UI.
30
+ HIGHLIGHT_DURATION_MS = 300
31
+
32
+ # Creates a new Events manager.
33
+ def initialize
34
+ @entries = []
35
+ @color_cycle = EventColorCycle.new
36
+ @none_count = 0
37
+ @lit_type = nil
38
+ @lit_until = Timestamp.now
39
+ @live = {}
40
+ end
41
+
42
+ # Records a new event.
43
+ #
44
+ # [event] RatatuiRuby::Event object.
45
+ # [context] Hash of additional context (e.g., last_dimensions).
46
+ #
47
+ # === Example
48
+ #
49
+ # events.record(mouse_event)
50
+ def record(event, context: {})
51
+ if event.is_a?(RatatuiRuby::Event::None) || event == :none
52
+ @none_count += 1
53
+ return
54
+ end
55
+
56
+ color = @color_cycle.next_color
57
+ timestamp = Timestamp.now
58
+ entry = EventEntry.create(event, color, timestamp)
59
+ @entries << entry
60
+ update_lit_type(entry)
61
+
62
+ display_type = live_type_for(entry.type)
63
+ @live[display_type] = { time: Time.now, description: entry.description }
64
+ end
65
+
66
+ private def live_type_for(type)
67
+ case type
68
+ when :focus_gained, :focus_lost
69
+ :focus
70
+ else
71
+ type
72
+ end
73
+ end
74
+
75
+ # Returns the most recent live event data for a type.
76
+ #
77
+ # [type] Symbol event type to look up.
78
+ #
79
+ # === Example
80
+ #
81
+ # events.live_event(:key) #=> { time: ..., description: "..." }
82
+ def live_event(type)
83
+ @live[type]
84
+ end
85
+
86
+ # Returns all recorded live event data.
87
+ #
88
+ # === Example
89
+ #
90
+ # events.live_events #=> { key: { ... }, mouse: { ... } }
91
+ def live_events
92
+ @live
93
+ end
94
+
95
+ # Returns the most recent entries up to the given limit.
96
+ #
97
+ # [max_entries] Integer maximum number of entries to return.
98
+ #
99
+ # === Example
100
+ #
101
+ # events.visible(10) #=> [#<EventEntry ...>, ...]
102
+ def visible(max_entries)
103
+ @entries.last(max_entries)
104
+ end
105
+
106
+ # Checks if any events have been recorded.
107
+ #
108
+ # === Example
109
+ #
110
+ # events.empty? #=> true
111
+ def empty?
112
+ @entries.empty?
113
+ end
114
+
115
+ # Returns the count of events for a type.
116
+ #
117
+ # [type] Symbol event type.
118
+ #
119
+ # === Example
120
+ #
121
+ # events.count(:key) #=> 5
122
+ def count(type)
123
+ return @none_count if type == :none
124
+
125
+ @entries.count { |e| e.matches_type?(type) }
126
+ end
127
+
128
+ # Returns counts grouped by subtype (kind or modifier status).
129
+ #
130
+ # [type] Symbol event type.
131
+ #
132
+ # === Example
133
+ #
134
+ # events.sub_counts(:mouse) #=> { "down" => 1, "up" => 2 }
135
+ def sub_counts(type)
136
+ return {} if type == :none
137
+
138
+ entries = @entries.select { |e| e.matches_type?(type) }
139
+
140
+ defaults = { key: %w[unmodified modified], focus: %w[gained lost], mouse: %w[down up drag moved scroll_up scroll_down] }
141
+ entries.each_with_object(defaults.fetch(type, []).to_h { |k| [k, 0] }) do |entry, counts|
142
+ group = if entry.event.respond_to?(:kind)
143
+ entry.event.kind.to_s
144
+ elsif entry.event.respond_to?(:modifiers)
145
+ entry.event.modifiers.empty? ? "unmodified" : "modified"
146
+ elsif type == :focus
147
+ entry.type.to_s.sub("focus_", "")
148
+ end
149
+
150
+ counts[group] += 1 if group
151
+ end
152
+ end
153
+
154
+ # Checks if a type should be highlighted.
155
+ #
156
+ # [type] Symbol event type.
157
+ #
158
+ # === Example
159
+ #
160
+ # events.lit?(:key) #=> true
161
+ def lit?(type)
162
+ return false if Timestamp.now.milliseconds >= @lit_until.milliseconds
163
+
164
+ @lit_type == type
165
+ end
166
+
167
+ # Returns all event entries.
168
+ #
169
+ # === Example
170
+ #
171
+ # events.entries #=> [#<EventEntry ...>, ...]
172
+ def entries
173
+ @entries
174
+ end
175
+
176
+ private def update_lit_type(entry)
177
+ @lit_type = live_type_for(entry.type)
178
+ @lit_until = Timestamp.new(milliseconds: Timestamp.now.milliseconds + HIGHLIGHT_DURATION_MS)
179
+ end
180
+ end
@@ -0,0 +1,57 @@
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
+ require_relative "timestamp"
7
+
8
+ # Manages temporary visual highlights for different event types.
9
+ #
10
+ # Users need visual feedback when an event occurs, but highlights should fade.
11
+ # Manually tracking timers for every highlightable element is complex.
12
+ #
13
+ # This class manages the "lit" state of multiple keys with a consistent duration.
14
+ #
15
+ # Use it to trigger and check for temporary UI highlights.
16
+ #
17
+ # === Examples
18
+ #
19
+ # highlight = Highlight.new
20
+ # highlight.light_up(:key)
21
+ # highlight.lit?(:key) #=> true
22
+ # sleep(0.4)
23
+ # highlight.lit?(:key) #=> false
24
+ class Highlight
25
+ # Duration in milliseconds that a highlight remains active.
26
+ DURATION_MS = 300
27
+
28
+ # Creates a new Highlight manager.
29
+ def initialize
30
+ @lit_types = {}
31
+ end
32
+
33
+ # Triggers a highlight for the given type.
34
+ #
35
+ # [type] Symbol to highlight.
36
+ #
37
+ # === Example
38
+ #
39
+ # highlight.light_up(:mouse)
40
+ def light_up(type)
41
+ @lit_types[type] = Timestamp.now
42
+ end
43
+
44
+ # Checks if a highlight is currently active for the given type.
45
+ #
46
+ # [type] Symbol to check.
47
+ #
48
+ # === Example
49
+ #
50
+ # highlight.lit?(:mouse) #=> true
51
+ def lit?(type)
52
+ timestamp = @lit_types[type]
53
+ return false unless timestamp
54
+
55
+ !timestamp.elapsed?(DURATION_MS)
56
+ end
57
+ end
@@ -0,0 +1,54 @@
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
+ # Represents a high-resolution point in time.
7
+ #
8
+ # Comparing events and calculating durations requires consistent time measurement.
9
+ # Standard Time objects are often too granular or complex for simple millisecond offsets.
10
+ #
11
+ # This class provides a millisecond-precision timestamp for event measurement.
12
+ #
13
+ # Use it to track event timing, calculate elapsed time, or trigger debouncing.
14
+ #
15
+ # === Examples
16
+ #
17
+ # timestamp = Timestamp.now
18
+ # puts timestamp.milliseconds
19
+ #
20
+ # if timestamp.elapsed?(300)
21
+ # puts "More than 300ms have passed."
22
+ # end
23
+ class Timestamp < Data.define(:milliseconds)
24
+ # Returns a new Timestamp representing the current time.
25
+ #
26
+ # === Example
27
+ #
28
+ # Timestamp.now #=> #<struct Timestamp milliseconds=123456789>
29
+ def self.now
30
+ new(milliseconds: (Time.now.to_f * 1000).to_i)
31
+ end
32
+
33
+ # Checks if a duration has passed since this timestamp.
34
+ #
35
+ # [duration_ms] Integer duration in milliseconds.
36
+ #
37
+ # === Example
38
+ #
39
+ # timestamp = Timestamp.now
40
+ # sleep(0.5)
41
+ # timestamp.elapsed?(300) #=> true
42
+ def elapsed?(duration_ms)
43
+ Timestamp.now.milliseconds >= milliseconds + duration_ms
44
+ end
45
+
46
+ # Returns the current time in milliseconds.
47
+ #
48
+ # === Example
49
+ #
50
+ # Timestamp.current #=> 123456789
51
+ def self.current
52
+ now.milliseconds
53
+ end
54
+ end
@@ -0,0 +1,24 @@
1
+ ┌Event Counts──────┐ ┌Live Display─────────────────────────────────────────────┐
2
+ │Key: 0 │ │Type Time Description │
3
+ │ Unmodified: 0 │ │Key — — │
4
+ │ Modified: 0 │ │Mouse — — │
5
+ │Mouse: 0 │ │Resize — — │
6
+ │ Down: 0 │ │Paste — — │
7
+ │ Up: 0 │ │Focus XX:XX:XX #<RatatuiRuby::Event::FocusLost:0xXXXXXX│
8
+ │ Drag: 0 │ │ │
9
+ │ Moved: 0 │ └─────────────────────────────────────────────────────────┘
10
+ │ Scroll_up: 0 │ ┌Event Log────────────────────────────────────────────────┐
11
+ │ Scroll_down: 0 │ │#<RatatuiRuby::Event::FocusLost:0xXXXXXX> │
12
+ │Resize: 0 │ │ │
13
+ │Paste: 0 │ │ │
14
+ │Focus: 1 │ │ │
15
+ │ Gained: 0 │ │ │
16
+ │ Lost: 1 │ │ │
17
+ │None: 0 │ │ │
18
+ │ │ │ │
19
+ │ │ │ │
20
+ │ │ │ │
21
+ └──────────────────┘ └─────────────────────────────────────────────────────────┘
22
+ ┌Controls──────────────────────────────────────────────────────────────────────┐
23
+ │q: Quit Ctrl+C: Quit │
24
+ └──────────────────────────────────────────────────────────────────────────────┘
@@ -0,0 +1,24 @@
1
+ ┌Event Counts──────┐ ┌Live Display─────────────────────────────────────────────┐
2
+ │Key: 0 │ │Type Time Description │
3
+ │ Unmodified: 0 │ │Key — — │
4
+ │ Modified: 0 │ │Mouse — — │
5
+ │Mouse: 0 │ │Resize — — │
6
+ │ Down: 0 │ │Paste — — │
7
+ │ Up: 0 │ │Focus XX:XX:XX #<RatatuiRuby::Event::FocusGained:0xXXXXXX│
8
+ │ Drag: 0 │ │ │
9
+ │ Moved: 0 │ └─────────────────────────────────────────────────────────┘
10
+ │ Scroll_up: 0 │ ┌Event Log────────────────────────────────────────────────┐
11
+ │ Scroll_down: 0 │ │#<RatatuiRuby::Event::FocusLost:0xXXXXXX> │
12
+ │Resize: 0 │ │ │
13
+ │Paste: 0 │ │#<RatatuiRuby::Event::FocusGained:0xXXXXXX> │
14
+ │Focus: 2 │ │ │
15
+ │ Gained: 1 │ │ │
16
+ │ Lost: 1 │ │ │
17
+ │None: 0 │ │ │
18
+ │ │ │ │
19
+ │ │ │ │
20
+ │ │ │ │
21
+ └──────────────────┘ └─────────────────────────────────────────────────────────┘
22
+ ┌Controls──────────────────────────────────────────────────────────────────────┐
23
+ │q: Quit Ctrl+C: Quit │
24
+ └──────────────────────────────────────────────────────────────────────────────┘
@@ -0,0 +1,24 @@
1
+ ┌Event Counts──────┐ ┌Live Display─────────────────────────────────────────────┐
2
+ │Key: 0 │ │Type Time Description │
3
+ │ Unmodified: 0 │ │Key — — │
4
+ │ Modified: 0 │ │Mouse — — │
5
+ │Mouse: 0 │ │Resize XX:XX:XX #<RatatuiRuby::Event::Resize:0xXXXXXX│
6
+ │ Down: 0 │ │Paste — — │
7
+ │ Up: 0 │ │Focus — — │
8
+ │ Drag: 0 │ │ │
9
+ │ Moved: 0 │ └─────────────────────────────────────────────────────────┘
10
+ │ Scroll_up: 0 │ ┌Event Log────────────────────────────────────────────────┐
11
+ │ Scroll_down: 0 │ │#<RatatuiRuby::Event::Resize:0xXXXXXX │
12
+ │Resize: 1 │ │@width=100, @height=24> │
13
+ │Paste: 0 │ │ │
14
+ │Focus: 0 │ │ │
15
+ │ Gained: 0 │ │ │
16
+ │ Lost: 0 │ │ │
17
+ │None: 0 │ │ │
18
+ │ │ │ │
19
+ │ │ │ │
20
+ │ │ │ │
21
+ └──────────────────┘ └─────────────────────────────────────────────────────────┘
22
+ ┌Controls──────────────────────────────────────────────────────────────────────┐
23
+ │q: Quit Ctrl+C: Quit │
24
+ └──────────────────────────────────────────────────────────────────────────────┘
@@ -0,0 +1,24 @@
1
+ ┌Event Counts──────┐ ┌Live Display─────────────────────────────────────────────┐
2
+ │Key: 1 │ │Type Time Description │
3
+ │ Unmodified: 1 │ │Key XX:XX:XX #<RatatuiRuby::Event::Key code="a" mod│
4
+ │ Modified: 0 │ │Mouse — — │
5
+ │Mouse: 0 │ │Resize — — │
6
+ │ Down: 0 │ │Paste — — │
7
+ │ Up: 0 │ │Focus — — │
8
+ │ Drag: 0 │ │ │
9
+ │ Moved: 0 │ └─────────────────────────────────────────────────────────┘
10
+ │ Scroll_up: 0 │ ┌Event Log────────────────────────────────────────────────┐
11
+ │ Scroll_down: 0 │ │#<RatatuiRuby::Event::Key code="a" modifiers=[]> │
12
+ │Resize: 0 │ │ │
13
+ │Paste: 0 │ │ │
14
+ │Focus: 0 │ │ │
15
+ │ Gained: 0 │ │ │
16
+ │ Lost: 0 │ │ │
17
+ │None: 0 │ │ │
18
+ │ │ │ │
19
+ │ │ │ │
20
+ │ │ │ │
21
+ └──────────────────┘ └─────────────────────────────────────────────────────────┘
22
+ ┌Controls──────────────────────────────────────────────────────────────────────┐
23
+ │q: Quit Ctrl+C: Quit │
24
+ └──────────────────────────────────────────────────────────────────────────────┘
@@ -0,0 +1,24 @@
1
+ ┌Event Counts──────┐ ┌Live Display─────────────────────────────────────────────┐
2
+ │Key: 1 │ │Type Time Description │
3
+ │ Unmodified: 0 │ │Key XX:XX:XX #<RatatuiRuby::Event::Key code="x" mod│
4
+ │ Modified: 1 │ │Mouse — — │
5
+ │Mouse: 0 │ │Resize — — │
6
+ │ Down: 0 │ │Paste — — │
7
+ │ Up: 0 │ │Focus — — │
8
+ │ Drag: 0 │ │ │
9
+ │ Moved: 0 │ └─────────────────────────────────────────────────────────┘
10
+ │ Scroll_up: 0 │ ┌Event Log────────────────────────────────────────────────┐
11
+ │ Scroll_down: 0 │ │#<RatatuiRuby::Event::Key code="x" modifiers=["ctrl"]> │
12
+ │Resize: 0 │ │ │
13
+ │Paste: 0 │ │ │
14
+ │Focus: 0 │ │ │
15
+ │ Gained: 0 │ │ │
16
+ │ Lost: 0 │ │ │
17
+ │None: 0 │ │ │
18
+ │ │ │ │
19
+ │ │ │ │
20
+ │ │ │ │
21
+ └──────────────────┘ └─────────────────────────────────────────────────────────┘
22
+ ┌Controls──────────────────────────────────────────────────────────────────────┐
23
+ │q: Quit Ctrl+C: Quit │
24
+ └──────────────────────────────────────────────────────────────────────────────┘
@@ -0,0 +1,24 @@
1
+ ┌Event Counts──────┐ ┌Live Display─────────────────────────────────────────────┐
2
+ │Key: 0 │ │Type Time Description │
3
+ │ Unmodified: 0 │ │Key — — │
4
+ │ Modified: 0 │ │Mouse XX:XX:XX #<RatatuiRuby::Event::Mouse:0xXXXXXX│
5
+ │Mouse: 1 │ │Resize — — │
6
+ │ Down: 1 │ │Paste — — │
7
+ │ Up: 0 │ │Focus — — │
8
+ │ Drag: 0 │ │ │
9
+ │ Moved: 0 │ └─────────────────────────────────────────────────────────┘
10
+ │ Scroll_up: 0 │ ┌Event Log────────────────────────────────────────────────┐
11
+ │ Scroll_down: 0 │ │#<RatatuiRuby::Event::Mouse:0xXXXXXX │
12
+ │Resize: 0 │ │@kind="down", @x=40, @y=12, @button="left", │
13
+ │Paste: 0 │ │@modifiers=[]> │
14
+ │Focus: 0 │ │ │
15
+ │ Gained: 0 │ │ │
16
+ │ Lost: 0 │ │ │
17
+ │None: 0 │ │ │
18
+ │ │ │ │
19
+ │ │ │ │
20
+ │ │ │ │
21
+ └──────────────────┘ └─────────────────────────────────────────────────────────┘
22
+ ┌Controls──────────────────────────────────────────────────────────────────────┐
23
+ │q: Quit Ctrl+C: Quit │
24
+ └──────────────────────────────────────────────────────────────────────────────┘
@@ -0,0 +1,24 @@
1
+ ┌Event Counts──────┐ ┌Live Display─────────────────────────────────────────────┐
2
+ │Key: 0 │ │Type Time Description │
3
+ │ Unmodified: 0 │ │Key — — │
4
+ │ Modified: 0 │ │Mouse XX:XX:XX #<RatatuiRuby::Event::Mouse:0xXXXXXX│
5
+ │Mouse: 1 │ │Resize — — │
6
+ │ Down: 0 │ │Paste — — │
7
+ │ Up: 0 │ │Focus — — │
8
+ │ Drag: 1 │ │ │
9
+ │ Moved: 0 │ └─────────────────────────────────────────────────────────┘
10
+ │ Scroll_up: 0 │ ┌Event Log────────────────────────────────────────────────┐
11
+ │ Scroll_down: 0 │ │#<RatatuiRuby::Event::Mouse:0xXXXXXX │
12
+ │Resize: 0 │ │@kind="drag", @x=25, @y=8, @button="left", @modifiers=[]>│
13
+ │Paste: 0 │ │ │
14
+ │Focus: 0 │ │ │
15
+ │ Gained: 0 │ │ │
16
+ │ Lost: 0 │ │ │
17
+ │None: 0 │ │ │
18
+ │ │ │ │
19
+ │ │ │ │
20
+ │ │ │ │
21
+ └──────────────────┘ └─────────────────────────────────────────────────────────┘
22
+ ┌Controls──────────────────────────────────────────────────────────────────────┐
23
+ │q: Quit Ctrl+C: Quit │
24
+ └──────────────────────────────────────────────────────────────────────────────┘
@@ -0,0 +1,24 @@
1
+ ┌Event Counts──────┐ ┌Live Display─────────────────────────────────────────────┐
2
+ │Key: 3 │ │Type Time Description │
3
+ │ Unmodified: 3 │ │Key XX:XX:XX #<RatatuiRuby::Event::Key code="c" mod│
4
+ │ Modified: 0 │ │Mouse XX:XX:XX #<RatatuiRuby::Event::Mouse:0xXXXXXX│
5
+ │Mouse: 1 │ │Resize — — │
6
+ │ Down: 1 │ │Paste — — │
7
+ │ Up: 0 │ │Focus — — │
8
+ │ Drag: 0 │ │ │
9
+ │ Moved: 0 │ └─────────────────────────────────────────────────────────┘
10
+ │ Scroll_up: 0 │ ┌Event Log────────────────────────────────────────────────┐
11
+ │ Scroll_down: 0 │ │#<RatatuiRuby::Event::Key code="a" modifiers=[]> │
12
+ │Resize: 0 │ │ │
13
+ │Paste: 0 │ │#<RatatuiRuby::Event::Key code="b" modifiers=[]> │
14
+ │Focus: 0 │ │ │
15
+ │ Gained: 0 │ │#<RatatuiRuby::Event::Key code="c" modifiers=[]> │
16
+ │ Lost: 0 │ │ │
17
+ │None: 0 │ │#<RatatuiRuby::Event::Mouse:0xXXXXXX │
18
+ │ │ │@kind="down", @x=10, @y=5, @button="left", @modifiers=[]>│
19
+ │ │ │ │
20
+ │ │ │ │
21
+ └──────────────────┘ └─────────────────────────────────────────────────────────┘
22
+ ┌Controls──────────────────────────────────────────────────────────────────────┐
23
+ │q: Quit Ctrl+C: Quit │
24
+ └──────────────────────────────────────────────────────────────────────────────┘
@@ -0,0 +1,24 @@
1
+ ┌Event Counts──────┐ ┌Live Display─────────────────────────────────────────────┐
2
+ │Key: 0 │ │Type Time Description │
3
+ │ Unmodified: 0 │ │Key — — │
4
+ │ Modified: 0 │ │Mouse — — │
5
+ │Mouse: 0 │ │Resize — — │
6
+ │ Down: 0 │ │Paste XX:XX:XX #<RatatuiRuby::Event::Paste:0xXXXXXX│
7
+ │ Up: 0 │ │Focus — — │
8
+ │ Drag: 0 │ │ │
9
+ │ Moved: 0 │ └─────────────────────────────────────────────────────────┘
10
+ │ Scroll_up: 0 │ ┌Event Log────────────────────────────────────────────────┐
11
+ │ Scroll_down: 0 │ │#<RatatuiRuby::Event::Paste:0xXXXXXX │
12
+ │Resize: 0 │ │@content="Hello World"> │
13
+ │Paste: 1 │ │ │
14
+ │Focus: 0 │ │ │
15
+ │ Gained: 0 │ │ │
16
+ │ Lost: 0 │ │ │
17
+ │None: 0 │ │ │
18
+ │ │ │ │
19
+ │ │ │ │
20
+ │ │ │ │
21
+ └──────────────────┘ └─────────────────────────────────────────────────────────┘
22
+ ┌Controls──────────────────────────────────────────────────────────────────────┐
23
+ │q: Quit Ctrl+C: Quit │
24
+ └──────────────────────────────────────────────────────────────────────────────┘
@@ -0,0 +1,24 @@
1
+ ┌Event Counts──────┐ ┌Live Display─────────────────────────────────────────────┐
2
+ │Key: 0 │ │Type Time Description │
3
+ │ Unmodified: 0 │ │Key — — │
4
+ │ Modified: 0 │ │Mouse — — │
5
+ │Mouse: 0 │ │Resize XX:XX:XX #<RatatuiRuby::Event::Resize:0xXXXXXX│
6
+ │ Down: 0 │ │Paste — — │
7
+ │ Up: 0 │ │Focus — — │
8
+ │ Drag: 0 │ │ │
9
+ │ Moved: 0 │ └─────────────────────────────────────────────────────────┘
10
+ │ Scroll_up: 0 │ ┌Event Log────────────────────────────────────────────────┐
11
+ │ Scroll_down: 0 │ │#<RatatuiRuby::Event::Resize:0xXXXXXX │
12
+ │Resize: 1 │ │@width=100, @height=30> │
13
+ │Paste: 0 │ │ │
14
+ │Focus: 0 │ │ │
15
+ │ Gained: 0 │ │ │
16
+ │ Lost: 0 │ │ │
17
+ │None: 0 │ │ │
18
+ │ │ │ │
19
+ │ │ │ │
20
+ │ │ │ │
21
+ └──────────────────┘ └─────────────────────────────────────────────────────────┘
22
+ ┌Controls──────────────────────────────────────────────────────────────────────┐
23
+ │q: Quit Ctrl+C: Quit │
24
+ └──────────────────────────────────────────────────────────────────────────────┘
@@ -0,0 +1,24 @@
1
+ ┌Event Counts──────┐ ┌Live Display─────────────────────────────────────────────┐
2
+ │Key: 0 │ │Type Time Description │
3
+ │ Unmodified: 0 │ │Key — — │
4
+ │ Modified: 0 │ │Mouse XX:XX:XX #<RatatuiRuby::Event::Mouse:0xXXXXXX│
5
+ │Mouse: 1 │ │Resize — — │
6
+ │ Down: 1 │ │Paste — — │
7
+ │ Up: 0 │ │Focus — — │
8
+ │ Drag: 0 │ │ │
9
+ │ Moved: 0 │ └─────────────────────────────────────────────────────────┘
10
+ │ Scroll_up: 0 │ ┌Event Log────────────────────────────────────────────────┐
11
+ │ Scroll_down: 0 │ │#<RatatuiRuby::Event::Mouse:0xXXXXXX │
12
+ │Resize: 0 │ │@kind="down", @x=50, @y=10, @button="right", │
13
+ │Paste: 0 │ │@modifiers=[]> │
14
+ │Focus: 0 │ │ │
15
+ │ Gained: 0 │ │ │
16
+ │ Lost: 0 │ │ │
17
+ │None: 0 │ │ │
18
+ │ │ │ │
19
+ │ │ │ │
20
+ │ │ │ │
21
+ └──────────────────┘ └─────────────────────────────────────────────────────────┘
22
+ ┌Controls──────────────────────────────────────────────────────────────────────┐
23
+ │q: Quit Ctrl+C: Quit │
24
+ └──────────────────────────────────────────────────────────────────────────────┘
@@ -0,0 +1,24 @@
1
+ ┌Event Counts──────┐ ┌Live Display─────────────────────────────────────────────┐
2
+ │Key: 0 │ │Type Time Description │
3
+ │ Unmodified: 0 │ │Key — — │
4
+ │ Modified: 0 │ │Mouse — — │
5
+ │Mouse: 0 │ │Resize XX:XX:XX #<RatatuiRuby::Event::Resize:0xXXXXXX│
6
+ │ Down: 0 │ │Paste — — │
7
+ │ Up: 0 │ │Focus — — │
8
+ │ Drag: 0 │ │ │
9
+ │ Moved: 0 │ └─────────────────────────────────────────────────────────┘
10
+ │ Scroll_up: 0 │ ┌Event Log────────────────────────────────────────────────┐
11
+ │ Scroll_down: 0 │ │#<RatatuiRuby::Event::Resize:0xXXXXXX │
12
+ │Resize: 1 │ │@width=80, @height=30> │
13
+ │Paste: 0 │ │ │
14
+ │Focus: 0 │ │ │
15
+ │ Gained: 0 │ │ │
16
+ │ Lost: 0 │ │ │
17
+ │None: 0 │ │ │
18
+ │ │ │ │
19
+ │ │ │ │
20
+ │ │ │ │
21
+ └──────────────────┘ └─────────────────────────────────────────────────────────┘
22
+ ┌Controls──────────────────────────────────────────────────────────────────────┐
23
+ │q: Quit Ctrl+C: Quit │
24
+ └──────────────────────────────────────────────────────────────────────────────┘
@@ -0,0 +1,24 @@
1
+ ┌Event Counts──────┐ ┌Live Display─────────────────────────────────────────────┐
2
+ │Key: 0 │ │Type Time Description │
3
+ │ Unmodified: 0 │ │Key — — │
4
+ │ Modified: 0 │ │Mouse — — │
5
+ │Mouse: 0 │ │Resize — — │
6
+ │ Down: 0 │ │Paste — — │
7
+ │ Up: 0 │ │Focus — — │
8
+ │ Drag: 0 │ │ │
9
+ │ Moved: 0 │ └─────────────────────────────────────────────────────────┘
10
+ │ Scroll_up: 0 │ ┌Event Log────────────────────────────────────────────────┐
11
+ │ Scroll_down: 0 │ │No events yet... │
12
+ │Resize: 0 │ │ │
13
+ │Paste: 0 │ │ │
14
+ │Focus: 0 │ │ │
15
+ │ Gained: 0 │ │ │
16
+ │ Lost: 0 │ │ │
17
+ │None: 0 │ │ │
18
+ │ │ │ │
19
+ │ │ │ │
20
+ │ │ │ │
21
+ └──────────────────┘ └─────────────────────────────────────────────────────────┘
22
+ ┌Controls──────────────────────────────────────────────────────────────────────┐
23
+ │q: Quit Ctrl+C: Quit │
24
+ └──────────────────────────────────────────────────────────────────────────────┘