ratatui_ruby 1.1.0 → 1.1.1

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 (259) hide show
  1. checksums.yaml +4 -4
  2. data/ext/ratatui_ruby/Cargo.lock +1 -1
  3. data/ext/ratatui_ruby/Cargo.toml +1 -1
  4. data/lib/ratatui_ruby/version.rb +1 -1
  5. metadata +1 -255
  6. data/.builds/ruby-3.2.yml +0 -54
  7. data/.builds/ruby-3.3.yml +0 -54
  8. data/.builds/ruby-3.4.yml +0 -54
  9. data/.builds/ruby-4.0.0.yml +0 -54
  10. data/.pre-commit-config.yaml +0 -16
  11. data/.rubocop.yml +0 -10
  12. data/AGENTS.md +0 -147
  13. data/CHANGELOG.md +0 -736
  14. data/README.md +0 -187
  15. data/README.rdoc +0 -302
  16. data/Rakefile +0 -11
  17. data/Steepfile +0 -50
  18. data/doc/concepts/application_architecture.md +0 -321
  19. data/doc/concepts/application_testing.md +0 -193
  20. data/doc/concepts/async.md +0 -190
  21. data/doc/concepts/custom_widgets.md +0 -247
  22. data/doc/concepts/debugging.md +0 -401
  23. data/doc/concepts/event_handling.md +0 -162
  24. data/doc/concepts/interactive_design.md +0 -146
  25. data/doc/contributors/auditing/parity.md +0 -239
  26. data/doc/contributors/design/ruby_frontend.md +0 -448
  27. data/doc/contributors/design/rust_backend.md +0 -434
  28. data/doc/contributors/design.md +0 -11
  29. data/doc/contributors/developing_examples.md +0 -400
  30. data/doc/contributors/documentation_style.md +0 -121
  31. data/doc/contributors/index.md +0 -21
  32. data/doc/contributors/releasing.md +0 -215
  33. data/doc/contributors/todo/align/api_completeness_audit-finished.md +0 -381
  34. data/doc/contributors/todo/align/api_completeness_audit-unfinished.md +0 -200
  35. data/doc/contributors/todo/align/term.md +0 -351
  36. data/doc/contributors/todo/align/terminal.md +0 -647
  37. data/doc/contributors/todo/future_work.md +0 -169
  38. data/doc/contributors/upstream_requests/paragraph_span_rects.md +0 -259
  39. data/doc/contributors/upstream_requests/tab_rects.md +0 -173
  40. data/doc/contributors/upstream_requests/title_rects.md +0 -132
  41. data/doc/custom.css +0 -22
  42. data/doc/getting_started/quickstart.md +0 -291
  43. data/doc/getting_started/why.md +0 -93
  44. data/doc/images/app_all_events.png +0 -0
  45. data/doc/images/app_cli_rich_moments.gif +0 -0
  46. data/doc/images/app_color_picker.png +0 -0
  47. data/doc/images/app_debugging_showcase.gif +0 -0
  48. data/doc/images/app_debugging_showcase.png +0 -0
  49. data/doc/images/app_external_editor.gif +0 -0
  50. data/doc/images/app_login_form.png +0 -0
  51. data/doc/images/app_stateful_interaction.png +0 -0
  52. data/doc/images/verify_quickstart_dsl.png +0 -0
  53. data/doc/images/verify_quickstart_layout.png +0 -0
  54. data/doc/images/verify_quickstart_lifecycle.png +0 -0
  55. data/doc/images/verify_readme_usage.png +0 -0
  56. data/doc/images/widget_barchart.png +0 -0
  57. data/doc/images/widget_block.png +0 -0
  58. data/doc/images/widget_box.png +0 -0
  59. data/doc/images/widget_calendar.png +0 -0
  60. data/doc/images/widget_canvas.png +0 -0
  61. data/doc/images/widget_cell.png +0 -0
  62. data/doc/images/widget_center.png +0 -0
  63. data/doc/images/widget_chart.png +0 -0
  64. data/doc/images/widget_gauge.png +0 -0
  65. data/doc/images/widget_layout_split.png +0 -0
  66. data/doc/images/widget_line_gauge.png +0 -0
  67. data/doc/images/widget_list.png +0 -0
  68. data/doc/images/widget_map.png +0 -0
  69. data/doc/images/widget_overlay.png +0 -0
  70. data/doc/images/widget_popup.png +0 -0
  71. data/doc/images/widget_ratatui_logo.png +0 -0
  72. data/doc/images/widget_ratatui_mascot.png +0 -0
  73. data/doc/images/widget_rect.png +0 -0
  74. data/doc/images/widget_render.png +0 -0
  75. data/doc/images/widget_rich_text.png +0 -0
  76. data/doc/images/widget_scroll_text.png +0 -0
  77. data/doc/images/widget_scrollbar.png +0 -0
  78. data/doc/images/widget_sparkline.png +0 -0
  79. data/doc/images/widget_style_colors.png +0 -0
  80. data/doc/images/widget_table.png +0 -0
  81. data/doc/images/widget_tabs.png +0 -0
  82. data/doc/images/widget_text_width.png +0 -0
  83. data/doc/index.md +0 -34
  84. data/doc/troubleshooting/async.md +0 -4
  85. data/doc/troubleshooting/terminal_limitations.md +0 -131
  86. data/doc/troubleshooting/tui_output.md +0 -197
  87. data/examples/app_all_events/README.md +0 -114
  88. data/examples/app_all_events/app.rb +0 -98
  89. data/examples/app_all_events/model/app_model.rb +0 -159
  90. data/examples/app_all_events/model/event_color_cycle.rb +0 -43
  91. data/examples/app_all_events/model/event_entry.rb +0 -94
  92. data/examples/app_all_events/model/msg.rb +0 -39
  93. data/examples/app_all_events/model/timestamp.rb +0 -56
  94. data/examples/app_all_events/update.rb +0 -75
  95. data/examples/app_all_events/view/app_view.rb +0 -80
  96. data/examples/app_all_events/view/controls_view.rb +0 -54
  97. data/examples/app_all_events/view/counts_view.rb +0 -61
  98. data/examples/app_all_events/view/live_view.rb +0 -72
  99. data/examples/app_all_events/view/log_view.rb +0 -57
  100. data/examples/app_all_events/view.rb +0 -9
  101. data/examples/app_cli_rich_moments/README.md +0 -81
  102. data/examples/app_cli_rich_moments/app.rb +0 -189
  103. data/examples/app_color_picker/README.md +0 -156
  104. data/examples/app_color_picker/app.rb +0 -76
  105. data/examples/app_color_picker/clipboard.rb +0 -86
  106. data/examples/app_color_picker/color.rb +0 -193
  107. data/examples/app_color_picker/controls.rb +0 -92
  108. data/examples/app_color_picker/copy_dialog.rb +0 -168
  109. data/examples/app_color_picker/export_pane.rb +0 -128
  110. data/examples/app_color_picker/harmony.rb +0 -58
  111. data/examples/app_color_picker/input.rb +0 -176
  112. data/examples/app_color_picker/main_container.rb +0 -180
  113. data/examples/app_color_picker/palette.rb +0 -111
  114. data/examples/app_debugging_showcase/README.md +0 -119
  115. data/examples/app_debugging_showcase/app.rb +0 -318
  116. data/examples/app_external_editor/README.md +0 -62
  117. data/examples/app_external_editor/app.rb +0 -344
  118. data/examples/app_login_form/README.md +0 -58
  119. data/examples/app_login_form/app.rb +0 -109
  120. data/examples/app_stateful_interaction/README.md +0 -35
  121. data/examples/app_stateful_interaction/app.rb +0 -328
  122. data/examples/timeout_demo.rb +0 -45
  123. data/examples/verify_quickstart_dsl/README.md +0 -55
  124. data/examples/verify_quickstart_dsl/app.rb +0 -49
  125. data/examples/verify_quickstart_layout/README.md +0 -77
  126. data/examples/verify_quickstart_layout/app.rb +0 -73
  127. data/examples/verify_quickstart_lifecycle/README.md +0 -68
  128. data/examples/verify_quickstart_lifecycle/app.rb +0 -62
  129. data/examples/verify_readme_usage/README.md +0 -49
  130. data/examples/verify_readme_usage/app.rb +0 -42
  131. data/examples/verify_website_managed/README.md +0 -48
  132. data/examples/verify_website_managed/app.rb +0 -36
  133. data/examples/verify_website_menu/README.md +0 -60
  134. data/examples/verify_website_menu/app.rb +0 -84
  135. data/examples/verify_website_spinner/README.md +0 -44
  136. data/examples/verify_website_spinner/app.rb +0 -34
  137. data/examples/widget_barchart/README.md +0 -58
  138. data/examples/widget_barchart/app.rb +0 -240
  139. data/examples/widget_block/README.md +0 -44
  140. data/examples/widget_block/app.rb +0 -258
  141. data/examples/widget_box/README.md +0 -54
  142. data/examples/widget_box/app.rb +0 -255
  143. data/examples/widget_calendar/README.md +0 -48
  144. data/examples/widget_calendar/app.rb +0 -115
  145. data/examples/widget_canvas/README.md +0 -31
  146. data/examples/widget_canvas/app.rb +0 -130
  147. data/examples/widget_cell/README.md +0 -45
  148. data/examples/widget_cell/app.rb +0 -112
  149. data/examples/widget_center/README.md +0 -33
  150. data/examples/widget_center/app.rb +0 -118
  151. data/examples/widget_chart/README.md +0 -50
  152. data/examples/widget_chart/app.rb +0 -220
  153. data/examples/widget_gauge/README.md +0 -50
  154. data/examples/widget_gauge/app.rb +0 -229
  155. data/examples/widget_layout_split/README.md +0 -53
  156. data/examples/widget_layout_split/app.rb +0 -260
  157. data/examples/widget_line_gauge/README.md +0 -50
  158. data/examples/widget_line_gauge/app.rb +0 -219
  159. data/examples/widget_list/README.md +0 -58
  160. data/examples/widget_list/app.rb +0 -382
  161. data/examples/widget_map/README.md +0 -48
  162. data/examples/widget_map/app.rb +0 -95
  163. data/examples/widget_overlay/README.md +0 -45
  164. data/examples/widget_overlay/app.rb +0 -250
  165. data/examples/widget_popup/README.md +0 -45
  166. data/examples/widget_popup/app.rb +0 -106
  167. data/examples/widget_ratatui_logo/README.md +0 -43
  168. data/examples/widget_ratatui_logo/app.rb +0 -104
  169. data/examples/widget_ratatui_mascot/README.md +0 -43
  170. data/examples/widget_ratatui_mascot/app.rb +0 -95
  171. data/examples/widget_rect/README.md +0 -53
  172. data/examples/widget_rect/app.rb +0 -222
  173. data/examples/widget_render/README.md +0 -46
  174. data/examples/widget_render/app.rb +0 -186
  175. data/examples/widget_render/app.rbs +0 -41
  176. data/examples/widget_rich_text/README.md +0 -44
  177. data/examples/widget_rich_text/app.rb +0 -193
  178. data/examples/widget_scroll_text/README.md +0 -46
  179. data/examples/widget_scroll_text/app.rb +0 -109
  180. data/examples/widget_scrollbar/README.md +0 -46
  181. data/examples/widget_scrollbar/app.rb +0 -155
  182. data/examples/widget_sparkline/README.md +0 -51
  183. data/examples/widget_sparkline/app.rb +0 -277
  184. data/examples/widget_style_colors/README.md +0 -43
  185. data/examples/widget_style_colors/app.rb +0 -83
  186. data/examples/widget_table/README.md +0 -57
  187. data/examples/widget_table/app.rb +0 -285
  188. data/examples/widget_tabs/README.md +0 -50
  189. data/examples/widget_tabs/app.rb +0 -183
  190. data/examples/widget_text_width/README.md +0 -44
  191. data/examples/widget_text_width/app.rb +0 -117
  192. data/migrate_to_buffer.rb +0 -145
  193. data/mise.toml +0 -8
  194. data/tasks/autodoc/examples.rb +0 -87
  195. data/tasks/autodoc/member.rb +0 -58
  196. data/tasks/autodoc/name.rb +0 -21
  197. data/tasks/autodoc.rake +0 -21
  198. data/tasks/bump/bump_workflow.rb +0 -49
  199. data/tasks/bump/cargo_lockfile.rb +0 -21
  200. data/tasks/bump/changelog.rb +0 -104
  201. data/tasks/bump/header.rb +0 -32
  202. data/tasks/bump/history.rb +0 -32
  203. data/tasks/bump/links.rb +0 -69
  204. data/tasks/bump/manifest.rb +0 -33
  205. data/tasks/bump/patch_release.rb +0 -19
  206. data/tasks/bump/release_branch.rb +0 -17
  207. data/tasks/bump/release_from_trunk.rb +0 -49
  208. data/tasks/bump/repository.rb +0 -54
  209. data/tasks/bump/ruby_gem.rb +0 -29
  210. data/tasks/bump/sem_ver.rb +0 -44
  211. data/tasks/bump/unreleased_section.rb +0 -73
  212. data/tasks/bump.rake +0 -61
  213. data/tasks/doc/documentation.rb +0 -59
  214. data/tasks/doc/link/file_url.rb +0 -30
  215. data/tasks/doc/link/relative_path.rb +0 -61
  216. data/tasks/doc/link/web_url.rb +0 -55
  217. data/tasks/doc/link.rb +0 -52
  218. data/tasks/doc/link_audit.rb +0 -116
  219. data/tasks/doc/problem.rb +0 -40
  220. data/tasks/doc/source_file.rb +0 -93
  221. data/tasks/doc.rake +0 -905
  222. data/tasks/example_viewer.html.erb +0 -172
  223. data/tasks/extension.rake +0 -14
  224. data/tasks/license/headers_md.rb +0 -223
  225. data/tasks/license/headers_rb.rb +0 -210
  226. data/tasks/license/license_utils.rb +0 -130
  227. data/tasks/license/snippets_md.rb +0 -315
  228. data/tasks/license/snippets_rdoc.rb +0 -150
  229. data/tasks/license.rake +0 -91
  230. data/tasks/lint.rake +0 -170
  231. data/tasks/rbs_predicates/predicate_catalog.rb +0 -52
  232. data/tasks/rbs_predicates/predicate_tests.rb +0 -124
  233. data/tasks/rbs_predicates/rbs_signature.rb +0 -63
  234. data/tasks/rbs_predicates.rake +0 -31
  235. data/tasks/rdoc_config.rb +0 -29
  236. data/tasks/resources/build.yml.erb +0 -60
  237. data/tasks/resources/index.html.erb +0 -141
  238. data/tasks/resources/rubies.yml +0 -7
  239. data/tasks/sourcehut.rake +0 -110
  240. data/tasks/steep.rake +0 -11
  241. data/tasks/terminal_preview/app_screenshot.rb +0 -45
  242. data/tasks/terminal_preview/crash_report.rb +0 -54
  243. data/tasks/terminal_preview/example_app.rb +0 -27
  244. data/tasks/terminal_preview/launcher_script.rb +0 -48
  245. data/tasks/terminal_preview/preview_collection.rb +0 -60
  246. data/tasks/terminal_preview/preview_timing.rb +0 -24
  247. data/tasks/terminal_preview/safety_confirmation.rb +0 -58
  248. data/tasks/terminal_preview/saved_screenshot.rb +0 -56
  249. data/tasks/terminal_preview/system_appearance.rb +0 -13
  250. data/tasks/terminal_preview/terminal_window.rb +0 -138
  251. data/tasks/terminal_preview/window_id.rb +0 -16
  252. data/tasks/terminal_preview.rake +0 -30
  253. data/tasks/test.rake +0 -36
  254. data/tasks/website/index_page.rb +0 -30
  255. data/tasks/website/version.rb +0 -122
  256. data/tasks/website/version_menu.rb +0 -68
  257. data/tasks/website/versioned_documentation.rb +0 -83
  258. data/tasks/website/website.rb +0 -53
  259. data/tasks/website.rake +0 -28
