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,45 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
3
|
+
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
4
|
+
-->
|
|
5
|
+
|
|
6
|
+
# Box (Block) Widget Example
|
|
7
|
+
|
|
8
|
+
Demonstrates visual container attributes with interactive cycling.
|
|
9
|
+
|
|
10
|
+
Widgets often float in a void. Without boundaries, interfaces become a chaotic mess of text. `Block` (often called a Box) provides the structure and visual hierarchy needed to organize information.
|
|
11
|
+
|
|
12
|
+
## Features Demonstrated
|
|
13
|
+
|
|
14
|
+
- **Border Types**: Native styles like `:plain`, `:rounded`, `:double`, `:thick`.
|
|
15
|
+
- **Custom Borders**: defining completely custom character sets (e.g. using numbers or letters for borders).
|
|
16
|
+
- **Styling**: Independent control over border color, background style, and title style.
|
|
17
|
+
- **Positioning**: Placing titles on the `:top` or `:bottom` border (`position`).
|
|
18
|
+
- **Alignment**: Aligning titles to `:left`, `:center`, or `:right` (`alignment`).
|
|
19
|
+
|
|
20
|
+
## Hotkeys
|
|
21
|
+
|
|
22
|
+
- **Arrow Keys**: Change Border/Content Color
|
|
23
|
+
- **Space**: Cycle Border Type (`border_type`)
|
|
24
|
+
- **c**: Cycle Custom Border Set (`border_set`)
|
|
25
|
+
- **Enter**: Cycle Title Alignment (`title_alignment`)
|
|
26
|
+
- **s**: Cycle Content Style (`style`)
|
|
27
|
+
- **t**: Cycle Title Style (`title_style`)
|
|
28
|
+
- **b**: Cycle Border Style (`border_style`)
|
|
29
|
+
- **q**: Quit
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
ruby examples/widget_box_demo/app.rb
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Learning Outcomes
|
|
38
|
+
|
|
39
|
+
Use this example if you need to...
|
|
40
|
+
- Group related widgets together.
|
|
41
|
+
- Create distinct "panels" or "cards" in your UI.
|
|
42
|
+
- Style borders to indicate state (e.g., Red border for error state).
|
|
43
|
+
- Understand the difference between `style` (content) and `border_style` (frame).
|
|
44
|
+
|
|
45
|
+

