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,110 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
5
|
-
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
6
|
-
|
|
7
|
-
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
8
|
-
require "minitest/autorun"
|
|
9
|
-
require "ratatui_ruby/test_helper"
|
|
10
|
-
|
|
11
|
-
require_relative "app"
|
|
12
|
-
|
|
13
|
-
class TestScrollTextApp < Minitest::Test
|
|
14
|
-
include RatatuiRuby::TestHelper
|
|
15
|
-
|
|
16
|
-
def setup
|
|
17
|
-
@app = ScrollTextApp.new
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def test_demo_initialization
|
|
21
|
-
assert_instance_of ScrollTextApp, @app
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def test_initial_rendering
|
|
25
|
-
with_test_terminal do
|
|
26
|
-
# Queue quit
|
|
27
|
-
inject_key(:q)
|
|
28
|
-
|
|
29
|
-
@app.run
|
|
30
|
-
|
|
31
|
-
content = buffer_content
|
|
32
|
-
|
|
33
|
-
# Should show Line 1 somewhere in the output
|
|
34
|
-
assert content.any? { |line| line.include?("Line 1") }
|
|
35
|
-
# Should show controls
|
|
36
|
-
assert content.any? { |line| line.include?("Controls") }
|
|
37
|
-
assert content.any? { |line| line.include?("Vert Scroll (0/102)") }
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def test_scroll_down
|
|
42
|
-
with_test_terminal do
|
|
43
|
-
# Scroll down then quit
|
|
44
|
-
inject_keys(:down, :q)
|
|
45
|
-
|
|
46
|
-
@app.run
|
|
47
|
-
|
|
48
|
-
content = buffer_content
|
|
49
|
-
|
|
50
|
-
# Should show controls with updated Y position
|
|
51
|
-
assert content.any? { |line| line.include?("Vert Scroll (1/102)") }
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def test_scroll_right
|
|
56
|
-
with_test_terminal do
|
|
57
|
-
# Scroll right then quit
|
|
58
|
-
inject_keys(:right, :q)
|
|
59
|
-
|
|
60
|
-
@app.run
|
|
61
|
-
|
|
62
|
-
content = buffer_content
|
|
63
|
-
|
|
64
|
-
# Should render without error
|
|
65
|
-
assert content.any? { |line| line.include?("Controls") }
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def test_scroll_left_at_edge
|
|
70
|
-
with_test_terminal do
|
|
71
|
-
# Scroll left then quit (boundary test)
|
|
72
|
-
inject_keys(:left, :q)
|
|
73
|
-
|
|
74
|
-
@app.run
|
|
75
|
-
|
|
76
|
-
content = buffer_content
|
|
77
|
-
|
|
78
|
-
# Should still show the controls
|
|
79
|
-
assert content.any? { |line| line.include?("Vert Scroll") }
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def test_scroll_up_at_top
|
|
84
|
-
with_test_terminal do
|
|
85
|
-
# Scroll up then quit (boundary test)
|
|
86
|
-
inject_keys(:up, :q)
|
|
87
|
-
|
|
88
|
-
@app.run
|
|
89
|
-
|
|
90
|
-
content = buffer_content
|
|
91
|
-
|
|
92
|
-
# Should still show the controls
|
|
93
|
-
assert content.any? { |line| line.include?("Controls") }
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def test_multiple_scrolls
|
|
98
|
-
with_test_terminal do
|
|
99
|
-
# Scroll down and right multiple times
|
|
100
|
-
inject_keys(:down, :down, :right, :right, :right, :q)
|
|
101
|
-
|
|
102
|
-
@app.run
|
|
103
|
-
|
|
104
|
-
content = buffer_content
|
|
105
|
-
|
|
106
|
-
# Should render without error
|
|
107
|
-
assert content.any? { |line| line.include?("Scrollable Text") }
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
end
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
4
|
-
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
5
|
-
|
|
6
|
-
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
7
|
-
require "ratatui_ruby"
|
|
8
|
-
|
|
9
|
-
# Simple Scrollbar Demo
|
|
10
|
-
class ScrollbarDemoApp
|
|
11
|
-
def initialize
|
|
12
|
-
@scroll_position = 0
|
|
13
|
-
@content_length = 50
|
|
14
|
-
@lines = (1..@content_length).map { |i| "Line #{i}" }
|
|
15
|
-
@orientation_index = 0
|
|
16
|
-
@orientations = [
|
|
17
|
-
:vertical,
|
|
18
|
-
:vertical_right,
|
|
19
|
-
:vertical_left,
|
|
20
|
-
:horizontal,
|
|
21
|
-
:horizontal_bottom,
|
|
22
|
-
:horizontal_top
|
|
23
|
-
]
|
|
24
|
-
@theme_index = 0
|
|
25
|
-
@themes = [
|
|
26
|
-
{
|
|
27
|
-
name: "Standard",
|
|
28
|
-
track_symbol: nil,
|
|
29
|
-
thumb_symbol: "█",
|
|
30
|
-
track_style: nil,
|
|
31
|
-
thumb_style: nil,
|
|
32
|
-
begin_symbol: nil,
|
|
33
|
-
end_symbol: nil
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
name: "Rounded",
|
|
37
|
-
track_symbol: "│",
|
|
38
|
-
thumb_symbol: "┃",
|
|
39
|
-
track_style: { fg: "dark_gray" },
|
|
40
|
-
thumb_style: { fg: "cyan" },
|
|
41
|
-
begin_symbol: "▲",
|
|
42
|
-
end_symbol: "▼"
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
name: "ASCII",
|
|
46
|
-
track_symbol: "|",
|
|
47
|
-
thumb_symbol: "#",
|
|
48
|
-
track_style: { fg: "white" },
|
|
49
|
-
thumb_style: { fg: "red" },
|
|
50
|
-
begin_symbol: "^",
|
|
51
|
-
end_symbol: "v"
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
name: "Minimal",
|
|
55
|
-
track_symbol: " ",
|
|
56
|
-
thumb_symbol: "▐",
|
|
57
|
-
track_style: nil,
|
|
58
|
-
thumb_style: { fg: "yellow" },
|
|
59
|
-
begin_symbol: nil,
|
|
60
|
-
end_symbol: nil
|
|
61
|
-
}
|
|
62
|
-
]
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def run
|
|
66
|
-
RatatuiRuby.run do
|
|
67
|
-
loop do
|
|
68
|
-
draw
|
|
69
|
-
event = RatatuiRuby.poll_event
|
|
70
|
-
break if event == "q" || event == :ctrl_c
|
|
71
|
-
|
|
72
|
-
handle_event(event)
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
private def handle_event(event)
|
|
78
|
-
return unless event
|
|
79
|
-
|
|
80
|
-
if event.mouse?
|
|
81
|
-
case event.kind
|
|
82
|
-
when "scroll_up"
|
|
83
|
-
@scroll_position = [@scroll_position - 1, 0].max
|
|
84
|
-
when "scroll_down"
|
|
85
|
-
@scroll_position = [@scroll_position + 1, @content_length].min
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
if event.key? && event.to_s == "s"
|
|
90
|
-
@theme_index = (@theme_index + 1) % @themes.length
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
if event.key? && event.to_s == "o"
|
|
94
|
-
@orientation_index = (@orientation_index + 1) % @orientations.length
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
private def draw
|
|
99
|
-
# Calculate visible lines based on scroll position
|
|
100
|
-
# In a real app, you'd want to know the height of the available area.
|
|
101
|
-
# For this demo, we'll just show all lines but offset the text.
|
|
102
|
-
visible_lines = @lines[@scroll_position..-1] || []
|
|
103
|
-
|
|
104
|
-
# Paragraph with content
|
|
105
|
-
theme = @themes[@theme_index]
|
|
106
|
-
orientation = @orientations[@orientation_index]
|
|
107
|
-
|
|
108
|
-
p = RatatuiRuby::Paragraph.new(
|
|
109
|
-
text: visible_lines.join("\n"),
|
|
110
|
-
block: RatatuiRuby::Block.new(
|
|
111
|
-
titles: [
|
|
112
|
-
{ content: "Scroll with Mouse Wheel | Theme: #{theme[:name]} | Orientation: #{orientation}" },
|
|
113
|
-
{ content: "Press 's' to cycle theme, 'o' to cycle orientation", position: :bottom, alignment: :center }
|
|
114
|
-
],
|
|
115
|
-
borders: [:all]
|
|
116
|
-
)
|
|
117
|
-
)
|
|
118
|
-
|
|
119
|
-
# Scrollbar
|
|
120
|
-
s = RatatuiRuby::Scrollbar.new(
|
|
121
|
-
content_length: @content_length,
|
|
122
|
-
position: @scroll_position,
|
|
123
|
-
orientation: orientation,
|
|
124
|
-
track_symbol: theme[:track_symbol],
|
|
125
|
-
thumb_symbol: theme[:thumb_symbol],
|
|
126
|
-
track_style: theme[:track_style],
|
|
127
|
-
thumb_style: theme[:thumb_style],
|
|
128
|
-
begin_symbol: theme[:begin_symbol],
|
|
129
|
-
end_symbol: theme[:end_symbol]
|
|
130
|
-
)
|
|
131
|
-
|
|
132
|
-
# Use Overlay to stack Scrollbar on top of Paragraph.
|
|
133
|
-
# The Scrollbar will position itself on the correct edge (top/bottom/left/right)
|
|
134
|
-
# based on its orientation, demonstrating that the property works independently of layout.
|
|
135
|
-
overlay = RatatuiRuby::Overlay.new(
|
|
136
|
-
layers: [p, s]
|
|
137
|
-
)
|
|
138
|
-
|
|
139
|
-
RatatuiRuby.draw(overlay)
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
ScrollbarDemoApp.new.run if __FILE__ == $PROGRAM_NAME
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
4
|
-
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
5
|
-
|
|
6
|
-
require "test_helper"
|
|
7
|
-
require_relative "app"
|
|
8
|
-
|
|
9
|
-
class TestScrollbarDemoApp < Minitest::Test
|
|
10
|
-
include RatatuiRuby::TestHelper
|
|
11
|
-
|
|
12
|
-
def setup
|
|
13
|
-
@app = ScrollbarDemoApp.new
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def test_initial_render
|
|
17
|
-
with_test_terminal do
|
|
18
|
-
# Queue quit event to exit loop immediately
|
|
19
|
-
inject_key(:q)
|
|
20
|
-
|
|
21
|
-
# Stub init_terminal/restore_terminal to use test terminal
|
|
22
|
-
@app.run
|
|
23
|
-
|
|
24
|
-
content = buffer_content
|
|
25
|
-
|
|
26
|
-
# Top border with title (truncated due to small width)
|
|
27
|
-
assert_includes content[0], "Scroll"
|
|
28
|
-
# First line of content
|
|
29
|
-
assert_includes content[1], "Line 1"
|
|
30
|
-
# Scrollbar area (far right)
|
|
31
|
-
assert_equal "█", content[1][-1]
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def test_scroll_down
|
|
36
|
-
with_test_terminal do
|
|
37
|
-
# Queue scroll down + quit
|
|
38
|
-
inject_event(RatatuiRuby::Event::Mouse.new(kind: "scroll_down", x: 0, y: 0, button: "none"))
|
|
39
|
-
inject_key(:q)
|
|
40
|
-
|
|
41
|
-
@app.run
|
|
42
|
-
|
|
43
|
-
content = buffer_content
|
|
44
|
-
|
|
45
|
-
# Now it should start from Line 2
|
|
46
|
-
assert_includes content[1], "Line 2"
|
|
47
|
-
refute_includes content[1], "Line 1"
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def test_scroll_up
|
|
52
|
-
with_test_terminal do
|
|
53
|
-
# Queue scroll down + scroll up + quit
|
|
54
|
-
inject_event(RatatuiRuby::Event::Mouse.new(kind: "scroll_down", x: 0, y: 0, button: "none"))
|
|
55
|
-
inject_event(RatatuiRuby::Event::Mouse.new(kind: "scroll_up", x: 0, y: 0, button: "none"))
|
|
56
|
-
inject_key(:q)
|
|
57
|
-
|
|
58
|
-
@app.run
|
|
59
|
-
|
|
60
|
-
content = buffer_content
|
|
61
|
-
|
|
62
|
-
assert_includes content[1], "Line 1"
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def test_theme_cycling
|
|
67
|
-
with_test_terminal do
|
|
68
|
-
# Queue 's' + quit
|
|
69
|
-
inject_keys(:s, :q)
|
|
70
|
-
|
|
71
|
-
@app.run
|
|
72
|
-
|
|
73
|
-
content = buffer_content
|
|
74
|
-
assert_match(/Theme: Rounded/, content[0])
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
end
|
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
4
|
-
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
5
|
-
|
|
6
|
-
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
7
|
-
require "ratatui_ruby"
|
|
8
|
-
|
|
9
|
-
# Demonstrates Sparkline widget with interactive attribute cycling.
|
|
10
|
-
class SparklineDemoApp
|
|
11
|
-
def initialize
|
|
12
|
-
# Data sets with different characteristics
|
|
13
|
-
@data_sets = [
|
|
14
|
-
{
|
|
15
|
-
name: "Steady Growth",
|
|
16
|
-
data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
name: "With Gaps",
|
|
20
|
-
data: [5, nil, 8, nil, 6, nil, 9, nil, 7, nil, 10, nil]
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
name: "Random",
|
|
24
|
-
data: [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8]
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
name: "Sawtooth",
|
|
28
|
-
data: [1, 2, 3, 4, 5, 4, 3, 2, 1, 2, 3, 4]
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
name: "Peaks",
|
|
32
|
-
data: [1, 5, 1, 8, 1, 6, 1, 9, 1, 7, 1, 10]
|
|
33
|
-
}
|
|
34
|
-
]
|
|
35
|
-
@data_index = 0
|
|
36
|
-
|
|
37
|
-
@directions = [
|
|
38
|
-
{ name: "Left to Right", direction: :left_to_right },
|
|
39
|
-
{ name: "Right to Left", direction: :right_to_left }
|
|
40
|
-
]
|
|
41
|
-
@direction_index = 0
|
|
42
|
-
|
|
43
|
-
@styles = [
|
|
44
|
-
{ name: "Green", style: RatatuiRuby::Style.new(fg: :green) },
|
|
45
|
-
{ name: "Yellow", style: RatatuiRuby::Style.new(fg: :yellow) },
|
|
46
|
-
{ name: "Red", style: RatatuiRuby::Style.new(fg: :red) },
|
|
47
|
-
{ name: "Cyan", style: RatatuiRuby::Style.new(fg: :cyan) },
|
|
48
|
-
{ name: "Magenta", style: RatatuiRuby::Style.new(fg: :magenta) }
|
|
49
|
-
]
|
|
50
|
-
@style_index = 0
|
|
51
|
-
|
|
52
|
-
@absent_symbols = [
|
|
53
|
-
{ name: "None", symbol: nil },
|
|
54
|
-
{ name: "Dot (·)", symbol: "·" },
|
|
55
|
-
{ name: "Square (▫)", symbol: "▫" },
|
|
56
|
-
{ name: "Dash (-)", symbol: "-" },
|
|
57
|
-
{ name: "Underscore (_)", symbol: "_" }
|
|
58
|
-
]
|
|
59
|
-
@absent_symbol_index = 1
|
|
60
|
-
|
|
61
|
-
@absent_styles = [
|
|
62
|
-
{ name: "Default", style: nil },
|
|
63
|
-
{ name: "Dark Gray", style: RatatuiRuby::Style.new(fg: :dark_gray) },
|
|
64
|
-
{ name: "Dim Red", style: RatatuiRuby::Style.new(fg: :red, modifiers: [:dim]) },
|
|
65
|
-
{ name: "Dim Yellow", style: RatatuiRuby::Style.new(fg: :yellow, modifiers: [:dim]) }
|
|
66
|
-
]
|
|
67
|
-
@absent_style_index = 0
|
|
68
|
-
|
|
69
|
-
@bar_sets = [
|
|
70
|
-
{ name: "Default (Block)", set: nil },
|
|
71
|
-
{ name: "Numbers (0-8)", set: {
|
|
72
|
-
0 => "0", 1 => "1", 2 => "2", 3 => "3", 4 => "4", 5 => "5", 6 => "6", 7 => "7", 8 => "8"
|
|
73
|
-
}},
|
|
74
|
-
{ name: "ASCII (Heights)", set: [" ", "_", ".", "-", "=", "+", "*", "#", "@"] }
|
|
75
|
-
]
|
|
76
|
-
@bar_set_index = 0
|
|
77
|
-
|
|
78
|
-
@counter = 0
|
|
79
|
-
@hotkey_style = RatatuiRuby::Style.new(modifiers: [:bold, :underlined])
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def run
|
|
83
|
-
RatatuiRuby.run do
|
|
84
|
-
loop do
|
|
85
|
-
render
|
|
86
|
-
break if handle_input == :quit
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
private
|
|
92
|
-
|
|
93
|
-
def render
|
|
94
|
-
@counter += 1
|
|
95
|
-
|
|
96
|
-
data_set = @data_sets[@data_index]
|
|
97
|
-
direction = @directions[@direction_index][:direction]
|
|
98
|
-
style = @styles[@style_index][:style]
|
|
99
|
-
absent_symbol = @absent_symbols[@absent_symbol_index][:symbol]
|
|
100
|
-
absent_value_style = @absent_styles[@absent_style_index][:style]
|
|
101
|
-
bar_set = @bar_sets[@bar_set_index][:set]
|
|
102
|
-
|
|
103
|
-
# Use static data for clarity when cycling options
|
|
104
|
-
current_data = data_set[:data]
|
|
105
|
-
|
|
106
|
-
layout = RatatuiRuby::Layout.new(
|
|
107
|
-
direction: :vertical,
|
|
108
|
-
constraints: [
|
|
109
|
-
RatatuiRuby::Constraint.fill(1),
|
|
110
|
-
RatatuiRuby::Constraint.length(6),
|
|
111
|
-
],
|
|
112
|
-
children: [
|
|
113
|
-
# Main content area with multiple sparkline examples
|
|
114
|
-
RatatuiRuby::Layout.new(
|
|
115
|
-
direction: :vertical,
|
|
116
|
-
constraints: [
|
|
117
|
-
RatatuiRuby::Constraint.length(1),
|
|
118
|
-
RatatuiRuby::Constraint.length(3),
|
|
119
|
-
RatatuiRuby::Constraint.length(3),
|
|
120
|
-
RatatuiRuby::Constraint.length(3),
|
|
121
|
-
RatatuiRuby::Constraint.length(3),
|
|
122
|
-
RatatuiRuby::Constraint.fill(1)
|
|
123
|
-
],
|
|
124
|
-
children: [
|
|
125
|
-
RatatuiRuby::Paragraph.new(
|
|
126
|
-
text: "Sparkline Widget Demo - Cycle attributes with hotkeys"
|
|
127
|
-
),
|
|
128
|
-
# Sparkline 1: Main interactive sparkline
|
|
129
|
-
RatatuiRuby::Sparkline.new(
|
|
130
|
-
data: current_data,
|
|
131
|
-
direction:,
|
|
132
|
-
style:,
|
|
133
|
-
absent_value_symbol: absent_symbol,
|
|
134
|
-
absent_value_style:,
|
|
135
|
-
bar_set:,
|
|
136
|
-
block: RatatuiRuby::Block.new(title: "Interactive Sparkline")
|
|
137
|
-
),
|
|
138
|
-
# Sparkline 2: Same data, opposite direction
|
|
139
|
-
RatatuiRuby::Sparkline.new(
|
|
140
|
-
data: current_data.reverse,
|
|
141
|
-
direction:,
|
|
142
|
-
style:,
|
|
143
|
-
absent_value_symbol: absent_symbol,
|
|
144
|
-
absent_value_style:,
|
|
145
|
-
bar_set:,
|
|
146
|
-
block: RatatuiRuby::Block.new(title: "Reversed Data")
|
|
147
|
-
),
|
|
148
|
-
# Sparkline 3: Without absent value symbol (for comparison)
|
|
149
|
-
RatatuiRuby::Sparkline.new(
|
|
150
|
-
data: current_data,
|
|
151
|
-
direction:,
|
|
152
|
-
style:,
|
|
153
|
-
bar_set:,
|
|
154
|
-
block: RatatuiRuby::Block.new(title: "Without Absent Marker")
|
|
155
|
-
),
|
|
156
|
-
# Sparkline 4: Gap pattern responsive to absent marker controls
|
|
157
|
-
RatatuiRuby::Sparkline.new(
|
|
158
|
-
data: [5, nil, 8, nil, 6, nil, 9, nil, 7, nil, 10, nil],
|
|
159
|
-
direction:,
|
|
160
|
-
style: RatatuiRuby::Style.new(fg: :blue),
|
|
161
|
-
absent_value_symbol: absent_symbol,
|
|
162
|
-
absent_value_style:,
|
|
163
|
-
bar_set:,
|
|
164
|
-
block: RatatuiRuby::Block.new(title: "Gap Pattern (Responsive)")
|
|
165
|
-
),
|
|
166
|
-
RatatuiRuby::Paragraph.new(text: "")
|
|
167
|
-
]
|
|
168
|
-
),
|
|
169
|
-
# Bottom control panel
|
|
170
|
-
RatatuiRuby::Block.new(
|
|
171
|
-
title: "Controls",
|
|
172
|
-
borders: [:all],
|
|
173
|
-
children: [
|
|
174
|
-
RatatuiRuby::Paragraph.new(
|
|
175
|
-
text: [
|
|
176
|
-
# Line 1: Data
|
|
177
|
-
RatatuiRuby::Text::Line.new(spans: [
|
|
178
|
-
RatatuiRuby::Text::Span.new(content: "↑/↓", style: @hotkey_style),
|
|
179
|
-
RatatuiRuby::Text::Span.new(content: ": Data (#{@data_sets[@data_index][:name]})")
|
|
180
|
-
]),
|
|
181
|
-
# Line 2: View
|
|
182
|
-
RatatuiRuby::Text::Line.new(spans: [
|
|
183
|
-
RatatuiRuby::Text::Span.new(content: "d", style: @hotkey_style),
|
|
184
|
-
RatatuiRuby::Text::Span.new(content: ": Direction (#{@directions[@direction_index][:name]}) "),
|
|
185
|
-
RatatuiRuby::Text::Span.new(content: "c", style: @hotkey_style),
|
|
186
|
-
RatatuiRuby::Text::Span.new(content: ": Color (#{@styles[@style_index][:name]})")
|
|
187
|
-
]),
|
|
188
|
-
# Line 3: Markers
|
|
189
|
-
RatatuiRuby::Text::Line.new(spans: [
|
|
190
|
-
RatatuiRuby::Text::Span.new(content: "m", style: @hotkey_style),
|
|
191
|
-
RatatuiRuby::Text::Span.new(content: ": Absent Value Symbol (#{@absent_symbols[@absent_symbol_index][:name]}) "),
|
|
192
|
-
RatatuiRuby::Text::Span.new(content: "s", style: @hotkey_style),
|
|
193
|
-
RatatuiRuby::Text::Span.new(content: ": Absent Value Style (#{@absent_styles[@absent_style_index][:name]})")
|
|
194
|
-
]),
|
|
195
|
-
# Line 4: General
|
|
196
|
-
RatatuiRuby::Text::Line.new(spans: [
|
|
197
|
-
RatatuiRuby::Text::Span.new(content: "b", style: @hotkey_style),
|
|
198
|
-
RatatuiRuby::Text::Span.new(content: ": Bar Set (#{@bar_sets[@bar_set_index][:name]}) "),
|
|
199
|
-
RatatuiRuby::Text::Span.new(content: "q", style: @hotkey_style),
|
|
200
|
-
RatatuiRuby::Text::Span.new(content: ": Quit")
|
|
201
|
-
])
|
|
202
|
-
]
|
|
203
|
-
)
|
|
204
|
-
]
|
|
205
|
-
)
|
|
206
|
-
]
|
|
207
|
-
)
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
RatatuiRuby.draw(layout)
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
def handle_input
|
|
214
|
-
event = RatatuiRuby.poll_event
|
|
215
|
-
return unless event
|
|
216
|
-
|
|
217
|
-
case event
|
|
218
|
-
in {type: :key, code: "q"} | {type: :key, code: "c", modifiers: ["ctrl"]}
|
|
219
|
-
:quit
|
|
220
|
-
in type: :key, code: "up"
|
|
221
|
-
@data_index = (@data_index - 1) % @data_sets.length
|
|
222
|
-
in type: :key, code: "down"
|
|
223
|
-
@data_index = (@data_index + 1) % @data_sets.length
|
|
224
|
-
in type: :key, code: "d"
|
|
225
|
-
@direction_index = (@direction_index + 1) % @directions.length
|
|
226
|
-
in type: :key, code: "c"
|
|
227
|
-
@style_index = (@style_index + 1) % @styles.length
|
|
228
|
-
in type: :key, code: "m"
|
|
229
|
-
@absent_symbol_index = (@absent_symbol_index + 1) % @absent_symbols.length
|
|
230
|
-
in type: :key, code: "s"
|
|
231
|
-
@absent_style_index = (@absent_style_index + 1) % @absent_styles.length
|
|
232
|
-
in type: :key, code: "b"
|
|
233
|
-
@bar_set_index = (@bar_set_index + 1) % @bar_sets.length
|
|
234
|
-
else
|
|
235
|
-
nil
|
|
236
|
-
end
|
|
237
|
-
end
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
SparklineDemoApp.new.run if __FILE__ == $PROGRAM_NAME
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
4
|
-
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
5
|
-
|
|
6
|
-
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
7
|
-
require "ratatui_ruby"
|
|
8
|
-
require "ratatui_ruby/test_helper"
|
|
9
|
-
require "minitest/autorun"
|
|
10
|
-
require_relative "app"
|
|
11
|
-
|
|
12
|
-
class TestSparklineDemoApp < Minitest::Test
|
|
13
|
-
include RatatuiRuby::TestHelper
|
|
14
|
-
|
|
15
|
-
def setup
|
|
16
|
-
@app = SparklineDemoApp.new
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def test_initial_render
|
|
20
|
-
with_test_terminal do
|
|
21
|
-
inject_key(:q)
|
|
22
|
-
@app.run
|
|
23
|
-
|
|
24
|
-
content = buffer_content.join("\n")
|
|
25
|
-
assert_includes content, "Sparkline Widget Demo"
|
|
26
|
-
assert_includes content, "Interactive Sparkline"
|
|
27
|
-
assert_includes content, "Reversed Data"
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def test_cycle_data_set_up
|
|
32
|
-
with_test_terminal do
|
|
33
|
-
inject_keys(:up, :q)
|
|
34
|
-
@app.run
|
|
35
|
-
|
|
36
|
-
content = buffer_content.join("\n")
|
|
37
|
-
# Should still render after cycling
|
|
38
|
-
assert_includes content, "Sparkline Widget Demo"
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def test_cycle_data_set_down
|
|
43
|
-
with_test_terminal do
|
|
44
|
-
inject_keys(:down, :down, :q)
|
|
45
|
-
@app.run
|
|
46
|
-
|
|
47
|
-
content = buffer_content.join("\n")
|
|
48
|
-
assert_includes content, "Sparkline Widget Demo"
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def test_cycle_direction
|
|
53
|
-
with_test_terminal do
|
|
54
|
-
inject_keys(:d, :q)
|
|
55
|
-
@app.run
|
|
56
|
-
|
|
57
|
-
content = buffer_content.join("\n")
|
|
58
|
-
assert_includes content, "Sparkline Widget Demo"
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def test_cycle_color
|
|
63
|
-
with_test_terminal do
|
|
64
|
-
inject_keys(:c, :c, :q)
|
|
65
|
-
@app.run
|
|
66
|
-
|
|
67
|
-
content = buffer_content.join("\n")
|
|
68
|
-
assert_includes content, "Sparkline Widget Demo"
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def test_cycle_absent_marker
|
|
73
|
-
with_test_terminal do
|
|
74
|
-
inject_keys(:m, :m, :m, :q)
|
|
75
|
-
@app.run
|
|
76
|
-
|
|
77
|
-
content = buffer_content.join("\n")
|
|
78
|
-
assert_includes content, "Sparkline Widget Demo"
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def test_cycle_absent_style
|
|
83
|
-
with_test_terminal do
|
|
84
|
-
inject_keys(:s, :s, :q)
|
|
85
|
-
@app.run
|
|
86
|
-
|
|
87
|
-
content = buffer_content.join("\n")
|
|
88
|
-
assert_includes content, "Sparkline Widget Demo"
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
def test_cycle_bar_set
|
|
93
|
-
with_test_terminal do
|
|
94
|
-
inject_keys(:b, :q)
|
|
95
|
-
@app.run
|
|
96
|
-
|
|
97
|
-
content = buffer_content.join("\n")
|
|
98
|
-
assert_includes content, "Sparkline Widget Demo"
|
|
99
|
-
# Verify render with Numbers set (one_eighth="1", etc.)
|
|
100
|
-
# Input data [1..12] with implicit max 12.
|
|
101
|
-
# With Numbers set, we expect digits 1-8 to appear.
|
|
102
|
-
# Just asserting no crash is a start, but let's check for the label update if possible
|
|
103
|
-
# The controls footer should update.
|
|
104
|
-
# assert_includes content, ": Bar Set" # Included in controls
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
end
|