ratatui_ruby 1.3.0 → 1.3.3

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 (301) hide show
  1. checksums.yaml +4 -4
  2. data/ext/ratatui_ruby/Cargo.lock +2 -1
  3. data/ext/ratatui_ruby/Cargo.toml +2 -1
  4. data/ext/ratatui_ruby/src/color.rs +1 -1
  5. data/ext/ratatui_ruby/src/errors.rs +1 -1
  6. data/ext/ratatui_ruby/src/events.rs +158 -19
  7. data/ext/ratatui_ruby/src/frame.rs +1 -1
  8. data/ext/ratatui_ruby/src/lib.rs +1 -1
  9. data/ext/ratatui_ruby/src/lib_header.rs +1 -1
  10. data/ext/ratatui_ruby/src/rendering.rs +1 -1
  11. data/ext/ratatui_ruby/src/string_width.rs +1 -1
  12. data/ext/ratatui_ruby/src/style.rs +1 -1
  13. data/ext/ratatui_ruby/src/terminal/capabilities.rs +1 -1
  14. data/ext/ratatui_ruby/src/terminal/init.rs +1 -1
  15. data/ext/ratatui_ruby/src/terminal/mod.rs +1 -1
  16. data/ext/ratatui_ruby/src/terminal/mutations.rs +1 -1
  17. data/ext/ratatui_ruby/src/terminal/queries.rs +1 -1
  18. data/ext/ratatui_ruby/src/terminal/query.rs +1 -1
  19. data/ext/ratatui_ruby/src/terminal/storage.rs +1 -1
  20. data/ext/ratatui_ruby/src/terminal/wrapper.rs +1 -1
  21. data/ext/ratatui_ruby/src/text.rs +1 -1
  22. data/ext/ratatui_ruby/src/widgets/barchart.rs +1 -1
  23. data/ext/ratatui_ruby/src/widgets/block.rs +1 -1
  24. data/ext/ratatui_ruby/src/widgets/calendar.rs +1 -1
  25. data/ext/ratatui_ruby/src/widgets/canvas.rs +1 -1
  26. data/ext/ratatui_ruby/src/widgets/center.rs +1 -1
  27. data/ext/ratatui_ruby/src/widgets/chart.rs +1 -1
  28. data/ext/ratatui_ruby/src/widgets/clear.rs +1 -1
  29. data/ext/ratatui_ruby/src/widgets/cursor.rs +1 -1
  30. data/ext/ratatui_ruby/src/widgets/gauge.rs +1 -1
  31. data/ext/ratatui_ruby/src/widgets/layout.rs +1 -1
  32. data/ext/ratatui_ruby/src/widgets/line_gauge.rs +1 -1
  33. data/ext/ratatui_ruby/src/widgets/list.rs +1 -1
  34. data/ext/ratatui_ruby/src/widgets/list_state.rs +1 -1
  35. data/ext/ratatui_ruby/src/widgets/mod.rs +1 -1
  36. data/ext/ratatui_ruby/src/widgets/overlay.rs +1 -1
  37. data/ext/ratatui_ruby/src/widgets/paragraph.rs +1 -1
  38. data/ext/ratatui_ruby/src/widgets/ratatui_logo.rs +1 -1
  39. data/ext/ratatui_ruby/src/widgets/ratatui_mascot.rs +1 -1
  40. data/ext/ratatui_ruby/src/widgets/scrollbar.rs +1 -1
  41. data/ext/ratatui_ruby/src/widgets/scrollbar_state.rs +1 -1
  42. data/ext/ratatui_ruby/src/widgets/sparkline.rs +1 -1
  43. data/ext/ratatui_ruby/src/widgets/table.rs +1 -1
  44. data/ext/ratatui_ruby/src/widgets/table_state.rs +1 -1
  45. data/ext/ratatui_ruby/src/widgets/tabs.rs +1 -1
  46. data/lib/ratatui_ruby/version.rb +1 -1
  47. metadata +1 -255
  48. data/.builds/ruby-3.2.yml +0 -54
  49. data/.builds/ruby-3.3.yml +0 -54
  50. data/.builds/ruby-3.4.yml +0 -54
  51. data/.builds/ruby-4.0.0.yml +0 -54
  52. data/.pre-commit-config.yaml +0 -16
  53. data/.rubocop.yml +0 -10
  54. data/AGENTS.md +0 -147
  55. data/CHANGELOG.md +0 -771
  56. data/README.md +0 -187
  57. data/README.rdoc +0 -302
  58. data/Rakefile +0 -11
  59. data/Steepfile +0 -50
  60. data/doc/concepts/application_architecture.md +0 -321
  61. data/doc/concepts/application_testing.md +0 -193
  62. data/doc/concepts/async.md +0 -190
  63. data/doc/concepts/custom_widgets.md +0 -247
  64. data/doc/concepts/debugging.md +0 -401
  65. data/doc/concepts/event_handling.md +0 -162
  66. data/doc/concepts/interactive_design.md +0 -146
  67. data/doc/contributors/auditing/parity.md +0 -239
  68. data/doc/contributors/design/ruby_frontend.md +0 -448
  69. data/doc/contributors/design/rust_backend.md +0 -434
  70. data/doc/contributors/design.md +0 -11
  71. data/doc/contributors/developing_examples.md +0 -400
  72. data/doc/contributors/documentation_style.md +0 -121
  73. data/doc/contributors/index.md +0 -21
  74. data/doc/contributors/releasing.md +0 -215
  75. data/doc/contributors/todo/align/api_completeness_audit-finished.md +0 -381
  76. data/doc/contributors/todo/align/api_completeness_audit-unfinished.md +0 -200
  77. data/doc/contributors/todo/align/term.md +0 -351
  78. data/doc/contributors/todo/align/terminal.md +0 -647
  79. data/doc/contributors/todo/future_work.md +0 -169
  80. data/doc/contributors/upstream_requests/paragraph_span_rects.md +0 -259
  81. data/doc/contributors/upstream_requests/tab_rects.md +0 -173
  82. data/doc/contributors/upstream_requests/title_rects.md +0 -132
  83. data/doc/custom.css +0 -22
  84. data/doc/getting_started/quickstart.md +0 -291
  85. data/doc/getting_started/why.md +0 -93
  86. data/doc/images/app_all_events.png +0 -0
  87. data/doc/images/app_cli_rich_moments.gif +0 -0
  88. data/doc/images/app_color_picker.png +0 -0
  89. data/doc/images/app_debugging_showcase.gif +0 -0
  90. data/doc/images/app_debugging_showcase.png +0 -0
  91. data/doc/images/app_external_editor.gif +0 -0
  92. data/doc/images/app_login_form.png +0 -0
  93. data/doc/images/app_stateful_interaction.png +0 -0
  94. data/doc/images/verify_quickstart_dsl.png +0 -0
  95. data/doc/images/verify_quickstart_layout.png +0 -0
  96. data/doc/images/verify_quickstart_lifecycle.png +0 -0
  97. data/doc/images/verify_readme_usage.png +0 -0
  98. data/doc/images/widget_barchart.png +0 -0
  99. data/doc/images/widget_block.png +0 -0
  100. data/doc/images/widget_box.png +0 -0
  101. data/doc/images/widget_calendar.png +0 -0
  102. data/doc/images/widget_canvas.png +0 -0
  103. data/doc/images/widget_cell.png +0 -0
  104. data/doc/images/widget_center.png +0 -0
  105. data/doc/images/widget_chart.png +0 -0
  106. data/doc/images/widget_gauge.png +0 -0
  107. data/doc/images/widget_layout_split.png +0 -0
  108. data/doc/images/widget_line_gauge.png +0 -0
  109. data/doc/images/widget_list.png +0 -0
  110. data/doc/images/widget_map.png +0 -0
  111. data/doc/images/widget_overlay.png +0 -0
  112. data/doc/images/widget_popup.png +0 -0
  113. data/doc/images/widget_ratatui_logo.png +0 -0
  114. data/doc/images/widget_ratatui_mascot.png +0 -0
  115. data/doc/images/widget_rect.png +0 -0
  116. data/doc/images/widget_render.png +0 -0
  117. data/doc/images/widget_rich_text.png +0 -0
  118. data/doc/images/widget_scroll_text.png +0 -0
  119. data/doc/images/widget_scrollbar.png +0 -0
  120. data/doc/images/widget_sparkline.png +0 -0
  121. data/doc/images/widget_style_colors.png +0 -0
  122. data/doc/images/widget_table.png +0 -0
  123. data/doc/images/widget_tabs.png +0 -0
  124. data/doc/images/widget_text_width.png +0 -0
  125. data/doc/index.md +0 -34
  126. data/doc/troubleshooting/async.md +0 -4
  127. data/doc/troubleshooting/terminal_limitations.md +0 -131
  128. data/doc/troubleshooting/tui_output.md +0 -197
  129. data/examples/app_all_events/README.md +0 -114
  130. data/examples/app_all_events/app.rb +0 -98
  131. data/examples/app_all_events/model/app_model.rb +0 -159
  132. data/examples/app_all_events/model/event_color_cycle.rb +0 -43
  133. data/examples/app_all_events/model/event_entry.rb +0 -94
  134. data/examples/app_all_events/model/msg.rb +0 -39
  135. data/examples/app_all_events/model/timestamp.rb +0 -56
  136. data/examples/app_all_events/update.rb +0 -75
  137. data/examples/app_all_events/view/app_view.rb +0 -80
  138. data/examples/app_all_events/view/controls_view.rb +0 -54
  139. data/examples/app_all_events/view/counts_view.rb +0 -61
  140. data/examples/app_all_events/view/live_view.rb +0 -72
  141. data/examples/app_all_events/view/log_view.rb +0 -57
  142. data/examples/app_all_events/view.rb +0 -9
  143. data/examples/app_cli_rich_moments/README.md +0 -81
  144. data/examples/app_cli_rich_moments/app.rb +0 -189
  145. data/examples/app_color_picker/README.md +0 -156
  146. data/examples/app_color_picker/app.rb +0 -76
  147. data/examples/app_color_picker/clipboard.rb +0 -86
  148. data/examples/app_color_picker/color.rb +0 -193
  149. data/examples/app_color_picker/controls.rb +0 -92
  150. data/examples/app_color_picker/copy_dialog.rb +0 -168
  151. data/examples/app_color_picker/export_pane.rb +0 -128
  152. data/examples/app_color_picker/harmony.rb +0 -58
  153. data/examples/app_color_picker/input.rb +0 -176
  154. data/examples/app_color_picker/main_container.rb +0 -180
  155. data/examples/app_color_picker/palette.rb +0 -111
  156. data/examples/app_debugging_showcase/README.md +0 -119
  157. data/examples/app_debugging_showcase/app.rb +0 -318
  158. data/examples/app_external_editor/README.md +0 -62
  159. data/examples/app_external_editor/app.rb +0 -344
  160. data/examples/app_login_form/README.md +0 -58
  161. data/examples/app_login_form/app.rb +0 -109
  162. data/examples/app_stateful_interaction/README.md +0 -35
  163. data/examples/app_stateful_interaction/app.rb +0 -328
  164. data/examples/timeout_demo.rb +0 -45
  165. data/examples/verify_quickstart_dsl/README.md +0 -55
  166. data/examples/verify_quickstart_dsl/app.rb +0 -49
  167. data/examples/verify_quickstart_layout/README.md +0 -77
  168. data/examples/verify_quickstart_layout/app.rb +0 -73
  169. data/examples/verify_quickstart_lifecycle/README.md +0 -68
  170. data/examples/verify_quickstart_lifecycle/app.rb +0 -62
  171. data/examples/verify_readme_usage/README.md +0 -49
  172. data/examples/verify_readme_usage/app.rb +0 -42
  173. data/examples/verify_website_managed/README.md +0 -48
  174. data/examples/verify_website_managed/app.rb +0 -36
  175. data/examples/verify_website_menu/README.md +0 -60
  176. data/examples/verify_website_menu/app.rb +0 -84
  177. data/examples/verify_website_spinner/README.md +0 -44
  178. data/examples/verify_website_spinner/app.rb +0 -34
  179. data/examples/widget_barchart/README.md +0 -58
  180. data/examples/widget_barchart/app.rb +0 -240
  181. data/examples/widget_block/README.md +0 -44
  182. data/examples/widget_block/app.rb +0 -258
  183. data/examples/widget_box/README.md +0 -54
  184. data/examples/widget_box/app.rb +0 -255
  185. data/examples/widget_calendar/README.md +0 -48
  186. data/examples/widget_calendar/app.rb +0 -115
  187. data/examples/widget_canvas/README.md +0 -31
  188. data/examples/widget_canvas/app.rb +0 -130
  189. data/examples/widget_cell/README.md +0 -45
  190. data/examples/widget_cell/app.rb +0 -112
  191. data/examples/widget_center/README.md +0 -33
  192. data/examples/widget_center/app.rb +0 -118
  193. data/examples/widget_chart/README.md +0 -50
  194. data/examples/widget_chart/app.rb +0 -220
  195. data/examples/widget_gauge/README.md +0 -50
  196. data/examples/widget_gauge/app.rb +0 -229
  197. data/examples/widget_layout_split/README.md +0 -53
  198. data/examples/widget_layout_split/app.rb +0 -260
  199. data/examples/widget_line_gauge/README.md +0 -50
  200. data/examples/widget_line_gauge/app.rb +0 -219
  201. data/examples/widget_list/README.md +0 -58
  202. data/examples/widget_list/app.rb +0 -382
  203. data/examples/widget_map/README.md +0 -48
  204. data/examples/widget_map/app.rb +0 -95
  205. data/examples/widget_overlay/README.md +0 -45
  206. data/examples/widget_overlay/app.rb +0 -250
  207. data/examples/widget_popup/README.md +0 -45
  208. data/examples/widget_popup/app.rb +0 -106
  209. data/examples/widget_ratatui_logo/README.md +0 -43
  210. data/examples/widget_ratatui_logo/app.rb +0 -104
  211. data/examples/widget_ratatui_mascot/README.md +0 -43
  212. data/examples/widget_ratatui_mascot/app.rb +0 -95
  213. data/examples/widget_rect/README.md +0 -53
  214. data/examples/widget_rect/app.rb +0 -222
  215. data/examples/widget_render/README.md +0 -46
  216. data/examples/widget_render/app.rb +0 -186
  217. data/examples/widget_render/app.rbs +0 -41
  218. data/examples/widget_rich_text/README.md +0 -44
  219. data/examples/widget_rich_text/app.rb +0 -193
  220. data/examples/widget_scroll_text/README.md +0 -46
  221. data/examples/widget_scroll_text/app.rb +0 -109
  222. data/examples/widget_scrollbar/README.md +0 -46
  223. data/examples/widget_scrollbar/app.rb +0 -155
  224. data/examples/widget_sparkline/README.md +0 -51
  225. data/examples/widget_sparkline/app.rb +0 -277
  226. data/examples/widget_style_colors/README.md +0 -43
  227. data/examples/widget_style_colors/app.rb +0 -83
  228. data/examples/widget_table/README.md +0 -57
  229. data/examples/widget_table/app.rb +0 -285
  230. data/examples/widget_tabs/README.md +0 -50
  231. data/examples/widget_tabs/app.rb +0 -183
  232. data/examples/widget_text_width/README.md +0 -44
  233. data/examples/widget_text_width/app.rb +0 -117
  234. data/migrate_to_buffer.rb +0 -145
  235. data/mise.toml +0 -8
  236. data/tasks/autodoc/examples.rb +0 -87
  237. data/tasks/autodoc/member.rb +0 -58
  238. data/tasks/autodoc/name.rb +0 -21
  239. data/tasks/autodoc.rake +0 -21
  240. data/tasks/bump/bump_workflow.rb +0 -49
  241. data/tasks/bump/cargo_lockfile.rb +0 -21
  242. data/tasks/bump/changelog.rb +0 -104
  243. data/tasks/bump/header.rb +0 -32
  244. data/tasks/bump/history.rb +0 -32
  245. data/tasks/bump/links.rb +0 -69
  246. data/tasks/bump/manifest.rb +0 -33
  247. data/tasks/bump/patch_release.rb +0 -19
  248. data/tasks/bump/release_branch.rb +0 -17
  249. data/tasks/bump/release_from_trunk.rb +0 -49
  250. data/tasks/bump/repository.rb +0 -54
  251. data/tasks/bump/ruby_gem.rb +0 -29
  252. data/tasks/bump/sem_ver.rb +0 -44
  253. data/tasks/bump/unreleased_section.rb +0 -73
  254. data/tasks/bump.rake +0 -61
  255. data/tasks/doc/documentation.rb +0 -59
  256. data/tasks/doc/link/file_url.rb +0 -30
  257. data/tasks/doc/link/relative_path.rb +0 -61
  258. data/tasks/doc/link/web_url.rb +0 -55
  259. data/tasks/doc/link.rb +0 -52
  260. data/tasks/doc/link_audit.rb +0 -116
  261. data/tasks/doc/problem.rb +0 -40
  262. data/tasks/doc/source_file.rb +0 -93
  263. data/tasks/doc.rake +0 -905
  264. data/tasks/example_viewer.html.erb +0 -172
  265. data/tasks/extension.rake +0 -14
  266. data/tasks/license/headers_md.rb +0 -223
  267. data/tasks/license/headers_rb.rb +0 -210
  268. data/tasks/license/license_utils.rb +0 -130
  269. data/tasks/license/snippets_md.rb +0 -315
  270. data/tasks/license/snippets_rdoc.rb +0 -150
  271. data/tasks/license.rake +0 -91
  272. data/tasks/lint.rake +0 -170
  273. data/tasks/rbs_predicates/predicate_catalog.rb +0 -52
  274. data/tasks/rbs_predicates/predicate_tests.rb +0 -124
  275. data/tasks/rbs_predicates/rbs_signature.rb +0 -63
  276. data/tasks/rbs_predicates.rake +0 -31
  277. data/tasks/rdoc_config.rb +0 -29
  278. data/tasks/resources/build.yml.erb +0 -60
  279. data/tasks/resources/index.html.erb +0 -141
  280. data/tasks/resources/rubies.yml +0 -7
  281. data/tasks/sourcehut.rake +0 -122
  282. data/tasks/steep.rake +0 -11
  283. data/tasks/terminal_preview/app_screenshot.rb +0 -45
  284. data/tasks/terminal_preview/crash_report.rb +0 -54
  285. data/tasks/terminal_preview/example_app.rb +0 -27
  286. data/tasks/terminal_preview/launcher_script.rb +0 -48
  287. data/tasks/terminal_preview/preview_collection.rb +0 -60
  288. data/tasks/terminal_preview/preview_timing.rb +0 -24
  289. data/tasks/terminal_preview/safety_confirmation.rb +0 -58
  290. data/tasks/terminal_preview/saved_screenshot.rb +0 -56
  291. data/tasks/terminal_preview/system_appearance.rb +0 -13
  292. data/tasks/terminal_preview/terminal_window.rb +0 -138
  293. data/tasks/terminal_preview/window_id.rb +0 -16
  294. data/tasks/terminal_preview.rake +0 -30
  295. data/tasks/test.rake +0 -36
  296. data/tasks/website/index_page.rb +0 -30
  297. data/tasks/website/version.rb +0 -122
  298. data/tasks/website/version_menu.rb +0 -68
  299. data/tasks/website/versioned_documentation.rb +0 -83
  300. data/tasks/website/website.rb +0 -53
  301. data/tasks/website.rake +0 -28
