ratatui_ruby 0.7.4 → 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 +70 -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 +35 -9
- 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 +127 -6
- 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 +13 -1
- data/examples/verify_quickstart_lifecycle/app.rb +10 -4
- 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 +171 -0
- 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 +144 -0
- 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 +116 -81
- 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 +9 -3
- 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 +15 -3
- data/doc/migration/v0_7_0.md +0 -236
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
6
|
+
#++
|
|
7
|
+
|
|
8
|
+
module RatatuiRuby
|
|
9
|
+
##
|
|
10
|
+
# Output protection for TUI sessions and batch/CLI mode.
|
|
11
|
+
#
|
|
12
|
+
# This module provides mechanisms to prevent accidental output to stdout/stderr
|
|
13
|
+
# during TUI sessions and to support headless (batch/CLI) mode for applications
|
|
14
|
+
# that can run with or without a TUI.
|
|
15
|
+
#
|
|
16
|
+
# @see guard_io
|
|
17
|
+
# @see headless!
|
|
18
|
+
module OutputGuard
|
|
19
|
+
# A null IO object that swallows all output.
|
|
20
|
+
#
|
|
21
|
+
# Used by {guard_io} to temporarily replace $stdout and $stderr.
|
|
22
|
+
# Implements method_missing to accept any IO method and discard output.
|
|
23
|
+
#
|
|
24
|
+
# Returns self for method chaining (e.g., puts.flush).
|
|
25
|
+
class NullIO
|
|
26
|
+
# Accepts any method call and returns self, discarding all output.
|
|
27
|
+
def method_missing(name, *args, &block)
|
|
28
|
+
self
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Reports that all methods are supported.
|
|
32
|
+
def respond_to_missing?(name, include_private = false)
|
|
33
|
+
true
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
##
|
|
38
|
+
# Whether headless (batch/pipeline/CLI) mode is enabled.
|
|
39
|
+
#
|
|
40
|
+
# When headless mode is active:
|
|
41
|
+
# - {guard_io} becomes a silent no-op (output is not swallowed)
|
|
42
|
+
# - {init_terminal} and {run} raise {Error::Invariant}
|
|
43
|
+
#
|
|
44
|
+
# Use this when your app has a `--no-tui` or `--batch` flag and you want
|
|
45
|
+
# the same code to work in both TUI and non-TUI modes.
|
|
46
|
+
#
|
|
47
|
+
# @see headless!
|
|
48
|
+
def is_headless?
|
|
49
|
+
@headless_mode
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
##
|
|
53
|
+
# Enables headless (batch/CLI) mode.
|
|
54
|
+
#
|
|
55
|
+
# Call this at app startup when running in batch/CLI mode (e.g., `--no-tui`).
|
|
56
|
+
# This tells RatatuiRuby that you intentionally don't want a TUI session.
|
|
57
|
+
#
|
|
58
|
+
# When headless mode is active:
|
|
59
|
+
# - {guard_io} becomes a silent no-op (output flows normally)
|
|
60
|
+
# - {init_terminal} and {run} raise {Error::Invariant}
|
|
61
|
+
#
|
|
62
|
+
# Headless mode and TUI sessions are mutually exclusive. Calling this
|
|
63
|
+
# while a TUI session is active raises {Error::Invariant}.
|
|
64
|
+
#
|
|
65
|
+
# === Why there is no exit_headless!
|
|
66
|
+
#
|
|
67
|
+
# Headless mode is a startup-time decision for the entire app run.
|
|
68
|
+
# If you need to temporarily exit TUI mode for user interaction
|
|
69
|
+
# (like lazygit does when editing a commit message), use
|
|
70
|
+
# {restore_terminal} and {init_terminal} instead:
|
|
71
|
+
#
|
|
72
|
+
#--
|
|
73
|
+
# SPDX-SnippetBegin
|
|
74
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
75
|
+
# SPDX-License-Identifier: MIT-0
|
|
76
|
+
#++
|
|
77
|
+
# RatatuiRuby.restore_terminal
|
|
78
|
+
# puts "Press enter to continue..."
|
|
79
|
+
# gets
|
|
80
|
+
# RatatuiRuby.init_terminal
|
|
81
|
+
#
|
|
82
|
+
#--
|
|
83
|
+
# SPDX-SnippetEnd
|
|
84
|
+
#++
|
|
85
|
+
# === Example
|
|
86
|
+
#
|
|
87
|
+
#--
|
|
88
|
+
# SPDX-SnippetBegin
|
|
89
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
90
|
+
# SPDX-License-Identifier: MIT-0
|
|
91
|
+
#++
|
|
92
|
+
# if ARGV.include?("--no-tui")
|
|
93
|
+
# RatatuiRuby.headless!
|
|
94
|
+
# process_batch_work # guard_io calls are silent no-ops
|
|
95
|
+
# else
|
|
96
|
+
# RatatuiRuby.run do |tui| # This branch only runs in TUI mode
|
|
97
|
+
# # ... TUI code ...
|
|
98
|
+
# end
|
|
99
|
+
# end
|
|
100
|
+
#
|
|
101
|
+
#--
|
|
102
|
+
# SPDX-SnippetEnd
|
|
103
|
+
#++
|
|
104
|
+
# Note: Calling {run} or {init_terminal} after {headless!} raises
|
|
105
|
+
# {Error::Invariant}. The block is never executed.
|
|
106
|
+
#
|
|
107
|
+
# @raise [Error::Invariant] if a TUI session is already active
|
|
108
|
+
# @see is_headless?
|
|
109
|
+
# @see restore_terminal
|
|
110
|
+
def headless!
|
|
111
|
+
if @tui_session_active
|
|
112
|
+
raise Error::Invariant, "Cannot enable headless mode: TUI session already active"
|
|
113
|
+
end
|
|
114
|
+
@headless_mode = true
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
##
|
|
118
|
+
# Guards a block from stdout/stderr output.
|
|
119
|
+
#
|
|
120
|
+
# During a TUI session, writes to $stdout or $stderr corrupt the display.
|
|
121
|
+
# Wrap code that might produce output (e.g., chatty gems) in this block.
|
|
122
|
+
#
|
|
123
|
+
# This temporarily replaces $stdout and $stderr with a {NullIO} object
|
|
124
|
+
# that discards all output. The original streams are restored when the
|
|
125
|
+
# block exits, even if an exception occurs.
|
|
126
|
+
#
|
|
127
|
+
# === Behavior by mode
|
|
128
|
+
#
|
|
129
|
+
# - **TUI session active**: Output is swallowed (guarded)
|
|
130
|
+
# - **Headless mode**: Silent no-op (output flows normally)
|
|
131
|
+
# - **Neither**: Warns and yields (catches potential mistakes)
|
|
132
|
+
#
|
|
133
|
+
# === Example
|
|
134
|
+
#
|
|
135
|
+
#--
|
|
136
|
+
# SPDX-SnippetBegin
|
|
137
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
138
|
+
# SPDX-License-Identifier: MIT-0
|
|
139
|
+
#++
|
|
140
|
+
# RatatuiRuby.run do |tui|
|
|
141
|
+
# RatatuiRuby.guard_io do
|
|
142
|
+
# SomeChattyGem.do_something # Any puts/warn calls are swallowed
|
|
143
|
+
# end
|
|
144
|
+
# end
|
|
145
|
+
#
|
|
146
|
+
#--
|
|
147
|
+
# SPDX-SnippetEnd
|
|
148
|
+
#++
|
|
149
|
+
# @see headless!
|
|
150
|
+
def guard_io
|
|
151
|
+
# TUI active: guard the output
|
|
152
|
+
if terminal_active?
|
|
153
|
+
$stdout = NullIO.new
|
|
154
|
+
$stderr = NullIO.new
|
|
155
|
+
begin
|
|
156
|
+
return yield
|
|
157
|
+
ensure
|
|
158
|
+
$stdout = Object::STDOUT
|
|
159
|
+
$stderr = Object::STDERR
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Headless mode: silent no-op
|
|
164
|
+
return yield if is_headless?
|
|
165
|
+
|
|
166
|
+
# Neither: warn about potential mistake
|
|
167
|
+
warn "guard_io called outside TUI session. If this is intentional (batch/CLI mode), call RatatuiRuby.headless! at startup to silence this warning."
|
|
168
|
+
yield
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
@@ -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: LGPL-3.0-or-later
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
module RatatuiRuby
|
|
@@ -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: LGPL-3.0-or-later
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
module RatatuiRuby
|
|
@@ -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: LGPL-3.0-or-later
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
module RatatuiRuby
|
|
@@ -20,6 +20,11 @@ module RatatuiRuby
|
|
|
20
20
|
#
|
|
21
21
|
# Run the interactive demo from the terminal:
|
|
22
22
|
#
|
|
23
|
+
#--
|
|
24
|
+
# SPDX-SnippetBegin
|
|
25
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
26
|
+
# SPDX-License-Identifier: MIT-0
|
|
27
|
+
#++
|
|
23
28
|
# ruby examples/widget_barchart/app.rb
|
|
24
29
|
#
|
|
25
30
|
# # Grouped Bar Chart
|
|
@@ -31,6 +36,9 @@ module RatatuiRuby
|
|
|
31
36
|
# bar_width: 5,
|
|
32
37
|
# group_gap: 3
|
|
33
38
|
# )
|
|
39
|
+
#--
|
|
40
|
+
# SPDX-SnippetEnd
|
|
41
|
+
#++
|
|
34
42
|
class BarChart < Data.define(:data, :bar_width, :bar_gap, :group_gap, :max, :style, :block, :direction, :label_style, :value_style, :bar_set)
|
|
35
43
|
##
|
|
36
44
|
##
|
|
@@ -45,23 +53,55 @@ module RatatuiRuby
|
|
|
45
53
|
# [<tt>Array</tt> of tuples]
|
|
46
54
|
# Ordered list of <tt>["Label", Value]</tt> or <tt>["Label", Value, Style]</tt> pairs.
|
|
47
55
|
# [<tt>Array</tt> of <tt>BarChart::BarGroup</tt>]
|
|
56
|
+
#--
|
|
57
|
+
# SPDX-SnippetBegin
|
|
58
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
59
|
+
# SPDX-License-Identifier: MIT-0
|
|
60
|
+
#++
|
|
48
61
|
# List of <tt>BarChart::BarGroup</tt> objects for grouped charts.
|
|
49
62
|
#
|
|
63
|
+
#--
|
|
64
|
+
# SPDX-SnippetEnd
|
|
65
|
+
#++
|
|
50
66
|
# === Examples
|
|
51
67
|
#
|
|
52
68
|
# Hash (Simple):
|
|
69
|
+
#--
|
|
70
|
+
# SPDX-SnippetBegin
|
|
71
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
72
|
+
# SPDX-License-Identifier: MIT-0
|
|
73
|
+
#++
|
|
53
74
|
# { "Apples" => 10, :Oranges => 15 }
|
|
54
75
|
#
|
|
76
|
+
#--
|
|
77
|
+
# SPDX-SnippetEnd
|
|
78
|
+
#++
|
|
55
79
|
# Array of Tuples (Ordered):
|
|
80
|
+
#--
|
|
81
|
+
# SPDX-SnippetBegin
|
|
82
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
83
|
+
# SPDX-License-Identifier: MIT-0
|
|
84
|
+
#++
|
|
56
85
|
# [["Mon", 20], ["Tue", 30], ["Wed", 25]]
|
|
57
86
|
#
|
|
87
|
+
#--
|
|
88
|
+
# SPDX-SnippetEnd
|
|
89
|
+
#++
|
|
58
90
|
# BarGroup (Grouped):
|
|
91
|
+
#--
|
|
92
|
+
# SPDX-SnippetBegin
|
|
93
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
94
|
+
# SPDX-License-Identifier: MIT-0
|
|
95
|
+
#++
|
|
59
96
|
# [
|
|
60
97
|
# RatatuiRuby::BarChart::BarGroup.new(label: "Q1", bars: [
|
|
61
98
|
# RatatuiRuby::BarChart::Bar.new(value: 50, label: "Rev"),
|
|
62
99
|
# RatatuiRuby::BarChart::Bar.new(value: 30, label: "Cost")
|
|
63
100
|
# ])
|
|
64
101
|
# ]
|
|
102
|
+
#--
|
|
103
|
+
# SPDX-SnippetEnd
|
|
104
|
+
#++
|
|
65
105
|
|
|
66
106
|
##
|
|
67
107
|
# :attr_reader: bar_width
|
|
@@ -110,6 +150,11 @@ module RatatuiRuby
|
|
|
110
150
|
#
|
|
111
151
|
# === Examples
|
|
112
152
|
#
|
|
153
|
+
#--
|
|
154
|
+
# SPDX-SnippetBegin
|
|
155
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
156
|
+
# SPDX-License-Identifier: MIT-0
|
|
157
|
+
#++
|
|
113
158
|
# bar_set: {
|
|
114
159
|
# empty: " ",
|
|
115
160
|
# one_eighth: " ",
|
|
@@ -129,6 +174,9 @@ module RatatuiRuby
|
|
|
129
174
|
#
|
|
130
175
|
# # Array (9 items)
|
|
131
176
|
# bar_set: [" ", " ", "▂", "▃", "▄", "▅", "▆", "▇", "█"]
|
|
177
|
+
#--
|
|
178
|
+
# SPDX-SnippetEnd
|
|
179
|
+
#++
|
|
132
180
|
|
|
133
181
|
BAR_KEYS = %i[empty one_eighth one_quarter three_eighths half five_eighths three_quarters seven_eighths full].freeze
|
|
134
182
|
|
|
@@ -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: LGPL-3.0-or-later
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
module RatatuiRuby
|
|
@@ -21,7 +21,7 @@ module RatatuiRuby
|
|
|
21
21
|
# Run the interactive demo from the terminal:
|
|
22
22
|
#
|
|
23
23
|
# ruby examples/widget_box/app.rb
|
|
24
|
-
class Block < Data.define(:title, :titles, :title_alignment, :title_style, :borders, :
|
|
24
|
+
class Block < Data.define(:title, :titles, :title_alignment, :title_style, :borders, :border_style, :border_type, :border_set, :style, :padding, :children)
|
|
25
25
|
##
|
|
26
26
|
# :attr_reader: title
|
|
27
27
|
# The main title displayed on the top border.
|
|
@@ -68,19 +68,12 @@ module RatatuiRuby
|
|
|
68
68
|
#
|
|
69
69
|
# Block.new(borders: [:left, :right]).borders # => [:left, :right]
|
|
70
70
|
|
|
71
|
-
##
|
|
72
|
-
# :attr_reader: border_color
|
|
73
|
-
# Color of the border lines.
|
|
74
|
-
#
|
|
75
|
-
# Deprecated: Use <tt>border_style:</tt> instead for full style support.
|
|
76
|
-
|
|
77
71
|
##
|
|
78
72
|
# :attr_reader: border_style
|
|
79
73
|
# Full style (colors/modifiers) for the border lines.
|
|
80
74
|
#
|
|
81
75
|
# A Style object or Hash with <tt>:fg</tt>, <tt>:bg</tt>, and <tt>:modifiers</tt>.
|
|
82
|
-
# This allows borders to be bold, italic, colored, etc.
|
|
83
|
-
# and <tt>border_style</tt> are provided, <tt>border_style</tt> takes precedence.
|
|
76
|
+
# This allows borders to be bold, italic, colored, etc.
|
|
84
77
|
|
|
85
78
|
##
|
|
86
79
|
# :attr_reader: border_type
|
|
@@ -115,8 +108,16 @@ module RatatuiRuby
|
|
|
115
108
|
#
|
|
116
109
|
# === Example
|
|
117
110
|
#
|
|
111
|
+
#--
|
|
112
|
+
# SPDX-SnippetBegin
|
|
113
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
114
|
+
# SPDX-License-Identifier: MIT-0
|
|
115
|
+
#++
|
|
118
116
|
# Block.new(padding: 2).padding # => 2
|
|
119
117
|
# Block.new(padding: [1, 1, 0, 0]).padding # => [1, 1, 0, 0]
|
|
118
|
+
#--
|
|
119
|
+
# SPDX-SnippetEnd
|
|
120
|
+
#++
|
|
120
121
|
|
|
121
122
|
##
|
|
122
123
|
# :attr_reader: children
|
|
@@ -126,11 +127,19 @@ module RatatuiRuby
|
|
|
126
127
|
#
|
|
127
128
|
# === Example
|
|
128
129
|
#
|
|
130
|
+
#--
|
|
131
|
+
# SPDX-SnippetBegin
|
|
132
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
133
|
+
# SPDX-License-Identifier: MIT-0
|
|
134
|
+
#++
|
|
129
135
|
# Block.new(
|
|
130
136
|
# title: "Content",
|
|
131
137
|
# borders: [:all],
|
|
132
138
|
# children: [Paragraph.new(text: "Hello")]
|
|
133
139
|
# )
|
|
140
|
+
#--
|
|
141
|
+
# SPDX-SnippetEnd
|
|
142
|
+
#++
|
|
134
143
|
|
|
135
144
|
# Creates a new Block.
|
|
136
145
|
#
|
|
@@ -144,8 +153,6 @@ module RatatuiRuby
|
|
|
144
153
|
# Base style for all titles (optional).
|
|
145
154
|
# [borders]
|
|
146
155
|
# Array of borders to show: <tt>:top</tt>, <tt>:bottom</tt>, <tt>:left</tt>, <tt>:right</tt>, or <tt>:all</tt> (default).
|
|
147
|
-
# [border_color]
|
|
148
|
-
# Color string or symbol (e.g., <tt>:red</tt>). Deprecated: use <tt>border_style</tt> instead.
|
|
149
156
|
# [border_style]
|
|
150
157
|
# Style object or Hash for the border lines.
|
|
151
158
|
# [border_type]
|
|
@@ -158,7 +165,7 @@ module RatatuiRuby
|
|
|
158
165
|
# Integer (uniform) or Array[4] (left, right, top, bottom).
|
|
159
166
|
# [children]
|
|
160
167
|
# Array of widgets to render inside the block (optional).
|
|
161
|
-
def initialize(title: nil, titles: [], title_alignment: nil, title_style: nil, borders: [:all],
|
|
168
|
+
def initialize(title: nil, titles: [], title_alignment: nil, title_style: nil, borders: [:all], border_style: nil, border_type: nil, border_set: nil, style: nil, padding: 0, children: [])
|
|
162
169
|
if border_set
|
|
163
170
|
border_set = border_set.dup
|
|
164
171
|
%i[top_left top_right bottom_left bottom_right vertical_left vertical_right horizontal_top horizontal_bottom].each do |long_key|
|
|
@@ -179,7 +186,6 @@ module RatatuiRuby
|
|
|
179
186
|
title_alignment:,
|
|
180
187
|
title_style:,
|
|
181
188
|
borders:,
|
|
182
|
-
border_color:,
|
|
183
189
|
border_style:,
|
|
184
190
|
border_type:,
|
|
185
191
|
border_set:,
|
|
@@ -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: LGPL-3.0-or-later
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
module RatatuiRuby
|
|
@@ -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: LGPL-3.0-or-later
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
module RatatuiRuby
|
|
@@ -171,6 +171,11 @@ module RatatuiRuby
|
|
|
171
171
|
#
|
|
172
172
|
# === Examples
|
|
173
173
|
#
|
|
174
|
+
#--
|
|
175
|
+
# SPDX-SnippetBegin
|
|
176
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
177
|
+
# SPDX-License-Identifier: MIT-0
|
|
178
|
+
#++
|
|
174
179
|
# Canvas.new(
|
|
175
180
|
# x_bounds: [-180, 180],
|
|
176
181
|
# y_bounds: [-90, 90],
|
|
@@ -180,6 +185,9 @@ module RatatuiRuby
|
|
|
180
185
|
# Shape::Label.new(x: -122.4, y: 37.8, text: "San Francisco")
|
|
181
186
|
# ]
|
|
182
187
|
# )
|
|
188
|
+
#--
|
|
189
|
+
# SPDX-SnippetEnd
|
|
190
|
+
#++
|
|
183
191
|
class Canvas < Data.define(:shapes, :x_bounds, :y_bounds, :marker, :block, :background_color)
|
|
184
192
|
##
|
|
185
193
|
# :attr_reader: shapes
|
|
@@ -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: LGPL-3.0-or-later
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
module RatatuiRuby
|
|
@@ -17,12 +17,20 @@ module RatatuiRuby
|
|
|
17
17
|
#
|
|
18
18
|
# === Examples
|
|
19
19
|
#
|
|
20
|
+
#--
|
|
21
|
+
# SPDX-SnippetBegin
|
|
22
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
23
|
+
# SPDX-License-Identifier: MIT-0
|
|
24
|
+
#++
|
|
20
25
|
# # Center a paragraph using 50% of width and height
|
|
21
26
|
# Center.new(
|
|
22
27
|
# child: Paragraph.new(text: "Hello"),
|
|
23
28
|
# width_percent: 50,
|
|
24
29
|
# height_percent: 50
|
|
25
30
|
# )
|
|
31
|
+
#--
|
|
32
|
+
# SPDX-SnippetEnd
|
|
33
|
+
#++
|
|
26
34
|
class Center < Data.define(:child, :width_percent, :height_percent)
|
|
27
35
|
##
|
|
28
36
|
# :attr_reader: child
|
|
@@ -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: LGPL-3.0-or-later
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
module RatatuiRuby
|
|
@@ -156,30 +156,4 @@ module RatatuiRuby
|
|
|
156
156
|
super
|
|
157
157
|
end
|
|
158
158
|
end
|
|
159
|
-
|
|
160
|
-
# A complex chart widget. (Legacy/Alias for Chart)
|
|
161
|
-
#
|
|
162
|
-
# [datasets] Array of Dataset objects.
|
|
163
|
-
# [x_labels] Array of Strings for the X-axis labels.
|
|
164
|
-
# [y_labels] Array of Strings for the Y-axis labels.
|
|
165
|
-
# [y_bounds] Array of two Floats [min, max] for the Y-axis.
|
|
166
|
-
# [block] Optional block widget to wrap the chart.
|
|
167
|
-
class LineChart < Data.define(:datasets, :x_labels, :y_labels, :y_bounds, :block)
|
|
168
|
-
# Creates a new LineChart widget.
|
|
169
|
-
#
|
|
170
|
-
# [datasets] Array of Dataset objects.
|
|
171
|
-
# [x_labels] Array of Strings for the X-axis labels.
|
|
172
|
-
# [y_labels] Array of Strings for the Y-axis labels.
|
|
173
|
-
# [y_bounds] Array of two Floats [min, max] for the Y-axis.
|
|
174
|
-
# [block] Optional block widget to wrap the chart.
|
|
175
|
-
def initialize(datasets:, x_labels: [], y_labels: [], y_bounds: [0.0, 100.0], block: nil)
|
|
176
|
-
super(
|
|
177
|
-
datasets:,
|
|
178
|
-
x_labels:,
|
|
179
|
-
y_labels:,
|
|
180
|
-
y_bounds: [Float(y_bounds[0]), Float(y_bounds[1])],
|
|
181
|
-
block:
|
|
182
|
-
)
|
|
183
|
-
end
|
|
184
|
-
end
|
|
185
159
|
end
|
|
@@ -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: LGPL-3.0-or-later
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
module RatatuiRuby
|
|
@@ -17,6 +17,11 @@ module RatatuiRuby
|
|
|
17
17
|
#
|
|
18
18
|
# === Examples
|
|
19
19
|
#
|
|
20
|
+
#--
|
|
21
|
+
# SPDX-SnippetBegin
|
|
22
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
23
|
+
# SPDX-License-Identifier: MIT-0
|
|
24
|
+
#++
|
|
20
25
|
# # Opaque Popup Construction
|
|
21
26
|
# Overlay.new(
|
|
22
27
|
# layers: [
|
|
@@ -36,6 +41,9 @@ module RatatuiRuby
|
|
|
36
41
|
#
|
|
37
42
|
# # Shortcut: rendering a block directly
|
|
38
43
|
# Clear.new(block: Block.new(title: "Cleared area", borders: [:all]))
|
|
44
|
+
#--
|
|
45
|
+
# SPDX-SnippetEnd
|
|
46
|
+
#++
|
|
39
47
|
class Clear < Data.define(:block)
|
|
40
48
|
##
|
|
41
49
|
# :attr_reader: block
|
|
@@ -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: LGPL-3.0-or-later
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
module RatatuiRuby
|
|
@@ -16,10 +16,18 @@ module RatatuiRuby
|
|
|
16
16
|
#
|
|
17
17
|
# === Examples
|
|
18
18
|
#
|
|
19
|
+
#--
|
|
20
|
+
# SPDX-SnippetBegin
|
|
21
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
22
|
+
# SPDX-License-Identifier: MIT-0
|
|
23
|
+
#++
|
|
19
24
|
# Constraint.length(5) # Exactly 5 cells
|
|
20
25
|
# Constraint.percentage(50) # Half the available space
|
|
21
26
|
# Constraint.min(10) # At least 10 cells, maybe more
|
|
22
27
|
# Constraint.fill(1) # Fill remaining space (weight 1)
|
|
28
|
+
#--
|
|
29
|
+
# SPDX-SnippetEnd
|
|
30
|
+
#++
|
|
23
31
|
class Constraint < Data.define(:type, :value)
|
|
24
32
|
##
|
|
25
33
|
# :attr_reader: type
|
|
@@ -33,8 +41,16 @@ module RatatuiRuby
|
|
|
33
41
|
|
|
34
42
|
# Requests a fixed size.
|
|
35
43
|
#
|
|
44
|
+
#--
|
|
45
|
+
# SPDX-SnippetBegin
|
|
46
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
47
|
+
# SPDX-License-Identifier: MIT-0
|
|
48
|
+
#++
|
|
36
49
|
# Constraint.length(10) # 10 characters wide/high
|
|
37
50
|
#
|
|
51
|
+
#--
|
|
52
|
+
# SPDX-SnippetEnd
|
|
53
|
+
#++
|
|
38
54
|
# [v] Number of cells (Integer).
|
|
39
55
|
def self.length(v)
|
|
40
56
|
new(type: :length, value: Integer(v))
|
|
@@ -42,8 +58,16 @@ module RatatuiRuby
|
|
|
42
58
|
|
|
43
59
|
# Requests a percentage of available space.
|
|
44
60
|
#
|
|
61
|
+
#--
|
|
62
|
+
# SPDX-SnippetBegin
|
|
63
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
64
|
+
# SPDX-License-Identifier: MIT-0
|
|
65
|
+
#++
|
|
45
66
|
# Constraint.percentage(25) # 25% of the area
|
|
46
67
|
#
|
|
68
|
+
#--
|
|
69
|
+
# SPDX-SnippetEnd
|
|
70
|
+
#++
|
|
47
71
|
# [v] Percentage 0-100 (Integer).
|
|
48
72
|
def self.percentage(v)
|
|
49
73
|
new(type: :percentage, value: Integer(v))
|
|
@@ -51,8 +75,16 @@ module RatatuiRuby
|
|
|
51
75
|
|
|
52
76
|
# Enforces a minimum size.
|
|
53
77
|
#
|
|
78
|
+
#--
|
|
79
|
+
# SPDX-SnippetBegin
|
|
80
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
81
|
+
# SPDX-License-Identifier: MIT-0
|
|
82
|
+
#++
|
|
54
83
|
# Constraint.min(5) # At least 5 cells
|
|
55
84
|
#
|
|
85
|
+
#--
|
|
86
|
+
# SPDX-SnippetEnd
|
|
87
|
+
#++
|
|
56
88
|
# This section will grow if space permits, but never shrink below +v+.
|
|
57
89
|
#
|
|
58
90
|
# [v] Minimum cells (Integer).
|
|
@@ -62,8 +94,16 @@ module RatatuiRuby
|
|
|
62
94
|
|
|
63
95
|
# Enforces a maximum size.
|
|
64
96
|
#
|
|
97
|
+
#--
|
|
98
|
+
# SPDX-SnippetBegin
|
|
99
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
100
|
+
# SPDX-License-Identifier: MIT-0
|
|
101
|
+
#++
|
|
65
102
|
# Constraint.max(10) # At most 10 cells
|
|
66
103
|
#
|
|
104
|
+
#--
|
|
105
|
+
# SPDX-SnippetEnd
|
|
106
|
+
#++
|
|
67
107
|
# [v] Maximum cells (Integer).
|
|
68
108
|
def self.max(v)
|
|
69
109
|
new(type: :max, value: Integer(v))
|
|
@@ -71,9 +111,17 @@ module RatatuiRuby
|
|
|
71
111
|
|
|
72
112
|
# Fills remaining space proportionally.
|
|
73
113
|
#
|
|
114
|
+
#--
|
|
115
|
+
# SPDX-SnippetBegin
|
|
116
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
117
|
+
# SPDX-License-Identifier: MIT-0
|
|
118
|
+
#++
|
|
74
119
|
# Constraint.fill(1) # Equal share
|
|
75
120
|
# Constraint.fill(2) # Double share
|
|
76
121
|
#
|
|
122
|
+
#--
|
|
123
|
+
# SPDX-SnippetEnd
|
|
124
|
+
#++
|
|
77
125
|
# Fill constraints distribute any space left after satisfying strict rules.
|
|
78
126
|
# They behave like flex-grow. A fill(2) takes twice as much space as a fill(1).
|
|
79
127
|
#
|
|
@@ -84,8 +132,16 @@ module RatatuiRuby
|
|
|
84
132
|
|
|
85
133
|
# Requests a specific ratio of the total space.
|
|
86
134
|
#
|
|
135
|
+
#--
|
|
136
|
+
# SPDX-SnippetBegin
|
|
137
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
138
|
+
# SPDX-License-Identifier: MIT-0
|
|
139
|
+
#++
|
|
87
140
|
# Constraint.ratio(1, 3) # 1/3rd of the area
|
|
88
141
|
#
|
|
142
|
+
#--
|
|
143
|
+
# SPDX-SnippetEnd
|
|
144
|
+
#++
|
|
89
145
|
# [numerator] Top part of fraction (Integer).
|
|
90
146
|
# [denominator] Bottom part of fraction (Integer).
|
|
91
147
|
def self.ratio(numerator, denominator)
|