|
|
@@ -6,7 +6,22 @@
|
|
|
6
6
|
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
7
7
|
require "ratatui_ruby"
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
# Demonstrates visual container attributes with interactive cycling.
|
|
10
|
+
#
|
|
11
|
+
# Widgets often float in void. Without boundaries, interfaces become a chaotic mess of text. Users need structure to parse information.
|
|
12
|
+
#
|
|
13
|
+
# This demo showcases the <tt>Block</tt> widget. It provides an interactive playground where you can cycle through different border types, colors, and title alignments in real-time.
|
|
14
|
+
#
|
|
15
|
+
# Use it to understand how to define distinct areas and create visual hierarchy in your terminal interface.
|
|
16
|
+
#
|
|
17
|
+
# === Example
|
|
18
|
+
#
|
|
19
|
+
# Run the demo from the terminal:
|
|
20
|
+
#
|
|
21
|
+
# ruby examples/widget_box_demo/app.rb
|
|
22
|
+
#
|
|
23
|
+
# rdoc-image:/doc/images/widget_box_demo.png
|
|
24
|
+
class WidgetBoxDemo
|
|
10
25
|
def initialize
|
|
11
26
|
# Border Types (ratatui native styles)
|
|
12
27
|
@border_types = [
|
|
@@ -15,7 +30,7 @@ class BoxDemoApp
|
|
|
15
30
|
{ name: "Double", type: :double },
|
|
16
31
|
{ name: "Thick", type: :thick },
|
|
17
32
|
{ name: "Quadrant Inside", type: :quadrant_inside },
|
|
18
|
-
{ name: "Quadrant Outside", type: :quadrant_outside }
|
|
33
|
+
{ name: "Quadrant Outside", type: :quadrant_outside },
|
|
19
34
|
]
|
|
20
35
|
@border_type_index = 0
|
|
21
36
|
|
|
@@ -23,14 +38,32 @@ class BoxDemoApp
|
|
|
23
38
|
# NOTE: We define these ONCE in initialize for efficiency.
|
|
24
39
|
@border_sets = [
|
|
25
40
|
{ name: "None", set: nil },
|
|
26
|
-
{
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
41
|
+
{
|
|
42
|
+
name: "Digits (Short)",
|
|
43
|
+
set: {
|
|
44
|
+
tl: "1",
|
|
45
|
+
tr: "2",
|
|
46
|
+
bl: "3",
|
|
47
|
+
br: "4",
|
|
48
|
+
vl: "5",
|
|
49
|
+
vr: "6",
|
|
50
|
+
ht: "7",
|
|
51
|
+
hb: "8",
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: "Letters (Long)",
|
|
56
|
+
set: {
|
|
57
|
+
top_left: "A",
|
|
58
|
+
top_right: "B",
|
|
59
|
+
bottom_left: "C",
|
|
60
|
+
bottom_right: "D",
|
|
61
|
+
vertical_left: "E",
|
|
62
|
+
vertical_right: "F",
|
|
63
|
+
horizontal_top: "G",
|
|
64
|
+
horizontal_bottom: "H",
|
|
65
|
+
},
|
|
66
|
+
},
|
|
34
67
|
]
|
|
35
68
|
@border_set_index = 0
|
|
36
69
|
|
|
@@ -39,26 +72,26 @@ class BoxDemoApp
|
|
|
39
72
|
{ name: "Red", color: "red" },
|
|
40
73
|
{ name: "Blue", color: "blue" },
|
|
41
74
|
{ name: "Yellow", color: "yellow" },
|
|
42
|
-
{ name: "Magenta", color: "magenta" }
|
|
75
|
+
{ name: "Magenta", color: "magenta" },
|
|
43
76
|
]
|
|
44
77
|
@color_index = 0
|
|
45
78
|
|
|
46
79
|
@title_alignments = [
|
|
47
80
|
{ name: "Left", alignment: :left },
|
|
48
81
|
{ name: "Center", alignment: :center },
|
|
49
|
-
{ name: "Right", alignment: :right }
|
|
82
|
+
{ name: "Right", alignment: :right },
|
|
50
83
|
]
|
|
51
84
|
@title_alignment_index = 0
|
|
52
85
|
|
|
53
86
|
@styles = [
|
|
54
87
|
{ name: "Default", style: nil },
|
|
55
|
-
{ name: "Blue on White", style: { fg: "blue", bg: "white", modifiers: [:bold] } }
|
|
88
|
+
{ name: "Blue on White", style: { fg: "blue", bg: "white", modifiers: [:bold] } },
|
|
56
89
|
]
|
|
57
90
|
@style_index = 0
|
|
58
91
|
|
|
59
92
|
@title_styles = [
|
|
60
93
|
{ name: "Default", style: nil },
|
|
61
|
-
{ name: "Yellow Bold Underlined", style: { fg: "yellow", modifiers: [:bold, :underlined] } }
|
|
94
|
+
{ name: "Yellow Bold Underlined", style: { fg: "yellow", modifiers: [:bold, :underlined] } },
|
|
62
95
|
]
|
|
63
96
|
@title_style_index = 0
|
|
64
97
|
|
|
@@ -66,15 +99,18 @@ class BoxDemoApp
|
|
|
66
99
|
{ name: "Default (no border style)", style: nil },
|
|
67
100
|
{ name: "Bold Red", style: { fg: "red", modifiers: [:bold] } },
|
|
68
101
|
{ name: "Cyan Italic", style: { fg: "cyan", modifiers: [:italic] } },
|
|
69
|
-
{ name: "Magenta Dim", style: { fg: "magenta", modifiers: [:dim] } }
|
|
102
|
+
{ name: "Magenta Dim", style: { fg: "magenta", modifiers: [:dim] } },
|
|
70
103
|
]
|
|
71
104
|
@border_style_index = 0
|
|
72
105
|
|
|
73
|
-
@hotkey_style =
|
|
106
|
+
@hotkey_style = nil # Initialized in run when tui is available
|
|
74
107
|
end
|
|
75
108
|
|
|
76
109
|
def run
|
|
77
|
-
RatatuiRuby.run do
|
|
110
|
+
RatatuiRuby.run do |tui|
|
|
111
|
+
@tui = tui
|
|
112
|
+
@hotkey_style = tui.style(modifiers: [:bold, :underlined])
|
|
113
|
+
|
|
78
114
|
loop do
|
|
79
115
|
render
|
|
80
116
|
break if handle_input == :quit
|
|
@@ -82,13 +118,11 @@ class BoxDemoApp
|
|
|
82
118
|
end
|
|
83
119
|
end
|
|
84
120
|
|
|
85
|
-
private
|
|
86
|
-
|
|
87
|
-
def render
|
|
121
|
+
private def render
|
|
88
122
|
# Get current values
|
|
89
123
|
border_type_config = @border_types[@border_type_index]
|
|
90
124
|
border_set_config = @border_sets[@border_set_index]
|
|
91
|
-
|
|
125
|
+
|
|
92
126
|
color_config = @colors[@color_index]
|
|
93
127
|
title_alignment_config = @title_alignments[@title_alignment_index]
|
|
94
128
|
style_config = @styles[@style_index]
|
|
@@ -106,7 +140,7 @@ class BoxDemoApp
|
|
|
106
140
|
type_display += " (Overridden)"
|
|
107
141
|
end
|
|
108
142
|
|
|
109
|
-
block =
|
|
143
|
+
block = @tui.block(
|
|
110
144
|
title: "Box Demo",
|
|
111
145
|
title_alignment: title_alignment_config[:alignment],
|
|
112
146
|
title_style: title_style_config[:style],
|
|
@@ -119,72 +153,73 @@ class BoxDemoApp
|
|
|
119
153
|
)
|
|
120
154
|
|
|
121
155
|
# Main content
|
|
122
|
-
main_panel =
|
|
156
|
+
main_panel = @tui.paragraph(
|
|
123
157
|
text: "Arrow Keys: Change Color\n\nCurrent Color: #{color_config[:name]}",
|
|
124
|
-
block
|
|
158
|
+
block:,
|
|
125
159
|
fg: style_config[:style] ? nil : color_config[:color],
|
|
126
160
|
style: style_config[:style],
|
|
127
161
|
alignment: :center
|
|
128
162
|
)
|
|
129
163
|
|
|
130
164
|
# Bottom control panel
|
|
131
|
-
control_panel =
|
|
165
|
+
control_panel = @tui.block(
|
|
132
166
|
title: "Controls",
|
|
133
167
|
borders: [:all],
|
|
134
168
|
children: [
|
|
135
|
-
|
|
169
|
+
@tui.paragraph(
|
|
136
170
|
text: [
|
|
137
171
|
# Line 1: Main Controls
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
172
|
+
@tui.text_line(spans: [
|
|
173
|
+
@tui.text_span(content: "↑↓←→", style: @hotkey_style),
|
|
174
|
+
@tui.text_span(content: ": Color (#{color_config[:name]}) "),
|
|
175
|
+
@tui.text_span(content: "q", style: @hotkey_style),
|
|
176
|
+
@tui.text_span(content: ": Quit"),
|
|
143
177
|
]),
|
|
144
178
|
# Line 2: Borders
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
179
|
+
@tui.text_line(spans: [
|
|
180
|
+
@tui.text_span(content: "space", style: @hotkey_style),
|
|
181
|
+
@tui.text_span(content: ": Border Type (#{type_display}) "),
|
|
182
|
+
@tui.text_span(content: "c", style: @hotkey_style),
|
|
183
|
+
@tui.text_span(content: ": Border Set (#{border_set_config[:name]})"),
|
|
150
184
|
]),
|
|
151
185
|
# Line 3: Styles
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
186
|
+
@tui.text_line(spans: [
|
|
187
|
+
@tui.text_span(content: "s", style: @hotkey_style),
|
|
188
|
+
@tui.text_span(content: ": Style (#{style_config[:name]}) "),
|
|
189
|
+
@tui.text_span(content: "b", style: @hotkey_style),
|
|
190
|
+
@tui.text_span(content: ": Border Style (#{border_style_config[:name]})"),
|
|
157
191
|
]),
|
|
158
192
|
# Line 4: Title
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
])
|
|
193
|
+
@tui.text_line(spans: [
|
|
194
|
+
@tui.text_span(content: "enter", style: @hotkey_style),
|
|
195
|
+
@tui.text_span(content: ": Align Title (#{title_alignment_config[:name]}) "),
|
|
196
|
+
@tui.text_span(content: "t", style: @hotkey_style),
|
|
197
|
+
@tui.text_span(content: ": Title Style (#{title_style_config[:name]})"),
|
|
198
|
+
]),
|
|
165
199
|
]
|
|
166
|
-
)
|
|
200
|
+
),
|
|
167
201
|
]
|
|
168
202
|
)
|
|
169
203
|
|
|
170
|
-
#
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
204
|
+
# 2. Render with Frame API
|
|
205
|
+
@tui.draw do |frame|
|
|
206
|
+
main_rect, control_rect = @tui.layout_split(
|
|
207
|
+
frame.area,
|
|
208
|
+
direction: :vertical,
|
|
209
|
+
constraints: [
|
|
210
|
+
@tui.constraint_fill(1),
|
|
211
|
+
@tui.constraint_length(6),
|
|
212
|
+
]
|
|
213
|
+
)
|
|
214
|
+
frame.render_widget(main_panel, main_rect)
|
|
215
|
+
frame.render_widget(control_panel, control_rect)
|
|
216
|
+
end
|
|
182
217
|
end
|
|
183
218
|
|
|
184
|
-
def handle_input
|
|
219
|
+
private def handle_input
|
|
185
220
|
# 3. Events
|
|
186
|
-
case
|
|
187
|
-
in {type: :key, code: "q"} | {type: :key, code: "c", modifiers: ["ctrl"]}
|
|
221
|
+
case @tui.poll_event
|
|
222
|
+
in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
|
|
188
223
|
:quit
|
|
189
224
|
in type: :key, code: "up"
|
|
190
225
|
@color_index = (@color_index - 1) % @colors.size
|
|
@@ -212,5 +247,4 @@ class BoxDemoApp
|
|
|
212
247
|
end
|
|
213
248
|
end
|
|
214
249
|
|
|
215
|
-
|
|
216
|
-
|
|
250
|
+
WidgetBoxDemo.new.run if __FILE__ == $0
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
3
|
+
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
4
|
+
-->
|
|
5
|
+
|
|
6
|
+
# Calendar Widget Example
|
|
7
|
+
|
|
8
|
+
Demonstrates a monthly calendar with customizable headers and event highlighting.
|
|
9
|
+
|
|
10
|
+
Rendering dates in a grid involves complex calculations for leap years and weekday offsets. This widget handles that logic, letting you focus on displaying dates.
|
|
11
|
+
|
|
12
|
+
## Features Demonstrated
|
|
13
|
+
|
|
14
|
+
- **Headers**: Toggling the Month name and Weekday labels.
|
|
15
|
+
- **Surrounding Days**: displaying (or hiding/dimming) days from the previous and next months to fill the grid.
|
|
16
|
+
- **Event Styling**: applying specific styles to individual `Time` or `Date` objects to highlight events.
|
|
17
|
+
|
|
18
|
+
## Hotkeys
|
|
19
|
+
|
|
20
|
+
- **h**: Toggle Month Header (`show_month_header`)
|
|
21
|
+
- **w**: Toggle Weekday Labels (`show_weekdays_header`)
|
|
22
|
+
- **s**: Toggle Surrounding Days (`show_surrounding`)
|
|
23
|
+
- **e**: Toggle Example Events (`events`)
|
|
24
|
+
- **q**: Quit
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
ruby examples/widget_calendar_demo/app.rb
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Learning Outcomes
|
|
33
|
+
|
|
34
|
+
Use this example if you need to...
|
|
35
|
+
- Display a date picker.
|
|
36
|
+
- Show a schedule or timeline view.
|
|
37
|
+
- Highlight specific dates (deadlines, holidays) on a calendar grid.
|
|
38
|
+
|
|
39
|
+

