ratatui_ruby 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.builds/ruby-3.2.yml +2 -2
- data/.builds/ruby-3.3.yml +2 -2
- data/.builds/ruby-3.4.yml +2 -2
- data/.builds/ruby-4.0.0.yml +2 -2
- data/.pre-commit-config.yaml +1 -1
- data/AGENTS.md +3 -3
- data/CHANGELOG.md +53 -1
- data/LICENSES/LGPL-3.0-or-later.txt +304 -0
- data/LICENSES/MIT-0.txt +16 -0
- data/README.md +33 -5
- data/Rakefile +1 -1
- data/doc/concepts/application_architecture.md +44 -3
- data/doc/concepts/application_testing.md +43 -1
- data/doc/concepts/async.md +32 -2
- data/doc/concepts/custom_widgets.md +247 -0
- data/doc/concepts/event_handling.md +32 -3
- data/doc/concepts/interactive_design.md +32 -2
- data/doc/contributors/auditing/parity.md +7 -1
- data/doc/contributors/design/ruby_frontend.md +85 -1
- data/doc/contributors/design/rust_backend.md +67 -1
- data/doc/contributors/developing_examples.md +56 -2
- data/doc/contributors/documentation_style.md +20 -3
- data/doc/contributors/future_work.md +169 -0
- data/doc/contributors/index.md +1 -1
- data/doc/contributors/v1.0.0_blockers.md +15 -175
- data/doc/getting_started/quickstart.md +22 -4
- data/doc/getting_started/why.md +1 -1
- data/doc/index.md +2 -1
- data/doc/troubleshooting/debugging.md +32 -2
- data/doc/troubleshooting/terminal_limitations.md +8 -2
- data/doc/troubleshooting/tui_output.md +42 -0
- data/examples/app_all_events/README.md +14 -2
- data/examples/app_all_events/app.rb +1 -1
- data/examples/app_all_events/model/app_model.rb +1 -1
- data/examples/app_all_events/model/event_color_cycle.rb +1 -1
- data/examples/app_all_events/model/event_entry.rb +1 -1
- data/examples/app_all_events/model/msg.rb +1 -1
- data/examples/app_all_events/model/timestamp.rb +1 -1
- data/examples/app_all_events/update.rb +1 -1
- data/examples/app_all_events/view/app_view.rb +1 -1
- data/examples/app_all_events/view/controls_view.rb +1 -1
- data/examples/app_all_events/view/counts_view.rb +1 -1
- data/examples/app_all_events/view/live_view.rb +1 -1
- data/examples/app_all_events/view/log_view.rb +1 -1
- data/examples/app_all_events/view.rb +1 -1
- data/examples/app_color_picker/README.md +20 -2
- data/examples/app_color_picker/app.rb +1 -1
- data/examples/app_color_picker/clipboard.rb +1 -1
- data/examples/app_color_picker/color.rb +1 -1
- data/examples/app_color_picker/controls.rb +1 -1
- data/examples/app_color_picker/copy_dialog.rb +1 -1
- data/examples/app_color_picker/export_pane.rb +1 -1
- data/examples/app_color_picker/harmony.rb +1 -1
- data/examples/app_color_picker/input.rb +1 -1
- data/examples/app_color_picker/main_container.rb +1 -1
- data/examples/app_color_picker/palette.rb +1 -1
- data/examples/app_login_form/README.md +8 -2
- data/examples/app_login_form/app.rb +1 -1
- data/examples/app_stateful_interaction/README.md +2 -2
- data/examples/app_stateful_interaction/app.rb +71 -17
- data/examples/timeout_demo.rb +1 -1
- data/examples/verify_quickstart_dsl/README.md +6 -0
- data/examples/verify_quickstart_dsl/app.rb +3 -3
- data/examples/verify_quickstart_layout/README.md +6 -0
- data/examples/verify_quickstart_layout/app.rb +3 -3
- data/examples/verify_quickstart_lifecycle/README.md +6 -0
- data/examples/verify_quickstart_lifecycle/app.rb +3 -3
- data/examples/verify_readme_usage/README.md +6 -0
- data/examples/verify_readme_usage/app.rb +3 -3
- data/examples/widget_barchart/README.md +6 -0
- data/examples/widget_barchart/app.rb +2 -2
- data/examples/widget_block/README.md +7 -1
- data/examples/widget_block/app.rb +2 -2
- data/examples/widget_box/README.md +6 -0
- data/examples/widget_box/app.rb +9 -6
- data/examples/widget_calendar/README.md +6 -0
- data/examples/widget_calendar/app.rb +2 -2
- data/examples/widget_canvas/README.md +4 -0
- data/examples/widget_canvas/app.rb +2 -2
- data/examples/widget_cell/README.md +6 -0
- data/examples/widget_cell/app.rb +2 -3
- data/examples/widget_center/README.md +4 -0
- data/examples/widget_center/app.rb +2 -2
- data/examples/widget_chart/README.md +6 -0
- data/examples/widget_chart/app.rb +2 -2
- data/examples/widget_gauge/README.md +6 -0
- data/examples/widget_gauge/app.rb +2 -2
- data/examples/widget_layout_split/README.md +6 -0
- data/examples/widget_layout_split/app.rb +3 -3
- data/examples/widget_line_gauge/README.md +6 -0
- data/examples/widget_line_gauge/app.rb +2 -2
- data/examples/widget_list/README.md +6 -0
- data/examples/widget_list/app.rb +2 -2
- data/examples/widget_map/README.md +8 -2
- data/examples/widget_map/app.rb +2 -2
- data/examples/widget_overlay/README.md +7 -1
- data/examples/widget_overlay/app.rb +2 -2
- data/examples/widget_popup/README.md +6 -0
- data/examples/widget_popup/app.rb +2 -2
- data/examples/widget_ratatui_logo/README.md +6 -0
- data/examples/widget_ratatui_logo/app.rb +2 -3
- data/examples/widget_ratatui_mascot/README.md +6 -0
- data/examples/widget_ratatui_mascot/app.rb +2 -2
- data/examples/widget_rect/README.md +12 -0
- data/examples/widget_rect/app.rb +40 -26
- data/examples/widget_render/README.md +6 -0
- data/examples/widget_render/app.rb +2 -2
- data/examples/widget_render/app.rbs +41 -0
- data/examples/widget_rich_text/README.md +6 -0
- data/examples/widget_rich_text/app.rb +2 -2
- data/examples/widget_scroll_text/README.md +6 -0
- data/examples/widget_scroll_text/app.rb +2 -2
- data/examples/widget_scrollbar/README.md +6 -0
- data/examples/widget_scrollbar/app.rb +2 -2
- data/examples/widget_sparkline/README.md +6 -0
- data/examples/widget_sparkline/app.rb +2 -2
- data/examples/widget_style_colors/README.md +6 -0
- data/examples/widget_style_colors/app.rb +2 -2
- data/examples/widget_table/README.md +8 -2
- data/examples/widget_table/app.rb +2 -2
- data/examples/widget_tabs/README.md +6 -0
- data/examples/widget_tabs/app.rb +2 -2
- data/examples/widget_text_width/README.md +6 -0
- data/examples/widget_text_width/app.rb +4 -4
- data/ext/ratatui_ruby/Cargo.lock +1 -1
- data/ext/ratatui_ruby/Cargo.toml +1 -1
- data/ext/ratatui_ruby/extconf.rb +2 -2
- data/ext/ratatui_ruby/src/rendering.rs +1 -1
- data/ext/ratatui_ruby/src/style.rs +0 -8
- data/ext/ratatui_ruby/src/widgets/chart.rs +0 -118
- data/ext/ratatui_ruby/src/widgets/list_state.rs +36 -0
- data/lib/ratatui_ruby/buffer/cell.rb +34 -2
- data/lib/ratatui_ruby/buffer.rb +2 -2
- data/lib/ratatui_ruby/cell.rb +34 -2
- data/lib/ratatui_ruby/event/focus_gained.rb +26 -2
- data/lib/ratatui_ruby/event/focus_lost.rb +26 -2
- data/lib/ratatui_ruby/event/key/character.rb +18 -2
- data/lib/ratatui_ruby/event/key/media.rb +2 -2
- data/lib/ratatui_ruby/event/key/modifier.rb +10 -2
- data/lib/ratatui_ruby/event/key/navigation.rb +2 -2
- data/lib/ratatui_ruby/event/key/system.rb +2 -2
- data/lib/ratatui_ruby/event/key.rb +114 -2
- data/lib/ratatui_ruby/event/mouse.rb +42 -2
- data/lib/ratatui_ruby/event/none.rb +10 -2
- data/lib/ratatui_ruby/event/paste.rb +34 -2
- data/lib/ratatui_ruby/event/resize.rb +34 -2
- data/lib/ratatui_ruby/event.rb +26 -2
- data/lib/ratatui_ruby/frame.rb +74 -2
- data/lib/ratatui_ruby/layout/constraint.rb +58 -2
- data/lib/ratatui_ruby/layout/layout.rb +47 -2
- data/lib/ratatui_ruby/layout/rect.rb +403 -2
- data/lib/ratatui_ruby/layout.rb +2 -2
- data/lib/ratatui_ruby/list_state.rb +113 -2
- data/lib/ratatui_ruby/output_guard.rb +26 -3
- data/lib/ratatui_ruby/schema/bar_chart/bar.rb +2 -2
- data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +2 -2
- data/lib/ratatui_ruby/schema/bar_chart.rb +50 -2
- data/lib/ratatui_ruby/schema/block.rb +21 -15
- data/lib/ratatui_ruby/schema/calendar.rb +2 -2
- data/lib/ratatui_ruby/schema/canvas.rb +10 -2
- data/lib/ratatui_ruby/schema/center.rb +10 -2
- data/lib/ratatui_ruby/schema/chart.rb +2 -28
- data/lib/ratatui_ruby/schema/clear.rb +10 -2
- data/lib/ratatui_ruby/schema/constraint.rb +58 -2
- data/lib/ratatui_ruby/schema/cursor.rb +10 -2
- data/lib/ratatui_ruby/schema/draw.rb +10 -2
- data/lib/ratatui_ruby/schema/gauge.rb +2 -2
- data/lib/ratatui_ruby/schema/layout.rb +18 -2
- data/lib/ratatui_ruby/schema/line_gauge.rb +2 -2
- data/lib/ratatui_ruby/schema/list.rb +10 -2
- data/lib/ratatui_ruby/schema/list_item.rb +10 -2
- data/lib/ratatui_ruby/schema/overlay.rb +10 -2
- data/lib/ratatui_ruby/schema/paragraph.rb +10 -2
- data/lib/ratatui_ruby/schema/ratatui_logo.rb +2 -2
- data/lib/ratatui_ruby/schema/ratatui_mascot.rb +2 -2
- data/lib/ratatui_ruby/schema/rect.rb +58 -2
- data/lib/ratatui_ruby/schema/row.rb +10 -2
- data/lib/ratatui_ruby/schema/scrollbar.rb +2 -2
- data/lib/ratatui_ruby/schema/shape/label.rb +10 -2
- data/lib/ratatui_ruby/schema/sparkline.rb +10 -2
- data/lib/ratatui_ruby/schema/style.rb +18 -2
- data/lib/ratatui_ruby/schema/table.rb +2 -2
- data/lib/ratatui_ruby/schema/tabs.rb +2 -2
- data/lib/ratatui_ruby/schema/text.rb +34 -2
- data/lib/ratatui_ruby/scrollbar_state.rb +10 -2
- data/lib/ratatui_ruby/style/style.rb +18 -2
- data/lib/ratatui_ruby/style.rb +2 -2
- data/lib/ratatui_ruby/table_state.rb +10 -2
- data/lib/ratatui_ruby/terminal_lifecycle.rb +18 -3
- data/lib/ratatui_ruby/test_helper/event_injection.rb +34 -2
- data/lib/ratatui_ruby/test_helper/snapshot.rb +74 -9
- data/lib/ratatui_ruby/test_helper/style_assertions.rb +98 -2
- data/lib/ratatui_ruby/test_helper/terminal.rb +50 -2
- data/lib/ratatui_ruby/test_helper/test_doubles.rb +18 -2
- data/lib/ratatui_ruby/test_helper.rb +10 -2
- data/lib/ratatui_ruby/tui/buffer_factories.rb +2 -2
- data/lib/ratatui_ruby/tui/canvas_factories.rb +2 -2
- data/lib/ratatui_ruby/tui/core.rb +2 -2
- data/lib/ratatui_ruby/tui/layout_factories.rb +32 -2
- data/lib/ratatui_ruby/tui/state_factories.rb +2 -2
- data/lib/ratatui_ruby/tui/style_factories.rb +2 -2
- data/lib/ratatui_ruby/tui/text_factories.rb +2 -2
- data/lib/ratatui_ruby/tui/widget_factories.rb +2 -2
- data/lib/ratatui_ruby/tui.rb +11 -3
- data/lib/ratatui_ruby/version.rb +3 -3
- data/lib/ratatui_ruby/widgets/bar_chart/bar.rb +2 -2
- data/lib/ratatui_ruby/widgets/bar_chart/bar_group.rb +2 -2
- data/lib/ratatui_ruby/widgets/bar_chart.rb +58 -2
- data/lib/ratatui_ruby/widgets/block.rb +37 -15
- data/lib/ratatui_ruby/widgets/calendar.rb +2 -2
- data/lib/ratatui_ruby/widgets/canvas.rb +10 -2
- data/lib/ratatui_ruby/widgets/cell.rb +10 -2
- data/lib/ratatui_ruby/widgets/center.rb +10 -2
- data/lib/ratatui_ruby/widgets/chart.rb +2 -28
- data/lib/ratatui_ruby/widgets/clear.rb +10 -2
- data/lib/ratatui_ruby/widgets/cursor.rb +10 -2
- data/lib/ratatui_ruby/widgets/gauge.rb +16 -2
- data/lib/ratatui_ruby/widgets/line_gauge.rb +16 -2
- data/lib/ratatui_ruby/widgets/list.rb +41 -2
- data/lib/ratatui_ruby/widgets/list_item.rb +10 -2
- data/lib/ratatui_ruby/widgets/overlay.rb +10 -2
- data/lib/ratatui_ruby/widgets/paragraph.rb +10 -2
- data/lib/ratatui_ruby/widgets/ratatui_logo.rb +2 -2
- data/lib/ratatui_ruby/widgets/ratatui_mascot.rb +2 -2
- data/lib/ratatui_ruby/widgets/row.rb +10 -2
- data/lib/ratatui_ruby/widgets/scrollbar.rb +2 -2
- data/lib/ratatui_ruby/widgets/shape/label.rb +10 -2
- data/lib/ratatui_ruby/widgets/sparkline.rb +10 -2
- data/lib/ratatui_ruby/widgets/table.rb +62 -2
- data/lib/ratatui_ruby/widgets/tabs.rb +2 -2
- data/lib/ratatui_ruby/widgets.rb +2 -2
- data/lib/ratatui_ruby.rb +90 -2
- data/sig/examples/app_all_events/view.rbs +7 -1
- data/sig/examples/app_all_events/view_state.rbs +7 -1
- data/sig/examples/app_color_picker/app.rbs +5 -0
- data/sig/examples/app_stateful_interaction/app.rbs +7 -1
- data/sig/examples/verify_quickstart_dsl/app.rbs +7 -1
- data/sig/examples/verify_quickstart_lifecycle/app.rbs +7 -1
- data/sig/examples/verify_readme_usage/app.rbs +7 -1
- data/sig/examples/widget_block_demo/app.rbs +6 -0
- data/sig/examples/widget_box_demo/app.rbs +7 -1
- data/sig/examples/widget_calendar_demo/app.rbs +7 -1
- data/sig/examples/widget_cell_demo/app.rbs +7 -1
- data/sig/examples/widget_chart_demo/app.rbs +7 -1
- data/sig/examples/widget_gauge_demo/app.rbs +7 -1
- data/sig/examples/widget_layout_split/app.rbs +7 -1
- data/sig/examples/widget_line_gauge_demo/app.rbs +7 -1
- data/sig/examples/widget_list_demo/app.rbs +5 -0
- data/sig/examples/widget_map_demo/app.rbs +7 -1
- data/sig/examples/widget_popup_demo/app.rbs +7 -1
- data/sig/examples/widget_ratatui_logo_demo/app.rbs +7 -1
- data/sig/examples/widget_ratatui_mascot_demo/app.rbs +7 -1
- data/sig/examples/widget_rect/app.rbs +7 -1
- data/sig/examples/widget_render/app.rbs +7 -1
- data/sig/examples/widget_rich_text/app.rbs +7 -1
- data/sig/examples/widget_scroll_text/app.rbs +7 -1
- data/sig/examples/widget_scrollbar_demo/app.rbs +7 -1
- data/sig/examples/widget_sparkline_demo/app.rbs +7 -1
- data/sig/examples/widget_style_colors/app.rbs +7 -1
- data/sig/examples/widget_table_demo/app.rbs +7 -1
- data/sig/examples/widget_text_width/app.rbs +7 -1
- data/sig/ratatui_ruby/event.rbs +7 -1
- data/sig/ratatui_ruby/frame.rbs +15 -3
- data/sig/ratatui_ruby/list_state.rbs +11 -1
- data/sig/ratatui_ruby/ratatui_ruby.rbs +8 -2
- data/sig/ratatui_ruby/schema/bar_chart/bar.rbs +7 -1
- data/sig/ratatui_ruby/schema/bar_chart/bar_group.rbs +6 -0
- data/sig/ratatui_ruby/schema/bar_chart.rbs +6 -0
- data/sig/ratatui_ruby/schema/block.rbs +7 -1
- data/sig/ratatui_ruby/schema/calendar.rbs +6 -0
- data/sig/ratatui_ruby/schema/canvas.rbs +6 -0
- data/sig/ratatui_ruby/schema/center.rbs +6 -0
- data/sig/ratatui_ruby/schema/chart.rbs +6 -9
- data/sig/ratatui_ruby/schema/constraint.rbs +6 -0
- data/sig/ratatui_ruby/schema/cursor.rbs +6 -0
- data/sig/ratatui_ruby/schema/draw.rbs +6 -0
- data/sig/ratatui_ruby/schema/gauge.rbs +9 -1
- data/sig/ratatui_ruby/schema/layout.rbs +6 -0
- data/sig/ratatui_ruby/schema/line_gauge.rbs +9 -1
- data/sig/ratatui_ruby/schema/list.rbs +9 -1
- data/sig/ratatui_ruby/schema/list_item.rbs +7 -1
- data/sig/ratatui_ruby/schema/overlay.rbs +6 -0
- data/sig/ratatui_ruby/schema/paragraph.rbs +6 -0
- data/sig/ratatui_ruby/schema/ratatui_logo.rbs +6 -0
- data/sig/ratatui_ruby/schema/ratatui_mascot.rbs +5 -0
- data/sig/ratatui_ruby/schema/rect.rbs +30 -0
- data/sig/ratatui_ruby/schema/row.rbs +7 -1
- data/sig/ratatui_ruby/schema/scrollbar.rbs +6 -0
- data/sig/ratatui_ruby/schema/sparkline.rbs +6 -0
- data/sig/ratatui_ruby/schema/style.rbs +7 -1
- data/sig/ratatui_ruby/schema/table.rbs +11 -1
- data/sig/ratatui_ruby/schema/tabs.rbs +6 -0
- data/sig/ratatui_ruby/schema/text.rbs +7 -1
- data/sig/ratatui_ruby/scrollbar_state.rbs +7 -1
- data/sig/ratatui_ruby/session.rbs +7 -1
- data/sig/ratatui_ruby/table_state.rbs +7 -1
- data/sig/ratatui_ruby/test_helper/event_injection.rbs +7 -1
- data/sig/ratatui_ruby/test_helper/snapshot.rbs +7 -1
- data/sig/ratatui_ruby/test_helper/style_assertions.rbs +7 -1
- data/sig/ratatui_ruby/test_helper/terminal.rbs +7 -1
- data/sig/ratatui_ruby/test_helper/test_doubles.rbs +7 -1
- data/sig/ratatui_ruby/test_helper.rbs +7 -1
- data/sig/ratatui_ruby/tui/buffer_factories.rbs +7 -1
- data/sig/ratatui_ruby/tui/canvas_factories.rbs +7 -1
- data/sig/ratatui_ruby/tui/core.rbs +7 -1
- data/sig/ratatui_ruby/tui/layout_factories.rbs +7 -1
- data/sig/ratatui_ruby/tui/state_factories.rbs +7 -1
- data/sig/ratatui_ruby/tui/style_factories.rbs +7 -1
- data/sig/ratatui_ruby/tui/text_factories.rbs +7 -1
- data/sig/ratatui_ruby/tui/widget_factories.rbs +7 -1
- data/sig/ratatui_ruby/tui.rbs +7 -1
- data/sig/ratatui_ruby/version.rbs +6 -0
- data/tasks/autodoc/examples.rb +1 -1
- data/tasks/autodoc/member.rb +1 -1
- data/tasks/autodoc/name.rb +1 -1
- data/tasks/bump/cargo_lockfile.rb +1 -1
- data/tasks/bump/changelog.rb +1 -1
- data/tasks/bump/header.rb +1 -1
- data/tasks/bump/history.rb +1 -1
- data/tasks/bump/links.rb +1 -1
- data/tasks/bump/manifest.rb +1 -1
- data/tasks/bump/ruby_gem.rb +1 -1
- data/tasks/bump/sem_ver.rb +1 -1
- data/tasks/bump/unreleased_section.rb +1 -1
- data/tasks/license/headers_md.rb +223 -0
- data/tasks/license/headers_rb.rb +210 -0
- data/tasks/license/license_utils.rb +130 -0
- data/tasks/license/snippets_md.rb +315 -0
- data/tasks/license/snippets_rdoc.rb +150 -0
- data/tasks/license.rake +91 -0
- data/tasks/rdoc_config.rb +1 -1
- data/tasks/resources/build.yml.erb +13 -7
- data/tasks/sourcehut.rake +3 -1
- data/tasks/terminal_preview/app_screenshot.rb +1 -1
- data/tasks/terminal_preview/crash_report.rb +1 -1
- data/tasks/terminal_preview/example_app.rb +1 -1
- data/tasks/terminal_preview/launcher_script.rb +1 -1
- data/tasks/terminal_preview/preview_collection.rb +1 -1
- data/tasks/terminal_preview/preview_timing.rb +1 -1
- data/tasks/terminal_preview/safety_confirmation.rb +1 -1
- data/tasks/terminal_preview/saved_screenshot.rb +1 -1
- data/tasks/terminal_preview/system_appearance.rb +1 -1
- data/tasks/terminal_preview/terminal_window.rb +1 -1
- data/tasks/terminal_preview/window_id.rb +1 -1
- data/tasks/website/index_page.rb +1 -1
- data/tasks/website/version.rb +1 -1
- data/tasks/website/version_menu.rb +1 -1
- data/tasks/website/versioned_documentation.rb +1 -1
- data/tasks/website/website.rb +1 -1
- metadata +13 -3
- data/doc/migration/v0_7_0.md +0 -236
|
@@ -29,9 +29,15 @@ Standard block gauges take up vertical space. Sometimes you only have one line t
|
|
|
29
29
|
|
|
30
30
|
## Usage
|
|
31
31
|
|
|
32
|
+
<!-- SPDX-SnippetBegin -->
|
|
33
|
+
<!--
|
|
34
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
35
|
+
SPDX-License-Identifier: MIT-0
|
|
36
|
+
-->
|
|
32
37
|
```bash
|
|
33
38
|
ruby examples/widget_line_gauge/app.rb
|
|
34
39
|
```
|
|
40
|
+
<!-- SPDX-SnippetEnd -->
|
|
35
41
|
|
|
36
42
|
## Learning Outcomes
|
|
37
43
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: MIT-0
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
@@ -36,9 +36,15 @@ Lists are the workhorse of terminal interfaces. Managing selection state, scroll
|
|
|
36
36
|
|
|
37
37
|
## Usage
|
|
38
38
|
|
|
39
|
+
<!-- SPDX-SnippetBegin -->
|
|
40
|
+
<!--
|
|
41
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
42
|
+
SPDX-License-Identifier: MIT-0
|
|
43
|
+
-->
|
|
39
44
|
```bash
|
|
40
45
|
ruby examples/widget_list/app.rb
|
|
41
46
|
```
|
|
47
|
+
<!-- SPDX-SnippetEnd -->
|
|
42
48
|
|
|
43
49
|
## Learning Outcomes
|
|
44
50
|
|
data/examples/widget_list/app.rb
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: MIT-0
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
SPDX-FileCopyrightText:
|
|
3
|
-
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
2
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
3
|
+
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
4
4
|
-->
|
|
5
5
|
|
|
6
6
|
# Map (World Map, Canvas) Example
|
|
@@ -27,9 +27,15 @@ Standard widgets are great for text, but sometimes you need to draw. The `Canvas
|
|
|
27
27
|
|
|
28
28
|
## Usage
|
|
29
29
|
|
|
30
|
+
<!-- SPDX-SnippetBegin -->
|
|
31
|
+
<!--
|
|
32
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
33
|
+
SPDX-License-Identifier: MIT-0
|
|
34
|
+
-->
|
|
30
35
|
```bash
|
|
31
36
|
ruby examples/widget_map/app.rb
|
|
32
37
|
```
|
|
38
|
+
<!-- SPDX-SnippetEnd -->
|
|
33
39
|
|
|
34
40
|
## Learning Outcomes
|
|
35
41
|
|
data/examples/widget_map/app.rb
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: MIT-0
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
SPDX-FileCopyrightText:
|
|
2
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
3
3
|
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
4
4
|
-->
|
|
5
5
|
# Overlay Example
|
|
@@ -24,9 +24,15 @@ This example demonstrates the `Overlay` composition pattern for layering widgets
|
|
|
24
24
|
|
|
25
25
|
## Usage
|
|
26
26
|
|
|
27
|
+
<!-- SPDX-SnippetBegin -->
|
|
28
|
+
<!--
|
|
29
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
30
|
+
SPDX-License-Identifier: MIT-0
|
|
31
|
+
-->
|
|
27
32
|
```bash
|
|
28
33
|
ruby examples/widget_overlay/app.rb
|
|
29
34
|
```
|
|
35
|
+
<!-- SPDX-SnippetEnd -->
|
|
30
36
|
|
|
31
37
|
## Learning Outcomes
|
|
32
38
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: MIT-0
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
@@ -24,9 +24,15 @@ Terminal renders are additive. If you draw a new widget over an old one, the bac
|
|
|
24
24
|
|
|
25
25
|
## Usage
|
|
26
26
|
|
|
27
|
+
<!-- SPDX-SnippetBegin -->
|
|
28
|
+
<!--
|
|
29
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
30
|
+
SPDX-License-Identifier: MIT-0
|
|
31
|
+
-->
|
|
27
32
|
```bash
|
|
28
33
|
ruby examples/widget_popup/app.rb
|
|
29
34
|
```
|
|
35
|
+
<!-- SPDX-SnippetEnd -->
|
|
30
36
|
|
|
31
37
|
## Learning Outcomes
|
|
32
38
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: MIT-0
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
@@ -22,9 +22,15 @@ A polished application often needs an "About" screen or a splash screen. This wi
|
|
|
22
22
|
|
|
23
23
|
## Usage
|
|
24
24
|
|
|
25
|
+
<!-- SPDX-SnippetBegin -->
|
|
26
|
+
<!--
|
|
27
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
28
|
+
SPDX-License-Identifier: MIT-0
|
|
29
|
+
-->
|
|
25
30
|
```bash
|
|
26
31
|
ruby examples/widget_ratatui_logo/app.rb
|
|
27
32
|
```
|
|
33
|
+
<!-- SPDX-SnippetEnd -->
|
|
28
34
|
|
|
29
35
|
## Learning Outcomes
|
|
30
36
|
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
#
|
|
6
|
-
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: MIT-0
|
|
7
6
|
#++
|
|
8
7
|
|
|
9
8
|
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
@@ -23,9 +23,15 @@ Interfaces can feel clinical. A friendly mascot adds charm and brand identity to
|
|
|
23
23
|
|
|
24
24
|
## Usage
|
|
25
25
|
|
|
26
|
+
<!-- SPDX-SnippetBegin -->
|
|
27
|
+
<!--
|
|
28
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
29
|
+
SPDX-License-Identifier: MIT-0
|
|
30
|
+
-->
|
|
26
31
|
```bash
|
|
27
32
|
ruby examples/widget_ratatui_mascot/app.rb
|
|
28
33
|
```
|
|
34
|
+
<!-- SPDX-SnippetEnd -->
|
|
29
35
|
|
|
30
36
|
## Learning Outcomes
|
|
31
37
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: MIT-0
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
@@ -14,6 +14,10 @@ TUI layouts are composed of rectangles. Understanding how to manipulate `Rect` o
|
|
|
14
14
|
## Features Demonstrated
|
|
15
15
|
|
|
16
16
|
- **Rect Attributes**: Investigating x, y, width, and height.
|
|
17
|
+
- **Edge Accessors**: Using `left`, `right`, `top`, `bottom` instead of manual math.
|
|
18
|
+
- **Size Methods**: Checking `area` and `empty?` for guard clauses.
|
|
19
|
+
- **Geometry Transformations**: Computing `inner`, `offset`, `union`, and `clamp`.
|
|
20
|
+
- **Iterators**: Traversing `rows`, `columns`, and `positions`.
|
|
17
21
|
- **Cached Layout Pattern**: Computing constraints in the render loop and reusing the resulting `Rect`s in the event loop for logic.
|
|
18
22
|
- **Hit Testing**: Using `Rect#contains?(x, y)` to determine if a mouse click happened inside a specific panel.
|
|
19
23
|
|
|
@@ -26,9 +30,15 @@ TUI layouts are composed of rectangles. Understanding how to manipulate `Rect` o
|
|
|
26
30
|
|
|
27
31
|
## Usage
|
|
28
32
|
|
|
33
|
+
<!-- SPDX-SnippetBegin -->
|
|
34
|
+
<!--
|
|
35
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
36
|
+
SPDX-License-Identifier: MIT-0
|
|
37
|
+
-->
|
|
29
38
|
```bash
|
|
30
39
|
ruby examples/widget_rect/app.rb
|
|
31
40
|
```
|
|
41
|
+
<!-- SPDX-SnippetEnd -->
|
|
32
42
|
|
|
33
43
|
## Learning Outcomes
|
|
34
44
|
|
|
@@ -37,5 +47,7 @@ Use this example if you need to...
|
|
|
37
47
|
- Handle mouse clicks on specific buttons or areas.
|
|
38
48
|
- Create resizable panes (like a split pane in an IDE).
|
|
39
49
|
- Debug layout issues by inspecting Rect coordinates.
|
|
50
|
+
- Compute inner padding, bounding boxes, or clamped popups.
|
|
51
|
+
- Iterate over rows, columns, or individual positions within a region.
|
|
40
52
|
|
|
41
53
|
[Read the source code →](app.rb)
|
data/examples/widget_rect/app.rb
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: MIT-0
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
@@ -14,9 +14,11 @@ require "ratatui_ruby"
|
|
|
14
14
|
#
|
|
15
15
|
# Rect is the fundamental geometry primitive for TUI layout. This example shows:
|
|
16
16
|
# - Rect attributes: x, y, width, height
|
|
17
|
+
# - Edge accessors: left, right, top, bottom
|
|
18
|
+
# - Geometry methods: area, empty?, union, inner, offset, clamp
|
|
19
|
+
# - Iterators: rows, columns, positions
|
|
17
20
|
# - Rect#contains? for hit testing mouse clicks
|
|
18
21
|
# - Layout.split returning cached rects for reuse
|
|
19
|
-
# - The layout caching pattern: compute in draw, reuse in handle_input
|
|
20
22
|
#
|
|
21
23
|
# Controls:
|
|
22
24
|
# ←/→: Adjust sidebar width
|
|
@@ -57,7 +59,7 @@ class WidgetRect
|
|
|
57
59
|
direction: :vertical,
|
|
58
60
|
constraints: [
|
|
59
61
|
@tui.constraint_fill(1),
|
|
60
|
-
@tui.constraint_length(
|
|
62
|
+
@tui.constraint_length(5),
|
|
61
63
|
]
|
|
62
64
|
)
|
|
63
65
|
|
|
@@ -88,21 +90,41 @@ class WidgetRect
|
|
|
88
90
|
end
|
|
89
91
|
|
|
90
92
|
private def render_content(frame)
|
|
93
|
+
r = @content_rect
|
|
94
|
+
inner_r = r.inner(2)
|
|
95
|
+
offset_r = r.offset(3, 2)
|
|
96
|
+
bounds = RatatuiRuby::Layout::Rect.new(x: 0, y: 0, width: 50, height: 20)
|
|
97
|
+
clamped = r.clamp(bounds)
|
|
98
|
+
union_r = r.union(@sidebar_rect)
|
|
99
|
+
|
|
91
100
|
text_content = [
|
|
92
101
|
@tui.text_line(spans: [
|
|
93
102
|
@tui.text_span(content: "Active View: ", style: @label_style),
|
|
94
103
|
@tui.text_span(content: MENU_ITEMS[@selected_index], style: @tui.style(fg: :green)),
|
|
95
104
|
]),
|
|
96
|
-
"",
|
|
97
105
|
@tui.text_line(spans: [
|
|
98
106
|
@tui.text_span(content: "Rect Attributes ", style: @label_style),
|
|
99
107
|
@tui.text_span(content: "(from Layout.split):", style: @dim_style),
|
|
100
108
|
]),
|
|
101
|
-
"
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
"",
|
|
109
|
+
" x:#{r.x} y:#{r.y} width:#{r.width} height:#{r.height}",
|
|
110
|
+
@tui.text_line(spans: [
|
|
111
|
+
@tui.text_span(content: "Edge Accessors:", style: @label_style),
|
|
112
|
+
]),
|
|
113
|
+
" left:#{r.left} right:#{r.right} top:#{r.top} bottom:#{r.bottom}",
|
|
114
|
+
@tui.text_line(spans: [
|
|
115
|
+
@tui.text_span(content: "Size Methods:", style: @label_style),
|
|
116
|
+
]),
|
|
117
|
+
" area:#{r.area} empty?:#{r.empty?}",
|
|
118
|
+
@tui.text_line(spans: [
|
|
119
|
+
@tui.text_span(content: "Geometry Transformations:", style: @label_style),
|
|
120
|
+
]),
|
|
121
|
+
" inner(2): x:#{inner_r.x} y:#{inner_r.y} w:#{inner_r.width} h:#{inner_r.height}",
|
|
122
|
+
" offset(3,2): x:#{offset_r.x} y:#{offset_r.y} clamp: x:#{clamped.x} y:#{clamped.y}",
|
|
123
|
+
" union(sidebar): w:#{union_r.width} h:#{union_r.height}",
|
|
124
|
+
@tui.text_line(spans: [
|
|
125
|
+
@tui.text_span(content: "Iterators:", style: @label_style),
|
|
126
|
+
]),
|
|
127
|
+
" rows:#{r.height} columns:#{r.width} positions:#{r.area}",
|
|
106
128
|
@tui.text_line(spans: [
|
|
107
129
|
@tui.text_span(content: "Hit Testing ", style: @label_style),
|
|
108
130
|
@tui.text_span(content: "(Rect#contains?):", style: @dim_style),
|
|
@@ -125,27 +147,19 @@ class WidgetRect
|
|
|
125
147
|
@tui.paragraph(
|
|
126
148
|
text: [
|
|
127
149
|
@tui.text_line(spans: [
|
|
128
|
-
@tui.text_span(content: "LAYOUT", style: @label_style),
|
|
129
|
-
@tui.text_span(content: " "),
|
|
130
150
|
@tui.text_span(content: "←", style: @hotkey_style),
|
|
131
|
-
@tui.text_span(content: "
|
|
151
|
+
@tui.text_span(content: "/"),
|
|
132
152
|
@tui.text_span(content: "→", style: @hotkey_style),
|
|
133
|
-
@tui.text_span(content: ":
|
|
134
|
-
@tui.text_span(content: "
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
@tui.text_span(content: "
|
|
138
|
-
@tui.text_span(content: "
|
|
139
|
-
@tui.text_span(content: "
|
|
140
|
-
@tui.text_span(content: ": Select menu item "),
|
|
153
|
+
@tui.text_span(content: ": Sidebar width "),
|
|
154
|
+
@tui.text_span(content: "↑", style: @hotkey_style),
|
|
155
|
+
@tui.text_span(content: "/"),
|
|
156
|
+
@tui.text_span(content: "↓", style: @hotkey_style),
|
|
157
|
+
@tui.text_span(content: ": Menu selection "),
|
|
158
|
+
@tui.text_span(content: "Click", style: @hotkey_style),
|
|
159
|
+
@tui.text_span(content: ": Hit test "),
|
|
141
160
|
@tui.text_span(content: "q", style: @hotkey_style),
|
|
142
161
|
@tui.text_span(content: ": Quit"),
|
|
143
162
|
]),
|
|
144
|
-
"",
|
|
145
|
-
@tui.text_line(spans: [
|
|
146
|
-
@tui.text_span(content: "HIT TESTING", style: @label_style),
|
|
147
|
-
@tui.text_span(content: " Click any panel → Rect#contains?(x, y) determines which rect was hit."),
|
|
148
|
-
]),
|
|
149
163
|
]
|
|
150
164
|
),
|
|
151
165
|
]
|
|
@@ -25,9 +25,15 @@ Sometimes standard widgets aren't enough. You need to draw custom shapes, games,
|
|
|
25
25
|
|
|
26
26
|
## Usage
|
|
27
27
|
|
|
28
|
+
<!-- SPDX-SnippetBegin -->
|
|
29
|
+
<!--
|
|
30
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
31
|
+
SPDX-License-Identifier: MIT-0
|
|
32
|
+
-->
|
|
28
33
|
```bash
|
|
29
34
|
ruby examples/widget_render/app.rb
|
|
30
35
|
```
|
|
36
|
+
<!-- SPDX-SnippetEnd -->
|
|
31
37
|
|
|
32
38
|
## Learning Outcomes
|
|
33
39
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: MIT-0
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: MIT-0
|
|
4
|
+
|
|
5
|
+
class DiagonalWidget
|
|
6
|
+
@widget_index: Integer
|
|
7
|
+
@widgets: Array[{ name: String, widget: (DiagonalWidget | CheckerboardWidget | BorderWidget) }]
|
|
8
|
+
@tui: RatatuiRuby::TUI
|
|
9
|
+
|
|
10
|
+
def run: () -> void
|
|
11
|
+
|
|
12
|
+
private def render: () -> void
|
|
13
|
+
private def handle_input: () -> Symbol?
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
class DiagonalWidget
|
|
17
|
+
def render: (RatatuiRuby::Rect area) -> Array[RatatuiRuby::Draw::StringCmd | RatatuiRuby::Draw::CellCmd]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class CheckerboardWidget
|
|
21
|
+
@char: String
|
|
22
|
+
|
|
23
|
+
def initialize: (?String char) -> void
|
|
24
|
+
def render: (RatatuiRuby::Rect area) -> Array[RatatuiRuby::Draw::StringCmd | RatatuiRuby::Draw::CellCmd]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class BorderWidget
|
|
28
|
+
def render: (RatatuiRuby::Rect area) -> Array[RatatuiRuby::Draw::StringCmd | RatatuiRuby::Draw::CellCmd]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class WidgetRender
|
|
32
|
+
@widget_index: Integer
|
|
33
|
+
@widgets: Array[{ name: String, widget: (DiagonalWidget | CheckerboardWidget | BorderWidget) }]
|
|
34
|
+
@tui: RatatuiRuby::TUI
|
|
35
|
+
|
|
36
|
+
def initialize: () -> void
|
|
37
|
+
def run: () -> void
|
|
38
|
+
|
|
39
|
+
private def render: () -> void
|
|
40
|
+
private def handle_input: () -> Symbol?
|
|
41
|
+
end
|
|
@@ -23,9 +23,15 @@ Standard strings are monochromatic. "Rich Text" is composed of `Lines` containin
|
|
|
23
23
|
|
|
24
24
|
## Usage
|
|
25
25
|
|
|
26
|
+
<!-- SPDX-SnippetBegin -->
|
|
27
|
+
<!--
|
|
28
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
29
|
+
SPDX-License-Identifier: MIT-0
|
|
30
|
+
-->
|
|
26
31
|
```bash
|
|
27
32
|
ruby examples/widget_rich_text/app.rb
|
|
28
33
|
```
|
|
34
|
+
<!-- SPDX-SnippetEnd -->
|
|
29
35
|
|
|
30
36
|
## Learning Outcomes
|
|
31
37
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: MIT-0
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
@@ -25,9 +25,15 @@ Sometimes text exceeds the available space. The `Paragraph` widget supports a `s
|
|
|
25
25
|
|
|
26
26
|
## Usage
|
|
27
27
|
|
|
28
|
+
<!-- SPDX-SnippetBegin -->
|
|
29
|
+
<!--
|
|
30
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
31
|
+
SPDX-License-Identifier: MIT-0
|
|
32
|
+
-->
|
|
28
33
|
```bash
|
|
29
34
|
ruby examples/widget_scroll_text/app.rb
|
|
30
35
|
```
|
|
36
|
+
<!-- SPDX-SnippetEnd -->
|
|
31
37
|
|
|
32
38
|
## Learning Outcomes
|
|
33
39
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: MIT-0
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
@@ -26,9 +26,15 @@ Content overflows. Users get lost in long lists. Scrollbars provide essential sp
|
|
|
26
26
|
|
|
27
27
|
## Usage
|
|
28
28
|
|
|
29
|
+
<!-- SPDX-SnippetBegin -->
|
|
30
|
+
<!--
|
|
31
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
32
|
+
SPDX-License-Identifier: MIT-0
|
|
33
|
+
-->
|
|
29
34
|
```bash
|
|
30
35
|
ruby examples/widget_scrollbar/app.rb
|
|
31
36
|
```
|
|
37
|
+
<!-- SPDX-SnippetEnd -->
|
|
32
38
|
|
|
33
39
|
## Learning Outcomes
|
|
34
40
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: MIT-0
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
@@ -30,9 +30,15 @@ Users need context. A single number ("90% CPU") tells you status, but not the tr
|
|
|
30
30
|
|
|
31
31
|
## Usage
|
|
32
32
|
|
|
33
|
+
<!-- SPDX-SnippetBegin -->
|
|
34
|
+
<!--
|
|
35
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
36
|
+
SPDX-License-Identifier: MIT-0
|
|
37
|
+
-->
|
|
33
38
|
```bash
|
|
34
39
|
ruby examples/widget_sparkline/app.rb
|
|
35
40
|
```
|
|
41
|
+
<!-- SPDX-SnippetEnd -->
|
|
36
42
|
|
|
37
43
|
## Learning Outcomes
|
|
38
44
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: MIT-0
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
@@ -22,9 +22,15 @@ Terminals support millions of colors. This example generates a mathematically pr
|
|
|
22
22
|
|
|
23
23
|
## Usage
|
|
24
24
|
|
|
25
|
+
<!-- SPDX-SnippetBegin -->
|
|
26
|
+
<!--
|
|
27
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
28
|
+
SPDX-License-Identifier: MIT-0
|
|
29
|
+
-->
|
|
25
30
|
```bash
|
|
26
31
|
ruby examples/widget_style_colors/app.rb
|
|
27
32
|
```
|
|
33
|
+
<!-- SPDX-SnippetEnd -->
|
|
28
34
|
|
|
29
35
|
## Learning Outcomes
|
|
30
36
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: MIT-0
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
SPDX-FileCopyrightText:
|
|
3
|
-
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
2
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
3
|
+
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
4
4
|
-->
|
|
5
5
|
|
|
6
6
|
# Table (Row, Cell) Example
|
|
@@ -36,9 +36,15 @@ Data grids are complex. Users expect to navigate them with keys, select rows, an
|
|
|
36
36
|
|
|
37
37
|
## Usage
|
|
38
38
|
|
|
39
|
+
<!-- SPDX-SnippetBegin -->
|
|
40
|
+
<!--
|
|
41
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
42
|
+
SPDX-License-Identifier: MIT-0
|
|
43
|
+
-->
|
|
39
44
|
```bash
|
|
40
45
|
ruby examples/widget_table/app.rb
|
|
41
46
|
```
|
|
47
|
+
<!-- SPDX-SnippetEnd -->
|
|
42
48
|
|
|
43
49
|
## Learning Outcomes
|
|
44
50
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: MIT-0
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
@@ -29,9 +29,15 @@ Screen real estate is limited. You cannot show everything at once. Tabs segregat
|
|
|
29
29
|
|
|
30
30
|
## Usage
|
|
31
31
|
|
|
32
|
+
<!-- SPDX-SnippetBegin -->
|
|
33
|
+
<!--
|
|
34
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
35
|
+
SPDX-License-Identifier: MIT-0
|
|
36
|
+
-->
|
|
32
37
|
```bash
|
|
33
38
|
ruby examples/widget_tabs/app.rb
|
|
34
39
|
```
|
|
40
|
+
<!-- SPDX-SnippetEnd -->
|
|
35
41
|
|
|
36
42
|
## Learning Outcomes
|
|
37
43
|
|
data/examples/widget_tabs/app.rb
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: MIT-0
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
@@ -23,9 +23,15 @@ Not all characters are created equal. In a TUI, "Width" means cell count, not st
|
|
|
23
23
|
|
|
24
24
|
## Usage
|
|
25
25
|
|
|
26
|
+
<!-- SPDX-SnippetBegin -->
|
|
27
|
+
<!--
|
|
28
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
29
|
+
SPDX-License-Identifier: MIT-0
|
|
30
|
+
-->
|
|
26
31
|
```bash
|
|
27
32
|
ruby examples/widget_text_width/app.rb
|
|
28
33
|
```
|
|
34
|
+
<!-- SPDX-SnippetEnd -->
|
|
29
35
|
|
|
30
36
|
## Learning Outcomes
|
|
31
37
|
|