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,240 +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
- # Demonstrates categorical data visualization with interactive attribute cycling.
12
- #
13
- # Raw tables of numbers are hard to scan. Comparing magnitudes requires mental arithmetic, which slows down decision-making.
14
- #
15
- # 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.
16
- #
17
- # Use it to understand how to visualize and compare discrete datasets effectively.
18
- #
19
- # === Example
20
- #
21
- # Run the demo from the terminal:
22
- #
23
- # ruby examples/widget_barchart/app.rb
24
- #
25
- # rdoc-image:/doc/images/widget_barchart.png
26
- class WidgetBarchart
27
- def initialize
28
- @data_index = 2
29
- @styles = nil # Initialized in run
30
- @style_index = 3
31
- @label_style_index = 3
32
- @value_style_index = 3
33
- @bar_sets = [
34
- { name: "Default", set: nil },
35
- { name: "Numbers (Short)", set: { 8 => "8", 7 => "7", 6 => "6", 5 => "5", 4 => "4", 3 => "3", 2 => "2", 1 => "1", 0 => "0" } },
36
- { 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: " " } },
37
- { name: "ASCII (Heights)", set: [" ", "_", ".", "-", "=", "+", "*", "#", "@"] },
38
- ]
39
- @bar_set_index = 0
40
- @direction = :vertical
41
- @bar_width = 8
42
- @bar_gap = 1
43
- @group_gap = 2
44
- @height_mode = :full
45
- @hotkey_style = nil
46
- end
47
-
48
- def run
49
- RatatuiRuby.run do |tui|
50
- @tui = tui
51
- init_styles
52
-
53
- loop do
54
- render
55
- break if handle_input == :quit
56
- end
57
- end
58
- end
59
-
60
- private def init_styles
61
- @styles = [
62
- { name: "Green", style: @tui.style(fg: :green) },
63
- { name: "Blue", style: @tui.style(fg: :blue) },
64
- { name: "Red", style: @tui.style(fg: :red) },
65
- { name: "Cyan", style: @tui.style(fg: :cyan) },
66
- { name: "Yellow Bold", style: @tui.style(fg: :yellow, modifiers: [:bold]) },
67
- { name: "Reversed", style: @tui.style(modifiers: [:reversed]) },
68
- ]
69
- @hotkey_style = @tui.style(modifiers: [:bold, :underlined])
70
- end
71
-
72
- private def current_data
73
- case @data_index
74
- when 0 # Simple Hash
75
- {
76
- "Q1" => 50,
77
- "Q2" => 80,
78
- "Q3" => 45,
79
- "Q4" => 60,
80
- "Q1'" => 55,
81
- "Q2'" => 85,
82
- "Q3'" => 50,
83
- "Q4'" => 65,
84
- }
85
- when 1 # Array with styles
86
- [
87
- ["Mon", 120],
88
- ["Tue", 150],
89
- ["Wed", 130],
90
- ["Thu", 160],
91
- ["Fri", 140],
92
- ["Sat", 110, @tui.style(fg: :red)],
93
- ["Sun", 100, @tui.style(fg: :red)],
94
- ]
95
- when 2 # Groups
96
- [
97
- @tui.bar_chart_bar_group(label: "2024", bars: [
98
- @tui.bar_chart_bar(value: 40, label: "Q1"),
99
- @tui.bar_chart_bar(value: 45, label: "Q2"),
100
- @tui.bar_chart_bar(value: 50, label: "Q3"),
101
- @tui.bar_chart_bar(value: 55, label: "Q4"),
102
- ]),
103
- @tui.bar_chart_bar_group(label: "2025", bars: [
104
- @tui.bar_chart_bar(value: 60, label: "Q1", style: @tui.style(fg: :yellow)),
105
- @tui.bar_chart_bar(value: 65, label: "Q2", style: @tui.style(fg: :yellow)),
106
- @tui.bar_chart_bar(value: 70, label: "Q3", style: @tui.style(fg: :yellow)),
107
- @tui.bar_chart_bar(value: 75, label: "Q4", style: @tui.style(fg: :yellow)),
108
- ]),
109
- ]
110
- end
111
- end
112
-
113
- private def data_name
114
- ["Simple Hash", "Styled Array", "Groups"][@data_index]
115
- end
116
-
117
- private def render
118
- @tui.draw do |frame|
119
- chart_area, controls_area = @tui.layout_split(
120
- frame.area,
121
- direction: :vertical,
122
- constraints: [
123
- @tui.constraint_fill(1),
124
- @tui.constraint_length(6),
125
- ]
126
- )
127
-
128
- # Handle Mini Mode
129
- effective_chart_area = if @height_mode == :mini
130
- mini_area, = @tui.layout_split(
131
- chart_area,
132
- direction: :vertical,
133
- constraints: [
134
- @tui.constraint_length(3),
135
- @tui.constraint_fill(1),
136
- ]
137
- )
138
- mini_area
139
- else
140
- chart_area
141
- end
142
-
143
- bar_chart = @tui.bar_chart(
144
- data: current_data,
145
- bar_width: @bar_width,
146
- style: @styles[@style_index][:style],
147
- bar_gap: @bar_gap,
148
- group_gap: @group_gap,
149
- direction: @direction,
150
- label_style: @styles[@label_style_index][:style],
151
- value_style: @styles[@value_style_index][:style],
152
- bar_set: @bar_sets[@bar_set_index][:set],
153
- block: @tui.block(
154
- title: "BarChart: #{data_name}",
155
- borders: [:all]
156
- )
157
- )
158
- frame.render_widget(bar_chart, effective_chart_area)
159
-
160
- render_controls(frame, controls_area)
161
- end
162
- end
163
-
164
- private def render_controls(frame, area)
165
- controls = @tui.block(
166
- title: "Controls",
167
- borders: [:all],
168
- children: [
169
- @tui.paragraph(
170
- text: [
171
- @tui.text_line(spans: [
172
- @tui.text_span(content: "d", style: @hotkey_style),
173
- @tui.text_span(content: ": Data (#{data_name}) "),
174
- @tui.text_span(content: "v", style: @hotkey_style),
175
- @tui.text_span(content: ": Direction (#{@direction}) "),
176
- @tui.text_span(content: "q", style: @hotkey_style),
177
- @tui.text_span(content: ": Quit"),
178
- ]),
179
- @tui.text_line(spans: [
180
- @tui.text_span(content: "w", style: @hotkey_style),
181
- @tui.text_span(content: ": Width (#{@bar_width}) "),
182
- @tui.text_span(content: "a", style: @hotkey_style),
183
- @tui.text_span(content: ": Gap (#{@bar_gap}) "),
184
- @tui.text_span(content: "g", style: @hotkey_style),
185
- @tui.text_span(content: ": Group Gap (#{@group_gap})"),
186
- ]),
187
- @tui.text_line(spans: [
188
- @tui.text_span(content: "s", style: @hotkey_style),
189
- @tui.text_span(content: ": Style (#{@styles[@style_index][:name]}) "),
190
- @tui.text_span(content: "x", style: @hotkey_style),
191
- @tui.text_span(content: ": Label (#{@styles[@label_style_index][:name]}) "),
192
- @tui.text_span(content: "z", style: @hotkey_style),
193
- @tui.text_span(content: ": Value (#{@styles[@value_style_index][:name]}) "),
194
- ]),
195
- @tui.text_line(spans: [
196
- @tui.text_span(content: "b", style: @hotkey_style),
197
- @tui.text_span(content: ": Set (#{@bar_sets[@bar_set_index][:name]}) "),
198
- @tui.text_span(content: "m", style: @hotkey_style),
199
- @tui.text_span(content: ": Mode (#{(@height_mode == :full) ? 'Full' : 'Mini'})"),
200
- ]),
201
- ]
202
- ),
203
- ]
204
- )
205
- frame.render_widget(controls, area)
206
- end
207
-
208
- private def handle_input
209
- case @tui.poll_event
210
- in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
211
- :quit
212
- in type: :key, code: "d"
213
- @data_index = (@data_index + 1) % 3
214
- in type: :key, code: "v"
215
- @direction = (@direction == :vertical) ? :horizontal : :vertical
216
- # Adjust width default based on direction for better UX, though user can manually adjust 'w'
217
- @bar_width = (@direction == :vertical) ? 8 : 1
218
- in type: :key, code: "w"
219
- @bar_width = (@bar_width % 10) + 1
220
- in type: :key, code: "a"
221
- @bar_gap = (@bar_gap + 1) % 5
222
- in type: :key, code: "g"
223
- @group_gap = (@group_gap + 1) % 5
224
- in type: :key, code: "s"
225
- @style_index = (@style_index + 1) % @styles.size
226
- in type: :key, code: "x"
227
- @label_style_index = (@label_style_index + 1) % @styles.size
228
- in type: :key, code: "z"
229
- @value_style_index = (@value_style_index + 1) % @styles.size
230
- in type: :key, code: "b"
231
- @bar_set_index = (@bar_set_index + 1) % @bar_sets.size
232
- in type: :key, code: "m"
233
- @height_mode = (@height_mode == :full) ? :mini : :full
234
- else
235
- # Ignore
236
- end
237
- end
238
- end
239
-
240
- WidgetBarchart.new.run if __FILE__ == $0
@@ -1,44 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
- SPDX-License-Identifier: CC-BY-SA-4.0
4
- -->
5
- # Block Example
6
-
7
- [![](../../doc/images/widget_block.png)](app.rb)
8
-
9
- This example demonstrates the versatile `Block` widget, which provides the visual container, borders, and titles for almost every other widget in `ratatui_ruby`.
10
-
11
- ## Key Concepts
12
-
13
- - **Borders:** Choose which sides to show and apply different border types (plain, rounded, double, thick, etc.).
14
- - **Titles:** Add a main title with alignment or multiple titles at the top and bottom with independent styles and positions.
15
- - **Padding:** Define inner spacing using uniform or directional (L/R/T/B) values.
16
- - **Styling:** Individually style the block's content area, its borders, and its titles.
17
- - **Custom Border Sets:** Create entirely custom border appearances by defining each character in the border set.
18
-
19
- ## Hotkeys
20
-
21
- - `t`: Cycle **Title** (None, Main Title)
22
- - `a`: Cycle **Title Alignment** (Left, Center, Right)
23
- - `s`: Cycle **Title Style** (None, Cyan Bold, Yellow Italic)
24
- - `e`: Cycle **Additional Titles** (None, Top+Bottom, Complex)
25
- - `b`: Cycle **Borders** (All, Top/Bottom, Left/Right, None)
26
- - `y`: Cycle **Border Type** (Rounded, Plain, Double, Thick, Quadrant, Custom)
27
- - `c`: Cycle **Border Style** (Magenta Bold, None, Green, Blue on White)
28
- - `p`: Cycle **Padding** (Uniform, None, Directional, Narrow)
29
- - `f`: Cycle **Base Style** (Dark Gray, None, White on Black)
30
- - `q`: **Quit**
31
-
32
- ## Usage
33
-
34
- <!-- SPDX-SnippetBegin -->
35
- <!--
36
- SPDX-FileCopyrightText: 2026 Kerrick Long
37
- SPDX-License-Identifier: MIT-0
38
- -->
39
- ```bash
40
- ruby examples/widget_block/app.rb
41
- ```
42
- <!-- SPDX-SnippetEnd -->
43
-
44
- [Read the source code →](app.rb)
@@ -1,258 +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
- # Demonstrates the Block widget with interactive attribute cycling.
12
- #
13
- # Blocks are the foundation of terminal layouts, providing structure, borders, and titles.
14
- # This demo showcases all available parameters, including advanced title positioning,
15
- # directional padding, and custom border sets.
16
- #
17
- # === Examples
18
- #
19
- # Run the demo from the terminal:
20
- #
21
- # ruby examples/widget_block/app.rb
22
- #
23
- # rdoc-image:/doc/images/widget_block.png
24
- class WidgetBlock
25
- def initialize
26
- @title_configs = [
27
- { name: "None", title: nil },
28
- { name: "Main Title", title: "Main Title" },
29
- ]
30
- @title_index = 1
31
-
32
- @titles_configs = [
33
- { name: "None", titles: [] },
34
- {
35
- name: "Top + Bottom",
36
- titles: [
37
- { content: "Top Right", alignment: :right, position: :top },
38
- { content: "Bottom Left", alignment: :left, position: :bottom },
39
- ],
40
- },
41
- {
42
- name: "Complex",
43
- titles: [
44
- { content: "★ Left ★", alignment: :left, position: :top },
45
- { content: "Center", alignment: :center, position: :top },
46
- { content: "Right", alignment: :right, position: :top },
47
- { content: "Bottom Center", alignment: :center, position: :bottom },
48
- ],
49
- },
50
- ]
51
- @titles_index = 1
52
-
53
- @alignment_configs = [
54
- { name: "Left", alignment: :left },
55
- { name: "Center", alignment: :center },
56
- { name: "Right", alignment: :right },
57
- ]
58
- @alignment_index = 1 # Center
59
-
60
- @border_configs = [
61
- { name: "All", borders: [:all] },
62
- { name: "Top/Bottom", borders: [:top, :bottom] },
63
- { name: "Left/Right", borders: [:left, :right] },
64
- { name: "None", borders: [] },
65
- ]
66
- @border_index = 0
67
-
68
- @border_type_configs = [
69
- { name: "Rounded", type: :rounded },
70
- { name: "Plain", type: :plain },
71
- { name: "Double", type: :double },
72
- { name: "Thick", type: :thick },
73
- { name: "Quadrant Inside", type: :quadrant_inside },
74
- { name: "Quadrant Outside", type: :quadrant_outside },
75
- {
76
- name: "Custom Set",
77
- type: nil,
78
- set: {
79
- top_left: "1",
80
- top_right: "2",
81
- bottom_left: "3",
82
- bottom_right: "4",
83
- vertical_left: "5",
84
- vertical_right: "6",
85
- horizontal_top: "7",
86
- horizontal_bottom: "8",
87
- },
88
- },
89
- ]
90
- @border_type_index = 0
91
-
92
- @padding_configs = [
93
- { name: "Uniform (2)", padding: 2 },
94
- { name: "None (0)", padding: 0 },
95
- { name: "Directional (L:4, T:2)", padding: [4, 0, 2, 0] },
96
- { name: "Narrow (H:1, V:0)", padding: [1, 1, 0, 0] },
97
- ]
98
- @padding_index = 0
99
- end
100
-
101
- def run
102
- RatatuiRuby.run do |tui|
103
- @tui = tui
104
-
105
- @title_styles = [
106
- { name: "None", style: nil },
107
- { name: "Magenta Bold", style: @tui.style(fg: :magenta, modifiers: [:bold]) },
108
- { name: "Cyan Bold", style: @tui.style(fg: :cyan, modifiers: [:bold]) },
109
- { name: "Yellow Italic", style: @tui.style(fg: :yellow, modifiers: [:italic]) },
110
- ]
111
- @title_style_index = 1 # Magenta Bold
112
-
113
- @border_styles = [
114
- { name: "Cyan", style: @tui.style(fg: :cyan) },
115
- { name: "Magenta Bold", style: @tui.style(fg: :magenta, modifiers: [:bold]) },
116
- { name: "None", style: nil },
117
- { name: "Blue on White", style: @tui.style(fg: :blue, bg: :white) },
118
- ]
119
- @border_style_index = 0
120
-
121
- @base_styles = [
122
- { name: "Dark Gray", style: @tui.style(fg: :dark_gray) },
123
- { name: "None", style: nil },
124
- { name: "White on Black", style: @tui.style(fg: :white, bg: :black) },
125
- ]
126
- @base_style_index = 1
127
-
128
- @hotkey_style = @tui.style(modifiers: [:bold, :underlined])
129
-
130
- loop do
131
- render
132
- break if handle_input == :quit
133
- sleep 0.05
134
- end
135
- end
136
- end
137
-
138
- private def render
139
- title_config = @title_configs[@title_index]
140
- titles_config = @titles_configs[@titles_index]
141
- alignment_config = @alignment_configs[@alignment_index]
142
- title_style_config = @title_styles[@title_style_index]
143
- border_config = @border_configs[@border_index]
144
- border_type_config = @border_type_configs[@border_type_index]
145
- border_style_config = @border_styles[@border_style_index]
146
- base_style_config = @base_styles[@base_style_index]
147
- padding_config = @padding_configs[@padding_index]
148
-
149
- @tui.draw do |frame|
150
- main_area, control_area = @tui.layout_split(
151
- frame.area,
152
- direction: :vertical,
153
- constraints: [
154
- @tui.constraint_fill(1),
155
- @tui.constraint_length(10),
156
- ]
157
- )
158
-
159
- # Render the demo block
160
- demo_block = @tui.block(
161
- title: title_config[:title],
162
- titles: titles_config[:titles],
163
- title_alignment: alignment_config[:alignment],
164
- title_style: title_style_config[:style],
165
- borders: border_config[:borders],
166
- border_type: border_type_config[:type],
167
- border_set: border_type_config[:set],
168
- border_style: border_style_config[:style],
169
- style: base_style_config[:style],
170
- padding: padding_config[:padding]
171
- )
172
-
173
- # Paragraph inside the block to show padding/content interaction
174
- content = @tui.paragraph(
175
- text: "This paragraph is rendered inside the Block widget.\n" \
176
- "You can see how padding and base style affect this content.\n\n" \
177
- "Current State:\n" \
178
- "• Padding: #{padding_config[:name]}\n" \
179
- "• Borders: #{border_config[:name]}\n" \
180
- "• Type: #{border_type_config[:name]}",
181
- block: demo_block
182
- )
183
- frame.render_widget(content, main_area)
184
-
185
- # Render control panel
186
- control_panel = @tui.block(
187
- title: "Controls",
188
- borders: [:all],
189
- children: [
190
- @tui.paragraph(
191
- text: [
192
- @tui.text_line(spans: [
193
- @tui.text_span(content: "t", style: @hotkey_style),
194
- @tui.text_span(content: ": Title (#{title_config[:name]}) "),
195
- @tui.text_span(content: "a", style: @hotkey_style),
196
- @tui.text_span(content: ": Alignment (#{alignment_config[:name]}) "),
197
- @tui.text_span(content: "s", style: @hotkey_style),
198
- @tui.text_span(content: ": Title Style (#{title_style_config[:name]})"),
199
- ]),
200
- @tui.text_line(spans: [
201
- @tui.text_span(content: "e", style: @hotkey_style),
202
- @tui.text_span(content: ": Additional Titles (#{titles_config[:name]})"),
203
- ]),
204
- @tui.text_line(spans: [
205
- @tui.text_span(content: "b", style: @hotkey_style),
206
- @tui.text_span(content: ": Borders (#{border_config[:name]}) "),
207
- @tui.text_span(content: "y", style: @hotkey_style),
208
- @tui.text_span(content: ": Border Type (#{border_type_config[:name]})"),
209
- ]),
210
- @tui.text_line(spans: [
211
- @tui.text_span(content: "c", style: @hotkey_style),
212
- @tui.text_span(content: ": Border Style (#{border_style_config[:name]}) "),
213
- @tui.text_span(content: "p", style: @hotkey_style),
214
- @tui.text_span(content: ": Padding (#{padding_config[:name]})"),
215
- ]),
216
- @tui.text_line(spans: [
217
- @tui.text_span(content: "f", style: @hotkey_style),
218
- @tui.text_span(content: ": Base Style (#{base_style_config[:name]}) "),
219
- @tui.text_span(content: "q", style: @hotkey_style),
220
- @tui.text_span(content: ": Quit"),
221
- ]),
222
- ]
223
- ),
224
- ]
225
- )
226
- frame.render_widget(control_panel, control_area)
227
- end
228
- end
229
-
230
- private def handle_input
231
- case @tui.poll_event
232
- in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
233
- :quit
234
- in type: :key, code: "t"
235
- @title_index = (@title_index + 1) % @title_configs.size
236
- in type: :key, code: "e"
237
- @titles_index = (@titles_index + 1) % @titles_configs.size
238
- in type: :key, code: "a"
239
- @alignment_index = (@alignment_index + 1) % @alignment_configs.size
240
- in type: :key, code: "s"
241
- @title_style_index = (@title_style_index + 1) % @title_styles.size
242
- in type: :key, code: "b"
243
- @border_index = (@border_index + 1) % @border_configs.size
244
- in type: :key, code: "y"
245
- @border_type_index = (@border_type_index + 1) % @border_type_configs.size
246
- in type: :key, code: "c"
247
- @border_style_index = (@border_style_index + 1) % @border_styles.size
248
- in type: :key, code: "p"
249
- @padding_index = (@padding_index + 1) % @padding_configs.size
250
- in type: :key, code: "f"
251
- @base_style_index = (@base_style_index + 1) % @base_styles.size
252
- else
253
- nil
254
- end
255
- end
256
- end
257
-
258
- WidgetBlock.new.run if __FILE__ == $PROGRAM_NAME
@@ -1,54 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
- SPDX-License-Identifier: CC-BY-SA-4.0
4
- -->
5
-
6
- # Block (Box) Example
7
-
8
- [![widget_box](../../doc/images/widget_box.png)](app.rb)
9
-
10
- Demonstrates visual container attributes with interactive cycling.
11
-
12
- Widgets often float in a void. Without boundaries, interfaces become a chaotic mess of text. `Block` (often called a Box) provides the structure and visual hierarchy needed to organize information.
13
-
14
- ## Features Demonstrated
15
-
16
- - **Border Types**: Native styles like `:plain`, `:rounded`, `:double`, `:thick`.
17
- - **Custom Borders**: defining completely custom character sets (e.g. using numbers or letters for borders).
18
- - **Styling**: Independent control over border color, background style, and title style.
19
- - **Positioning**: Placing titles on the `:top` or `:bottom` border (`position`).
20
- - **Alignment**: Aligning titles to `:left`, `:center`, or `:right` (`alignment`).
21
-
22
- ## Hotkeys
23
-
24
- - **Arrow Keys**: Change Border/Content Color
25
- - **Space**: Cycle Border Type (`border_type`)
26
- - **c**: Cycle Custom Border Set (`border_set`)
27
- - **Enter**: Cycle Title Alignment (`title_alignment`)
28
- - **s**: Cycle Content Style (`style`)
29
- - **t**: Cycle Title Style (`title_style`)
30
- - **b**: Cycle Border Style (`border_style`)
31
- - **q**: Quit
32
-
33
- ## Usage
34
-
35
- <!-- SPDX-SnippetBegin -->
36
- <!--
37
- SPDX-FileCopyrightText: 2026 Kerrick Long
38
- SPDX-License-Identifier: MIT-0
39
- -->
40
- ```bash
41
- ruby examples/widget_box/app.rb
42
- ```
43
- <!-- SPDX-SnippetEnd -->
44
-
45
- ## Learning Outcomes
46
-
47
- Use this example if you need to...
48
-
49
- - Group related widgets together.
50
- - Create distinct "panels" or "cards" in your UI.
51
- - Style borders to indicate state (e.g., Red border for error state).
52
- - Understand the difference between `style` (content) and `border_style` (frame).
53
-
54
- [Read the source code →](app.rb)