|
|
@@ -0,0 +1,109 @@
|
|
|
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 monthly calendar attributes with interactive cycling.
|
|
10
|
+
#
|
|
11
|
+
# Dates are complex. Rendering them in a grid requires calculation of leap years, month lengths, and day-of-week offsets.
|
|
12
|
+
# Use this widget to skip the boilerplate.
|
|
13
|
+
#
|
|
14
|
+
# This demo showcases the <tt>Calendar</tt> widget. It provides an interactive playground where you can toggle headers, weekday labels, and event highlights in real-time.
|
|
15
|
+
#
|
|
16
|
+
# Use it to understand how to render time-based data grids efficiently.
|
|
17
|
+
#
|
|
18
|
+
# === Example
|
|
19
|
+
#
|
|
20
|
+
# Run the demo from the terminal:
|
|
21
|
+
#
|
|
22
|
+
# ruby examples/widget_calendar_demo/app.rb
|
|
23
|
+
#
|
|
24
|
+
# rdoc-image:/doc/images/widget_calendar_demo.png
|
|
25
|
+
class WidgetCalendarDemo
|
|
26
|
+
def run
|
|
27
|
+
RatatuiRuby.run do |tui|
|
|
28
|
+
show_header = true
|
|
29
|
+
show_weekdays = true
|
|
30
|
+
show_surrounding = false
|
|
31
|
+
show_events = true
|
|
32
|
+
hotkey_style = tui.style(modifiers: [:bold])
|
|
33
|
+
|
|
34
|
+
loop do
|
|
35
|
+
now = Time.now
|
|
36
|
+
surrounding_style = show_surrounding ? tui.style(fg: "gray", modifiers: [:dim]) : nil
|
|
37
|
+
|
|
38
|
+
events_map = if show_events
|
|
39
|
+
{
|
|
40
|
+
now => tui.style(fg: "green", modifiers: [:bold]),
|
|
41
|
+
(now + (86400 * 2)) => tui.style(fg: "red", modifiers: [:underlined]),
|
|
42
|
+
(now - (86400 * 5)) => tui.style(fg: "blue", bg: "white"),
|
|
43
|
+
}
|
|
44
|
+
else
|
|
45
|
+
{}
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
calendar = tui.calendar(
|
|
49
|
+
year: now.year,
|
|
50
|
+
month: now.month,
|
|
51
|
+
events: events_map,
|
|
52
|
+
header_style: tui.style(fg: "yellow", modifiers: [:bold]),
|
|
53
|
+
show_month_header: show_header,
|
|
54
|
+
show_weekdays_header: show_weekdays,
|
|
55
|
+
show_surrounding: surrounding_style,
|
|
56
|
+
block: tui.block(borders: [:top, :left, :right])
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
controls = tui.paragraph(
|
|
60
|
+
text: [
|
|
61
|
+
tui.text_line(spans: [
|
|
62
|
+
tui.text_span(content: " h/w/s/e", style: hotkey_style),
|
|
63
|
+
tui.text_span(content: ": Toggle Header/Weekdays/Surrounding/Events "),
|
|
64
|
+
tui.text_span(content: "q", style: hotkey_style),
|
|
65
|
+
tui.text_span(content: ": Quit"),
|
|
66
|
+
]),
|
|
67
|
+
tui.text_line(spans: [
|
|
68
|
+
tui.text_span(content: " Events: ", style: hotkey_style),
|
|
69
|
+
tui.text_span(content: "Today (Green), +2d (Red), -5d (Blue) (#{show_events ? 'On' : 'Off'})"),
|
|
70
|
+
]),
|
|
71
|
+
],
|
|
72
|
+
block: tui.block(title: " Controls ", borders: [:all])
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
tui.draw do |frame|
|
|
76
|
+
calendar_area, controls_area = tui.layout_split(
|
|
77
|
+
frame.area,
|
|
78
|
+
direction: :vertical,
|
|
79
|
+
constraints: [
|
|
80
|
+
tui.constraint_min(0),
|
|
81
|
+
tui.constraint_length(4),
|
|
82
|
+
]
|
|
83
|
+
)
|
|
84
|
+
frame.render_widget(calendar, calendar_area)
|
|
85
|
+
frame.render_widget(controls, controls_area)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
case tui.poll_event
|
|
89
|
+
in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
|
|
90
|
+
break
|
|
91
|
+
in type: :key, code: "h"
|
|
92
|
+
show_header = !show_header
|
|
93
|
+
in type: :key, code: "w"
|
|
94
|
+
show_weekdays = !show_weekdays
|
|
95
|
+
in type: :key, code: "s"
|
|
96
|
+
show_surrounding = !show_surrounding
|
|
97
|
+
in type: :key, code: "e"
|
|
98
|
+
show_events = !show_events
|
|
99
|
+
else
|
|
100
|
+
nil
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
sleep 0.05
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
WidgetCalendarDemo.new.run if __FILE__ == $PROGRAM_NAME
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Canvas 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 `Canvas` widget, which provides a high-resolution drawing surface using Braille characters.
|
|
8
|
+
|
|
9
|
+
## Key Concepts
|
|
10
|
+
|
|
11
|
+
- **Shapes**: Supports `Point`, `Line`, `Rectangle`, `Circle`, and `Map`.
|
|
12
|
+
- **Coordinates**: Uses a float-based coordinate system independent of terminal cells.
|
|
13
|
+
- **Markers**: Can use Braille (high res) or block characters (lower res) for rendering.
|
|
14
|
+
|
|
15
|
+
## Controls
|
|
16
|
+
|
|
17
|
+
| Key | Action |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| `q` | Quit |
|
|
20
|
+
|
|
21
|
+
## Screenshot
|
|
22
|
+
|
|
23
|
+

|
|
24
|
+
|
|
25
|
+
## Source Code
|
|
26
|
+
|
|
27
|
+
- [app.rb](app.rb)
|
|
@@ -0,0 +1,123 @@
|
|
|
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: Canvas Widget
|
|
10
|
+
# Demonstrates how to draw geometric shapes (Points, Lines, Rects, Circles)
|
|
11
|
+
# on a high-resolution canvas.
|
|
12
|
+
class WidgetCanvasDemo
|
|
13
|
+
def initialize
|
|
14
|
+
@x_offset = 0.0
|
|
15
|
+
@y_offset = 0.0
|
|
16
|
+
@time = 0.0
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def run
|
|
20
|
+
RatatuiRuby.run do |tui|
|
|
21
|
+
@tui = tui
|
|
22
|
+
loop do
|
|
23
|
+
# Animate
|
|
24
|
+
@time += 0.1
|
|
25
|
+
@x_offset = Math.sin(@time) * 20.0
|
|
26
|
+
@y_offset = Math.cos(@time) * 20.0
|
|
27
|
+
|
|
28
|
+
render
|
|
29
|
+
break if handle_input == :quit
|
|
30
|
+
|
|
31
|
+
sleep 0.05
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private def render
|
|
37
|
+
@tui.draw do |frame|
|
|
38
|
+
# Define shapes
|
|
39
|
+
shapes = []
|
|
40
|
+
|
|
41
|
+
# 1. Static Grid (Lines)
|
|
42
|
+
(-100..100).step(20) do |i|
|
|
43
|
+
shapes << @tui.shape_line(x1: i.to_f, y1: -100.0, x2: i.to_f, y2: 100.0, color: :gray)
|
|
44
|
+
shapes << @tui.shape_line(x1: -100.0, y1: i.to_f, x2: 100.0, y2: i.to_f, color: :gray)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# 2. Moving Circle (The "Player")
|
|
48
|
+
shapes << @tui.shape_circle(
|
|
49
|
+
x: @x_offset,
|
|
50
|
+
y: @y_offset,
|
|
51
|
+
radius: 10.0,
|
|
52
|
+
color: :green
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# 3. Static Rectangle (Target)
|
|
56
|
+
shapes << @tui.shape_rectangle(
|
|
57
|
+
x: 30.0,
|
|
58
|
+
y: 30.0,
|
|
59
|
+
width: 20.0,
|
|
60
|
+
height: 20.0,
|
|
61
|
+
color: :red
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# 4. Points (Starfield)
|
|
65
|
+
# Deterministic "random" points
|
|
66
|
+
10.times do |i|
|
|
67
|
+
shapes << @tui.shape_point(
|
|
68
|
+
x: ((i * 37) % 200) - 100.0,
|
|
69
|
+
y: ((i * 19) % 200) - 100.0
|
|
70
|
+
)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# 5. Label
|
|
74
|
+
shapes << @tui.shape_line(x1: 0.0, y1: 0.0, x2: @x_offset, y2: @y_offset, color: :yellow)
|
|
75
|
+
|
|
76
|
+
canvas = @tui.canvas(
|
|
77
|
+
shapes:,
|
|
78
|
+
x_bounds: [-100.0, 100.0],
|
|
79
|
+
y_bounds: [-100.0, 100.0],
|
|
80
|
+
marker: :braille,
|
|
81
|
+
block: @tui.block(title: "Canvas Demo", borders: [:all])
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
# Main area for canvas
|
|
85
|
+
layout = @tui.layout_split(
|
|
86
|
+
frame.area,
|
|
87
|
+
direction: :vertical,
|
|
88
|
+
constraints: [
|
|
89
|
+
@tui.constraint_fill(1),
|
|
90
|
+
@tui.constraint_length(3),
|
|
91
|
+
]
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
frame.render_widget(canvas, layout[0])
|
|
95
|
+
|
|
96
|
+
# Controls
|
|
97
|
+
controls = @tui.paragraph(
|
|
98
|
+
text: [
|
|
99
|
+
@tui.text_line(spans: [
|
|
100
|
+
@tui.text_span(content: "Canvas auto-animates.", style: @tui.style(fg: :yellow)),
|
|
101
|
+
]),
|
|
102
|
+
@tui.text_line(spans: [
|
|
103
|
+
@tui.text_span(content: "q", style: @tui.style(modifiers: [:bold, :underlined])),
|
|
104
|
+
@tui.text_span(content: ": Quit"),
|
|
105
|
+
]),
|
|
106
|
+
],
|
|
107
|
+
block: @tui.block(borders: [:top])
|
|
108
|
+
)
|
|
109
|
+
frame.render_widget(controls, layout[1])
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def handle_input
|
|
114
|
+
case @tui.poll_event
|
|
115
|
+
in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
|
|
116
|
+
:quit
|
|
117
|
+
else
|
|
118
|
+
# Ignore other events
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
WidgetCanvasDemo.new.run if __FILE__ == $0
|
|
@@ -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
|
+
# Cell Widget Example
|
|
7
|
+
|
|
8
|
+
Demonstrates using `Cell` objects for granular control over individual character grid units.
|
|
9
|
+
|
|
10
|
+
Sometimes you need to render specific characters with unique styles outside of standard widgets. The `Cell` primitive allows you to build custom widgets or inject styled content into Tables.
|
|
11
|
+
|
|
12
|
+
## Features Demonstrated
|
|
13
|
+
|
|
14
|
+
- **Custom Widgets**: A `CheckeredBackground` widget built by rendering `Cell`s in a loop.
|
|
15
|
+
- **Table Integration**: Mixing simple Strings and rich `Cell` objects in a Table row.
|
|
16
|
+
- **Overlays**: Using `RatatuiRuby::Overlay` to stack widgets on top of each other.
|
|
17
|
+
- **Modifiers**: Using `rapid_blink`, `bold`, and `dim` on individual cells.
|
|
18
|
+
|
|
19
|
+
## Hotkeys
|
|
20
|
+
|
|
21
|
+
- **q** / **Ctrl+c**: Quit
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
ruby examples/widget_cell_demo/app.rb
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Learning Outcomes
|
|
30
|
+
|
|
31
|
+
Use this example if you need to...
|
|
32
|
+
- Create a custom widget (like a game board or specialized graph).
|
|
33
|
+
- Style specific cells in a Table (e.g., Green "OK", Red "FAIL").
|
|
34
|
+
- Understand how to position content precisely with `Cell`.
|
|
35
|
+
|
|
36
|
+

|