ratatui_ruby 0.4.0 → 0.5.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 +1 -1
- data/.builds/ruby-3.3.yml +1 -1
- data/.builds/ruby-3.4.yml +1 -1
- data/.builds/ruby-4.0.0.yml +1 -1
- data/AGENTS.md +87 -171
- data/CHANGELOG.md +38 -1
- data/README.md +8 -3
- data/REUSE.toml +20 -0
- data/doc/application_architecture.md +105 -45
- data/doc/application_testing.md +5 -3
- data/doc/contributors/design/ruby_frontend.md +9 -5
- data/doc/contributors/developing_examples.md +76 -18
- data/doc/contributors/documentation_style.md +7 -0
- data/doc/contributors/index.md +2 -0
- data/doc/event_handling.md +10 -4
- data/doc/images/app_all_events.png +0 -0
- data/doc/images/app_color_picker.png +0 -0
- data/doc/images/verify_readme_usage.png +0 -0
- data/doc/images/widget_barchart_demo.png +0 -0
- data/doc/images/widget_block_padding.png +0 -0
- data/doc/images/widget_block_titles.png +0 -0
- data/doc/images/widget_box_demo.png +0 -0
- data/doc/images/widget_calendar_demo.png +0 -0
- data/doc/images/widget_cell_demo.png +0 -0
- data/doc/images/widget_chart_demo.png +0 -0
- data/doc/images/widget_gauge_demo.png +0 -0
- data/doc/images/widget_layout_split.png +0 -0
- data/doc/images/widget_line_gauge_demo.png +0 -0
- data/doc/images/widget_list_demo.png +0 -0
- data/doc/images/widget_ratatui_logo_demo.png +0 -0
- data/doc/images/widget_ratatui_mascot_demo.png +0 -0
- data/doc/images/widget_render.png +0 -0
- data/doc/images/widget_scrollbar_demo.png +0 -0
- data/doc/images/widget_sparkline_demo.png +0 -0
- data/doc/images/widget_style_colors.png +0 -0
- data/doc/images/widget_table_flex.png +0 -0
- data/doc/images/widget_tabs_demo.png +0 -0
- data/doc/interactive_design.md +25 -30
- data/doc/quickstart.md +147 -120
- data/examples/app_all_events/README.md +81 -0
- data/examples/app_all_events/app.rb +93 -0
- data/examples/app_all_events/model/event_color_cycle.rb +41 -0
- data/examples/app_all_events/model/event_entry.rb +75 -0
- data/examples/app_all_events/model/events.rb +180 -0
- data/examples/app_all_events/model/highlight.rb +57 -0
- data/examples/app_all_events/model/timestamp.rb +54 -0
- data/examples/app_all_events/test/snapshots/after_focus_lost.txt +24 -0
- data/examples/app_all_events/test/snapshots/after_focus_regained.txt +24 -0
- data/examples/app_all_events/test/snapshots/after_horizontal_resize.txt +24 -0
- data/examples/app_all_events/test/snapshots/after_key_a.txt +24 -0
- data/examples/app_all_events/test/snapshots/after_key_ctrl_x.txt +24 -0
- data/examples/app_all_events/test/snapshots/after_mouse_click.txt +24 -0
- data/examples/app_all_events/test/snapshots/after_mouse_drag.txt +24 -0
- data/examples/app_all_events/test/snapshots/after_multiple_events.txt +24 -0
- data/examples/app_all_events/test/snapshots/after_paste.txt +24 -0
- data/examples/app_all_events/test/snapshots/after_resize.txt +24 -0
- data/examples/app_all_events/test/snapshots/after_right_click.txt +24 -0
- data/examples/app_all_events/test/snapshots/after_vertical_resize.txt +24 -0
- data/examples/app_all_events/test/snapshots/initial_state.txt +24 -0
- data/examples/app_all_events/view/app_view.rb +78 -0
- data/examples/app_all_events/view/controls_view.rb +50 -0
- data/examples/app_all_events/view/counts_view.rb +55 -0
- data/examples/app_all_events/view/live_view.rb +69 -0
- data/examples/app_all_events/view/log_view.rb +60 -0
- data/examples/app_all_events/view.rb +7 -0
- data/examples/app_all_events/view_state.rb +42 -0
- data/examples/app_color_picker/README.md +94 -0
- data/examples/app_color_picker/app.rb +112 -0
- data/examples/app_color_picker/clipboard.rb +84 -0
- data/examples/app_color_picker/color.rb +191 -0
- data/examples/app_color_picker/copy_dialog.rb +170 -0
- data/examples/app_color_picker/harmony.rb +56 -0
- data/examples/app_color_picker/input.rb +142 -0
- data/examples/app_color_picker/palette.rb +80 -0
- data/examples/app_color_picker/scene.rb +201 -0
- data/examples/{login_form → app_login_form}/app.rb +39 -42
- data/examples/{map_demo → app_map_demo}/app.rb +24 -21
- data/examples/{table_select → app_table_select}/app.rb +68 -65
- data/examples/{quickstart_dsl → verify_quickstart_dsl}/app.rb +15 -6
- data/examples/verify_quickstart_layout/app.rb +69 -0
- data/examples/{quickstart_lifecycle → verify_quickstart_lifecycle}/app.rb +19 -10
- data/examples/verify_readme_usage/app.rb +34 -0
- data/examples/widget_barchart_demo/app.rb +238 -0
- data/examples/{block_padding → widget_block_padding}/app.rb +17 -13
- data/examples/{block_titles → widget_block_titles}/app.rb +25 -17
- data/examples/{box_demo → widget_box_demo}/app.rb +99 -65
- data/examples/widget_calendar_demo/app.rb +109 -0
- data/examples/widget_cell_demo/app.rb +104 -0
- data/examples/widget_chart_demo/app.rb +213 -0
- data/examples/widget_gauge_demo/app.rb +212 -0
- data/examples/widget_layout_split/app.rb +246 -0
- data/examples/widget_line_gauge_demo/app.rb +217 -0
- data/examples/widget_list_demo/app.rb +382 -0
- data/examples/widget_list_styles/app.rb +141 -0
- data/examples/widget_popup_demo/app.rb +104 -0
- data/examples/widget_ratatui_logo_demo/app.rb +103 -0
- data/examples/widget_ratatui_mascot_demo/app.rb +93 -0
- data/examples/widget_rect/app.rb +205 -0
- data/examples/widget_render/app.rb +184 -0
- data/examples/widget_rich_text/app.rb +137 -0
- data/examples/widget_scroll_text/app.rb +108 -0
- data/examples/widget_scrollbar_demo/app.rb +153 -0
- data/examples/widget_sparkline_demo/app.rb +274 -0
- data/examples/widget_style_colors/app.rb +19 -21
- data/examples/widget_table_flex/app.rb +95 -0
- data/examples/widget_tabs_demo/app.rb +167 -0
- data/ext/ratatui_ruby/Cargo.lock +1 -1
- data/ext/ratatui_ruby/Cargo.toml +1 -1
- data/ext/ratatui_ruby/src/events.rs +121 -36
- data/ext/ratatui_ruby/src/frame.rs +115 -0
- data/ext/ratatui_ruby/src/lib.rs +79 -26
- data/ext/ratatui_ruby/src/rendering.rs +8 -4
- data/ext/ratatui_ruby/src/style.rs +138 -57
- data/ext/ratatui_ruby/src/terminal.rs +5 -9
- data/ext/ratatui_ruby/src/text.rs +13 -6
- data/ext/ratatui_ruby/src/widgets/barchart.rs +56 -54
- data/ext/ratatui_ruby/src/widgets/block.rs +7 -6
- data/ext/ratatui_ruby/src/widgets/canvas.rs +21 -3
- data/ext/ratatui_ruby/src/widgets/chart.rs +20 -10
- data/ext/ratatui_ruby/src/widgets/layout.rs +9 -4
- data/ext/ratatui_ruby/src/widgets/list.rs +32 -9
- data/ext/ratatui_ruby/src/widgets/overlay.rs +2 -1
- data/ext/ratatui_ruby/src/widgets/paragraph.rs +1 -1
- data/ext/ratatui_ruby/src/widgets/ratatui_logo.rs +19 -8
- data/ext/ratatui_ruby/src/widgets/ratatui_mascot.rs +17 -10
- data/ext/ratatui_ruby/src/widgets/scrollbar.rs +4 -2
- data/ext/ratatui_ruby/src/widgets/sparkline.rs +14 -11
- data/ext/ratatui_ruby/src/widgets/table.rs +8 -4
- data/ext/ratatui_ruby/src/widgets/tabs.rs +11 -11
- data/lib/ratatui_ruby/cell.rb +3 -3
- data/lib/ratatui_ruby/event/key.rb +1 -1
- data/lib/ratatui_ruby/event/none.rb +43 -0
- data/lib/ratatui_ruby/event.rb +56 -4
- data/lib/ratatui_ruby/frame.rb +87 -0
- data/lib/ratatui_ruby/schema/bar_chart/bar.rb +11 -11
- data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +1 -5
- data/lib/ratatui_ruby/schema/bar_chart.rb +217 -217
- data/lib/ratatui_ruby/schema/block.rb +163 -168
- data/lib/ratatui_ruby/schema/calendar.rb +66 -67
- data/lib/ratatui_ruby/schema/canvas.rb +63 -63
- data/lib/ratatui_ruby/schema/center.rb +46 -46
- data/lib/ratatui_ruby/schema/chart.rb +135 -143
- data/lib/ratatui_ruby/schema/clear.rb +42 -42
- data/lib/ratatui_ruby/schema/constraint.rb +76 -76
- data/lib/ratatui_ruby/schema/cursor.rb +25 -25
- data/lib/ratatui_ruby/schema/gauge.rb +53 -53
- data/lib/ratatui_ruby/schema/layout.rb +87 -87
- data/lib/ratatui_ruby/schema/line_gauge.rb +62 -62
- data/lib/ratatui_ruby/schema/list.rb +86 -84
- data/lib/ratatui_ruby/schema/overlay.rb +31 -31
- data/lib/ratatui_ruby/schema/paragraph.rb +80 -80
- data/lib/ratatui_ruby/schema/ratatui_logo.rb +10 -6
- data/lib/ratatui_ruby/schema/ratatui_mascot.rb +10 -5
- data/lib/ratatui_ruby/schema/rect.rb +60 -60
- data/lib/ratatui_ruby/schema/scrollbar.rb +119 -119
- data/lib/ratatui_ruby/schema/shape/label.rb +1 -1
- data/lib/ratatui_ruby/schema/sparkline.rb +111 -110
- data/lib/ratatui_ruby/schema/style.rb +46 -46
- data/lib/ratatui_ruby/schema/table.rb +112 -119
- data/lib/ratatui_ruby/schema/tabs.rb +66 -67
- data/lib/ratatui_ruby/session/autodoc.rb +417 -0
- data/lib/ratatui_ruby/session.rb +40 -23
- data/lib/ratatui_ruby/test_helper.rb +185 -19
- data/lib/ratatui_ruby/version.rb +1 -1
- data/lib/ratatui_ruby.rb +65 -39
- data/{examples/sparkline_demo → sig/examples/app_all_events}/app.rbs +3 -2
- data/sig/examples/app_all_events/model/event_entry.rbs +16 -0
- data/sig/examples/app_all_events/model/events.rbs +15 -0
- data/sig/examples/app_all_events/model/timestamp.rbs +11 -0
- data/sig/examples/app_all_events/view/app_view.rbs +8 -0
- data/sig/examples/app_all_events/view/controls_view.rbs +6 -0
- data/sig/examples/app_all_events/view/counts_view.rbs +6 -0
- data/sig/examples/app_all_events/view/live_view.rbs +6 -0
- data/sig/examples/app_all_events/view/log_view.rbs +6 -0
- data/sig/examples/app_all_events/view.rbs +8 -0
- data/sig/examples/app_all_events/view_state.rbs +15 -0
- data/{examples/list_demo → sig/examples/app_color_picker}/app.rbs +2 -2
- data/sig/examples/app_login_form/app.rbs +11 -0
- data/sig/examples/app_map_demo/app.rbs +11 -0
- data/sig/examples/app_table_select/app.rbs +11 -0
- data/sig/examples/verify_quickstart_dsl/app.rbs +11 -0
- data/sig/examples/verify_quickstart_lifecycle/app.rbs +11 -0
- data/sig/examples/verify_readme_usage/app.rbs +11 -0
- data/sig/examples/widget_block_padding/app.rbs +11 -0
- data/sig/examples/widget_block_titles/app.rbs +11 -0
- data/sig/examples/widget_box_demo/app.rbs +11 -0
- data/sig/examples/widget_calendar_demo/app.rbs +11 -0
- data/sig/examples/widget_cell_demo/app.rbs +11 -0
- data/sig/examples/widget_chart_demo/app.rbs +11 -0
- data/{examples/gauge_demo → sig/examples/widget_gauge_demo}/app.rbs +4 -0
- data/sig/examples/widget_layout_split/app.rbs +10 -0
- data/sig/examples/widget_line_gauge_demo/app.rbs +11 -0
- data/sig/examples/widget_list_demo/app.rbs +12 -0
- data/sig/examples/widget_list_styles/app.rbs +11 -0
- data/sig/examples/widget_popup_demo/app.rbs +11 -0
- data/sig/examples/widget_ratatui_logo_demo/app.rbs +11 -0
- data/sig/examples/widget_ratatui_mascot_demo/app.rbs +11 -0
- data/sig/examples/widget_rect/app.rbs +12 -0
- data/sig/examples/widget_render/app.rbs +10 -0
- data/sig/examples/widget_rich_text/app.rbs +11 -0
- data/sig/examples/widget_scroll_text/app.rbs +11 -0
- data/sig/examples/widget_scrollbar_demo/app.rbs +11 -0
- data/sig/examples/widget_sparkline_demo/app.rbs +10 -0
- data/{examples → sig/examples}/widget_style_colors/app.rbs +1 -1
- data/sig/examples/widget_table_flex/app.rbs +11 -0
- data/sig/ratatui_ruby/frame.rbs +9 -0
- data/sig/ratatui_ruby/ratatui_ruby.rbs +3 -2
- data/sig/ratatui_ruby/schema/draw.rbs +4 -0
- data/sig/ratatui_ruby/schema/layout.rbs +1 -1
- data/sig/ratatui_ruby/session.rbs +94 -0
- data/tasks/autodoc/inventory.rb +61 -0
- data/tasks/autodoc/member.rb +56 -0
- data/tasks/autodoc/name.rb +19 -0
- data/tasks/autodoc/notice.rb +26 -0
- data/tasks/autodoc/rbs.rb +38 -0
- data/tasks/autodoc/rdoc.rb +45 -0
- data/tasks/autodoc.rake +47 -0
- data/tasks/bump/history.rb +2 -2
- data/tasks/doc.rake +600 -6
- data/tasks/example_viewer.html.erb +172 -0
- data/tasks/lint.rake +8 -4
- data/tasks/resources/index.html.erb +6 -0
- data/tasks/sourcehut.rake +4 -4
- data/tasks/terminal_preview/app_screenshot.rb +1 -3
- data/tasks/terminal_preview/crash_report.rb +7 -9
- data/tasks/terminal_preview/launcher_script.rb +4 -6
- data/tasks/terminal_preview/preview_collection.rb +4 -6
- data/tasks/terminal_preview/safety_confirmation.rb +3 -5
- data/tasks/terminal_preview/saved_screenshot.rb +7 -9
- data/tasks/terminal_preview/terminal_window.rb +7 -9
- data/tasks/test.rake +1 -1
- data/tasks/website/index_page.rb +3 -3
- data/tasks/website/version.rb +10 -10
- data/tasks/website/version_menu.rb +10 -12
- data/tasks/website/versioned_documentation.rb +49 -17
- data/tasks/website/website.rb +6 -8
- data/tasks/website.rake +4 -4
- metadata +156 -125
- data/LICENSES/BSD-2-Clause.txt +0 -9
- data/doc/contributors/better_dx.md +0 -543
- data/doc/contributors/example_analysis.md +0 -82
- data/doc/images/all_events.png +0 -0
- data/doc/images/block_padding.png +0 -0
- data/doc/images/block_titles.png +0 -0
- data/doc/images/box_demo.png +0 -0
- data/doc/images/calendar_demo.png +0 -0
- data/doc/images/cell_demo.png +0 -0
- data/doc/images/chart_demo.png +0 -0
- data/doc/images/flex_layout.png +0 -0
- data/doc/images/gauge_demo.png +0 -0
- data/doc/images/line_gauge_demo.png +0 -0
- data/doc/images/list_demo.png +0 -0
- data/doc/images/readme_usage.png +0 -0
- data/doc/images/scrollbar_demo.png +0 -0
- data/doc/images/sparkline_demo.png +0 -0
- data/doc/images/table_flex.png +0 -0
- data/examples/all_events/app.rb +0 -169
- data/examples/all_events/app.rbs +0 -7
- data/examples/all_events/test_app.rb +0 -139
- data/examples/analytics/app.rb +0 -258
- data/examples/analytics/app.rbs +0 -7
- data/examples/analytics/test_app.rb +0 -132
- data/examples/block_padding/app.rbs +0 -7
- data/examples/block_padding/test_app.rb +0 -31
- data/examples/block_titles/app.rbs +0 -7
- data/examples/block_titles/test_app.rb +0 -34
- data/examples/box_demo/app.rbs +0 -7
- data/examples/box_demo/test_app.rb +0 -88
- data/examples/calendar_demo/app.rb +0 -101
- data/examples/calendar_demo/app.rbs +0 -7
- data/examples/calendar_demo/test_app.rb +0 -108
- data/examples/cell_demo/app.rb +0 -108
- data/examples/cell_demo/app.rbs +0 -7
- data/examples/cell_demo/test_app.rb +0 -36
- data/examples/chart_demo/app.rb +0 -203
- data/examples/chart_demo/app.rbs +0 -7
- data/examples/chart_demo/test_app.rb +0 -102
- data/examples/custom_widget/app.rb +0 -51
- data/examples/custom_widget/app.rbs +0 -7
- data/examples/custom_widget/test_app.rb +0 -30
- data/examples/flex_layout/app.rb +0 -156
- data/examples/flex_layout/app.rbs +0 -7
- data/examples/flex_layout/test_app.rb +0 -65
- data/examples/gauge_demo/app.rb +0 -182
- data/examples/gauge_demo/test_app.rb +0 -120
- data/examples/hit_test/app.rb +0 -175
- data/examples/hit_test/app.rbs +0 -7
- data/examples/hit_test/test_app.rb +0 -102
- data/examples/line_gauge_demo/app.rb +0 -190
- data/examples/line_gauge_demo/app.rbs +0 -7
- data/examples/line_gauge_demo/test_app.rb +0 -129
- data/examples/list_demo/app.rb +0 -253
- data/examples/list_demo/test_app.rb +0 -237
- data/examples/list_styles/app.rb +0 -140
- data/examples/list_styles/app.rbs +0 -7
- data/examples/list_styles/test_app.rb +0 -157
- data/examples/login_form/app.rbs +0 -7
- data/examples/login_form/test_app.rb +0 -51
- data/examples/map_demo/app.rbs +0 -7
- data/examples/map_demo/test_app.rb +0 -149
- data/examples/mouse_events/app.rb +0 -97
- data/examples/mouse_events/app.rbs +0 -7
- data/examples/mouse_events/test_app.rb +0 -53
- data/examples/popup_demo/app.rb +0 -103
- data/examples/popup_demo/app.rbs +0 -7
- data/examples/popup_demo/test_app.rb +0 -54
- data/examples/quickstart_dsl/app.rbs +0 -7
- data/examples/quickstart_dsl/test_app.rb +0 -29
- data/examples/quickstart_lifecycle/app.rbs +0 -7
- data/examples/quickstart_lifecycle/test_app.rb +0 -29
- data/examples/ratatui_logo_demo/app.rb +0 -79
- data/examples/ratatui_logo_demo/app.rbs +0 -7
- data/examples/ratatui_logo_demo/test_app.rb +0 -51
- data/examples/ratatui_mascot_demo/app.rb +0 -84
- data/examples/ratatui_mascot_demo/app.rbs +0 -7
- data/examples/ratatui_mascot_demo/test_app.rb +0 -47
- data/examples/readme_usage/app.rb +0 -29
- data/examples/readme_usage/app.rbs +0 -7
- data/examples/readme_usage/test_app.rb +0 -29
- data/examples/rich_text/app.rb +0 -141
- data/examples/rich_text/app.rbs +0 -7
- data/examples/rich_text/test_app.rb +0 -166
- data/examples/scroll_text/app.rb +0 -103
- data/examples/scroll_text/app.rbs +0 -7
- data/examples/scroll_text/test_app.rb +0 -110
- data/examples/scrollbar_demo/app.rb +0 -143
- data/examples/scrollbar_demo/app.rbs +0 -7
- data/examples/scrollbar_demo/test_app.rb +0 -77
- data/examples/sparkline_demo/app.rb +0 -240
- data/examples/sparkline_demo/test_app.rb +0 -107
- data/examples/table_flex/app.rb +0 -65
- data/examples/table_flex/app.rbs +0 -7
- data/examples/table_flex/test_app.rb +0 -36
- data/examples/table_select/app.rbs +0 -7
- data/examples/table_select/test_app.rb +0 -180
- data/examples/widget_style_colors/test_app.rb +0 -48
- /data/doc/images/{analytics.png → app_analytics.png} +0 -0
- /data/doc/images/{custom_widget.png → app_custom_widget.png} +0 -0
- /data/doc/images/{login_form.png → app_login_form.png} +0 -0
- /data/doc/images/{map_demo.png → app_map_demo.png} +0 -0
- /data/doc/images/{mouse_events.png → app_mouse_events.png} +0 -0
- /data/doc/images/{table_select.png → app_table_select.png} +0 -0
- /data/doc/images/{quickstart_dsl.png → verify_quickstart_dsl.png} +0 -0
- /data/doc/images/{ratatui_logo_demo.png → verify_quickstart_layout.png} +0 -0
- /data/doc/images/{quickstart_lifecycle.png → verify_quickstart_lifecycle.png} +0 -0
- /data/doc/images/{list_styles.png → widget_list_styles.png} +0 -0
- /data/doc/images/{popup_demo.png → widget_popup_demo.png} +0 -0
- /data/doc/images/{hit_test.png → widget_rect.png} +0 -0
- /data/doc/images/{rich_text.png → widget_rich_text.png} +0 -0
- /data/doc/images/{scroll_text.png → widget_scroll_text.png} +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
require "timeout"
|
|
3
4
|
require "minitest/mock"
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
require "fileutils"
|
|
6
6
|
|
|
7
7
|
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
8
8
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
@@ -45,25 +45,24 @@ module RatatuiRuby
|
|
|
45
45
|
# +timeout+:: maximum execution time in seconds (default: 2). Pass nil to disable.
|
|
46
46
|
#
|
|
47
47
|
# If a block is given, it is executed within the test terminal context.
|
|
48
|
-
def with_test_terminal(width = 80, height = 24,
|
|
48
|
+
def with_test_terminal(width = 80, height = 24, **opts)
|
|
49
49
|
RatatuiRuby.init_test_terminal(width, height)
|
|
50
50
|
# Flush any lingering events from previous tests
|
|
51
|
-
while RatatuiRuby.poll_event
|
|
51
|
+
while (event = RatatuiRuby.poll_event) && !event.none?; end
|
|
52
52
|
|
|
53
53
|
RatatuiRuby.stub :init_terminal, nil do
|
|
54
54
|
RatatuiRuby.stub :restore_terminal, nil do
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
yield
|
|
60
|
-
end
|
|
61
|
-
else
|
|
55
|
+
@_ratatui_test_terminal_active = true
|
|
56
|
+
timeout = opts.fetch(:timeout, 2)
|
|
57
|
+
if timeout
|
|
58
|
+
Timeout.timeout(timeout) do
|
|
62
59
|
yield
|
|
63
60
|
end
|
|
64
|
-
|
|
65
|
-
|
|
61
|
+
else
|
|
62
|
+
yield
|
|
66
63
|
end
|
|
64
|
+
ensure
|
|
65
|
+
@_ratatui_test_terminal_active = false
|
|
67
66
|
end
|
|
68
67
|
end
|
|
69
68
|
ensure
|
|
@@ -121,8 +120,8 @@ module RatatuiRuby
|
|
|
121
120
|
def inject_event(event)
|
|
122
121
|
unless @_ratatui_test_terminal_active
|
|
123
122
|
raise "Events must be injected inside a `with_test_terminal` block. " \
|
|
124
|
-
|
|
125
|
-
|
|
123
|
+
"Calling this method outside the block causes a race condition where the event " \
|
|
124
|
+
"is flushed before the application starts."
|
|
126
125
|
end
|
|
127
126
|
|
|
128
127
|
case event
|
|
@@ -134,7 +133,7 @@ module RatatuiRuby
|
|
|
134
133
|
button: event.button,
|
|
135
134
|
x: event.x,
|
|
136
135
|
y: event.y,
|
|
137
|
-
modifiers: event.modifiers
|
|
136
|
+
modifiers: event.modifiers,
|
|
138
137
|
})
|
|
139
138
|
when RatatuiRuby::Event::Resize
|
|
140
139
|
RatatuiRuby.inject_test_event("resize", { width: event.width, height: event.height })
|
|
@@ -149,6 +148,45 @@ module RatatuiRuby
|
|
|
149
148
|
end
|
|
150
149
|
end
|
|
151
150
|
|
|
151
|
+
##
|
|
152
|
+
# Injects a mouse event.
|
|
153
|
+
#
|
|
154
|
+
# inject_mouse(x: 10, y: 5, kind: :down, button: :left)
|
|
155
|
+
def inject_mouse(x:, y:, kind: :down, modifiers: [], button: :left)
|
|
156
|
+
event = RatatuiRuby::Event::Mouse.new(
|
|
157
|
+
kind: kind.to_s,
|
|
158
|
+
x:,
|
|
159
|
+
y:,
|
|
160
|
+
button: button.to_s,
|
|
161
|
+
modifiers:
|
|
162
|
+
)
|
|
163
|
+
inject_event(event)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
##
|
|
167
|
+
# Injects a mouse left click (down) event.
|
|
168
|
+
#
|
|
169
|
+
# inject_click(x: 10, y: 5)
|
|
170
|
+
def inject_click(x:, y:, modifiers: [])
|
|
171
|
+
inject_mouse(x:, y:, kind: :down, modifiers:, button: :left)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
##
|
|
175
|
+
# Injects a mouse right click (down) event.
|
|
176
|
+
#
|
|
177
|
+
# inject_right_click(x: 10, y: 5)
|
|
178
|
+
def inject_right_click(x:, y:, modifiers: [])
|
|
179
|
+
inject_mouse(x:, y:, kind: :down, modifiers:, button: :right)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
##
|
|
183
|
+
# Injects a mouse drag event.
|
|
184
|
+
#
|
|
185
|
+
# inject_drag(x: 10, y: 5)
|
|
186
|
+
def inject_drag(x:, y:, modifiers: [], button: :left)
|
|
187
|
+
inject_mouse(x:, y:, kind: :drag, modifiers:, button:)
|
|
188
|
+
end
|
|
189
|
+
|
|
152
190
|
##
|
|
153
191
|
# Injects multiple Key events into the queue.
|
|
154
192
|
#
|
|
@@ -176,14 +214,14 @@ module RatatuiRuby
|
|
|
176
214
|
parts = arg.to_s.split("_")
|
|
177
215
|
code = parts.pop
|
|
178
216
|
modifiers = parts
|
|
179
|
-
RatatuiRuby::Event::Key.new(code
|
|
217
|
+
RatatuiRuby::Event::Key.new(code:, modifiers:)
|
|
180
218
|
when Hash
|
|
181
219
|
RatatuiRuby::Event::Key.new(**arg)
|
|
182
220
|
when RatatuiRuby::Event::Key
|
|
183
221
|
arg
|
|
184
222
|
else
|
|
185
223
|
raise ArgumentError, "Invalid key argument: #{arg.inspect}. Expected String, Symbol, Hash, or Key event."
|
|
186
|
-
|
|
224
|
+
end
|
|
187
225
|
inject_event(event)
|
|
188
226
|
end
|
|
189
227
|
end
|
|
@@ -213,6 +251,134 @@ module RatatuiRuby
|
|
|
213
251
|
end
|
|
214
252
|
end
|
|
215
253
|
end
|
|
254
|
+
|
|
255
|
+
##
|
|
256
|
+
# Mock frame for unit testing views.
|
|
257
|
+
#
|
|
258
|
+
# Captures widgets passed to +render_widget+ for inspection.
|
|
259
|
+
# Does not render anything—purely captures the output.
|
|
260
|
+
#
|
|
261
|
+
# == Examples
|
|
262
|
+
#
|
|
263
|
+
# frame = MockFrame.new
|
|
264
|
+
# View::Log.new.call(state, tui, frame, area)
|
|
265
|
+
# widget = frame.rendered_widgets.first[:widget]
|
|
266
|
+
# assert_equal "Event Log", widget.block.title
|
|
267
|
+
MockFrame = Data.define(:rendered_widgets) do
|
|
268
|
+
def initialize(rendered_widgets: [])
|
|
269
|
+
super
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
def render_widget(widget, area)
|
|
273
|
+
rendered_widgets << { widget:, area: }
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
##
|
|
278
|
+
# Stub area for unit testing views.
|
|
279
|
+
#
|
|
280
|
+
# Provides the minimal interface views expect (+width+, +height+).
|
|
281
|
+
#
|
|
282
|
+
# == Examples
|
|
283
|
+
#
|
|
284
|
+
# area = StubRect.new(width: 60, height: 20)
|
|
285
|
+
StubRect = Data.define(:x, :y, :width, :height) do
|
|
286
|
+
def initialize(x: 0, y: 0, width: 80, height: 24)
|
|
287
|
+
super
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
##
|
|
292
|
+
# Asserts that the current screen content matches a stored snapshot.
|
|
293
|
+
#
|
|
294
|
+
# This method simplifies snapshot testing by automatically resolving the snapshot path
|
|
295
|
+
# relative to the test file calling this method. It assumes a "snapshots" directory
|
|
296
|
+
# exists in the same directory as the test file.
|
|
297
|
+
#
|
|
298
|
+
# # In test/test_login.rb
|
|
299
|
+
# assert_snapshot("login_screen")
|
|
300
|
+
# # Look for: test/snapshots/login_screen.txt
|
|
301
|
+
#
|
|
302
|
+
# # With normalization block
|
|
303
|
+
# assert_snapshot("clock") do |actual|
|
|
304
|
+
# actual.map { |l| l.gsub(/\d{2}:\d{2}/, "XX:XX") }
|
|
305
|
+
# end
|
|
306
|
+
#
|
|
307
|
+
# [name] String name of the snapshot (without extension).
|
|
308
|
+
# [msg] String optional failure message.
|
|
309
|
+
def assert_snapshot(name, msg = nil, &)
|
|
310
|
+
# Get the path of the test file calling this method
|
|
311
|
+
caller_path = caller_locations(1, 1).first.path
|
|
312
|
+
snapshot_dir = File.join(File.dirname(caller_path), "snapshots")
|
|
313
|
+
snapshot_path = File.join(snapshot_dir, "#{name}.txt")
|
|
314
|
+
|
|
315
|
+
assert_screen_matches(snapshot_path, msg, &)
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
##
|
|
319
|
+
# Asserts that the current screen content matches the expected content.
|
|
320
|
+
#
|
|
321
|
+
# Users need to verify that the entire TUI screen looks exactly as expected.
|
|
322
|
+
# Manually checking every cell or line is tedious and error-prone.
|
|
323
|
+
#
|
|
324
|
+
# This helper compares the current buffer content against an expected string (file path)
|
|
325
|
+
# or array of strings. It supports automatic snapshot creation and updating via
|
|
326
|
+
# the +UPDATE_SNAPSHOTS+ environment variable.
|
|
327
|
+
#
|
|
328
|
+
# Use it to verify complex UI states, layouts, and renderings.
|
|
329
|
+
#
|
|
330
|
+
# == Usage
|
|
331
|
+
#
|
|
332
|
+
# # Direct comparison
|
|
333
|
+
# assert_screen_matches(["Line 1", "Line 2"])
|
|
334
|
+
#
|
|
335
|
+
# # File comparison
|
|
336
|
+
# assert_screen_matches("test/snapshots/login.txt")
|
|
337
|
+
#
|
|
338
|
+
# # With normalization (e.g., masking dynamic data)
|
|
339
|
+
# assert_screen_matches("test/snapshots/dashboard.txt") do |lines|
|
|
340
|
+
# lines.map { |l| l.gsub(/User ID: \d+/, "User ID: XXX") }
|
|
341
|
+
# end
|
|
342
|
+
#
|
|
343
|
+
# [expected] String (file path) or Array<String> (content).
|
|
344
|
+
# [msg] String optional failure message.
|
|
345
|
+
def assert_screen_matches(expected, msg = nil)
|
|
346
|
+
actual_lines = buffer_content
|
|
347
|
+
|
|
348
|
+
if block_given?
|
|
349
|
+
actual_lines = yield(actual_lines)
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
if expected.is_a?(String)
|
|
353
|
+
# Snapshot file mode
|
|
354
|
+
snapshot_path = expected
|
|
355
|
+
update_snapshots = ENV["UPDATE_SNAPSHOTS"] == "1" || ENV["UPDATE_SNAPSHOTS"] == "true"
|
|
356
|
+
|
|
357
|
+
if !File.exist?(snapshot_path) || update_snapshots
|
|
358
|
+
FileUtils.mkdir_p(File.dirname(snapshot_path))
|
|
359
|
+
File.write(snapshot_path, "#{actual_lines.join("\n")}\n")
|
|
360
|
+
if update_snapshots
|
|
361
|
+
puts "Updated snapshot: #{snapshot_path}"
|
|
362
|
+
else
|
|
363
|
+
puts "Created snapshot: #{snapshot_path}"
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
expected_lines = File.readlines(snapshot_path, chomp: true)
|
|
368
|
+
else
|
|
369
|
+
# Direct comparison mode
|
|
370
|
+
expected_lines = expected
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
msg ||= "Screen content mismatch"
|
|
374
|
+
|
|
375
|
+
assert_equal expected_lines.size, actual_lines.size, "#{msg}: Line count mismatch"
|
|
376
|
+
|
|
377
|
+
expected_lines.each_with_index do |expected_line, i|
|
|
378
|
+
actual_line = actual_lines[i]
|
|
379
|
+
assert_equal expected_line, actual_line,
|
|
380
|
+
"#{msg}: Line #{i + 1} mismatch.\nExpected: #{expected_line.inspect}\nActual: #{actual_line.inspect}"
|
|
381
|
+
end
|
|
382
|
+
end
|
|
216
383
|
end
|
|
217
384
|
end
|
|
218
|
-
|
data/lib/ratatui_ruby/version.rb
CHANGED
data/lib/ratatui_ruby.rb
CHANGED
|
@@ -34,6 +34,7 @@ require_relative "ratatui_ruby/schema/text"
|
|
|
34
34
|
require_relative "ratatui_ruby/schema/draw"
|
|
35
35
|
require_relative "ratatui_ruby/event"
|
|
36
36
|
require_relative "ratatui_ruby/cell"
|
|
37
|
+
require_relative "ratatui_ruby/frame"
|
|
37
38
|
|
|
38
39
|
begin
|
|
39
40
|
require "ratatui_ruby/ratatui_ruby"
|
|
@@ -71,6 +72,23 @@ module RatatuiRuby
|
|
|
71
72
|
attr_accessor :experimental_warnings
|
|
72
73
|
end
|
|
73
74
|
|
|
75
|
+
##
|
|
76
|
+
# :singleton-method: restore_terminal
|
|
77
|
+
# Restores the terminal to its original state.
|
|
78
|
+
# Leaves alternate screen and disables raw mode.
|
|
79
|
+
#
|
|
80
|
+
# (Native method implemented in Rust)
|
|
81
|
+
|
|
82
|
+
##
|
|
83
|
+
# :singleton-method: inject_test_event
|
|
84
|
+
# Injects a mock event into the event queue for testing purposes.
|
|
85
|
+
# [event_type] "key" or "mouse"
|
|
86
|
+
# [data] a Hash containing event data
|
|
87
|
+
#
|
|
88
|
+
# inject_test_event("key", { code: "a" })
|
|
89
|
+
#
|
|
90
|
+
# (Native method implemented in Rust)
|
|
91
|
+
|
|
74
92
|
##
|
|
75
93
|
# Warns about usage of an experimental feature unless warnings are suppressed.
|
|
76
94
|
#
|
|
@@ -91,40 +109,67 @@ module RatatuiRuby
|
|
|
91
109
|
private_class_method :_init_terminal
|
|
92
110
|
|
|
93
111
|
##
|
|
94
|
-
#
|
|
95
|
-
# :call-seq: restore_terminal() -> nil
|
|
112
|
+
# Draws the given UI node tree to the terminal.
|
|
96
113
|
#
|
|
97
|
-
#
|
|
98
|
-
#
|
|
114
|
+
# TUI applications need to render widgets to the screen. Rendering could
|
|
115
|
+
# happen all at once with a pre-built tree, or incrementally with direct
|
|
116
|
+
# frame access.
|
|
99
117
|
#
|
|
100
|
-
#
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
# :method: draw
|
|
104
|
-
# :call-seq: draw(node) -> nil
|
|
118
|
+
# This method handles both. Pass a tree for declarative rendering, or
|
|
119
|
+
# pass a block to manipulate the frame directly. The block receives a
|
|
120
|
+
# {Frame} object for imperative drawing.
|
|
105
121
|
#
|
|
106
|
-
#
|
|
107
|
-
#
|
|
122
|
+
# [tree] A widget tree (Paragraph, Layout, etc.) to render. Optional if
|
|
123
|
+
# a block is given.
|
|
108
124
|
#
|
|
109
|
-
#
|
|
125
|
+
# === Examples
|
|
126
|
+
#
|
|
127
|
+
# Legacy declarative style (tree-based):
|
|
128
|
+
#
|
|
129
|
+
# RatatuiRuby.draw(Paragraph.new(text: "Hello"))
|
|
130
|
+
#
|
|
131
|
+
# New imperative style (block-based):
|
|
132
|
+
#
|
|
133
|
+
# RatatuiRuby.draw do |frame|
|
|
134
|
+
# frame.render_widget(Paragraph.new(text: "Hello"), frame.area)
|
|
135
|
+
# end
|
|
136
|
+
#
|
|
137
|
+
def self.draw(tree = nil, &block)
|
|
138
|
+
if tree && block
|
|
139
|
+
raise ArgumentError, "Cannot provide both a tree and a block to draw"
|
|
140
|
+
end
|
|
141
|
+
unless tree || block
|
|
142
|
+
raise ArgumentError, "Must provide either a tree or a block to draw"
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
if tree
|
|
146
|
+
_draw(tree)
|
|
147
|
+
else
|
|
148
|
+
_draw(&block)
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# (Native method _draw implemented in Rust)
|
|
153
|
+
private_class_method :_draw
|
|
110
154
|
|
|
111
155
|
##
|
|
112
|
-
# :method: poll_event
|
|
113
|
-
# :call-seq: poll_event() -> Event, nil
|
|
114
|
-
#
|
|
115
156
|
# Checks for user input.
|
|
116
157
|
#
|
|
117
158
|
# Returns a discrete event (Key, Mouse, Resize) if one is available in the queue.
|
|
118
|
-
# Returns
|
|
159
|
+
# Returns RatatuiRuby::Event::None if the queue is empty (non-blocking).
|
|
119
160
|
#
|
|
120
161
|
# === Example
|
|
121
162
|
#
|
|
122
163
|
# event = RatatuiRuby.poll_event
|
|
123
|
-
#
|
|
164
|
+
# if event.none?
|
|
165
|
+
# puts "No input available"
|
|
166
|
+
# elsif event.key?
|
|
167
|
+
# puts "Key pressed"
|
|
168
|
+
# end
|
|
124
169
|
#
|
|
125
170
|
def self.poll_event
|
|
126
171
|
raw = _poll_event
|
|
127
|
-
return
|
|
172
|
+
return Event::None.new if raw.nil?
|
|
128
173
|
|
|
129
174
|
case raw[:type]
|
|
130
175
|
when :key
|
|
@@ -155,21 +200,6 @@ module RatatuiRuby
|
|
|
155
200
|
private_class_method :_poll_event
|
|
156
201
|
|
|
157
202
|
##
|
|
158
|
-
# :method: inject_test_event
|
|
159
|
-
# :call-seq: inject_test_event(event_type, data) -> nil
|
|
160
|
-
#
|
|
161
|
-
# Injects a mock event into the event queue for testing purposes.
|
|
162
|
-
# [event_type] "key" or "mouse"
|
|
163
|
-
# [data] a Hash containing event data
|
|
164
|
-
#
|
|
165
|
-
# inject_test_event("key", { code: "a" })
|
|
166
|
-
#
|
|
167
|
-
# (Native method implemented in Rust)
|
|
168
|
-
|
|
169
|
-
##
|
|
170
|
-
# :method: run
|
|
171
|
-
# :call-seq: run { |session| ... } -> Object
|
|
172
|
-
#
|
|
173
203
|
# Starts the TUI application lifecycle.
|
|
174
204
|
#
|
|
175
205
|
# Managing generic setup/teardown (raw mode, alternate screen) manualy is error-prone. If your app crashes, the terminal might be left in a broken state.
|
|
@@ -184,16 +214,13 @@ module RatatuiRuby
|
|
|
184
214
|
# end
|
|
185
215
|
def self.run(focus_events: true, bracketed_paste: true)
|
|
186
216
|
require_relative "ratatui_ruby/session"
|
|
187
|
-
init_terminal(focus_events
|
|
217
|
+
init_terminal(focus_events:, bracketed_paste:)
|
|
188
218
|
yield Session.new
|
|
189
219
|
ensure
|
|
190
220
|
restore_terminal
|
|
191
221
|
end
|
|
192
222
|
|
|
193
223
|
##
|
|
194
|
-
# :method: get_cell_at
|
|
195
|
-
# :call-seq: get_cell_at(x, y) -> Cell
|
|
196
|
-
#
|
|
197
224
|
# Inspects the terminal buffer at specific coordinates.
|
|
198
225
|
#
|
|
199
226
|
# When writing tests, you need to verify that your widget drew the correct characters and styles.
|
|
@@ -224,6 +251,5 @@ module RatatuiRuby
|
|
|
224
251
|
private_class_method :_get_cell_at
|
|
225
252
|
|
|
226
253
|
# Hide native Layout._split helper
|
|
227
|
-
Layout.singleton_class.
|
|
228
|
-
|
|
254
|
+
Layout.singleton_class.__send__(:private, :_split)
|
|
229
255
|
end
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
2
|
+
#
|
|
2
3
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
3
4
|
|
|
4
|
-
class
|
|
5
|
+
class AppAllEvents
|
|
5
6
|
# @public
|
|
6
|
-
def self.new: () ->
|
|
7
|
+
def self.new: () -> AppAllEvents
|
|
7
8
|
|
|
8
9
|
# @public
|
|
9
10
|
def run: () -> void
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
2
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
class EventEntry < Data
|
|
5
|
+
attr_reader type: Symbol
|
|
6
|
+
attr_reader sub_key: Symbol | String | nil
|
|
7
|
+
attr_reader color: Symbol
|
|
8
|
+
attr_reader timestamp: Timestamp
|
|
9
|
+
attr_reader data: Hash[Symbol, untyped]
|
|
10
|
+
|
|
11
|
+
def self.from_event(type: Symbol, sub_key: Symbol | String | nil, color: Symbol, timestamp: Timestamp, data: Hash[Symbol, untyped]) -> instance
|
|
12
|
+
def matches_type?: (Symbol check_type) -> bool
|
|
13
|
+
def matches_sub_type?: (Symbol check_type, Symbol | String check_sub_key) -> bool
|
|
14
|
+
def matches_kind?: (String kind) -> bool
|
|
15
|
+
def self.new: (?type: Symbol, ?sub_key: Symbol | String | nil, ?color: Symbol, ?timestamp: Timestamp, ?data: Hash[Symbol, untyped]) -> instance
|
|
16
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
2
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
class Events
|
|
5
|
+
def initialize: () -> void
|
|
6
|
+
def record: (Symbol type, ?time: Time, ?description: String, ?sub_key: Symbol | String | nil, ?data: Hash[Symbol, untyped], ?live_type: Symbol) -> void
|
|
7
|
+
def live_event: (Symbol type) -> { time: Time, description: String } | nil
|
|
8
|
+
def live_events: () -> Hash[Symbol, { time: Time, description: String }]
|
|
9
|
+
def visible: (Integer max_entries) -> Array[EventEntry]
|
|
10
|
+
def empty?: () -> bool
|
|
11
|
+
def count: (Symbol type, ?Symbol | nil sub_type) -> Integer
|
|
12
|
+
def count_by_kind: (String kind) -> Integer
|
|
13
|
+
def lit?: (Symbol type, ?Symbol | String | nil sub_key) -> bool
|
|
14
|
+
def entries: () -> Array[EventEntry]
|
|
15
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
2
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
class Timestamp < Data
|
|
5
|
+
attr_reader milliseconds: Integer
|
|
6
|
+
|
|
7
|
+
def self.now: () -> instance
|
|
8
|
+
def self.current: () -> Integer
|
|
9
|
+
def elapsed?: (Integer duration_ms) -> bool
|
|
10
|
+
def self.new: (?milliseconds: Numeric) -> instance
|
|
11
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
2
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
module View
|
|
5
|
+
interface _View
|
|
6
|
+
def call(state: ViewState, tui: RatatuiRuby::Session, frame: RatatuiRuby::Frame, area: RatatuiRuby::Rect) -> void
|
|
7
|
+
end
|
|
8
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
2
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
class ViewState < Data
|
|
5
|
+
attr_reader events: Events
|
|
6
|
+
attr_reader focused: bool
|
|
7
|
+
attr_reader hotkey_style: RatatuiRuby::Style
|
|
8
|
+
attr_reader dimmed_style: RatatuiRuby::Style
|
|
9
|
+
attr_reader lit_style: RatatuiRuby::Style
|
|
10
|
+
attr_reader border_color: Symbol
|
|
11
|
+
attr_reader area: RatatuiRuby::Rect?
|
|
12
|
+
|
|
13
|
+
def self.build(events: Events, focused: bool, tui: RatatuiRuby::Session, _resize_sub_counter: untyped) -> instance
|
|
14
|
+
def self.new: (?events: Events, ?focused: bool, ?hotkey_style: RatatuiRuby::Style, ?dimmed_style: RatatuiRuby::Style, ?lit_style: RatatuiRuby::Style, ?border_color: Symbol, ?area: RatatuiRuby::Rect | nil) -> instance
|
|
15
|
+
end
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
4
4
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
5
5
|
|
|
6
|
-
class
|
|
6
|
+
class AppColorPicker
|
|
7
7
|
# @public
|
|
8
|
-
def self.new: () ->
|
|
8
|
+
def self.new: () -> AppColorPicker
|
|
9
9
|
|
|
10
10
|
# @public
|
|
11
11
|
def run: () -> void
|