ratatui_ruby 0.4.0 → 0.6.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 +98 -176
- data/CHANGELOG.md +80 -6
- data/README.md +19 -7
- data/REUSE.toml +15 -0
- data/doc/application_architecture.md +179 -45
- data/doc/application_testing.md +80 -32
- data/doc/contributors/design/ruby_frontend.md +48 -8
- data/doc/contributors/design/rust_backend.md +1 -0
- data/doc/contributors/developing_examples.md +191 -48
- data/doc/contributors/documentation_style.md +7 -0
- data/doc/contributors/examples_audit/p1_high.md +21 -0
- data/doc/contributors/examples_audit/p2_moderate.md +81 -0
- data/doc/contributors/examples_audit.md +41 -0
- data/doc/contributors/index.md +2 -0
- data/doc/event_handling.md +21 -7
- data/doc/images/app_all_events.png +0 -0
- data/doc/images/app_color_picker.png +0 -0
- data/doc/images/app_login_form.png +0 -0
- data/doc/images/app_stateful_interaction.png +0 -0
- data/doc/images/verify_quickstart_dsl.png +0 -0
- data/doc/images/verify_quickstart_layout.png +0 -0
- data/doc/images/verify_quickstart_lifecycle.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_demo.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_canvas_demo.png +0 -0
- data/doc/images/widget_cell_demo.png +0 -0
- data/doc/images/widget_center_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_overlay_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_rich_text.png +0 -0
- data/doc/images/widget_scroll_text.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_demo.png +0 -0
- data/doc/images/widget_table_flex.png +0 -0
- data/doc/images/widget_tabs_demo.png +0 -0
- data/doc/images/widget_text_width.png +0 -0
- data/doc/interactive_design.md +25 -30
- data/doc/quickstart.md +150 -130
- data/doc/terminal_limitations.md +92 -0
- data/examples/app_all_events/README.md +99 -0
- data/examples/app_all_events/app.rb +96 -0
- data/examples/app_all_events/model/app_model.rb +157 -0
- data/examples/app_all_events/model/event_color_cycle.rb +41 -0
- data/examples/app_all_events/model/event_entry.rb +92 -0
- data/examples/app_all_events/model/msg.rb +37 -0
- data/examples/app_all_events/model/timestamp.rb +54 -0
- data/examples/app_all_events/update.rb +73 -0
- data/examples/app_all_events/view/app_view.rb +78 -0
- data/examples/app_all_events/view/controls_view.rb +52 -0
- data/examples/app_all_events/view/counts_view.rb +59 -0
- data/examples/app_all_events/view/live_view.rb +70 -0
- data/examples/app_all_events/view/log_view.rb +55 -0
- data/examples/app_all_events/view.rb +7 -0
- data/examples/app_color_picker/README.md +134 -0
- data/examples/app_color_picker/app.rb +74 -0
- data/examples/app_color_picker/clipboard.rb +84 -0
- data/examples/app_color_picker/color.rb +191 -0
- data/examples/app_color_picker/controls.rb +90 -0
- data/examples/app_color_picker/copy_dialog.rb +166 -0
- data/examples/app_color_picker/export_pane.rb +126 -0
- data/examples/app_color_picker/harmony.rb +56 -0
- data/examples/app_color_picker/input.rb +174 -0
- data/examples/app_color_picker/main_container.rb +178 -0
- data/examples/app_color_picker/palette.rb +109 -0
- data/examples/app_login_form/README.md +47 -0
- data/examples/{login_form → app_login_form}/app.rb +38 -42
- data/examples/app_stateful_interaction/README.md +31 -0
- data/examples/app_stateful_interaction/app.rb +272 -0
- data/examples/timeout_demo.rb +43 -0
- data/examples/verify_quickstart_dsl/README.md +48 -0
- data/examples/{quickstart_dsl → verify_quickstart_dsl}/app.rb +17 -6
- data/examples/verify_quickstart_layout/README.md +71 -0
- data/examples/verify_quickstart_layout/app.rb +71 -0
- data/examples/verify_quickstart_lifecycle/README.md +56 -0
- data/examples/verify_quickstart_lifecycle/app.rb +54 -0
- data/examples/verify_readme_usage/README.md +43 -0
- data/examples/verify_readme_usage/app.rb +40 -0
- data/examples/widget_barchart_demo/README.md +49 -0
- data/examples/widget_barchart_demo/app.rb +238 -0
- data/examples/widget_block_demo/README.md +34 -0
- data/examples/widget_block_demo/app.rb +256 -0
- data/examples/widget_box_demo/README.md +45 -0
- data/examples/{box_demo → widget_box_demo}/app.rb +99 -65
- data/examples/widget_calendar_demo/README.md +39 -0
- data/examples/widget_calendar_demo/app.rb +109 -0
- data/examples/widget_canvas_demo/README.md +27 -0
- data/examples/widget_canvas_demo/app.rb +123 -0
- data/examples/widget_cell_demo/README.md +36 -0
- data/examples/widget_cell_demo/app.rb +111 -0
- data/examples/widget_center_demo/README.md +29 -0
- data/examples/widget_center_demo/app.rb +116 -0
- data/examples/widget_chart_demo/README.md +41 -0
- data/examples/widget_chart_demo/app.rb +218 -0
- data/examples/widget_gauge_demo/README.md +41 -0
- data/examples/widget_gauge_demo/app.rb +212 -0
- data/examples/widget_layout_split/README.md +44 -0
- data/examples/widget_layout_split/app.rb +246 -0
- data/examples/widget_line_gauge_demo/README.md +41 -0
- data/examples/widget_line_gauge_demo/app.rb +217 -0
- data/examples/widget_list_demo/README.md +49 -0
- data/examples/widget_list_demo/app.rb +366 -0
- data/examples/widget_map_demo/README.md +39 -0
- data/examples/{map_demo → widget_map_demo}/app.rb +24 -21
- data/examples/widget_overlay_demo/app.rb +248 -0
- data/examples/widget_popup_demo/README.md +36 -0
- data/examples/widget_popup_demo/app.rb +104 -0
- data/examples/widget_ratatui_logo_demo/README.md +34 -0
- data/examples/widget_ratatui_logo_demo/app.rb +103 -0
- data/examples/widget_ratatui_mascot_demo/README.md +34 -0
- data/examples/widget_ratatui_mascot_demo/app.rb +93 -0
- data/examples/widget_rect/README.md +38 -0
- data/examples/widget_rect/app.rb +205 -0
- data/examples/widget_render/README.md +37 -0
- data/examples/widget_render/app.rb +184 -0
- data/examples/widget_rich_text/README.md +35 -0
- data/examples/widget_rich_text/app.rb +166 -0
- data/examples/widget_scroll_text/README.md +37 -0
- data/examples/widget_scroll_text/app.rb +107 -0
- data/examples/widget_scrollbar_demo/README.md +37 -0
- data/examples/widget_scrollbar_demo/app.rb +153 -0
- data/examples/widget_sparkline_demo/README.md +42 -0
- data/examples/widget_sparkline_demo/app.rb +275 -0
- data/examples/widget_style_colors/README.md +34 -0
- data/examples/widget_style_colors/app.rb +19 -21
- data/examples/widget_table_demo/README.md +48 -0
- data/examples/widget_table_demo/app.rb +239 -0
- data/examples/widget_tabs_demo/README.md +41 -0
- data/examples/widget_tabs_demo/app.rb +181 -0
- data/examples/widget_text_width/README.md +35 -0
- data/examples/widget_text_width/app.rb +106 -0
- data/ext/ratatui_ruby/Cargo.lock +11 -4
- data/ext/ratatui_ruby/Cargo.toml +2 -1
- data/ext/ratatui_ruby/src/events.rs +359 -62
- data/ext/ratatui_ruby/src/frame.rs +227 -0
- data/ext/ratatui_ruby/src/lib.rs +110 -27
- data/ext/ratatui_ruby/src/rendering.rs +8 -4
- data/ext/ratatui_ruby/src/string_width.rs +101 -0
- data/ext/ratatui_ruby/src/style.rs +138 -57
- data/ext/ratatui_ruby/src/terminal.rs +42 -22
- data/ext/ratatui_ruby/src/text.rs +14 -7
- data/ext/ratatui_ruby/src/widgets/barchart.rs +74 -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/gauge.rs +9 -2
- data/ext/ratatui_ruby/src/widgets/layout.rs +9 -4
- data/ext/ratatui_ruby/src/widgets/line_gauge.rs +9 -2
- data/ext/ratatui_ruby/src/widgets/list.rs +211 -12
- data/ext/ratatui_ruby/src/widgets/list_state.rs +137 -0
- data/ext/ratatui_ruby/src/widgets/mod.rs +3 -0
- 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 +97 -3
- data/ext/ratatui_ruby/src/widgets/scrollbar_state.rs +169 -0
- data/ext/ratatui_ruby/src/widgets/sparkline.rs +14 -11
- data/ext/ratatui_ruby/src/widgets/table.rs +121 -5
- data/ext/ratatui_ruby/src/widgets/table_state.rs +121 -0
- data/ext/ratatui_ruby/src/widgets/tabs.rs +11 -11
- data/lib/ratatui_ruby/cell.rb +7 -7
- data/lib/ratatui_ruby/event/key/character.rb +35 -0
- data/lib/ratatui_ruby/event/key/media.rb +44 -0
- data/lib/ratatui_ruby/event/key/modifier.rb +95 -0
- data/lib/ratatui_ruby/event/key/navigation.rb +55 -0
- data/lib/ratatui_ruby/event/key/system.rb +45 -0
- data/lib/ratatui_ruby/event/key.rb +112 -52
- data/lib/ratatui_ruby/event/mouse.rb +3 -3
- data/lib/ratatui_ruby/event/none.rb +43 -0
- data/lib/ratatui_ruby/event/paste.rb +1 -1
- data/lib/ratatui_ruby/event.rb +56 -4
- data/lib/ratatui_ruby/frame.rb +183 -0
- data/lib/ratatui_ruby/list_state.rb +88 -0
- data/lib/ratatui_ruby/schema/bar_chart/bar.rb +13 -13
- 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 +30 -25
- data/lib/ratatui_ruby/schema/gauge.rb +54 -52
- 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 +103 -80
- data/lib/ratatui_ruby/schema/list_item.rb +41 -0
- 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 +99 -56
- 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 +66 -46
- data/lib/ratatui_ruby/schema/table.rb +126 -115
- data/lib/ratatui_ruby/schema/tabs.rb +66 -67
- data/lib/ratatui_ruby/schema/text.rb +69 -1
- data/lib/ratatui_ruby/scrollbar_state.rb +112 -0
- data/lib/ratatui_ruby/session/autodoc.rb +482 -0
- data/lib/ratatui_ruby/session.rb +55 -23
- data/lib/ratatui_ruby/table_state.rb +90 -0
- data/lib/ratatui_ruby/test_helper/event_injection.rb +169 -0
- data/lib/ratatui_ruby/test_helper/snapshot.rb +390 -0
- data/lib/ratatui_ruby/test_helper/style_assertions.rb +351 -0
- data/lib/ratatui_ruby/test_helper/terminal.rb +127 -0
- data/lib/ratatui_ruby/test_helper/test_doubles.rb +68 -0
- data/lib/ratatui_ruby/test_helper.rb +66 -193
- data/lib/ratatui_ruby/version.rb +1 -1
- data/lib/ratatui_ruby.rb +100 -51
- 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_stateful_interaction/app.rbs +33 -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_demo/app.rbs +32 -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_map_demo/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_demo/app.rbs +11 -0
- data/sig/examples/widget_text_width/app.rbs +10 -0
- data/sig/ratatui_ruby/event.rbs +11 -1
- data/sig/ratatui_ruby/frame.rbs +11 -0
- data/sig/ratatui_ruby/list_state.rbs +13 -0
- data/sig/ratatui_ruby/ratatui_ruby.rbs +5 -4
- data/sig/ratatui_ruby/schema/bar_chart/bar.rbs +3 -3
- data/sig/ratatui_ruby/schema/draw.rbs +4 -0
- data/sig/ratatui_ruby/schema/gauge.rbs +2 -2
- data/sig/ratatui_ruby/schema/layout.rbs +1 -1
- data/sig/ratatui_ruby/schema/line_gauge.rbs +2 -2
- data/sig/ratatui_ruby/schema/list.rbs +4 -2
- data/sig/ratatui_ruby/schema/list_item.rbs +10 -0
- data/sig/ratatui_ruby/schema/rect.rbs +3 -0
- data/sig/ratatui_ruby/schema/style.rbs +3 -3
- data/sig/ratatui_ruby/schema/table.rbs +3 -1
- data/sig/ratatui_ruby/schema/text.rbs +8 -6
- data/sig/ratatui_ruby/scrollbar_state.rbs +18 -0
- data/sig/ratatui_ruby/session.rbs +107 -0
- data/sig/ratatui_ruby/table_state.rbs +15 -0
- data/sig/ratatui_ruby/test_helper/event_injection.rbs +16 -0
- data/sig/ratatui_ruby/test_helper/snapshot.rbs +12 -0
- data/sig/ratatui_ruby/test_helper/style_assertions.rbs +64 -0
- data/sig/ratatui_ruby/test_helper/terminal.rbs +14 -0
- data/sig/ratatui_ruby/test_helper/test_doubles.rbs +22 -0
- data/sig/ratatui_ruby/test_helper.rbs +5 -4
- data/tasks/autodoc/examples.rb +79 -0
- data/tasks/autodoc/inventory.rb +63 -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 +53 -0
- data/tasks/bump/changelog.rb +3 -3
- data/tasks/bump/history.rb +2 -2
- data/tasks/bump/links.rb +67 -0
- 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 +70 -30
- data/tasks/terminal_preview/app_screenshot.rb +14 -6
- 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 +10 -11
- 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 +232 -127
- 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/list_styles.png +0 -0
- data/doc/images/login_form.png +0 -0
- data/doc/images/quickstart_dsl.png +0 -0
- data/doc/images/quickstart_lifecycle.png +0 -0
- data/doc/images/readme_usage.png +0 -0
- data/doc/images/rich_text.png +0 -0
- data/doc/images/scroll_text.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/doc/images/table_select.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.rb +0 -63
- data/examples/block_padding/app.rbs +0 -7
- data/examples/block_padding/test_app.rb +0 -31
- data/examples/block_titles/app.rb +0 -61
- 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.rb +0 -39
- 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.rb +0 -198
- 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/tasks/bump/comparison_links.rb +0 -41
- /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/{mouse_events.png → app_mouse_events.png} +0 -0
- /data/doc/images/{map_demo.png → widget_map_demo.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/ratatui_logo_demo.png → exe/.gitkeep} +0 -0
|
@@ -0,0 +1,166 @@
|
|
|
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
|
+
# Rich Text Example
|
|
10
|
+
# Demonstrates the Span and Line objects for styling individual words
|
|
11
|
+
# within a block of text.
|
|
12
|
+
class WidgetRichText
|
|
13
|
+
def initialize
|
|
14
|
+
@scroll_pos = 0
|
|
15
|
+
@color_index = 0
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def run
|
|
19
|
+
RatatuiRuby.run do |tui|
|
|
20
|
+
@tui = tui
|
|
21
|
+
loop do
|
|
22
|
+
render
|
|
23
|
+
event = handle_input
|
|
24
|
+
break if event == :quit
|
|
25
|
+
sleep 0.05
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private def render
|
|
31
|
+
@tui.draw do |frame|
|
|
32
|
+
layout = @tui.layout_split(
|
|
33
|
+
frame.area,
|
|
34
|
+
direction: :vertical,
|
|
35
|
+
constraints: [
|
|
36
|
+
@tui.constraint_percentage(50),
|
|
37
|
+
@tui.constraint_percentage(50),
|
|
38
|
+
]
|
|
39
|
+
)
|
|
40
|
+
frame.render_widget(simple_text_line_example, layout[0])
|
|
41
|
+
frame.render_widget(complex_example, layout[1])
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private def simple_text_line_example
|
|
46
|
+
# Example 1: A line with mixed styles
|
|
47
|
+
@tui.paragraph(
|
|
48
|
+
text: [
|
|
49
|
+
@tui.text_line(
|
|
50
|
+
spans: [
|
|
51
|
+
@tui.text_span(
|
|
52
|
+
content: "Normal text, ",
|
|
53
|
+
style: nil
|
|
54
|
+
),
|
|
55
|
+
@tui.text_span(
|
|
56
|
+
content: "Bold Text",
|
|
57
|
+
style: @tui.style(modifiers: [:bold])
|
|
58
|
+
),
|
|
59
|
+
@tui.text_span(
|
|
60
|
+
content: ", ",
|
|
61
|
+
style: nil
|
|
62
|
+
),
|
|
63
|
+
@tui.text_span(
|
|
64
|
+
content: "Italic Text",
|
|
65
|
+
style: @tui.style(modifiers: [:italic])
|
|
66
|
+
),
|
|
67
|
+
@tui.text_span(
|
|
68
|
+
content: ", ",
|
|
69
|
+
style: nil
|
|
70
|
+
),
|
|
71
|
+
@tui.text_span(
|
|
72
|
+
content: "Red Text",
|
|
73
|
+
style: @tui.style(fg: :red)
|
|
74
|
+
),
|
|
75
|
+
@tui.text_span(
|
|
76
|
+
content: ".",
|
|
77
|
+
style: nil
|
|
78
|
+
),
|
|
79
|
+
]
|
|
80
|
+
),
|
|
81
|
+
@tui.text_line(spans: []),
|
|
82
|
+
@tui.text_line(
|
|
83
|
+
spans: [
|
|
84
|
+
@tui.text_span(content: "Integer Color Test: "),
|
|
85
|
+
@tui.text_span(content: "Color #{@color_index}", style: @tui.style(fg: @color_index)),
|
|
86
|
+
@tui.text_span(content: " (Use "),
|
|
87
|
+
@tui.text_span(content: "↑ ↓", style: @tui.style(modifiers: [:bold])),
|
|
88
|
+
@tui.text_span(content: " for +/- 1,", style: nil),
|
|
89
|
+
@tui.text_span(content: "→ ←", style: @tui.style(modifiers: [:bold])),
|
|
90
|
+
@tui.text_span(content: " for +/- 10)", style: nil),
|
|
91
|
+
]
|
|
92
|
+
),
|
|
93
|
+
],
|
|
94
|
+
block: @tui.block(
|
|
95
|
+
title: "Simple Rich Text",
|
|
96
|
+
borders: [:all]
|
|
97
|
+
)
|
|
98
|
+
)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
private def complex_example
|
|
102
|
+
# Example 2: Multiple lines with different styles
|
|
103
|
+
@tui.paragraph(
|
|
104
|
+
text: [
|
|
105
|
+
@tui.text_line(
|
|
106
|
+
spans: [
|
|
107
|
+
@tui.text_span(content: "✓ ", style: @tui.style(fg: :green, modifiers: [:bold])),
|
|
108
|
+
@tui.text_span(content: "Feature Complete", style: nil),
|
|
109
|
+
@tui.text_span(content: " - All tests passing", style: @tui.style(fg: :gray)),
|
|
110
|
+
]
|
|
111
|
+
),
|
|
112
|
+
@tui.text_line(
|
|
113
|
+
spans: [
|
|
114
|
+
@tui.text_span(content: "⚠ ", style: @tui.style(fg: :yellow, modifiers: [:bold])),
|
|
115
|
+
@tui.text_span(content: "Warning", style: nil),
|
|
116
|
+
@tui.text_span(content: " - Documentation pending", style: @tui.style(fg: :gray)),
|
|
117
|
+
]
|
|
118
|
+
),
|
|
119
|
+
@tui.text_line(
|
|
120
|
+
spans: [
|
|
121
|
+
@tui.text_span(content: "✗ ", style: @tui.style(fg: :red, modifiers: [:bold])),
|
|
122
|
+
@tui.text_span(content: "Not Started", style: nil),
|
|
123
|
+
@tui.text_span(content: " - Performance benchmarks", style: @tui.style(fg: :gray)),
|
|
124
|
+
]
|
|
125
|
+
),
|
|
126
|
+
@tui.text_line(spans: []),
|
|
127
|
+
@tui.text_line(
|
|
128
|
+
spans: [
|
|
129
|
+
@tui.text_span(content: "Press ", style: nil),
|
|
130
|
+
@tui.text_span(content: "Q", style: @tui.style(modifiers: [:bold])),
|
|
131
|
+
@tui.text_span(content: " to quit, ", style: nil),
|
|
132
|
+
@tui.text_span(content: "↑ ↓", style: @tui.style(modifiers: [:bold])),
|
|
133
|
+
@tui.text_span(content: " to adjust color by 1, ", style: nil),
|
|
134
|
+
@tui.text_span(content: "← →", style: @tui.style(modifiers: [:bold])),
|
|
135
|
+
@tui.text_span(content: " to adjust color by 10.", style: nil),
|
|
136
|
+
]
|
|
137
|
+
),
|
|
138
|
+
],
|
|
139
|
+
block: @tui.block(
|
|
140
|
+
title: "Status Report",
|
|
141
|
+
borders: [:all]
|
|
142
|
+
)
|
|
143
|
+
)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
private def handle_input
|
|
147
|
+
event = @tui.poll_event
|
|
148
|
+
return :quit if event == "q" || event == :esc || event == :ctrl_c
|
|
149
|
+
|
|
150
|
+
if event.left?
|
|
151
|
+
@color_index = (@color_index - 10) % 256
|
|
152
|
+
elsif event.right?
|
|
153
|
+
@color_index = (@color_index + 10) % 256
|
|
154
|
+
elsif event.up?
|
|
155
|
+
@color_index = (@color_index + 1) % 256
|
|
156
|
+
elsif event.down?
|
|
157
|
+
@color_index = (@color_index - 1) % 256
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
nil
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
if __FILE__ == $0
|
|
165
|
+
WidgetRichText.new.run
|
|
166
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
3
|
+
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
4
|
+
-->
|
|
5
|
+
|
|
6
|
+
# Scroll Text Example
|
|
7
|
+
|
|
8
|
+
Demonstrates scrolling long text content within a fixed viewport.
|
|
9
|
+
|
|
10
|
+
Sometimes text exceeds the available space. The `Paragraph` widget supports a `scroll` parameter to simulate a viewport, allowing users to pan vertically and horizontally.
|
|
11
|
+
|
|
12
|
+
## Features Demonstrated
|
|
13
|
+
|
|
14
|
+
- **Vertical Scrolling**: Moving through lines of text.
|
|
15
|
+
- **Horizontal Scrolling**: Panning across long, unwrapped lines.
|
|
16
|
+
- **State Management**: tracking `scroll_x` and `scroll_y` offsets in the application state.
|
|
17
|
+
|
|
18
|
+
## Hotkeys
|
|
19
|
+
|
|
20
|
+
- **Arrows (↑/↓)**: Scroll Vertically (`scroll`)
|
|
21
|
+
- **Arrows (←/→)**: Scroll Horizontally (`scroll`)
|
|
22
|
+
- **q**: Quit
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
ruby examples/widget_scroll_text/app.rb
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Learning Outcomes
|
|
31
|
+
|
|
32
|
+
Use this example if you need to...
|
|
33
|
+
- Build a log viewer.
|
|
34
|
+
- Create a "terms and conditions" scrollbox.
|
|
35
|
+
- Display code snippets that might be wider than the terminal.
|
|
36
|
+
|
|
37
|
+

