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