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,111 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
4
|
+
|
|
5
|
+
# frozen_string_literal: true
|
|
6
|
+
|
|
7
|
+
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
8
|
+
require "ratatui_ruby"
|
|
9
|
+
|
|
10
|
+
# A custom widget that fills its area with a checkered pattern using Cell objects.
|
|
11
|
+
class CheckeredBackground
|
|
12
|
+
def initialize(tui)
|
|
13
|
+
@tui = tui
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def render(area)
|
|
17
|
+
cell = @tui.cell(char: "░", fg: :dark_gray)
|
|
18
|
+
commands = []
|
|
19
|
+
area.height.times do |y|
|
|
20
|
+
area.width.times do |x|
|
|
21
|
+
# Checkerboard logic
|
|
22
|
+
if (x + y).even?
|
|
23
|
+
# Use a dim cell for the background pattern
|
|
24
|
+
commands << @tui.draw_cell(area.x + x, area.y + y, cell)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
commands
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class WidgetCellDemo
|
|
33
|
+
def run
|
|
34
|
+
RatatuiRuby.run do |tui|
|
|
35
|
+
@tui = tui
|
|
36
|
+
# Define some reusable cells for our table
|
|
37
|
+
ok_cell = @tui.cell(char: "OK", fg: :green)
|
|
38
|
+
fail_cell = @tui.cell(char: "FAIL", fg: :red, modifiers: ["bold"])
|
|
39
|
+
pending_cell = @tui.cell(char: "...", fg: :yellow, modifiers: ["dim"])
|
|
40
|
+
|
|
41
|
+
# A mix of Strings and Cells in rows
|
|
42
|
+
rows = [
|
|
43
|
+
["Database", ok_cell],
|
|
44
|
+
["Cache", ok_cell],
|
|
45
|
+
["Worker", fail_cell],
|
|
46
|
+
["Analytics", pending_cell],
|
|
47
|
+
["Web Server", @tui.cell(char: "RESTARTING", fg: :blue, modifiers: ["rapid_blink"])],
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
table = @tui.table(
|
|
51
|
+
header: ["Service", @tui.cell(char: "Status", modifiers: ["underlined"])],
|
|
52
|
+
rows:,
|
|
53
|
+
widths: [
|
|
54
|
+
@tui.constraint_percentage(70),
|
|
55
|
+
@tui.constraint_percentage(30),
|
|
56
|
+
],
|
|
57
|
+
block: @tui.block(title: "System Status", borders: :all),
|
|
58
|
+
column_spacing: 1
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
# Main loop
|
|
62
|
+
loop do
|
|
63
|
+
@tui.draw do |frame|
|
|
64
|
+
# Create a layout that holds both widgets
|
|
65
|
+
# We use a vertical layout:
|
|
66
|
+
# Top: Custom CheckeredBackground with specific height
|
|
67
|
+
# Bottom: Table using remaining space
|
|
68
|
+
top_area, bottom_area = @tui.layout_split(
|
|
69
|
+
frame.area,
|
|
70
|
+
direction: :vertical,
|
|
71
|
+
constraints: [
|
|
72
|
+
@tui.constraint_length(10), # Top section
|
|
73
|
+
@tui.constraint_min(0), # Bottom section
|
|
74
|
+
]
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# Top Child: An Overlay of Paragraph on top of CheckeredBackground
|
|
78
|
+
overlay = @tui.overlay(
|
|
79
|
+
layers: [
|
|
80
|
+
CheckeredBackground.new(@tui),
|
|
81
|
+
@tui.center(
|
|
82
|
+
width_percent: 50,
|
|
83
|
+
height_percent: 50,
|
|
84
|
+
child: @tui.paragraph(
|
|
85
|
+
text: "Custom Widget Demo\n(CheckeredBackground)",
|
|
86
|
+
alignment: :center,
|
|
87
|
+
block: @tui.block(borders: :all, title: "Overlay")
|
|
88
|
+
)
|
|
89
|
+
),
|
|
90
|
+
]
|
|
91
|
+
)
|
|
92
|
+
frame.render_widget(overlay, top_area)
|
|
93
|
+
|
|
94
|
+
# Bottom Child: The Table
|
|
95
|
+
frame.render_widget(table, bottom_area)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
case @tui.poll_event
|
|
99
|
+
in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
|
|
100
|
+
break
|
|
101
|
+
else
|
|
102
|
+
nil
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
if __FILE__ == $0
|
|
110
|
+
WidgetCellDemo.new.run
|
|
111
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Center Widget Demo
|
|
2
|
+
<!--
|
|
3
|
+
SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
4
|
+
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
This example demonstrates the `Center` widget, which positions a child widget in the center of the available area.
|
|
8
|
+
|
|
9
|
+
## Key Concepts
|
|
10
|
+
|
|
11
|
+
- **Centering**: The widget automatically calculates the necessary padding to center its child.
|
|
12
|
+
- **Sizing**: You can control the size of the centered area using `width_percent` and `height_percent`.
|
|
13
|
+
- **Composition**: The `Center` widget wraps another widget (the child), making it easy to compose layouts.
|
|
14
|
+
|
|
15
|
+
## Controls
|
|
16
|
+
|
|
17
|
+
| Key | Action |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| `←` / `→` | Decrease / Increase width percentage |
|
|
20
|
+
| `↑` / `↓` | Increase / Decrease height percentage |
|
|
21
|
+
| `q` | Quit |
|
|
22
|
+
|
|
23
|
+
## Screenshot
|
|
24
|
+
|
|
25
|
+

|
|
26
|
+
|
|
27
|
+
## Source Code
|
|
28
|
+
|
|
29
|
+
- [app.rb](app.rb)
|
|
@@ -0,0 +1,116 @@
|
|
|
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: Center Widget
|
|
10
|
+
# Demonstrates how to center content horizontally and vertically
|
|
11
|
+
# with adjustable width/height percentages.
|
|
12
|
+
class WidgetCenterDemo
|
|
13
|
+
def initialize
|
|
14
|
+
@width_percent = 50
|
|
15
|
+
@height_percent = 50
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def run
|
|
19
|
+
RatatuiRuby.run do |tui|
|
|
20
|
+
@tui = tui
|
|
21
|
+
loop do
|
|
22
|
+
render
|
|
23
|
+
break if handle_input == :quit
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private def render
|
|
29
|
+
@tui.draw do |frame|
|
|
30
|
+
layout = @tui.layout_split(
|
|
31
|
+
frame.area,
|
|
32
|
+
direction: :vertical,
|
|
33
|
+
constraints: [
|
|
34
|
+
@tui.constraint_fill(1),
|
|
35
|
+
@tui.constraint_length(3),
|
|
36
|
+
]
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
# 1. Main Area
|
|
40
|
+
# Background block frames the centered content
|
|
41
|
+
bg_block = @tui.block(
|
|
42
|
+
title: "Center Widget Demo",
|
|
43
|
+
borders: [:all],
|
|
44
|
+
style: @tui.style(fg: :gray)
|
|
45
|
+
)
|
|
46
|
+
frame.render_widget(bg_block, layout[0])
|
|
47
|
+
|
|
48
|
+
# 2. Centered Content
|
|
49
|
+
# The content itself is just a block with some text
|
|
50
|
+
content = @tui.paragraph(
|
|
51
|
+
text: [
|
|
52
|
+
@tui.text_line(
|
|
53
|
+
spans: [
|
|
54
|
+
@tui.text_span(content: "Centered Area", style: @tui.style(modifiers: [:bold])),
|
|
55
|
+
],
|
|
56
|
+
alignment: :center
|
|
57
|
+
),
|
|
58
|
+
@tui.text_line(spans: []),
|
|
59
|
+
@tui.text_line(spans: [@tui.text_span(content: "Width: #{@width_percent}%", style: @tui.style(fg: :cyan))], alignment: :center),
|
|
60
|
+
@tui.text_line(spans: [@tui.text_span(content: "Height: #{@height_percent}%", style: @tui.style(fg: :magenta))], alignment: :center),
|
|
61
|
+
],
|
|
62
|
+
block: @tui.block(
|
|
63
|
+
title: "Child Widget",
|
|
64
|
+
borders: [:all],
|
|
65
|
+
style: @tui.style(fg: :white)
|
|
66
|
+
),
|
|
67
|
+
alignment: :center
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
# Create the Center widget
|
|
71
|
+
center_widget = @tui.center(
|
|
72
|
+
child: content,
|
|
73
|
+
width_percent: @width_percent,
|
|
74
|
+
height_percent: @height_percent
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# Render center widget into the main layout area
|
|
78
|
+
frame.render_widget(center_widget, layout[0])
|
|
79
|
+
|
|
80
|
+
# 3. Controls
|
|
81
|
+
control_text = @tui.paragraph(
|
|
82
|
+
text: [
|
|
83
|
+
@tui.text_line(spans: [
|
|
84
|
+
@tui.text_span(content: "←/→", style: @tui.style(modifiers: [:bold, :underlined])),
|
|
85
|
+
@tui.text_span(content: ": Width "),
|
|
86
|
+
@tui.text_span(content: "↑/↓", style: @tui.style(modifiers: [:bold, :underlined])),
|
|
87
|
+
@tui.text_span(content: ": Height "),
|
|
88
|
+
@tui.text_span(content: "q", style: @tui.style(modifiers: [:bold, :underlined])),
|
|
89
|
+
@tui.text_span(content: ": Quit"),
|
|
90
|
+
]),
|
|
91
|
+
],
|
|
92
|
+
block: @tui.block(borders: [:top], style: @tui.style(bg: :black))
|
|
93
|
+
)
|
|
94
|
+
frame.render_widget(control_text, layout[1])
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def handle_input
|
|
99
|
+
case @tui.poll_event
|
|
100
|
+
in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
|
|
101
|
+
:quit
|
|
102
|
+
in { type: :key, code: "left" }
|
|
103
|
+
@width_percent = [@width_percent - 5, 5].max
|
|
104
|
+
in { type: :key, code: "right" }
|
|
105
|
+
@width_percent = [@width_percent + 5, 100].min
|
|
106
|
+
in { type: :key, code: "up" }
|
|
107
|
+
@height_percent = [@height_percent + 5, 100].min
|
|
108
|
+
in { type: :key, code: "down" }
|
|
109
|
+
@height_percent = [@height_percent - 5, 5].max
|
|
110
|
+
else
|
|
111
|
+
# Ignore other events
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
WidgetCenterDemo.new.run if __FILE__ == $0
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
3
|
+
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
4
|
+
-->
|
|
5
|
+
|
|
6
|
+
# Chart Widget Example
|
|
7
|
+
|
|
8
|
+
Demonstrates Cartesian plotting with interactive styling and configuration.
|
|
9
|
+
|
|
10
|
+
Trends and patterns are invisible in raw logs. Charts visualize X/Y datasets to reveal the story behind the data.
|
|
11
|
+
|
|
12
|
+
## Features Demonstrated
|
|
13
|
+
|
|
14
|
+
- **Dataset Types**: Line charts and Scatter plots.
|
|
15
|
+
- **Markers**: Braille patterns, dots, blocks, and bars.
|
|
16
|
+
- **Axis Configuration**: Controlling labels, bounds, and alignment (Left/Center/Right).
|
|
17
|
+
- **Legend**: Positioning the legend in any of the four corners or hiding it based on constraints.
|
|
18
|
+
|
|
19
|
+
## Hotkeys
|
|
20
|
+
|
|
21
|
+
- **m**: Cycle Marker Type (`marker`)
|
|
22
|
+
- **s**: Cycle Dataset Style (`style`)
|
|
23
|
+
- **x**: Cycle X-Axis Alignment (`labels_alignment`)
|
|
24
|
+
- **y**: Cycle Y-Axis Alignment (`labels_alignment`)
|
|
25
|
+
- **l**: Cycle Legend Position (`legend_position`)
|
|
26
|
+
- **q**: Quit
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
ruby examples/widget_chart_demo/app.rb
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Learning Outcomes
|
|
35
|
+
|
|
36
|
+
Use this example if you need to...
|
|
37
|
+
- Plot real-time data monitoring (CPU history, request latency).
|
|
38
|
+
- Visualize mathematical functions.
|
|
39
|
+
- Compare multiple datasets on the same axis.
|
|
40
|
+
|
|
41
|
+

|
|
@@ -0,0 +1,218 @@
|
|
|
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 Cartesian plotting attributes with interactive cycling.
|
|
10
|
+
#
|
|
11
|
+
# Trends and patterns are invisible in raw logs. You need to see the shape of the data to understand the story it tells.
|
|
12
|
+
#
|
|
13
|
+
# This demo showcases the <tt>Chart</tt> widget. It provides an interactive playground where you can toggle marker types, axis alignments, and legend positions in real-time.
|
|
14
|
+
#
|
|
15
|
+
# Use it to understand how to visualize complex X/Y datasets and trends efficiently.
|
|
16
|
+
#
|
|
17
|
+
# === Example
|
|
18
|
+
#
|
|
19
|
+
# Run the demo from the terminal:
|
|
20
|
+
#
|
|
21
|
+
# ruby examples/widget_chart_demo/app.rb
|
|
22
|
+
#
|
|
23
|
+
# rdoc-image:/doc/images/widget_chart_demo.png
|
|
24
|
+
class WidgetChartDemo
|
|
25
|
+
MARKERS = [
|
|
26
|
+
{ name: "Dot (·)", marker: :dot },
|
|
27
|
+
{ name: "Braille", marker: :braille },
|
|
28
|
+
{ name: "Block (█)", marker: :block },
|
|
29
|
+
{ name: "Bar", marker: :bar },
|
|
30
|
+
].freeze
|
|
31
|
+
|
|
32
|
+
X_ALIGNMENTS = [
|
|
33
|
+
{ name: "Left", alignment: :left },
|
|
34
|
+
{ name: "Center", alignment: :center },
|
|
35
|
+
{ name: "Right", alignment: :right },
|
|
36
|
+
].freeze
|
|
37
|
+
|
|
38
|
+
Y_ALIGNMENTS = [
|
|
39
|
+
{ name: "Left", alignment: :left },
|
|
40
|
+
{ name: "Center", alignment: :center },
|
|
41
|
+
{ name: "Right", alignment: :right },
|
|
42
|
+
].freeze
|
|
43
|
+
|
|
44
|
+
LEGEND_POSITIONS = [
|
|
45
|
+
{ name: "Top Right", position: :top_right },
|
|
46
|
+
{ name: "Top Left", position: :top_left },
|
|
47
|
+
{ name: "Bottom Right", position: :bottom_right },
|
|
48
|
+
{ name: "Bottom Left", position: :bottom_left },
|
|
49
|
+
].freeze
|
|
50
|
+
|
|
51
|
+
def run
|
|
52
|
+
RatatuiRuby.run do |tui|
|
|
53
|
+
@tui = tui
|
|
54
|
+
init_styles
|
|
55
|
+
|
|
56
|
+
# Support seeded random for deterministic testing
|
|
57
|
+
# Set RATA_SEED=42 for reproducible scatter plot data
|
|
58
|
+
seed = ENV.fetch("RATA_SEED", nil)
|
|
59
|
+
@rng = seed ? Random.new(seed.to_i) : Random.new
|
|
60
|
+
|
|
61
|
+
@marker_index = 0
|
|
62
|
+
@dataset_style_index = 0
|
|
63
|
+
@x_alignment_index = 1
|
|
64
|
+
@y_alignment_index = 2
|
|
65
|
+
@legend_position_index = 0
|
|
66
|
+
|
|
67
|
+
loop do
|
|
68
|
+
render
|
|
69
|
+
break if handle_input == :quit
|
|
70
|
+
sleep 0.05
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
private def init_styles
|
|
76
|
+
@hotkey_style = @tui.style(modifiers: [:bold, :underlined])
|
|
77
|
+
@dataset_styles = [
|
|
78
|
+
{ name: "Yellow", style: @tui.style(fg: :yellow) },
|
|
79
|
+
{ name: "Green", style: @tui.style(fg: :green) },
|
|
80
|
+
{ name: "Cyan", style: @tui.style(fg: :cyan) },
|
|
81
|
+
{ name: "Red", style: @tui.style(fg: :red) },
|
|
82
|
+
{ name: "Magenta", style: @tui.style(fg: :magenta) },
|
|
83
|
+
{ name: "Bold Blue", style: @tui.style(fg: :blue, modifiers: [:bold]) },
|
|
84
|
+
{ name: "Dim White", style: @tui.style(fg: :white, modifiers: [:dim]) },
|
|
85
|
+
{ name: "Italic Green", style: @tui.style(fg: :green, modifiers: [:italic]) },
|
|
86
|
+
{ name: "Alert (Red/White/Bar)", style: @tui.style(fg: :white, bg: :red, modifiers: [:bold]) },
|
|
87
|
+
]
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
private def render
|
|
91
|
+
# Static sample data: sine wave with wider range for better visibility
|
|
92
|
+
line_data = (0..50).map do |i|
|
|
93
|
+
x = i / 5.0
|
|
94
|
+
[x, Math.sin(x)]
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Scatter: Random points (deterministic when RATA_SEED is set)
|
|
98
|
+
scatter_data = (0..20).map do |_|
|
|
99
|
+
[@rng.rand(0.0..10.0), @rng.rand(-1.0..1.0)]
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
style = @dataset_styles[@dataset_style_index][:style]
|
|
103
|
+
# Ensure the second dataset has a different style
|
|
104
|
+
scatter_style = @dataset_styles[(@dataset_style_index + 2) % @dataset_styles.length][:style]
|
|
105
|
+
|
|
106
|
+
datasets = [
|
|
107
|
+
@tui.dataset(
|
|
108
|
+
name: "Line",
|
|
109
|
+
data: line_data,
|
|
110
|
+
style:,
|
|
111
|
+
marker: (style.modifiers.include?(:bold) && style.bg) ? :bar : MARKERS[@marker_index][:marker],
|
|
112
|
+
graph_type: :line
|
|
113
|
+
),
|
|
114
|
+
@tui.dataset(
|
|
115
|
+
name: "Scatter",
|
|
116
|
+
data: scatter_data,
|
|
117
|
+
style: scatter_style,
|
|
118
|
+
marker: (scatter_style.modifiers.include?(:bold) && scatter_style.bg) ? :bar : MARKERS[@marker_index][:marker],
|
|
119
|
+
graph_type: :scatter
|
|
120
|
+
),
|
|
121
|
+
]
|
|
122
|
+
|
|
123
|
+
chart = @tui.chart(
|
|
124
|
+
datasets:,
|
|
125
|
+
x_axis: @tui.axis(
|
|
126
|
+
title: "Time",
|
|
127
|
+
bounds: [0.0, 10.0],
|
|
128
|
+
labels: %w[0 5 10],
|
|
129
|
+
style: @tui.style(fg: :yellow),
|
|
130
|
+
labels_alignment: X_ALIGNMENTS[@x_alignment_index][:alignment]
|
|
131
|
+
),
|
|
132
|
+
y_axis: @tui.axis(
|
|
133
|
+
title: "Amplitude",
|
|
134
|
+
bounds: [-1.0, 1.0],
|
|
135
|
+
labels: %w[-1 0 1],
|
|
136
|
+
style: @tui.style(fg: :cyan),
|
|
137
|
+
labels_alignment: Y_ALIGNMENTS[@y_alignment_index][:alignment]
|
|
138
|
+
),
|
|
139
|
+
block: @tui.block(
|
|
140
|
+
title: "Chart Widget Demo",
|
|
141
|
+
borders: [:all]
|
|
142
|
+
),
|
|
143
|
+
legend_position: LEGEND_POSITIONS[@legend_position_index][:position],
|
|
144
|
+
hidden_legend_constraints: [
|
|
145
|
+
@tui.constraint_min(20),
|
|
146
|
+
@tui.constraint_min(10),
|
|
147
|
+
]
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
controls = @tui.block(
|
|
151
|
+
title: "Controls",
|
|
152
|
+
borders: [:all],
|
|
153
|
+
children: [
|
|
154
|
+
@tui.paragraph(
|
|
155
|
+
text: [
|
|
156
|
+
# Line 1: Markers & Colors
|
|
157
|
+
@tui.text_line(spans: [
|
|
158
|
+
@tui.text_span(content: "m", style: @hotkey_style),
|
|
159
|
+
@tui.text_span(content: ": Marker (#{MARKERS[@marker_index][:name]}) "),
|
|
160
|
+
@tui.text_span(content: "s", style: @hotkey_style),
|
|
161
|
+
@tui.text_span(content: ": Style (#{@dataset_styles[@dataset_style_index][:name]})"),
|
|
162
|
+
]),
|
|
163
|
+
# Line 2: Axis alignments
|
|
164
|
+
@tui.text_line(spans: [
|
|
165
|
+
@tui.text_span(content: "x", style: @hotkey_style),
|
|
166
|
+
@tui.text_span(content: ": X Align (#{X_ALIGNMENTS[@x_alignment_index][:name]}) "),
|
|
167
|
+
@tui.text_span(content: "y", style: @hotkey_style),
|
|
168
|
+
@tui.text_span(content: ": Y Align (#{Y_ALIGNMENTS[@y_alignment_index][:name]}) "),
|
|
169
|
+
@tui.text_span(content: "l", style: @hotkey_style),
|
|
170
|
+
@tui.text_span(content: ": Legend (#{LEGEND_POSITIONS[@legend_position_index][:name]})"),
|
|
171
|
+
]),
|
|
172
|
+
# Line 3: Quit
|
|
173
|
+
@tui.text_line(spans: [
|
|
174
|
+
@tui.text_span(content: "q", style: @hotkey_style),
|
|
175
|
+
@tui.text_span(content: ": Quit"),
|
|
176
|
+
]),
|
|
177
|
+
]
|
|
178
|
+
),
|
|
179
|
+
]
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
@tui.draw do |frame|
|
|
183
|
+
chart_area, controls_area = @tui.layout_split(
|
|
184
|
+
frame.area,
|
|
185
|
+
direction: :vertical,
|
|
186
|
+
constraints: [
|
|
187
|
+
@tui.constraint_fill(1),
|
|
188
|
+
@tui.constraint_length(5),
|
|
189
|
+
]
|
|
190
|
+
)
|
|
191
|
+
frame.render_widget(chart, chart_area)
|
|
192
|
+
frame.render_widget(controls, controls_area)
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
private def handle_input
|
|
197
|
+
event = @tui.poll_event
|
|
198
|
+
|
|
199
|
+
case event
|
|
200
|
+
in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
|
|
201
|
+
:quit
|
|
202
|
+
in type: :key, code: "m"
|
|
203
|
+
@marker_index = (@marker_index + 1) % MARKERS.length
|
|
204
|
+
in type: :key, code: "s"
|
|
205
|
+
@dataset_style_index = (@dataset_style_index + 1) % @dataset_styles.length
|
|
206
|
+
in type: :key, code: "x"
|
|
207
|
+
@x_alignment_index = (@x_alignment_index + 1) % X_ALIGNMENTS.length
|
|
208
|
+
in type: :key, code: "y"
|
|
209
|
+
@y_alignment_index = (@y_alignment_index + 1) % Y_ALIGNMENTS.length
|
|
210
|
+
in type: :key, code: "l"
|
|
211
|
+
@legend_position_index = (@legend_position_index + 1) % LEGEND_POSITIONS.length
|
|
212
|
+
else
|
|
213
|
+
nil
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
WidgetChartDemo.new.run if __FILE__ == $PROGRAM_NAME
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
3
|
+
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
4
|
+
-->
|
|
5
|
+
|
|
6
|
+
# Gauge Widget Example
|
|
7
|
+
|
|
8
|
+
Demonstrates progress bars with interactive configuration.
|
|
9
|
+
|
|
10
|
+
Long-running tasks create anxiety. Users need to know the system is working. Gauges provide visual feedback on completion status.
|
|
11
|
+
|
|
12
|
+
## Features Demonstrated
|
|
13
|
+
|
|
14
|
+
- **Progress styles**: standard block characters or Unicode bars.
|
|
15
|
+
- **Labels**: Customizing the text overlay (Percentage, Ratio, etc.).
|
|
16
|
+
- **Styling**: Independent control of the filled gauge color and the background track.
|
|
17
|
+
- **Thresholds**: Implementing multi-colored gauges based on values.
|
|
18
|
+
|
|
19
|
+
## Hotkeys
|
|
20
|
+
|
|
21
|
+
- **Arrows (←/→)**: Adjust Ratio (`ratio`)
|
|
22
|
+
- **g**: Cycle Gauge Color (`gauge_style`)
|
|
23
|
+
- **b**: Cycle Background Style (`style`)
|
|
24
|
+
- **u**: Toggle Unicode Mode (`use_unicode`)
|
|
25
|
+
- **l**: Cycle Label Mode (`label`)
|
|
26
|
+
- **q**: Quit
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
ruby examples/widget_gauge_demo/app.rb
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Learning Outcomes
|
|
35
|
+
|
|
36
|
+
Use this example if you need to...
|
|
37
|
+
- Show download or upload progress.
|
|
38
|
+
- Visualize resource quotas (disk space, memory usage).
|
|
39
|
+
- Create "health bars" or status indicators.
|
|
40
|
+
|
|
41
|
+

|