|
|
@@ -0,0 +1,107 @@
|
|
|
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
|
+
# Demo: Scrollable Paragraph
|
|
10
|
+
# Shows how to scroll through long text content using arrow keys
|
|
11
|
+
#
|
|
12
|
+
# Helper: Disable experimental warnings since we use line_count/line_width
|
|
13
|
+
RatatuiRuby.experimental_warnings = false
|
|
14
|
+
|
|
15
|
+
class WidgetScrollText
|
|
16
|
+
def run
|
|
17
|
+
RatatuiRuby.run do |tui|
|
|
18
|
+
@tui = tui
|
|
19
|
+
@scroll_x = 0
|
|
20
|
+
@scroll_y = 0
|
|
21
|
+
|
|
22
|
+
@lines = (1..100).map do |i|
|
|
23
|
+
"Line #{i}: " + ("This is a long line of text that can be scrolled horizontally. " * 3) + "End of line #{i}"
|
|
24
|
+
end
|
|
25
|
+
@hotkey_style = @tui.style(modifiers: [:bold, :underlined])
|
|
26
|
+
|
|
27
|
+
loop do
|
|
28
|
+
draw
|
|
29
|
+
break if handle_input == :quit
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def render
|
|
35
|
+
# No-op for compatibility if needed, or alias to draw, but draw now uses @tui
|
|
36
|
+
draw
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def handle_input
|
|
40
|
+
case @tui.poll_event
|
|
41
|
+
in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
|
|
42
|
+
:quit
|
|
43
|
+
in type: :key, code: "up"
|
|
44
|
+
@scroll_y = [@scroll_y - 1, 0].max
|
|
45
|
+
in type: :key, code: "down"
|
|
46
|
+
@scroll_y = [@scroll_y + 1, @lines.length].min
|
|
47
|
+
in type: :key, code: "left"
|
|
48
|
+
@scroll_x = [@scroll_x - 1, 0].max
|
|
49
|
+
in type: :key, code: "right"
|
|
50
|
+
@scroll_x = [@scroll_x + 1, 100].min
|
|
51
|
+
else
|
|
52
|
+
nil
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private def draw
|
|
57
|
+
@tui.draw do |frame|
|
|
58
|
+
layout = @tui.layout_split(
|
|
59
|
+
frame.area,
|
|
60
|
+
direction: :vertical,
|
|
61
|
+
constraints: [
|
|
62
|
+
@tui.constraint_fill(1),
|
|
63
|
+
@tui.constraint_length(5),
|
|
64
|
+
]
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
text = @lines.join("\n")
|
|
68
|
+
|
|
69
|
+
# Main content
|
|
70
|
+
main_paragraph = @tui.paragraph(
|
|
71
|
+
text:,
|
|
72
|
+
scroll: [@scroll_y, @scroll_x],
|
|
73
|
+
block: @tui.block(
|
|
74
|
+
title: "Scrollable Text (#{text.lines.count} lines)",
|
|
75
|
+
borders: [:all]
|
|
76
|
+
)
|
|
77
|
+
)
|
|
78
|
+
frame.render_widget(main_paragraph, layout[0])
|
|
79
|
+
|
|
80
|
+
# Bottom control panel
|
|
81
|
+
control_text = [
|
|
82
|
+
@tui.text_line(spans: [
|
|
83
|
+
@tui.text_span(content: "NAVIGATION (Size: #{main_paragraph.line_count(65535)}x#{main_paragraph.line_width})", style: @tui.style(modifiers: [:bold])),
|
|
84
|
+
]),
|
|
85
|
+
@tui.text_line(spans: [
|
|
86
|
+
@tui.text_span(content: "↑/↓", style: @hotkey_style),
|
|
87
|
+
@tui.text_span(content: ": Vert Scroll (#{@scroll_y}/#{main_paragraph.line_count(65535)}) "),
|
|
88
|
+
@tui.text_span(content: "←/→", style: @hotkey_style),
|
|
89
|
+
@tui.text_span(content: ": Horz Scroll (#{@scroll_x}/#{main_paragraph.line_width}) "),
|
|
90
|
+
@tui.text_span(content: "q", style: @hotkey_style),
|
|
91
|
+
@tui.text_span(content: ": Quit"),
|
|
92
|
+
]),
|
|
93
|
+
]
|
|
94
|
+
|
|
95
|
+
control_paragraph = @tui.paragraph(
|
|
96
|
+
text: control_text,
|
|
97
|
+
block: @tui.block(
|
|
98
|
+
title: "Controls",
|
|
99
|
+
borders: [:all]
|
|
100
|
+
)
|
|
101
|
+
)
|
|
102
|
+
frame.render_widget(control_paragraph, layout[1])
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
WidgetScrollText.new.run if __FILE__ == $PROGRAM_NAME
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
3
|
+
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
4
|
+
-->
|
|
5
|
+
|
|
6
|
+
# Scrollbar Widget Example
|
|
7
|
+
|
|
8
|
+
Demonstrates explicit scrollbars for navigation feedback.
|
|
9
|
+
|
|
10
|
+
Content overflows. Users get lost in long lists. Scrollbars provide essential spatial awareness ("How far down am I?") and navigation controls.
|
|
11
|
+
|
|
12
|
+
## Features Demonstrated
|
|
13
|
+
|
|
14
|
+
- **Orientation**: Vertical, Horizontal, and variation modes (Right/Left, Top/Bottom).
|
|
15
|
+
- **Styling**: Custom characters for Track, Thumb, and arrows.
|
|
16
|
+
- **State Integration**: Linking the scrollbar `position` to the content view state.
|
|
17
|
+
|
|
18
|
+
## Hotkeys
|
|
19
|
+
|
|
20
|
+
- **Mouse Wheel**: Scroll content (`position`)
|
|
21
|
+
- **s**: Cycle Scrollbar Theme (Standard, Rounded, ASCII, Minimal)
|
|
22
|
+
- **o**: Cycle Orientation (`orientation`)
|
|
23
|
+
- **q**: Quit
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
ruby examples/widget_scrollbar_demo/app.rb
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Learning Outcomes
|
|
32
|
+
|
|
33
|
+
Use this example if you need to...
|
|
34
|
+
- Add visual scroll indicators to Lists or Tables.
|
|
35
|
+
- Implement specialized inputs like sliders or volume controls.
|
|
36
|
+
|
|
37
|
+

|
|
@@ -0,0 +1,153 @@
|
|
|
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 viewport navigation with interactive theme and orientation cycling.
|
|
10
|
+
#
|
|
11
|
+
# Content overflows. Users get lost in long lists without landmarks. They need to know where they are and how much is left.
|
|
12
|
+
#
|
|
13
|
+
# This demo showcases the <tt>Scrollbar</tt> widget. It provides an interactive playground where you can toggle orientations and cycle through different themes (Standard, Rounded, ASCII, Minimal) in real-time.
|
|
14
|
+
#
|
|
15
|
+
# Use it to understand how to provide spatial awareness and navigation cues for overflowing content.
|
|
16
|
+
#
|
|
17
|
+
# === Example
|
|
18
|
+
#
|
|
19
|
+
# Run the demo from the terminal:
|
|
20
|
+
#
|
|
21
|
+
# ruby examples/widget_scrollbar_demo/app.rb
|
|
22
|
+
#
|
|
23
|
+
# rdoc-image:/doc/images/widget_scrollbar_demo.png
|
|
24
|
+
class WidgetScrollbarDemo
|
|
25
|
+
def initialize
|
|
26
|
+
@scroll_position = 0
|
|
27
|
+
@content_length = 50
|
|
28
|
+
@lines = (1..@content_length).map { |i| "Line #{i}" }
|
|
29
|
+
@orientation_index = 0
|
|
30
|
+
@orientations = [
|
|
31
|
+
:vertical,
|
|
32
|
+
:vertical_right,
|
|
33
|
+
:vertical_left,
|
|
34
|
+
:horizontal,
|
|
35
|
+
:horizontal_bottom,
|
|
36
|
+
:horizontal_top,
|
|
37
|
+
]
|
|
38
|
+
@theme_index = 0
|
|
39
|
+
@themes = [
|
|
40
|
+
{
|
|
41
|
+
name: "Standard",
|
|
42
|
+
track_symbol: nil,
|
|
43
|
+
thumb_symbol: "█",
|
|
44
|
+
track_style: nil,
|
|
45
|
+
thumb_style: nil,
|
|
46
|
+
begin_symbol: nil,
|
|
47
|
+
end_symbol: nil,
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: "Rounded",
|
|
51
|
+
track_symbol: "│",
|
|
52
|
+
thumb_symbol: "┃",
|
|
53
|
+
track_style: { fg: "dark_gray" },
|
|
54
|
+
thumb_style: { fg: "cyan" },
|
|
55
|
+
begin_symbol: "▲",
|
|
56
|
+
end_symbol: "▼",
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: "ASCII",
|
|
60
|
+
track_symbol: "|",
|
|
61
|
+
thumb_symbol: "#",
|
|
62
|
+
track_style: { fg: "white" },
|
|
63
|
+
thumb_style: { fg: "red" },
|
|
64
|
+
begin_symbol: "^",
|
|
65
|
+
end_symbol: "v",
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: "Minimal",
|
|
69
|
+
track_symbol: " ",
|
|
70
|
+
thumb_symbol: "▐",
|
|
71
|
+
track_style: nil,
|
|
72
|
+
thumb_style: { fg: "yellow" },
|
|
73
|
+
begin_symbol: nil,
|
|
74
|
+
end_symbol: nil,
|
|
75
|
+
},
|
|
76
|
+
]
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def run
|
|
80
|
+
RatatuiRuby.run do |tui|
|
|
81
|
+
@tui = tui
|
|
82
|
+
loop do
|
|
83
|
+
draw
|
|
84
|
+
event = @tui.poll_event
|
|
85
|
+
break if event == "q" || event == :ctrl_c
|
|
86
|
+
|
|
87
|
+
handle_event(event)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
private def handle_event(event)
|
|
93
|
+
if event.mouse?
|
|
94
|
+
case event.kind
|
|
95
|
+
when "scroll_up"
|
|
96
|
+
@scroll_position = [@scroll_position - 1, 0].max
|
|
97
|
+
when "scroll_down"
|
|
98
|
+
@scroll_position = [@scroll_position + 1, @content_length].min
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
if event.key? && event.to_s == "s"
|
|
103
|
+
@theme_index = (@theme_index + 1) % @themes.length
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
if event.key? && event.to_s == "o"
|
|
107
|
+
@orientation_index = (@orientation_index + 1) % @orientations.length
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
private def draw
|
|
112
|
+
@tui.draw do |frame|
|
|
113
|
+
# Calculate visible lines based on scroll position
|
|
114
|
+
# In a real app, you'd want to know the height of the available area.
|
|
115
|
+
# For this demo, we'll just show all lines but offset the text.
|
|
116
|
+
visible_lines = @lines[@scroll_position..-1] || []
|
|
117
|
+
|
|
118
|
+
# Paragraph with content
|
|
119
|
+
theme = @themes[@theme_index]
|
|
120
|
+
orientation = @orientations[@orientation_index]
|
|
121
|
+
|
|
122
|
+
p = @tui.paragraph(
|
|
123
|
+
text: visible_lines.join("\n"),
|
|
124
|
+
block: @tui.block(
|
|
125
|
+
titles: [
|
|
126
|
+
{ content: "Scroll with Mouse Wheel | Theme: #{theme[:name]} | Orientation: #{orientation}" },
|
|
127
|
+
{ content: "Press 's' to cycle theme, 'o' to cycle orientation", position: :bottom, alignment: :center },
|
|
128
|
+
],
|
|
129
|
+
borders: [:all]
|
|
130
|
+
)
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
# Scrollbar
|
|
134
|
+
s = @tui.scrollbar(
|
|
135
|
+
content_length: @content_length,
|
|
136
|
+
position: @scroll_position,
|
|
137
|
+
orientation:,
|
|
138
|
+
track_symbol: theme[:track_symbol],
|
|
139
|
+
thumb_symbol: theme[:thumb_symbol],
|
|
140
|
+
track_style: theme[:track_style],
|
|
141
|
+
thumb_style: theme[:thumb_style],
|
|
142
|
+
begin_symbol: theme[:begin_symbol],
|
|
143
|
+
end_symbol: theme[:end_symbol]
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
# Render paragraph first, then scrollbar on top
|
|
147
|
+
frame.render_widget(p, frame.area)
|
|
148
|
+
frame.render_widget(s, frame.area)
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
WidgetScrollbarDemo.new.run if __FILE__ == $PROGRAM_NAME
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
3
|
+
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
4
|
+
-->
|
|
5
|
+
|
|
6
|
+
# Sparkline Widget Example
|
|
7
|
+
|
|
8
|
+
Demonstrates high-density data visualization in a condensed footprint.
|
|
9
|
+
|
|
10
|
+
Users need context. A single number ("90% CPU") tells you status, but not the trend. Full charts take up too much space. Sparklines condense history into a single line, perfect for headers and dashboards.
|
|
11
|
+
|
|
12
|
+
## Features Demonstrated
|
|
13
|
+
|
|
14
|
+
- **High Density**: Showing dozens of data points in a small area.
|
|
15
|
+
- **Direction**: Rendering Left-to-Right (standard) or Right-to-Left (like a scrolling ticker).
|
|
16
|
+
- **Gaps**: Handling `nil` values with "absent symbols" to indicate missing data.
|
|
17
|
+
- **Styling**: Using colors and custom characters to indicate severity or type.
|
|
18
|
+
|
|
19
|
+
## Hotkeys
|
|
20
|
+
|
|
21
|
+
- **Up/Down (↑/↓)**: Cycle Data Set (`data`)
|
|
22
|
+
- **d**: Cycle Direction (`direction`)
|
|
23
|
+
- **c**: Cycle Color (`style`)
|
|
24
|
+
- **m**: Cycle Absent Value Marker Symbol (`absent_value_symbol`)
|
|
25
|
+
- **s**: Cycle Absent Value Marker Style (`absent_value_style`)
|
|
26
|
+
- **b**: Cycle Bar Character Set (`bar_set`)
|
|
27
|
+
- **q**: Quit
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
ruby examples/widget_sparkline_demo/app.rb
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Learning Outcomes
|
|
36
|
+
|
|
37
|
+
Use this example if you need to...
|
|
38
|
+
- Add a "CPU Load" graph to your header.
|
|
39
|
+
- Visualize stock price trends in a list row.
|
|
40
|
+
- Monitor memory usage over the last 60 seconds.
|
|
41
|
+
|
|
42
|
+

|