@@ -1,48 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
- SPDX-License-Identifier: CC-BY-SA-4.0
4
- -->
5
-
6
- # Map (World Map, Canvas) Example
7
-
8
- [![widget_map](../../doc/images/widget_map.png)](app.rb)
9
-
10
- Demonstrates drawing custom graphics and maps using the standard Braille and Block patterns.
11
-
12
- Standard widgets are great for text, but sometimes you need to draw. The `Canvas` widget gives you a high-resolution coordinate system (x, y) to render shapes, lines, and data visualizations that go beyond the grid.
13
-
14
- ## Features Demonstrated
15
-
16
- - **High-Resolution Drawing**: Using Braille patterns (`⣿`) to effectively double the vertical and horizontal resolution of the terminal.
17
- - **Layers**: Drawing multiple shapes (Map, Circles, Lines) in a specific order.
18
- - **Animation**: Updating coordinates in a loop to create smooth motion.
19
- - **World Map**: Using the built-in `Map` shape for geographic data.
20
-
21
- ## Hotkeys
22
-
23
- - **b**: Cycle Background Color (`background_color`)
24
- - **m**: Cycle Marker Type (`marker`)
25
- - **l**: Toggle Labels (modifies `shapes`)
26
- - **q**: Quit
27
-
28
- ## Usage
29
-
30
- <!-- SPDX-SnippetBegin -->
31
- <!--
32
- SPDX-FileCopyrightText: 2026 Kerrick Long
33
- SPDX-License-Identifier: MIT-0
34
- -->
35
- ```bash
36
- ruby examples/widget_map/app.rb
37
- ```
38
- <!-- SPDX-SnippetEnd -->
39
-
40
- ## Learning Outcomes
41
-
42
- Use this example if you need to...
43
-
44
- - Render geographic data (World, USA, Europe).
45
- - Overlay custom labels and markers on a map.
46
- - Animate visual elements on top of a static background.
47
-
48
- [Read the source code →](app.rb)
@@ -1,95 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- #--
4
- # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: MIT-0
6
- #++
7
-
8
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
9
- require "ratatui_ruby"
10
-
11
- # An example of the Canvas widget showing a world map and animated shapes.
12
- class WidgetMap
13
- include RatatuiRuby::Widgets
14
-
15
- COLORS = [:black, :blue, :white, nil].freeze
16
- MARKERS = [:braille, :half_block, :dot, :block, :bar, :quadrant, :sextant, :octant].freeze
17
-
18
- # Returns a Canvas view for the map demo with the given circle radius.
19
- #
20
- # +tui+:: The RatatuiRuby::TUI instance.
21
- # +radius+:: The radius of the animated circle.
22
- # +marker+:: The marker type.
23
- # +background_color+:: The background color of the canvas.
24
- # +show_labels+:: Whether to show city labels.
25
- def view(tui, radius, marker = :braille, background_color = nil, show_labels: true)
26
- shapes = [
27
- tui.shape_map(color: :green, resolution: :high),
28
- tui.shape_circle(x: 0.0, y: 0.0, radius:, color: :red),
29
- tui.shape_line(x1: 0.0, y1: 0.0, x2: 50.0, y2: 25.0, color: :yellow),
30
- ]
31
-
32
- if show_labels
33
- shapes += [
34
- tui.shape_label(x: -0.1, y: 51.5, text: "London", style: tui.style(fg: :cyan)),
35
- tui.shape_label(x: 139.7, y: 35.7, text: "Tokyo", style: tui.style(fg: :magenta)),
36
- tui.shape_label(x: -74.0, y: 40.7, text: "New York", style: tui.style(fg: :yellow)),
37
- tui.shape_label(x: -122.4, y: 37.8, text: "San Francisco", style: tui.style(fg: :blue)),
38
- tui.shape_label(x: 151.2, y: -33.9, text: "Sydney", style: tui.style(fg: :green)),
39
- ]
40
- end
41
-
42
- tui.canvas(
43
- shapes:,
44
- x_bounds: [-180.0, 180.0],
45
- y_bounds: [-90.0, 90.0],
46
- marker:,
47
- block: tui.block(title: "World Map ['b' bg, 'm' marker: #{marker}, 'l' labels: #{show_labels ? 'on' : 'off'}]", borders: :all),
48
- background_color:
49
- )
50
- end
51
-
52
- # Runs the map demo loop.
53
- def run
54
- RatatuiRuby.run do |tui|
55
- radius = 0.0
56
- direction = 1
57
- bg_index = 0
58
- marker_index = 0
59
- show_labels = true
60
-
61
- loop do
62
- # Animate the circle radius
63
- radius += 0.5 * direction
64
- if radius > 10.0 || radius < 0.0
65
- direction *= -1
66
- end
67
-
68
- # Define the view
69
- canvas = view(tui, radius, MARKERS[marker_index], COLORS[bg_index], show_labels:)
70
-
71
- tui.draw do |frame|
72
- frame.render_widget(canvas, frame.area)
73
- end
74
-
75
- event = tui.poll_event
76
- case event
77
- in { type: :key, code: "q" } | { type: :key, code: :ctrl_c }
78
- break
79
- in type: :key, code: "b"
80
- bg_index = (bg_index + 1) % COLORS.size
81
- in type: :key, code: "m"
82
- marker_index = (marker_index + 1) % MARKERS.size
83
- in type: :key, code: "l"
84
- show_labels = !show_labels
85
- else
86
- # Ignore other events
87
- end
88
-
89
- sleep 0.05
90
- end
91
- end
92
- end
93
- end
94
-
95
- WidgetMap.new.run if __FILE__ == $PROGRAM_NAME
@@ -1,45 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
- SPDX-License-Identifier: CC-BY-SA-4.0
4
- -->
5
- # Overlay Example
6
-
7
- [![](../../doc/images/widget_overlay.png)](app.rb)
8
-
9
- This example demonstrates the `Overlay` composition pattern for layering widgets with depth. Modals, notifications, and floating panels all require stacking widgets on top of each other.
10
-
11
- ## Key Concepts
12
-
13
- - **Layer Composition:** Rendering widgets in order creates visual depth — later renders appear "on top."
14
- - **Clear Widget:** Using `tui.clear` before rendering a modal erases the background, preventing content bleed-through.
15
- - **Dynamic Layer Control:** Toggle the number of visible overlay layers at runtime.
16
- - **Layer Ordering:** Swap which overlay appears in front to demonstrate z-ordering.
17
-
18
- ## Hotkeys
19
-
20
- - `0`/`1`/`2`: Set number of visible overlay layers
21
- - `space`: Swap overlay order (which modal is on top)
22
- - `c`: Toggle Clear widget (on/off)
23
- - `q`: Quit
24
-
25
- ## Usage
26
-
27
- <!-- SPDX-SnippetBegin -->
28
- <!--
29
- SPDX-FileCopyrightText: 2026 Kerrick Long
30
- SPDX-License-Identifier: MIT-0
31
- -->
32
- ```bash
33
- ruby examples/widget_overlay/app.rb
34
- ```
35
- <!-- SPDX-SnippetEnd -->
36
-
37
- ## Learning Outcomes
38
-
39
- Use this example if you need to...
40
-
41
- - Build modal dialogs or confirmation popups.
42
- - Layer notifications over existing content.
43
- - Understand the Clear widget's role in opaque overlays.
44
-
45
- [Read the source code →](app.rb)
@@ -1,250 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- #--
4
- # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: MIT-0
6
- #++
7
-
8
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
9
- require "ratatui_ruby"
10
-
11
- HEADLINES = [
12
- "Scientists Discover New Species of Deep-Sea Octopus Near Hawaii",
13
- "Global Climate Summit Reaches Historic Agreement on Emissions",
14
- "Tech Giant Announces Breakthrough in Quantum Computing Research",
15
- "Local Community Garden Initiative Expands to Ten More Cities",
16
- "Astronomers Detect Unusual Radio Signals from Distant Galaxy",
17
- "New Study Links Mediterranean Diet to Improved Heart Health",
18
- "Electric Vehicle Sales Surge as Battery Technology Improves",
19
- "Ancient Manuscripts Reveal Previously Unknown Trading Routes",
20
- "Renewable Energy Now Powers 40% of National Grid",
21
- "Robotics Team Develops AI System for Disaster Response",
22
- "Archaeological Dig Uncovers Evidence of Early Human Settlement",
23
- "Major Airline Commits to Carbon-Neutral Flights by 2035",
24
- "Breakthrough Treatment Shows Promise for Rare Genetic Disease",
25
- "City Council Approves Expanded Public Transportation Network",
26
- "Marine Biologists Track Migration Patterns of Endangered Whales",
27
- "New App Helps Farmers Optimize Water Usage During Drought",
28
- "International Space Station Extends Mission Timeline to 2030",
29
- "Local Schools Implement Innovative STEM Education Program",
30
- "Wildlife Conservation Efforts Lead to Species Population Recovery",
31
- "Research Team Creates Biodegradable Alternative to Plastic Packaging",
32
- "Historic Theater Restoration Project Nears Completion",
33
- "Cybersecurity Experts Warn of Emerging Online Threats",
34
- "Community Food Bank Serves Record Number of Families This Year",
35
- "Innovative Urban Planning Reduces Traffic Congestion by 30%",
36
- ].freeze
37
-
38
- # Overlay Example
39
- # Demonstrates the Overlay widget for layering widgets with depth.
40
- class WidgetOverlay
41
- def initialize
42
- @layer_count = 2 # Start with 2 layers visible
43
- @swapped = false
44
- @clear = true
45
- end
46
-
47
- def run
48
- RatatuiRuby.run do |tui|
49
- @tui = tui
50
- loop do
51
- tui.draw do |frame|
52
- render(frame)
53
- end
54
- break if handle_input == :quit
55
- sleep 0.05
56
- end
57
- end
58
- end
59
-
60
- private def render(frame)
61
- area = frame.area
62
-
63
- # Split into main area and control panel
64
- layout = @tui.layout_split(
65
- area,
66
- direction: :vertical,
67
- constraints: [
68
- @tui.constraint_fill(1),
69
- @tui.constraint_length(5),
70
- ]
71
- )
72
-
73
- main_area = layout[0]
74
- control_area = layout[1]
75
-
76
- # Render background layer - RSS reader
77
- frame.render_widget(background_layer, main_area)
78
-
79
- # Render upper layers based on layer_count and swap state
80
- if @swapped
81
- render_beta_layer(frame, main_area) if @layer_count >= 2
82
- render_notification_layer(frame, main_area) if @layer_count >= 1
83
- else
84
- render_notification_layer(frame, main_area) if @layer_count >= 1
85
- render_beta_layer(frame, main_area) if @layer_count >= 2
86
- end
87
-
88
- # Render control panel
89
- frame.render_widget(control_panel, control_area)
90
- end
91
-
92
- def background_layer
93
- @background_layer ||= @tui.list(
94
- items: HEADLINES,
95
- block: @tui.block(
96
- title: "RSS Reader",
97
- borders: [:all]
98
- )
99
- )
100
- end
101
-
102
- def render_notification_layer(frame, area)
103
- # Position modal: 20% from top, 60% height, 15% from left, 70% width
104
-
105
- vertical_sections = @tui.layout_split(
106
- area,
107
- direction: :vertical,
108
- constraints: [
109
- @tui.constraint_fill(2),
110
- @tui.constraint_fill(5),
111
- @tui.constraint_fill(3),
112
- ]
113
- )
114
-
115
- horizontal_sections = @tui.layout_split(
116
- vertical_sections[1],
117
- direction: :horizontal,
118
- constraints: [
119
- @tui.constraint_fill(1),
120
- @tui.constraint_fill(5),
121
- @tui.constraint_fill(1),
122
- ]
123
- )
124
-
125
- modal_rect = horizontal_sections[1]
126
-
127
- frame.render_widget(@tui.clear, modal_rect) if @clear
128
-
129
- # Render the modal content
130
- frame.render_widget(
131
- @tui.paragraph(
132
- text: "Your feeds have been updated",
133
- wrap: true,
134
- alignment: :center,
135
- block: @tui.block(
136
- title: "Notification",
137
- borders: [:all],
138
- border_style: @tui.style(fg: :black),
139
- style: @tui.style(bg: :red, fg: :black)
140
- )
141
- ),
142
- modal_rect
143
- )
144
- end
145
-
146
- def render_beta_layer(frame, area)
147
- # Position modal: 30% from top, 40% height, 25% from left, 50% width
148
-
149
- vertical_sections = @tui.layout_split(
150
- area,
151
- direction: :vertical,
152
- constraints: [
153
- @tui.constraint_fill(3),
154
- @tui.constraint_fill(4),
155
- @tui.constraint_fill(2),
156
- ]
157
- )
158
-
159
- horizontal_sections = @tui.layout_split(
160
- vertical_sections[1],
161
- direction: :horizontal,
162
- constraints: [
163
- @tui.constraint_fill(2),
164
- @tui.constraint_fill(3),
165
- @tui.constraint_fill(2),
166
- ]
167
- )
168
-
169
- modal_rect = horizontal_sections[1]
170
-
171
- frame.render_widget(@tui.clear, modal_rect) if @clear
172
-
173
- # Render the modal content
174
- frame.render_widget(
175
- beta_paragraph,
176
- modal_rect
177
- )
178
- end
179
-
180
- def beta_paragraph
181
- @beta_paragraph ||= @tui.paragraph(
182
- text: "Thank you for being a beta tester. To give feedback, shout very loudly and we will hear you. Be careful not to scare the llamas.",
183
- wrap: true,
184
- alignment: :left,
185
- block: @tui.block(
186
- title: "Beta Program",
187
- borders: [:all],
188
- border_style: @tui.style(fg: :black),
189
- style: @tui.style(bg: :blue, fg: :black)
190
- )
191
- )
192
- end
193
-
194
- def control_panel
195
- bold_underline = @tui.style(modifiers: [:bold, :underlined])
196
-
197
- first_controls = [
198
- @tui.text_span(content: "0", style: bold_underline),
199
- @tui.text_span(content: "/"),
200
- @tui.text_span(content: "1", style: bold_underline),
201
- @tui.text_span(content: "/"),
202
- @tui.text_span(content: "2", style: bold_underline),
203
- @tui.text_span(content: ": Change number of overlays | "),
204
- @tui.text_span(content: "space", style: bold_underline),
205
- @tui.text_span(content: ": Swap overlay order"),
206
- ]
207
- second_controls = [
208
- @tui.text_span(content: "c", style: bold_underline),
209
- @tui.text_span(content: ": Toggle clear (currently #{@clear ? 'on' : 'off'})"),
210
- ]
211
- third_controls = [
212
- @tui.text_span(content: "q", style: bold_underline),
213
- @tui.text_span(content: ": Quit"),
214
- ]
215
-
216
- first = @tui.text_line(spans: first_controls)
217
- second = @tui.text_line(spans: second_controls)
218
- third = @tui.text_line(spans: third_controls)
219
-
220
- @tui.paragraph(
221
- text: [first, second, third],
222
- alignment: :center,
223
- block: @tui.block(
224
- title: "Controls",
225
- borders: [:all]
226
- )
227
- )
228
- end
229
-
230
- 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: "0" }
235
- @layer_count = 0
236
- in { type: :key, code: "1" }
237
- @layer_count = 1
238
- in { type: :key, code: "2" }
239
- @layer_count = 2
240
- in { type: :key, code: " " }
241
- @swapped = !@swapped
242
- in { type: :key, code: "c" }
243
- @clear = !@clear
244
- else
245
- nil
246
- end
247
- end
248
- end
249
-
250
- WidgetOverlay.new.run if __FILE__ == $PROGRAM_NAME
@@ -1,45 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
- SPDX-License-Identifier: CC-BY-SA-4.0
4
- -->
5
-
6
- # Clear (Popup, Modal) Example
7
-
8
- [![widget_popup](../../doc/images/widget_popup.png)](app.rb)
9
-
10
- Demonstrates how to render opaque overlays on top of content.
11
-
12
- Terminal renders are additive. If you draw a new widget over an old one, the background colors might mix if not handled correctly. The `Clear` widget resets the area to default (usually transparent/black) to ensure a clean canvas for popups.
13
-
14
- ## Features Demonstrated
15
-
16
- - **The `Clear` Widget**: Printing spaces over an area to "erase" what was underneath.
17
- - **Centering**: Using `Layout` constraints to perfectly center a block on screen.
18
- - **Style Bleed**: showing what happens when you *don't* use `Clear` (background colors leak through).
19
-
20
- ## Hotkeys
21
-
22
- - **Space**: Toggle Clear Widget (Observe the red background effect when disabled)
23
- - **q**: Quit
24
-
25
- ## Usage
26
-
27
- <!-- SPDX-SnippetBegin -->
28
- <!--
29
- SPDX-FileCopyrightText: 2026 Kerrick Long
30
- SPDX-License-Identifier: MIT-0
31
- -->
32
- ```bash
33
- ruby examples/widget_popup/app.rb
34
- ```
35
- <!-- SPDX-SnippetEnd -->
36
-
37
- ## Learning Outcomes
38
-
39
- Use this example if you need to...
40
-
41
- - Create a modal dialog (Confirm, Alert, Form).
42
- - Implement a dropdown menu that overlays other content.
43
- - Fix visual artifacts where old text shows through new widgets.
44
-
45
- [Read the source code →](app.rb)
@@ -1,106 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- #--
4
- # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: MIT-0
6
- #++
7
-
8
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
9
- require "ratatui_ruby"
10
-
11
- # Popup Example
12
- # Demonstrates the Clear widget for creating opaque popups.
13
-
14
- class WidgetPopup
15
- def initialize
16
- @clear_enabled = false
17
- end
18
-
19
- def run
20
- RatatuiRuby.run do |tui|
21
- loop do
22
- tui.draw do |frame|
23
- render(tui, frame)
24
- end
25
- break if handle_input(tui) == :quit
26
- sleep 0.05
27
- end
28
- end
29
- end
30
-
31
- private def render(tui, frame)
32
- area = frame.area
33
-
34
- # 1. Background: Loud Red Background
35
- # This demonstrates "Style Bleed" where the background color persists
36
- # unless explicitly cleared or overwritten.
37
- background = tui.paragraph(
38
- text: "BACKGROUND RED " * 100,
39
- style: tui.style(bg: :red, fg: :white),
40
- wrap: true
41
- )
42
- frame.render_widget(background, area)
43
-
44
- # 2. Popup Area Calculation
45
- # Center the popup vertically and horizontally
46
- vertical_layout = tui.layout_split(
47
- area,
48
- direction: :vertical,
49
- constraints: [
50
- tui.constraint_percentage(25),
51
- tui.constraint_percentage(50), # 50% height
52
- tui.constraint_percentage(25),
53
- ]
54
- )
55
- popup_area_vertical = vertical_layout[1]
56
-
57
- horizontal_layout = tui.layout_split(
58
- popup_area_vertical,
59
- direction: :horizontal,
60
- constraints: [
61
- tui.constraint_percentage(20),
62
- tui.constraint_percentage(60), # 60% width
63
- tui.constraint_percentage(20),
64
- ]
65
- )
66
- popup_area = horizontal_layout[1]
67
-
68
- # 3. Popup Content
69
- # Without Clear, this will "inherit" the red background from underneath.
70
- popup_text = if @clear_enabled
71
- "✓ Clear is ENABLED\n\nResets background to default\n(Usually Black/Transparent)\n\nPress Space to toggle"
72
- else
73
- "✗ Clear is DISABLED\n\nStyle Bleed: Popup is RED!\n(Inherits background style)\n\nPress Space to toggle"
74
- end
75
-
76
- popup_content = tui.paragraph(
77
- text: popup_text,
78
- alignment: :center,
79
- block: tui.block(
80
- title: "Popup (q to quit, space to toggle)",
81
- borders: [:all]
82
- )
83
- )
84
-
85
- # 4. Render Popup
86
- if @clear_enabled
87
- # With Clear: Resets the style in the popup area before rendering content
88
- frame.render_widget(tui.clear, popup_area)
89
- end
90
-
91
- frame.render_widget(popup_content, popup_area)
92
- end
93
-
94
- private def handle_input(tui)
95
- case tui.poll_event
96
- in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
97
- :quit
98
- in type: :key, code: " "
99
- @clear_enabled = !@clear_enabled
100
- else
101
- nil
102
- end
103
- end
104
- end
105
-
106
- WidgetPopup.new.run if __FILE__ == $0
@@ -1,43 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
- SPDX-License-Identifier: CC-BY-SA-4.0
4
- -->
5
-
6
- # Ratatui Logo Example
7
-
8
- [![widget_ratatui_logo](../../doc/images/widget_ratatui_logo.png)](app.rb)
9
-
10
- Demonstrates branding with the official logo widget.
11
-
12
- A polished application often needs an "About" screen or a splash screen. This widget provides the standardized project branding.
13
-
14
- ## Features Demonstrated
15
-
16
- - **RatatuiLogo Widget**: Renders the Ratatui ASCII art logo.
17
- - **Centering**: Techniques for centering fixed-size content in a fluid layout.
18
-
19
- ## Hotkeys
20
-
21
- - **q**: Quit
22
-
23
- ## Usage
24
-
25
- <!-- SPDX-SnippetBegin -->
26
- <!--
27
- SPDX-FileCopyrightText: 2026 Kerrick Long
28
- SPDX-License-Identifier: MIT-0
29
- -->
30
- ```bash
31
- ruby examples/widget_ratatui_logo/app.rb
32
- ```
33
- <!-- SPDX-SnippetEnd -->
34
-
35
- ## Learning Outcomes
36
-
37
- Use this example if you need to...
38
-
39
- - Create a splash screen.
40
- - Add an "About" modal to your application.
41
- - See how to center a widget both vertically and horizontally.
42
-
43
- [Read the source code →](app.rb)