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
|
@@ -7,7 +7,7 @@ $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
|
7
7
|
require "ratatui_ruby"
|
|
8
8
|
|
|
9
9
|
# An example of the Canvas widget showing a world map and animated shapes.
|
|
10
|
-
class
|
|
10
|
+
class WidgetMapDemo
|
|
11
11
|
include RatatuiRuby
|
|
12
12
|
|
|
13
13
|
COLORS = [:black, :blue, :white, nil].freeze
|
|
@@ -15,40 +15,41 @@ class MapDemoApp
|
|
|
15
15
|
|
|
16
16
|
# Returns a Canvas view for the map demo with the given circle radius.
|
|
17
17
|
#
|
|
18
|
+
# +tui+:: The RatatuiRuby::Session instance.
|
|
18
19
|
# +radius+:: The radius of the animated circle.
|
|
19
20
|
# +marker+:: The marker type.
|
|
20
21
|
# +background_color+:: The background color of the canvas.
|
|
21
22
|
# +show_labels+:: Whether to show city labels.
|
|
22
|
-
def view(radius, marker = :braille, background_color = nil, show_labels: true)
|
|
23
|
+
def view(tui, radius, marker = :braille, background_color = nil, show_labels: true)
|
|
23
24
|
shapes = [
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
tui.shape_map(color: :green, resolution: :high),
|
|
26
|
+
tui.shape_circle(x: 0.0, y: 0.0, radius:, color: :red),
|
|
27
|
+
tui.shape_line(x1: 0.0, y1: 0.0, x2: 50.0, y2: 25.0, color: :yellow),
|
|
27
28
|
]
|
|
28
29
|
|
|
29
30
|
if show_labels
|
|
30
31
|
shapes += [
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
tui.shape_label(x: -0.1, y: 51.5, text: "London", style: tui.style(fg: :cyan)),
|
|
33
|
+
tui.shape_label(x: 139.7, y: 35.7, text: "Tokyo", style: tui.style(fg: :magenta)),
|
|
34
|
+
tui.shape_label(x: -74.0, y: 40.7, text: "New York", style: tui.style(fg: :yellow)),
|
|
35
|
+
tui.shape_label(x: -122.4, y: 37.8, text: "San Francisco", style: tui.style(fg: :blue)),
|
|
36
|
+
tui.shape_label(x: 151.2, y: -33.9, text: "Sydney", style: tui.style(fg: :green)),
|
|
36
37
|
]
|
|
37
38
|
end
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
shapes
|
|
40
|
+
tui.canvas(
|
|
41
|
+
shapes:,
|
|
41
42
|
x_bounds: [-180.0, 180.0],
|
|
42
43
|
y_bounds: [-90.0, 90.0],
|
|
43
|
-
marker
|
|
44
|
-
block:
|
|
45
|
-
background_color:
|
|
44
|
+
marker:,
|
|
45
|
+
block: tui.block(title: "World Map ['b' bg, 'm' marker: #{marker}, 'l' labels: #{show_labels ? 'on' : 'off'}]", borders: :all),
|
|
46
|
+
background_color:
|
|
46
47
|
)
|
|
47
48
|
end
|
|
48
49
|
|
|
49
50
|
# Runs the map demo loop.
|
|
50
51
|
def run
|
|
51
|
-
RatatuiRuby.run do
|
|
52
|
+
RatatuiRuby.run do |tui|
|
|
52
53
|
radius = 0.0
|
|
53
54
|
direction = 1
|
|
54
55
|
bg_index = 0
|
|
@@ -63,13 +64,15 @@ class MapDemoApp
|
|
|
63
64
|
end
|
|
64
65
|
|
|
65
66
|
# Define the view
|
|
66
|
-
|
|
67
|
+
canvas = view(tui, radius, MARKERS[marker_index], COLORS[bg_index], show_labels:)
|
|
67
68
|
|
|
68
|
-
|
|
69
|
+
tui.draw do |frame|
|
|
70
|
+
frame.render_widget(canvas, frame.area)
|
|
71
|
+
end
|
|
69
72
|
|
|
70
|
-
event =
|
|
73
|
+
event = tui.poll_event
|
|
71
74
|
case event
|
|
72
|
-
in {type: :key, code: "q"} | {type: :key, code: :ctrl_c}
|
|
75
|
+
in { type: :key, code: "q" } | { type: :key, code: :ctrl_c }
|
|
73
76
|
break
|
|
74
77
|
in type: :key, code: "b"
|
|
75
78
|
bg_index = (bg_index + 1) % COLORS.size
|
|
@@ -87,4 +90,4 @@ class MapDemoApp
|
|
|
87
90
|
end
|
|
88
91
|
end
|
|
89
92
|
|
|
90
|
-
|
|
93
|
+
WidgetMapDemo.new.run if __FILE__ == $PROGRAM_NAME
|
|
@@ -0,0 +1,248 @@
|
|
|
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
|
+
HEADLINES = [
|
|
10
|
+
"Scientists Discover New Species of Deep-Sea Octopus Near Hawaii",
|
|
11
|
+
"Global Climate Summit Reaches Historic Agreement on Emissions",
|
|
12
|
+
"Tech Giant Announces Breakthrough in Quantum Computing Research",
|
|
13
|
+
"Local Community Garden Initiative Expands to Ten More Cities",
|
|
14
|
+
"Astronomers Detect Unusual Radio Signals from Distant Galaxy",
|
|
15
|
+
"New Study Links Mediterranean Diet to Improved Heart Health",
|
|
16
|
+
"Electric Vehicle Sales Surge as Battery Technology Improves",
|
|
17
|
+
"Ancient Manuscripts Reveal Previously Unknown Trading Routes",
|
|
18
|
+
"Renewable Energy Now Powers 40% of National Grid",
|
|
19
|
+
"Robotics Team Develops AI System for Disaster Response",
|
|
20
|
+
"Archaeological Dig Uncovers Evidence of Early Human Settlement",
|
|
21
|
+
"Major Airline Commits to Carbon-Neutral Flights by 2035",
|
|
22
|
+
"Breakthrough Treatment Shows Promise for Rare Genetic Disease",
|
|
23
|
+
"City Council Approves Expanded Public Transportation Network",
|
|
24
|
+
"Marine Biologists Track Migration Patterns of Endangered Whales",
|
|
25
|
+
"New App Helps Farmers Optimize Water Usage During Drought",
|
|
26
|
+
"International Space Station Extends Mission Timeline to 2030",
|
|
27
|
+
"Local Schools Implement Innovative STEM Education Program",
|
|
28
|
+
"Wildlife Conservation Efforts Lead to Species Population Recovery",
|
|
29
|
+
"Research Team Creates Biodegradable Alternative to Plastic Packaging",
|
|
30
|
+
"Historic Theater Restoration Project Nears Completion",
|
|
31
|
+
"Cybersecurity Experts Warn of Emerging Online Threats",
|
|
32
|
+
"Community Food Bank Serves Record Number of Families This Year",
|
|
33
|
+
"Innovative Urban Planning Reduces Traffic Congestion by 30%",
|
|
34
|
+
].freeze
|
|
35
|
+
|
|
36
|
+
# Overlay Demo Example
|
|
37
|
+
# Demonstrates the Overlay widget for layering widgets with depth.
|
|
38
|
+
class WidgetOverlayDemo
|
|
39
|
+
def initialize
|
|
40
|
+
@layer_count = 2 # Start with 2 layers visible
|
|
41
|
+
@swapped = false
|
|
42
|
+
@clear = true
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def run
|
|
46
|
+
RatatuiRuby.run do |tui|
|
|
47
|
+
@tui = tui
|
|
48
|
+
loop do
|
|
49
|
+
tui.draw do |frame|
|
|
50
|
+
render(frame)
|
|
51
|
+
end
|
|
52
|
+
break if handle_input == :quit
|
|
53
|
+
sleep 0.05
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private def render(frame)
|
|
59
|
+
area = frame.area
|
|
60
|
+
|
|
61
|
+
# Split into main area and control panel
|
|
62
|
+
layout = @tui.layout_split(
|
|
63
|
+
area,
|
|
64
|
+
direction: :vertical,
|
|
65
|
+
constraints: [
|
|
66
|
+
@tui.constraint_fill(1),
|
|
67
|
+
@tui.constraint_length(5),
|
|
68
|
+
]
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
main_area = layout[0]
|
|
72
|
+
control_area = layout[1]
|
|
73
|
+
|
|
74
|
+
# Render background layer - RSS reader
|
|
75
|
+
frame.render_widget(background_layer, main_area)
|
|
76
|
+
|
|
77
|
+
# Render upper layers based on layer_count and swap state
|
|
78
|
+
if @swapped
|
|
79
|
+
render_beta_layer(frame, main_area) if @layer_count >= 2
|
|
80
|
+
render_notification_layer(frame, main_area) if @layer_count >= 1
|
|
81
|
+
else
|
|
82
|
+
render_notification_layer(frame, main_area) if @layer_count >= 1
|
|
83
|
+
render_beta_layer(frame, main_area) if @layer_count >= 2
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Render control panel
|
|
87
|
+
frame.render_widget(control_panel, control_area)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def background_layer
|
|
91
|
+
@background_layer ||= @tui.list(
|
|
92
|
+
items: HEADLINES,
|
|
93
|
+
block: @tui.block(
|
|
94
|
+
title: "RSS Reader",
|
|
95
|
+
borders: [:all]
|
|
96
|
+
)
|
|
97
|
+
)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def render_notification_layer(frame, area)
|
|
101
|
+
# Position modal: 20% from top, 60% height, 15% from left, 70% width
|
|
102
|
+
|
|
103
|
+
vertical_sections = @tui.layout_split(
|
|
104
|
+
area,
|
|
105
|
+
direction: :vertical,
|
|
106
|
+
constraints: [
|
|
107
|
+
@tui.constraint_fill(2),
|
|
108
|
+
@tui.constraint_fill(5),
|
|
109
|
+
@tui.constraint_fill(3),
|
|
110
|
+
]
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
horizontal_sections = @tui.layout_split(
|
|
114
|
+
vertical_sections[1],
|
|
115
|
+
direction: :horizontal,
|
|
116
|
+
constraints: [
|
|
117
|
+
@tui.constraint_fill(1),
|
|
118
|
+
@tui.constraint_fill(5),
|
|
119
|
+
@tui.constraint_fill(1),
|
|
120
|
+
]
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
modal_rect = horizontal_sections[1]
|
|
124
|
+
|
|
125
|
+
frame.render_widget(@tui.clear, modal_rect) if @clear
|
|
126
|
+
|
|
127
|
+
# Render the modal content
|
|
128
|
+
frame.render_widget(
|
|
129
|
+
@tui.paragraph(
|
|
130
|
+
text: "Your feeds have been updated",
|
|
131
|
+
wrap: true,
|
|
132
|
+
alignment: :center,
|
|
133
|
+
block: @tui.block(
|
|
134
|
+
title: "Notification",
|
|
135
|
+
borders: [:all],
|
|
136
|
+
border_style: @tui.style(fg: :black),
|
|
137
|
+
style: @tui.style(bg: :red, fg: :black)
|
|
138
|
+
)
|
|
139
|
+
),
|
|
140
|
+
modal_rect
|
|
141
|
+
)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def render_beta_layer(frame, area)
|
|
145
|
+
# Position modal: 30% from top, 40% height, 25% from left, 50% width
|
|
146
|
+
|
|
147
|
+
vertical_sections = @tui.layout_split(
|
|
148
|
+
area,
|
|
149
|
+
direction: :vertical,
|
|
150
|
+
constraints: [
|
|
151
|
+
@tui.constraint_fill(3),
|
|
152
|
+
@tui.constraint_fill(4),
|
|
153
|
+
@tui.constraint_fill(2),
|
|
154
|
+
]
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
horizontal_sections = @tui.layout_split(
|
|
158
|
+
vertical_sections[1],
|
|
159
|
+
direction: :horizontal,
|
|
160
|
+
constraints: [
|
|
161
|
+
@tui.constraint_fill(2),
|
|
162
|
+
@tui.constraint_fill(3),
|
|
163
|
+
@tui.constraint_fill(2),
|
|
164
|
+
]
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
modal_rect = horizontal_sections[1]
|
|
168
|
+
|
|
169
|
+
frame.render_widget(@tui.clear, modal_rect) if @clear
|
|
170
|
+
|
|
171
|
+
# Render the modal content
|
|
172
|
+
frame.render_widget(
|
|
173
|
+
beta_paragraph,
|
|
174
|
+
modal_rect
|
|
175
|
+
)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def beta_paragraph
|
|
179
|
+
@beta_paragraph ||= @tui.paragraph(
|
|
180
|
+
text: "Thank you for being a beta tester. To give feedback, shout very loudly and we will hear you. Be careful not to scare the llamas.",
|
|
181
|
+
wrap: true,
|
|
182
|
+
alignment: :left,
|
|
183
|
+
block: @tui.block(
|
|
184
|
+
title: "Beta Program",
|
|
185
|
+
borders: [:all],
|
|
186
|
+
border_style: @tui.style(fg: :black),
|
|
187
|
+
style: @tui.style(bg: :blue, fg: :black)
|
|
188
|
+
)
|
|
189
|
+
)
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def control_panel
|
|
193
|
+
bold_underline = @tui.style(modifiers: [:bold, :underlined])
|
|
194
|
+
|
|
195
|
+
first_controls = [
|
|
196
|
+
@tui.text_span(content: "0", style: bold_underline),
|
|
197
|
+
@tui.text_span(content: "/"),
|
|
198
|
+
@tui.text_span(content: "1", style: bold_underline),
|
|
199
|
+
@tui.text_span(content: "/"),
|
|
200
|
+
@tui.text_span(content: "2", style: bold_underline),
|
|
201
|
+
@tui.text_span(content: ": Change number of overlays | "),
|
|
202
|
+
@tui.text_span(content: "space", style: bold_underline),
|
|
203
|
+
@tui.text_span(content: ": Swap overlay order"),
|
|
204
|
+
]
|
|
205
|
+
second_controls = [
|
|
206
|
+
@tui.text_span(content: "c", style: bold_underline),
|
|
207
|
+
@tui.text_span(content: ": Toggle clear (currently #{@clear ? 'on' : 'off'})"),
|
|
208
|
+
]
|
|
209
|
+
third_controls = [
|
|
210
|
+
@tui.text_span(content: "q", style: bold_underline),
|
|
211
|
+
@tui.text_span(content: ": Quit"),
|
|
212
|
+
]
|
|
213
|
+
|
|
214
|
+
first = @tui.text_line(spans: first_controls)
|
|
215
|
+
second = @tui.text_line(spans: second_controls)
|
|
216
|
+
third = @tui.text_line(spans: third_controls)
|
|
217
|
+
|
|
218
|
+
@tui.paragraph(
|
|
219
|
+
text: [first, second, third],
|
|
220
|
+
alignment: :center,
|
|
221
|
+
block: @tui.block(
|
|
222
|
+
title: "Controls",
|
|
223
|
+
borders: [:all]
|
|
224
|
+
)
|
|
225
|
+
)
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def handle_input
|
|
229
|
+
case @tui.poll_event
|
|
230
|
+
in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
|
|
231
|
+
:quit
|
|
232
|
+
in { type: :key, code: "0" }
|
|
233
|
+
@layer_count = 0
|
|
234
|
+
in { type: :key, code: "1" }
|
|
235
|
+
@layer_count = 1
|
|
236
|
+
in { type: :key, code: "2" }
|
|
237
|
+
@layer_count = 2
|
|
238
|
+
in { type: :key, code: " " }
|
|
239
|
+
@swapped = !@swapped
|
|
240
|
+
in { type: :key, code: "c" }
|
|
241
|
+
@clear = !@clear
|
|
242
|
+
else
|
|
243
|
+
nil
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
WidgetOverlayDemo.new.run if __FILE__ == $PROGRAM_NAME
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
3
|
+
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
4
|
+
-->
|
|
5
|
+
|
|
6
|
+
# Popup (Clear) Widget Example
|
|
7
|
+
|
|
8
|
+
Demonstrates how to render opaque overlays on top of content.
|
|
9
|
+
|
|
10
|
+
Terminal renders are additive. If you draw a new widget over an old one, the background colors might mix if not handled correctly. The `Clear` widget resets the area to default (usually transparent/black) to ensure a clean canvas for popups.
|
|
11
|
+
|
|
12
|
+
## Features Demonstrated
|
|
13
|
+
|
|
14
|
+
- **The `Clear` Widget**: Printing spaces over an area to "erase" what was underneath.
|
|
15
|
+
- **Centering**: Using `Layout` constraints to perfectly center a block on screen.
|
|
16
|
+
- **Style Bleed**: showing what happens when you *don't* use `Clear` (background colors leak through).
|
|
17
|
+
|
|
18
|
+
## Hotkeys
|
|
19
|
+
|
|
20
|
+
- **Space**: Toggle Clear Widget (Observe the red background effect when disabled)
|
|
21
|
+
- **q**: Quit
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
ruby examples/widget_popup_demo/app.rb
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Learning Outcomes
|
|
30
|
+
|
|
31
|
+
Use this example if you need to...
|
|
32
|
+
- Create a modal dialog (Confirm, Alert, Form).
|
|
33
|
+
- Implement a dropdown menu that overlays other content.
|
|
34
|
+
- Fix visual artifacts where old text shows through new widgets.
|
|
35
|
+
|
|
36
|
+

|
|
@@ -0,0 +1,104 @@
|
|
|
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
|
+
# Popup Demo Example
|
|
10
|
+
# Demonstrates the Clear widget for creating opaque popups.
|
|
11
|
+
|
|
12
|
+
class WidgetPopupDemo
|
|
13
|
+
def initialize
|
|
14
|
+
@clear_enabled = false
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def run
|
|
18
|
+
RatatuiRuby.run do |tui|
|
|
19
|
+
loop do
|
|
20
|
+
tui.draw do |frame|
|
|
21
|
+
render(tui, frame)
|
|
22
|
+
end
|
|
23
|
+
break if handle_input(tui) == :quit
|
|
24
|
+
sleep 0.05
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private def render(tui, frame)
|
|
30
|
+
area = frame.area
|
|
31
|
+
|
|
32
|
+
# 1. Background: Loud Red Background
|
|
33
|
+
# This demonstrates "Style Bleed" where the background color persists
|
|
34
|
+
# unless explicitly cleared or overwritten.
|
|
35
|
+
background = tui.paragraph(
|
|
36
|
+
text: "BACKGROUND RED " * 100,
|
|
37
|
+
style: tui.style(bg: :red, fg: :white),
|
|
38
|
+
wrap: true
|
|
39
|
+
)
|
|
40
|
+
frame.render_widget(background, area)
|
|
41
|
+
|
|
42
|
+
# 2. Popup Area Calculation
|
|
43
|
+
# Center the popup vertically and horizontally
|
|
44
|
+
vertical_layout = tui.layout_split(
|
|
45
|
+
area,
|
|
46
|
+
direction: :vertical,
|
|
47
|
+
constraints: [
|
|
48
|
+
tui.constraint_percentage(25),
|
|
49
|
+
tui.constraint_percentage(50), # 50% height
|
|
50
|
+
tui.constraint_percentage(25),
|
|
51
|
+
]
|
|
52
|
+
)
|
|
53
|
+
popup_area_vertical = vertical_layout[1]
|
|
54
|
+
|
|
55
|
+
horizontal_layout = tui.layout_split(
|
|
56
|
+
popup_area_vertical,
|
|
57
|
+
direction: :horizontal,
|
|
58
|
+
constraints: [
|
|
59
|
+
tui.constraint_percentage(20),
|
|
60
|
+
tui.constraint_percentage(60), # 60% width
|
|
61
|
+
tui.constraint_percentage(20),
|
|
62
|
+
]
|
|
63
|
+
)
|
|
64
|
+
popup_area = horizontal_layout[1]
|
|
65
|
+
|
|
66
|
+
# 3. Popup Content
|
|
67
|
+
# Without Clear, this will "inherit" the red background from underneath.
|
|
68
|
+
popup_text = if @clear_enabled
|
|
69
|
+
"✓ Clear is ENABLED\n\nResets background to default\n(Usually Black/Transparent)\n\nPress Space to toggle"
|
|
70
|
+
else
|
|
71
|
+
"✗ Clear is DISABLED\n\nStyle Bleed: Popup is RED!\n(Inherits background style)\n\nPress Space to toggle"
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
popup_content = tui.paragraph(
|
|
75
|
+
text: popup_text,
|
|
76
|
+
alignment: :center,
|
|
77
|
+
block: tui.block(
|
|
78
|
+
title: "Popup Demo (q to quit, space to toggle)",
|
|
79
|
+
borders: [:all]
|
|
80
|
+
)
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
# 4. Render Popup
|
|
84
|
+
if @clear_enabled
|
|
85
|
+
# With Clear: Resets the style in the popup area before rendering content
|
|
86
|
+
frame.render_widget(tui.clear, popup_area)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
frame.render_widget(popup_content, popup_area)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
private def handle_input(tui)
|
|
93
|
+
case tui.poll_event
|
|
94
|
+
in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
|
|
95
|
+
:quit
|
|
96
|
+
in type: :key, code: " "
|
|
97
|
+
@clear_enabled = !@clear_enabled
|
|
98
|
+
else
|
|
99
|
+
nil
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
WidgetPopupDemo.new.run if __FILE__ == $0
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
3
|
+
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
4
|
+
-->
|
|
5
|
+
|
|
6
|
+
# Ratatui Logo Example
|
|
7
|
+
|
|
8
|
+
Demonstrates branding with the official logo widget.
|
|
9
|
+
|
|
10
|
+
A polished application often needs an "About" screen or a splash screen. This widget provides the standardized project branding.
|
|
11
|
+
|
|
12
|
+
## Features Demonstrated
|
|
13
|
+
|
|
14
|
+
- **RatatuiLogo Widget**: Renders the Ratatui ASCII art logo.
|
|
15
|
+
- **Centering**: Techniques for centering fixed-size content in a fluid layout.
|
|
16
|
+
|
|
17
|
+
## Hotkeys
|
|
18
|
+
|
|
19
|
+
- **q**: Quit
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
ruby examples/widget_ratatui_logo_demo/app.rb
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Learning Outcomes
|
|
28
|
+
|
|
29
|
+
Use this example if you need to...
|
|
30
|
+
- Create a splash screen.
|
|
31
|
+
- Add an "About" modal to your application.
|
|
32
|
+
- See how to center a widget both vertically and horizontally.
|
|
33
|
+
|
|
34
|
+

|
|
@@ -0,0 +1,103 @@
|
|
|
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
|
+
# Demonstrates branding visualization with the official logo.
|
|
11
|
+
#
|
|
12
|
+
# Branding is important for identity. Users need to recognize the tools they use.
|
|
13
|
+
#
|
|
14
|
+
# This demo showcases the <tt>RatatuiLogo</tt> widget. It renders the logo in a centered layout.
|
|
15
|
+
#
|
|
16
|
+
# Use it to understand how to incorporate the project's visual identity into your terminal application.
|
|
17
|
+
#
|
|
18
|
+
# === Example
|
|
19
|
+
#
|
|
20
|
+
# Run the demo from the terminal:
|
|
21
|
+
#
|
|
22
|
+
# ruby examples/widget_ratatui_logo_demo/app.rb
|
|
23
|
+
#
|
|
24
|
+
# rdoc-image:/doc/images/widget_ratatui_logo_demo.png
|
|
25
|
+
class WidgetRatatuiLogoDemo
|
|
26
|
+
def run
|
|
27
|
+
RatatuiRuby.run do |tui|
|
|
28
|
+
loop do
|
|
29
|
+
render(tui)
|
|
30
|
+
break if handle_input(tui) == :quit
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private def render(tui)
|
|
36
|
+
tui.draw do |frame|
|
|
37
|
+
# Layout
|
|
38
|
+
layout = tui.layout_split(
|
|
39
|
+
frame.area,
|
|
40
|
+
direction: :vertical,
|
|
41
|
+
constraints: [
|
|
42
|
+
tui.constraint_fill(1), # Fill remaining space
|
|
43
|
+
tui.constraint_length(3),
|
|
44
|
+
]
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
# Main Area
|
|
48
|
+
main_area = layout[0]
|
|
49
|
+
|
|
50
|
+
# Center the logo using nested Layouts
|
|
51
|
+
# Logo is roughly 47x8
|
|
52
|
+
# Vertical Center
|
|
53
|
+
v_center_layout = tui.layout_split(
|
|
54
|
+
main_area,
|
|
55
|
+
direction: :vertical,
|
|
56
|
+
flex: :center,
|
|
57
|
+
constraints: [tui.constraint_length(10)] # Height + margin
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
# Horizontal Center
|
|
61
|
+
h_center_layout = tui.layout_split(
|
|
62
|
+
v_center_layout[0],
|
|
63
|
+
direction: :horizontal,
|
|
64
|
+
flex: :center,
|
|
65
|
+
constraints: [tui.constraint_length(50)] # Width + margin
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
# Main content: The Logo
|
|
69
|
+
logo = RatatuiRuby::RatatuiLogo.new
|
|
70
|
+
frame.render_widget(logo, h_center_layout[0])
|
|
71
|
+
|
|
72
|
+
# Control Panel
|
|
73
|
+
control_area = layout[1]
|
|
74
|
+
|
|
75
|
+
control_text = tui.text_line(spans: [
|
|
76
|
+
tui.text_span(content: "q", style: tui.style(modifiers: [:bold, :underlined])),
|
|
77
|
+
tui.text_span(content: ": Quit"),
|
|
78
|
+
])
|
|
79
|
+
|
|
80
|
+
control_panel = tui.paragraph(
|
|
81
|
+
text: [control_text],
|
|
82
|
+
block: tui.block(
|
|
83
|
+
title: "Controls",
|
|
84
|
+
borders: [:top],
|
|
85
|
+
style: tui.style(fg: :dark_gray)
|
|
86
|
+
)
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
frame.render_widget(control_panel, control_area)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
private def handle_input(tui)
|
|
94
|
+
case tui.poll_event
|
|
95
|
+
in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
|
|
96
|
+
:quit
|
|
97
|
+
else
|
|
98
|
+
nil
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
WidgetRatatuiLogoDemo.new.run if __FILE__ == $0
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
3
|
+
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
4
|
+
-->
|
|
5
|
+
|
|
6
|
+
# Ratatui Mascot Example
|
|
7
|
+
|
|
8
|
+
Demonstrates the project mascot widget for adding personality.
|
|
9
|
+
|
|
10
|
+
Interfaces can feel clinical. A friendly mascot adds charm and brand identity to your terminal application.
|
|
11
|
+
|
|
12
|
+
## Features Demonstrated
|
|
13
|
+
|
|
14
|
+
- **RatatuiMascot Widget**: Renders the ASCII art mascot.
|
|
15
|
+
- **Block Integration**: Wrapping the mascot in a bordered block title.
|
|
16
|
+
|
|
17
|
+
## Hotkeys
|
|
18
|
+
|
|
19
|
+
- **b**: Toggle Block Border (`block`)
|
|
20
|
+
- **q**: Quit
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
ruby examples/widget_ratatui_mascot_demo/app.rb
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Learning Outcomes
|
|
29
|
+
|
|
30
|
+
Use this example if you need to...
|
|
31
|
+
- Add visual flair to your UI.
|
|
32
|
+
- Create a friendly empty state or success screen.
|
|
33
|
+
|
|
34
|
+

|