@@ -1,255 +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 visual container attributes with interactive cycling.
12
- #
13
- # Widgets often float in void. Without boundaries, interfaces become a chaotic mess of text. Users need structure to parse information.
14
- #
15
- # This demo showcases the <tt>Block</tt> widget. It provides an interactive playground where you can cycle through different border types, colors, and title alignments in real-time.
16
- #
17
- # Use it to understand how to define distinct areas and create visual hierarchy in your terminal interface.
18
- #
19
- # === Example
20
- #
21
- # Run the demo from the terminal:
22
- #
23
- # ruby examples/widget_box/app.rb
24
- #
25
- # rdoc-image:/doc/images/widget_box.png
26
- class WidgetBox
27
- def initialize
28
- # Border Types (ratatui native styles)
29
- @border_types = [
30
- { name: "Plain", type: :plain },
31
- { name: "Rounded", type: :rounded },
32
- { name: "Double", type: :double },
33
- { name: "Thick", type: :thick },
34
- { name: "Quadrant Inside", type: :quadrant_inside },
35
- { name: "Quadrant Outside", type: :quadrant_outside },
36
- ]
37
- @border_type_index = 0
38
-
39
- # Custom Border Sets
40
- # NOTE: We define these ONCE in initialize for efficiency.
41
- @border_sets = [
42
- { name: "None", set: nil },
43
- {
44
- name: "Digits (Short)",
45
- set: {
46
- tl: "1",
47
- tr: "2",
48
- bl: "3",
49
- br: "4",
50
- vl: "5",
51
- vr: "6",
52
- ht: "7",
53
- hb: "8",
54
- },
55
- },
56
- {
57
- name: "Letters (Long)",
58
- set: {
59
- top_left: "A",
60
- top_right: "B",
61
- bottom_left: "C",
62
- bottom_right: "D",
63
- vertical_left: "E",
64
- vertical_right: "F",
65
- horizontal_top: "G",
66
- horizontal_bottom: "H",
67
- },
68
- },
69
- ]
70
- @border_set_index = 0
71
-
72
- @colors = [
73
- { name: "Green", color: "green" },
74
- { name: "Red", color: "red" },
75
- { name: "Blue", color: "blue" },
76
- { name: "Yellow", color: "yellow" },
77
- { name: "Magenta", color: "magenta" },
78
- ]
79
- @color_index = 0
80
-
81
- @title_alignments = [
82
- { name: "Left", alignment: :left },
83
- { name: "Center", alignment: :center },
84
- { name: "Right", alignment: :right },
85
- ]
86
- @title_alignment_index = 0
87
-
88
- @styles = [
89
- { name: "Default", style: nil },
90
- { name: "Blue on White", style: { fg: "blue", bg: "white", modifiers: [:bold] } },
91
- ]
92
- @style_index = 0
93
-
94
- @title_styles = [
95
- { name: "Default", style: nil },
96
- { name: "Yellow Bold Underlined", style: { fg: "yellow", modifiers: [:bold, :underlined] } },
97
- ]
98
- @title_style_index = 0
99
-
100
- @border_styles = [
101
- { name: "Default (no border style)", style: nil },
102
- { name: "Bold Red", style: { fg: "red", modifiers: [:bold] } },
103
- { name: "Cyan Italic", style: { fg: "cyan", modifiers: [:italic] } },
104
- { name: "Magenta Dim", style: { fg: "magenta", modifiers: [:dim] } },
105
- ]
106
- @border_style_index = 0
107
-
108
- @hotkey_style = nil # Initialized in run when tui is available
109
- end
110
-
111
- def run
112
- RatatuiRuby.run do |tui|
113
- @tui = tui
114
- @hotkey_style = tui.style(modifiers: [:bold, :underlined])
115
-
116
- loop do
117
- render
118
- break if handle_input == :quit
119
- end
120
- end
121
- end
122
-
123
- private def render
124
- # Get current values
125
- border_type_config = @border_types[@border_type_index]
126
- border_set_config = @border_sets[@border_set_index]
127
-
128
- color_config = @colors[@color_index]
129
- title_alignment_config = @title_alignments[@title_alignment_index]
130
- style_config = @styles[@style_index]
131
- title_style_config = @title_styles[@title_style_index]
132
- border_style_config = @border_styles[@border_style_index]
133
-
134
- # 1. State/View
135
- # Use border_style if explicitly set; otherwise, only apply color picker
136
- # color when no content style is set (preserves original border_color behavior)
137
- effective_border_style = if border_style_config[:style]
138
- border_style_config[:style]
139
- elsif style_config[:style].nil?
140
- @tui.style(fg: color_config[:color])
141
- end
142
-
143
- # Show overridden status if border_set is active
144
- type_display = border_type_config[:name]
145
- if border_set_config[:set]
146
- type_display += " (Overridden)"
147
- end
148
-
149
- block = @tui.block(
150
- title: "Box",
151
- title_alignment: title_alignment_config[:alignment],
152
- title_style: title_style_config[:style],
153
- borders: [:all],
154
- border_style: effective_border_style,
155
- border_type: border_type_config[:type],
156
- border_set: border_set_config[:set],
157
- style: style_config[:style]
158
- )
159
-
160
- # Main content
161
- main_panel = @tui.paragraph(
162
- text: "Arrow Keys: Change Color\n\nCurrent Color: #{color_config[:name]}",
163
- block:,
164
- fg: style_config[:style] ? nil : color_config[:color],
165
- style: style_config[:style],
166
- alignment: :center
167
- )
168
-
169
- # Bottom control panel
170
- control_panel = @tui.block(
171
- title: "Controls",
172
- borders: [:all],
173
- children: [
174
- @tui.paragraph(
175
- text: [
176
- # Line 1: Main Controls
177
- @tui.text_line(spans: [
178
- @tui.text_span(content: "↑↓←→", style: @hotkey_style),
179
- @tui.text_span(content: ": Color (#{color_config[:name]}) "),
180
- @tui.text_span(content: "q", style: @hotkey_style),
181
- @tui.text_span(content: ": Quit"),
182
- ]),
183
- # Line 2: Borders
184
- @tui.text_line(spans: [
185
- @tui.text_span(content: "space", style: @hotkey_style),
186
- @tui.text_span(content: ": Border Type (#{type_display}) "),
187
- @tui.text_span(content: "c", style: @hotkey_style),
188
- @tui.text_span(content: ": Border Set (#{border_set_config[:name]})"),
189
- ]),
190
- # Line 3: Styles
191
- @tui.text_line(spans: [
192
- @tui.text_span(content: "s", style: @hotkey_style),
193
- @tui.text_span(content: ": Style (#{style_config[:name]}) "),
194
- @tui.text_span(content: "b", style: @hotkey_style),
195
- @tui.text_span(content: ": Border Style (#{border_style_config[:name]})"),
196
- ]),
197
- # Line 4: Title
198
- @tui.text_line(spans: [
199
- @tui.text_span(content: "enter", style: @hotkey_style),
200
- @tui.text_span(content: ": Align Title (#{title_alignment_config[:name]}) "),
201
- @tui.text_span(content: "t", style: @hotkey_style),
202
- @tui.text_span(content: ": Title Style (#{title_style_config[:name]})"),
203
- ]),
204
- ]
205
- ),
206
- ]
207
- )
208
-
209
- # 2. Render with Frame API
210
- @tui.draw do |frame|
211
- main_rect, control_rect = @tui.layout_split(
212
- frame.area,
213
- direction: :vertical,
214
- constraints: [
215
- @tui.constraint_fill(1),
216
- @tui.constraint_length(6),
217
- ]
218
- )
219
- frame.render_widget(main_panel, main_rect)
220
- frame.render_widget(control_panel, control_rect)
221
- end
222
- end
223
-
224
- private def handle_input
225
- # 3. Events
226
- case @tui.poll_event
227
- in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
228
- :quit
229
- in type: :key, code: "up"
230
- @color_index = (@color_index - 1) % @colors.size
231
- in type: :key, code: "down"
232
- @color_index = (@color_index + 1) % @colors.size
233
- in type: :key, code: "left"
234
- @color_index = (@color_index - 1) % @colors.size
235
- in type: :key, code: "right"
236
- @color_index = (@color_index + 1) % @colors.size
237
- in type: :key, code: " "
238
- @border_type_index = (@border_type_index + 1) % @border_types.size
239
- in type: :key, code: "c"
240
- @border_set_index = (@border_set_index + 1) % @border_sets.size
241
- in type: :key, code: "enter"
242
- @title_alignment_index = (@title_alignment_index + 1) % @title_alignments.size
243
- in type: :key, code: "s"
244
- @style_index = (@style_index + 1) % @styles.size
245
- in type: :key, code: "t"
246
- @title_style_index = (@title_style_index + 1) % @title_styles.size
247
- in type: :key, code: "b"
248
- @border_style_index = (@border_style_index + 1) % @border_styles.size
249
- else
250
- nil
251
- end
252
- end
253
- end
254
-
255
- WidgetBox.new.run if __FILE__ == $0
@@ -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
- # Calendar Widget Example
7
-
8
- [![widget_calendar](../../doc/images/widget_calendar.png)](app.rb)
9
-
10
- Demonstrates a monthly calendar with customizable headers and event highlighting.
11
-
12
- Rendering dates in a grid involves complex calculations for leap years and weekday offsets. This widget handles that logic, letting you focus on displaying dates.
13
-
14
- ## Features Demonstrated
15
-
16
- - **Headers**: Toggling the Month name and Weekday labels.
17
- - **Surrounding Days**: displaying (or hiding/dimming) days from the previous and next months to fill the grid.
18
- - **Event Styling**: applying specific styles to individual `Time` or `Date` objects to highlight events.
19
-
20
- ## Hotkeys
21
-
22
- - **h**: Toggle Month Header (`show_month_header`)
23
- - **w**: Toggle Weekday Labels (`show_weekdays_header`)
24
- - **s**: Toggle Surrounding Days (`show_surrounding`)
25
- - **e**: Toggle Example Events (`events`)
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_calendar/app.rb
37
- ```
38
- <!-- SPDX-SnippetEnd -->
39
-
40
- ## Learning Outcomes
41
-
42
- Use this example if you need to...
43
-
44
- - Display a date picker.
45
- - Show a schedule or timeline view.
46
- - Highlight specific dates (deadlines, holidays) on a calendar grid.
47
-
48
- [Read the source code →](app.rb)
@@ -1,115 +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 monthly calendar attributes with interactive cycling.
12
- #
13
- # Dates are complex. Rendering them in a grid requires calculation of leap years, month lengths, and day-of-week offsets.
14
- # Use this widget to skip the boilerplate.
15
- #
16
- # This demo showcases the <tt>Calendar</tt> widget. It provides an interactive playground where you can toggle headers, weekday labels, and event highlights in real-time.
17
- #
18
- # Use it to understand how to render time-based data grids efficiently.
19
- #
20
- # === Example
21
- #
22
- # Run the demo from the terminal:
23
- #
24
- # ruby examples/widget_calendar/app.rb
25
- #
26
- # rdoc-image:/doc/images/widget_calendar.png
27
- class WidgetCalendar
28
- def initialize(date: nil)
29
- @date = date
30
- end
31
-
32
- def run
33
- RatatuiRuby.run do |tui|
34
- show_header = true
35
- show_weekdays = true
36
- show_surrounding = false
37
- show_events = true
38
- hotkey_style = tui.style(modifiers: [:bold])
39
-
40
- loop do
41
- now = @date || Time.now
42
- surrounding_style = show_surrounding ? tui.style(fg: "gray", modifiers: [:dim]) : nil
43
-
44
- events_map = if show_events
45
- {
46
- now => tui.style(fg: "green", modifiers: [:bold]),
47
- (now + (86400 * 2)) => tui.style(fg: "red", modifiers: [:underlined]),
48
- (now - (86400 * 5)) => tui.style(fg: "blue", bg: "white"),
49
- }
50
- else
51
- {}
52
- end
53
-
54
- calendar = tui.calendar(
55
- year: now.year,
56
- month: now.month,
57
- events: events_map,
58
- header_style: tui.style(fg: "yellow", modifiers: [:bold]),
59
- show_month_header: show_header,
60
- show_weekdays_header: show_weekdays,
61
- show_surrounding: surrounding_style,
62
- block: tui.block(borders: [:top, :left, :right])
63
- )
64
-
65
- controls = tui.paragraph(
66
- text: [
67
- tui.text_line(spans: [
68
- tui.text_span(content: " h/w/s/e", style: hotkey_style),
69
- tui.text_span(content: ": Toggle Header/Weekdays/Surrounding/Events "),
70
- tui.text_span(content: "q", style: hotkey_style),
71
- tui.text_span(content: ": Quit"),
72
- ]),
73
- tui.text_line(spans: [
74
- tui.text_span(content: " Events: ", style: hotkey_style),
75
- tui.text_span(content: "Today (Green), +2d (Red), -5d (Blue) (#{show_events ? 'On' : 'Off'})"),
76
- ]),
77
- ],
78
- block: tui.block(title: " Controls ", borders: [:all])
79
- )
80
-
81
- tui.draw do |frame|
82
- calendar_area, controls_area = tui.layout_split(
83
- frame.area,
84
- direction: :vertical,
85
- constraints: [
86
- tui.constraint_min(0),
87
- tui.constraint_length(4),
88
- ]
89
- )
90
- frame.render_widget(calendar, calendar_area)
91
- frame.render_widget(controls, controls_area)
92
- end
93
-
94
- case tui.poll_event
95
- in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
96
- break
97
- in type: :key, code: "h"
98
- show_header = !show_header
99
- in type: :key, code: "w"
100
- show_weekdays = !show_weekdays
101
- in type: :key, code: "s"
102
- show_surrounding = !show_surrounding
103
- in type: :key, code: "e"
104
- show_events = !show_events
105
- else
106
- nil
107
- end
108
-
109
- sleep 0.05
110
- end
111
- end
112
- end
113
- end
114
-
115
- WidgetCalendar.new.run if __FILE__ == $PROGRAM_NAME
@@ -1,31 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
- SPDX-License-Identifier: CC-BY-SA-4.0
4
- -->
5
- # Canvas (Circle, Line, Point, Rectangle) Example
6
-
7
- [![widget_canvas](../../doc/images/widget_canvas.png)](app.rb)
8
-
9
- <!--
10
- SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
11
- SPDX-License-Identifier: CC-BY-SA-4.0
12
- -->
13
-
14
- This example demonstrates the `Canvas` widget, which provides a high-resolution drawing surface using Braille characters.
15
-
16
- ## Key Concepts
17
-
18
- - **Shapes**: Supports `Point`, `Line`, `Rectangle`, `Circle`, and `Map`.
19
- - **Coordinates**: Uses a float-based coordinate system independent of terminal cells.
20
- - **Markers**: Can use Braille (high res) or block characters (lower res) for rendering.
21
-
22
- ## Controls
23
-
24
- | Key | Action |
25
- | --- | --- |
26
- | `q` | Quit |
27
-
28
- ## Screenshot
29
- ## Source Code
30
-
31
- - [app.rb](app.rb)
@@ -1,130 +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
- # Canvas Widget
12
- # Demonstrates how to draw geometric shapes (Points, Lines, Rects, Circles)
13
- # on a high-resolution canvas.
14
- class WidgetCanvas
15
- def initialize
16
- @x_offset = 0.0
17
- @y_offset = 0.0
18
- @time = 0.0
19
- end
20
-
21
- def run
22
- RatatuiRuby.run do |tui|
23
- @tui = tui
24
- loop do
25
- # Animate
26
- @time += 0.1
27
- @x_offset = Math.sin(@time) * 20.0
28
- @y_offset = Math.cos(@time) * 20.0
29
-
30
- render
31
- break if handle_input == :quit
32
-
33
- sleep 0.05
34
- end
35
- end
36
- end
37
-
38
- private def render
39
- @tui.draw do |frame|
40
- # Define shapes using terse aliases (circle, rectangle, point, map, label)
41
- # These are shorter forms of shape_circle, shape_rectangle, etc.
42
- shapes = []
43
-
44
- # 1. Static Grid (Lines) - using shape_line (no terse alias for line)
45
- (-100..100).step(20) do |i|
46
- shapes << @tui.shape_line(x1: i.to_f, y1: -100.0, x2: i.to_f, y2: 100.0, color: :gray)
47
- shapes << @tui.shape_line(x1: -100.0, y1: i.to_f, x2: 100.0, y2: i.to_f, color: :gray)
48
- end
49
-
50
- # 2. Moving Circle (The "Player") - using terse 'circle' alias
51
- shapes << @tui.circle(
52
- x: @x_offset,
53
- y: @y_offset,
54
- radius: 10.0,
55
- color: :green
56
- )
57
-
58
- # 3. Static Rectangle (Target) - using shape_rectangle (no 'rectangle' alias
59
- # to avoid confusion with Layout::Rect)
60
- shapes << @tui.shape_rectangle(
61
- x: 30.0,
62
- y: 30.0,
63
- width: 20.0,
64
- height: 20.0,
65
- color: :red
66
- )
67
-
68
- # 4. Points (Starfield) - using terse 'point' alias
69
- # Deterministic "random" points
70
- 10.times do |i|
71
- shapes << @tui.point(
72
- x: ((i * 37) % 200) - 100.0,
73
- y: ((i * 19) % 200) - 100.0
74
- )
75
- end
76
-
77
- # 5. Connecting line from origin to player position
78
- shapes << @tui.shape_line(x1: 0.0, y1: 0.0, x2: @x_offset, y2: @y_offset, color: :yellow)
79
-
80
- canvas = @tui.canvas(
81
- shapes:,
82
- x_bounds: [-100.0, 100.0],
83
- y_bounds: [-100.0, 100.0],
84
- marker: :braille,
85
- block: @tui.block(title: "Canvas", borders: [:all])
86
- )
87
-
88
- # Main area for canvas
89
- layout = @tui.layout_split(
90
- frame.area,
91
- direction: :vertical,
92
- constraints: [
93
- @tui.constraint_fill(1),
94
- @tui.constraint_length(2),
95
- ]
96
- )
97
-
98
- frame.render_widget(canvas, layout[0])
99
-
100
- # Query: Canvas#get_point maps canvas coordinates to normalized [0.0, 1.0] grid
101
- normalized = canvas.get_point(@x_offset, @y_offset)
102
- norm_str = normalized ? format("[%.2f, %.2f]", normalized[0], normalized[1]) : "nil"
103
-
104
- # Controls showing query method demonstration (single concise line)
105
- controls = @tui.paragraph(
106
- text: [
107
- @tui.text_line(spans: [
108
- @tui.text_span(content: "q", style: @tui.style(modifiers: [:bold, :underlined])),
109
- @tui.text_span(content: ": Quit "),
110
- @tui.text_span(content: "get_point → ", style: @tui.style(fg: :dark_gray)),
111
- @tui.text_span(content: norm_str, style: @tui.style(fg: :cyan)),
112
- ]),
113
- ],
114
- block: @tui.block(borders: [:top])
115
- )
116
- frame.render_widget(controls, layout[1])
117
- end
118
- end
119
-
120
- def handle_input
121
- case @tui.poll_event
122
- in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
123
- :quit
124
- else
125
- # Ignore other events
126
- end
127
- end
128
- end
129
-
130
- WidgetCanvas.new.run if __FILE__ == $0
@@ -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
- # Cell Widget Example
7
-
8
- [![widget_cell](../../doc/images/widget_cell.png)](app.rb)
9
-
10
- Demonstrates using `Cell` objects for granular control over individual character grid units.
11
-
12
- Sometimes you need to render specific characters with unique styles outside of standard widgets. The `Cell` primitive allows you to build custom widgets or inject styled content into Tables.
13
-
14
- ## Features Demonstrated
15
-
16
- - **Custom Widgets**: A `CheckeredBackground` widget built by rendering `Cell`s in a loop.
17
- - **Table Integration**: Mixing simple Strings and rich `Cell` objects in a Table row.
18
- - **Overlays**: Using `RatatuiRuby::Overlay` to stack widgets on top of each other.
19
- - **Modifiers**: Using `rapid_blink`, `bold`, and `dim` on individual cells.
20
-
21
- ## Hotkeys
22
-
23
- - **q** / **Ctrl+c**: 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_cell/app.rb
34
- ```
35
- <!-- SPDX-SnippetEnd -->
36
-
37
- ## Learning Outcomes
38
-
39
- Use this example if you need to...
40
-
41
- - Create a custom widget (like a game board or specialized graph).
42
- - Style specific cells in a Table (e.g., Green "OK", Red "FAIL").
43
- - Understand how to position content precisely with `Cell`.
44
-
45
- [Read the source code →](app.rb)