ratatui_ruby 0.3.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.builds/ruby-3.2.yml +14 -12
- data/.builds/ruby-3.3.yml +14 -12
- data/.builds/ruby-3.4.yml +14 -12
- data/.builds/ruby-4.0.0.yml +14 -12
- data/AGENTS.md +89 -132
- data/CHANGELOG.md +223 -1
- data/README.md +23 -16
- data/REUSE.toml +20 -0
- data/doc/application_architecture.md +176 -0
- data/doc/application_testing.md +17 -10
- data/doc/contributors/design/ruby_frontend.md +11 -7
- data/doc/contributors/developing_examples.md +261 -0
- data/doc/contributors/documentation_style.md +104 -0
- data/doc/contributors/dwim_dx.md +366 -0
- data/doc/contributors/index.md +2 -0
- data/doc/custom.css +14 -0
- data/doc/event_handling.md +125 -0
- data/doc/images/app_all_events.png +0 -0
- data/doc/images/app_analytics.png +0 -0
- data/doc/images/app_color_picker.png +0 -0
- data/doc/images/app_custom_widget.png +0 -0
- data/doc/images/app_login_form.png +0 -0
- data/doc/images/app_map_demo.png +0 -0
- data/doc/images/app_mouse_events.png +0 -0
- data/doc/images/app_table_select.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_padding.png +0 -0
- data/doc/images/widget_block_titles.png +0 -0
- data/doc/images/widget_box_demo.png +0 -0
- data/doc/images/widget_calendar_demo.png +0 -0
- data/doc/images/widget_cell_demo.png +0 -0
- data/doc/images/widget_chart_demo.png +0 -0
- data/doc/images/widget_gauge_demo.png +0 -0
- data/doc/images/widget_layout_split.png +0 -0
- data/doc/images/widget_line_gauge_demo.png +0 -0
- data/doc/images/widget_list_demo.png +0 -0
- data/doc/images/widget_list_styles.png +0 -0
- data/doc/images/widget_popup_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_rect.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_flex.png +0 -0
- data/doc/images/widget_tabs_demo.png +0 -0
- data/doc/index.md +1 -0
- data/doc/interactive_design.md +116 -0
- data/doc/quickstart.md +186 -84
- data/examples/app_all_events/README.md +81 -0
- data/examples/app_all_events/app.rb +93 -0
- data/examples/app_all_events/model/event_color_cycle.rb +41 -0
- data/examples/app_all_events/model/event_entry.rb +75 -0
- data/examples/app_all_events/model/events.rb +180 -0
- data/examples/app_all_events/model/highlight.rb +57 -0
- data/examples/app_all_events/model/timestamp.rb +54 -0
- data/examples/app_all_events/test/snapshots/after_focus_lost.txt +24 -0
- data/examples/app_all_events/test/snapshots/after_focus_regained.txt +24 -0
- data/examples/app_all_events/test/snapshots/after_horizontal_resize.txt +24 -0
- data/examples/app_all_events/test/snapshots/after_key_a.txt +24 -0
- data/examples/app_all_events/test/snapshots/after_key_ctrl_x.txt +24 -0
- data/examples/app_all_events/test/snapshots/after_mouse_click.txt +24 -0
- data/examples/app_all_events/test/snapshots/after_mouse_drag.txt +24 -0
- data/examples/app_all_events/test/snapshots/after_multiple_events.txt +24 -0
- data/examples/app_all_events/test/snapshots/after_paste.txt +24 -0
- data/examples/app_all_events/test/snapshots/after_resize.txt +24 -0
- data/examples/app_all_events/test/snapshots/after_right_click.txt +24 -0
- data/examples/app_all_events/test/snapshots/after_vertical_resize.txt +24 -0
- data/examples/app_all_events/test/snapshots/initial_state.txt +24 -0
- data/examples/app_all_events/view/app_view.rb +78 -0
- data/examples/app_all_events/view/controls_view.rb +50 -0
- data/examples/app_all_events/view/counts_view.rb +55 -0
- data/examples/app_all_events/view/live_view.rb +69 -0
- data/examples/app_all_events/view/log_view.rb +60 -0
- data/{lib/ratatui_ruby/output.rb → examples/app_all_events/view.rb} +1 -1
- data/examples/app_all_events/view_state.rb +42 -0
- data/examples/app_color_picker/README.md +94 -0
- data/examples/app_color_picker/app.rb +112 -0
- data/examples/app_color_picker/clipboard.rb +84 -0
- data/examples/app_color_picker/color.rb +191 -0
- data/examples/app_color_picker/copy_dialog.rb +170 -0
- data/examples/app_color_picker/harmony.rb +56 -0
- data/examples/app_color_picker/input.rb +142 -0
- data/examples/app_color_picker/palette.rb +80 -0
- data/examples/app_color_picker/scene.rb +201 -0
- data/examples/app_login_form/app.rb +108 -0
- data/examples/app_map_demo/app.rb +93 -0
- data/examples/app_table_select/app.rb +201 -0
- data/examples/verify_quickstart_dsl/app.rb +45 -0
- data/examples/verify_quickstart_layout/app.rb +69 -0
- data/examples/verify_quickstart_lifecycle/app.rb +48 -0
- data/examples/verify_readme_usage/app.rb +34 -0
- data/examples/widget_barchart_demo/app.rb +238 -0
- data/examples/widget_block_padding/app.rb +67 -0
- data/examples/widget_block_titles/app.rb +69 -0
- data/examples/widget_box_demo/app.rb +250 -0
- data/examples/widget_calendar_demo/app.rb +109 -0
- data/examples/widget_cell_demo/app.rb +104 -0
- data/examples/widget_chart_demo/app.rb +213 -0
- data/examples/widget_gauge_demo/app.rb +212 -0
- data/examples/widget_layout_split/app.rb +246 -0
- data/examples/widget_line_gauge_demo/app.rb +217 -0
- data/examples/widget_list_demo/app.rb +382 -0
- data/examples/widget_list_styles/app.rb +141 -0
- data/examples/widget_popup_demo/app.rb +104 -0
- data/examples/widget_ratatui_logo_demo/app.rb +103 -0
- data/examples/widget_ratatui_mascot_demo/app.rb +93 -0
- data/examples/widget_rect/app.rb +205 -0
- data/examples/widget_render/app.rb +184 -0
- data/examples/widget_rich_text/app.rb +137 -0
- data/examples/widget_scroll_text/app.rb +108 -0
- data/examples/widget_scrollbar_demo/app.rb +153 -0
- data/examples/widget_sparkline_demo/app.rb +274 -0
- data/examples/widget_style_colors/app.rb +102 -0
- data/examples/widget_table_flex/app.rb +95 -0
- data/examples/widget_tabs_demo/app.rb +167 -0
- data/ext/ratatui_ruby/Cargo.lock +889 -115
- data/ext/ratatui_ruby/Cargo.toml +4 -3
- data/ext/ratatui_ruby/clippy.toml +7 -0
- data/ext/ratatui_ruby/extconf.rb +7 -0
- data/ext/ratatui_ruby/src/events.rs +293 -219
- data/ext/ratatui_ruby/src/frame.rs +115 -0
- data/ext/ratatui_ruby/src/lib.rs +105 -24
- data/ext/ratatui_ruby/src/rendering.rs +94 -10
- data/ext/ratatui_ruby/src/style.rs +357 -93
- data/ext/ratatui_ruby/src/terminal.rs +121 -31
- data/ext/ratatui_ruby/src/text.rs +178 -0
- data/ext/ratatui_ruby/src/widgets/barchart.rs +99 -24
- data/ext/ratatui_ruby/src/widgets/block.rs +32 -3
- data/ext/ratatui_ruby/src/widgets/calendar.rs +45 -44
- data/ext/ratatui_ruby/src/widgets/canvas.rs +44 -9
- data/ext/ratatui_ruby/src/widgets/chart.rs +79 -27
- data/ext/ratatui_ruby/src/widgets/clear.rs +3 -1
- data/ext/ratatui_ruby/src/widgets/gauge.rs +11 -4
- data/ext/ratatui_ruby/src/widgets/layout.rs +223 -15
- data/ext/ratatui_ruby/src/widgets/line_gauge.rs +92 -0
- data/ext/ratatui_ruby/src/widgets/list.rs +114 -11
- data/ext/ratatui_ruby/src/widgets/mod.rs +3 -0
- data/ext/ratatui_ruby/src/widgets/overlay.rs +4 -2
- data/ext/ratatui_ruby/src/widgets/paragraph.rs +35 -13
- data/ext/ratatui_ruby/src/widgets/ratatui_logo.rs +40 -0
- data/ext/ratatui_ruby/src/widgets/ratatui_mascot.rs +51 -0
- data/ext/ratatui_ruby/src/widgets/scrollbar.rs +61 -7
- data/ext/ratatui_ruby/src/widgets/sparkline.rs +73 -6
- data/ext/ratatui_ruby/src/widgets/table.rs +177 -64
- data/ext/ratatui_ruby/src/widgets/tabs.rs +105 -5
- data/lib/ratatui_ruby/cell.rb +166 -0
- data/lib/ratatui_ruby/event/focus_gained.rb +49 -0
- data/lib/ratatui_ruby/event/focus_lost.rb +50 -0
- data/lib/ratatui_ruby/event/key.rb +211 -0
- data/lib/ratatui_ruby/event/mouse.rb +124 -0
- data/lib/ratatui_ruby/event/none.rb +43 -0
- data/lib/ratatui_ruby/event/paste.rb +71 -0
- data/lib/ratatui_ruby/event/resize.rb +80 -0
- data/lib/ratatui_ruby/event.rb +131 -0
- data/lib/ratatui_ruby/frame.rb +87 -0
- data/lib/ratatui_ruby/schema/bar_chart/bar.rb +45 -0
- data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +23 -0
- data/lib/ratatui_ruby/schema/bar_chart.rb +226 -17
- data/lib/ratatui_ruby/schema/block.rb +178 -11
- data/lib/ratatui_ruby/schema/calendar.rb +70 -14
- data/lib/ratatui_ruby/schema/canvas.rb +213 -46
- data/lib/ratatui_ruby/schema/center.rb +46 -8
- data/lib/ratatui_ruby/schema/chart.rb +134 -32
- data/lib/ratatui_ruby/schema/clear.rb +22 -53
- data/lib/ratatui_ruby/schema/constraint.rb +72 -12
- data/lib/ratatui_ruby/schema/cursor.rb +23 -5
- data/lib/ratatui_ruby/schema/draw.rb +53 -0
- data/lib/ratatui_ruby/schema/gauge.rb +56 -12
- data/lib/ratatui_ruby/schema/layout.rb +91 -9
- data/lib/ratatui_ruby/schema/line_gauge.rb +78 -0
- data/lib/ratatui_ruby/schema/list.rb +92 -16
- data/lib/ratatui_ruby/schema/overlay.rb +29 -3
- data/lib/ratatui_ruby/schema/paragraph.rb +82 -25
- data/lib/ratatui_ruby/schema/ratatui_logo.rb +29 -0
- data/lib/ratatui_ruby/schema/ratatui_mascot.rb +34 -0
- data/lib/ratatui_ruby/schema/rect.rb +59 -10
- data/lib/ratatui_ruby/schema/scrollbar.rb +127 -19
- data/lib/ratatui_ruby/schema/shape/label.rb +66 -0
- data/lib/ratatui_ruby/schema/sparkline.rb +120 -12
- data/lib/ratatui_ruby/schema/style.rb +39 -11
- data/lib/ratatui_ruby/schema/table.rb +109 -18
- data/lib/ratatui_ruby/schema/tabs.rb +71 -10
- data/lib/ratatui_ruby/schema/text.rb +90 -0
- data/lib/ratatui_ruby/session/autodoc.rb +417 -0
- data/lib/ratatui_ruby/session.rb +163 -0
- data/lib/ratatui_ruby/test_helper.rb +322 -13
- data/lib/ratatui_ruby/version.rb +1 -1
- data/lib/ratatui_ruby.rb +184 -38
- data/sig/examples/app_all_events/app.rbs +11 -0
- 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/sig/examples/app_color_picker/app.rbs +12 -0
- data/sig/examples/app_login_form/app.rbs +11 -0
- data/sig/examples/app_map_demo/app.rbs +11 -0
- data/sig/examples/app_table_select/app.rbs +11 -0
- data/sig/examples/verify_quickstart_dsl/app.rbs +11 -0
- data/sig/examples/verify_quickstart_lifecycle/app.rbs +11 -0
- data/sig/examples/verify_readme_usage/app.rbs +11 -0
- data/sig/examples/widget_block_padding/app.rbs +11 -0
- data/sig/examples/widget_block_titles/app.rbs +11 -0
- data/sig/examples/widget_box_demo/app.rbs +11 -0
- data/sig/examples/widget_calendar_demo/app.rbs +11 -0
- data/sig/examples/widget_cell_demo/app.rbs +11 -0
- data/sig/examples/widget_chart_demo/app.rbs +11 -0
- data/sig/examples/widget_gauge_demo/app.rbs +11 -0
- data/sig/examples/widget_layout_split/app.rbs +10 -0
- data/sig/examples/widget_line_gauge_demo/app.rbs +11 -0
- data/sig/examples/widget_list_demo/app.rbs +12 -0
- data/sig/examples/widget_list_styles/app.rbs +11 -0
- data/sig/examples/widget_popup_demo/app.rbs +11 -0
- data/sig/examples/widget_ratatui_logo_demo/app.rbs +11 -0
- data/sig/examples/widget_ratatui_mascot_demo/app.rbs +11 -0
- data/sig/examples/widget_rect/app.rbs +12 -0
- data/sig/examples/widget_render/app.rbs +10 -0
- data/sig/examples/widget_rich_text/app.rbs +11 -0
- data/sig/examples/widget_scroll_text/app.rbs +11 -0
- data/sig/examples/widget_scrollbar_demo/app.rbs +11 -0
- data/sig/examples/widget_sparkline_demo/app.rbs +10 -0
- data/sig/examples/widget_style_colors/app.rbs +14 -0
- data/sig/examples/widget_table_flex/app.rbs +11 -0
- data/sig/ratatui_ruby/event.rbs +69 -0
- data/sig/ratatui_ruby/frame.rbs +9 -0
- data/sig/ratatui_ruby/ratatui_ruby.rbs +5 -3
- data/sig/ratatui_ruby/schema/bar_chart/bar.rbs +16 -0
- data/sig/ratatui_ruby/schema/bar_chart/bar_group.rbs +13 -0
- data/sig/ratatui_ruby/schema/bar_chart.rbs +20 -2
- data/sig/ratatui_ruby/schema/block.rbs +5 -4
- data/sig/ratatui_ruby/schema/calendar.rbs +6 -2
- data/sig/ratatui_ruby/schema/canvas.rbs +52 -39
- data/sig/ratatui_ruby/schema/center.rbs +3 -3
- data/sig/ratatui_ruby/schema/chart.rbs +8 -5
- data/sig/ratatui_ruby/schema/constraint.rbs +8 -5
- data/sig/ratatui_ruby/schema/cursor.rbs +1 -1
- data/sig/ratatui_ruby/schema/draw.rbs +27 -0
- data/sig/ratatui_ruby/schema/gauge.rbs +4 -2
- data/sig/ratatui_ruby/schema/layout.rbs +11 -1
- data/sig/ratatui_ruby/schema/line_gauge.rbs +16 -0
- data/sig/ratatui_ruby/schema/list.rbs +5 -1
- data/sig/ratatui_ruby/schema/paragraph.rbs +4 -1
- data/sig/ratatui_ruby/schema/ratatui_logo.rbs +8 -0
- data/sig/ratatui_ruby/{buffer.rbs → schema/ratatui_mascot.rbs} +4 -3
- data/sig/ratatui_ruby/schema/rect.rbs +2 -1
- data/sig/ratatui_ruby/schema/scrollbar.rbs +18 -2
- data/sig/ratatui_ruby/schema/sparkline.rbs +6 -2
- data/sig/ratatui_ruby/schema/table.rbs +8 -1
- data/sig/ratatui_ruby/schema/tabs.rbs +5 -1
- data/sig/ratatui_ruby/schema/text.rbs +22 -0
- data/sig/ratatui_ruby/session.rbs +94 -0
- data/tasks/autodoc/inventory.rb +61 -0
- data/tasks/autodoc/member.rb +56 -0
- data/tasks/autodoc/name.rb +19 -0
- data/tasks/autodoc/notice.rb +26 -0
- data/tasks/autodoc/rbs.rb +38 -0
- data/tasks/autodoc/rdoc.rb +45 -0
- data/tasks/autodoc.rake +47 -0
- data/tasks/bump/history.rb +2 -2
- data/tasks/doc.rake +600 -6
- data/tasks/example_viewer.html.erb +172 -0
- data/tasks/lint.rake +8 -4
- data/tasks/resources/build.yml.erb +13 -11
- data/tasks/resources/index.html.erb +6 -0
- data/tasks/sourcehut.rake +4 -4
- data/tasks/terminal_preview/app_screenshot.rb +33 -0
- data/tasks/terminal_preview/crash_report.rb +52 -0
- data/tasks/terminal_preview/example_app.rb +25 -0
- data/tasks/terminal_preview/launcher_script.rb +46 -0
- data/tasks/terminal_preview/preview_collection.rb +58 -0
- data/tasks/terminal_preview/preview_timing.rb +22 -0
- data/tasks/terminal_preview/safety_confirmation.rb +56 -0
- data/tasks/terminal_preview/saved_screenshot.rb +53 -0
- data/tasks/terminal_preview/system_appearance.rb +11 -0
- data/tasks/terminal_preview/terminal_window.rb +136 -0
- data/tasks/terminal_preview/window_id.rb +14 -0
- data/tasks/terminal_preview.rake +28 -0
- data/tasks/test.rake +2 -2
- 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 +206 -54
- data/LICENSES/BSD-2-Clause.txt +0 -9
- data/doc/images/examples-analytics.rb.png +0 -0
- data/doc/images/examples-box_demo.rb.png +0 -0
- data/doc/images/examples-calendar_demo.rb.png +0 -0
- data/doc/images/examples-chart_demo.rb.png +0 -0
- data/doc/images/examples-custom_widget.rb.png +0 -0
- data/doc/images/examples-dashboard.rb.png +0 -0
- data/doc/images/examples-list_styles.rb.png +0 -0
- data/doc/images/examples-login_form.rb.png +0 -0
- data/doc/images/examples-map_demo.rb.png +0 -0
- data/doc/images/examples-mouse_events.rb.png +0 -0
- data/doc/images/examples-popup_demo.rb.gif +0 -0
- data/doc/images/examples-quickstart_lifecycle.rb.png +0 -0
- data/doc/images/examples-scroll_text.rb.png +0 -0
- data/doc/images/examples-scrollbar_demo.rb.png +0 -0
- data/doc/images/examples-stock_ticker.rb.png +0 -0
- data/doc/images/examples-system_monitor.rb.png +0 -0
- data/doc/images/examples-table_select.rb.png +0 -0
- data/examples/analytics.rb +0 -88
- data/examples/box_demo.rb +0 -71
- data/examples/calendar_demo.rb +0 -55
- data/examples/chart_demo.rb +0 -84
- data/examples/custom_widget.rb +0 -43
- data/examples/dashboard.rb +0 -72
- data/examples/list_styles.rb +0 -66
- data/examples/login_form.rb +0 -115
- data/examples/map_demo.rb +0 -58
- data/examples/mouse_events.rb +0 -95
- data/examples/popup_demo.rb +0 -105
- data/examples/quickstart_dsl.rb +0 -30
- data/examples/quickstart_lifecycle.rb +0 -40
- data/examples/readme_usage.rb +0 -21
- data/examples/scroll_text.rb +0 -74
- data/examples/scrollbar_demo.rb +0 -75
- data/examples/stock_ticker.rb +0 -93
- data/examples/system_monitor.rb +0 -94
- data/examples/table_select.rb +0 -70
- data/examples/test_analytics.rb +0 -65
- data/examples/test_box_demo.rb +0 -38
- data/examples/test_calendar_demo.rb +0 -66
- data/examples/test_dashboard.rb +0 -38
- data/examples/test_list_styles.rb +0 -61
- data/examples/test_login_form.rb +0 -63
- data/examples/test_map_demo.rb +0 -100
- data/examples/test_popup_demo.rb +0 -62
- data/examples/test_scroll_text.rb +0 -130
- data/examples/test_stock_ticker.rb +0 -39
- data/examples/test_system_monitor.rb +0 -40
- data/examples/test_table_select.rb +0 -37
- data/ext/ratatui_ruby/src/buffer.rs +0 -54
- data/lib/ratatui_ruby/dsl.rb +0 -64
|
@@ -4,30 +4,90 @@
|
|
|
4
4
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
5
5
|
|
|
6
6
|
module RatatuiRuby
|
|
7
|
-
# Defines
|
|
7
|
+
# Defines the sizing rule for a layout section.
|
|
8
8
|
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
9
|
+
# Flexible layouts need rules. You can't just place widgets at absolute coordinates; they must adapt to changing terminal sizes.
|
|
10
|
+
#
|
|
11
|
+
# This class defines the rules of engagement. It tells the layout engine exactly how much space a section requires relative to others.
|
|
12
|
+
#
|
|
13
|
+
# Mix and match fixed lengths, percentages, ratios, and minimums. Build layouts that breathe.
|
|
14
|
+
#
|
|
15
|
+
# === Examples
|
|
16
|
+
#
|
|
17
|
+
# Constraint.length(5) # Exactly 5 cells
|
|
18
|
+
# Constraint.percentage(50) # Half the available space
|
|
19
|
+
# Constraint.min(10) # At least 10 cells, maybe more
|
|
20
|
+
# Constraint.fill(1) # Fill remaining space (weight 1)
|
|
11
21
|
class Constraint < Data.define(:type, :value)
|
|
12
|
-
|
|
22
|
+
##
|
|
23
|
+
# :attr_reader: type
|
|
24
|
+
# The type of constraint.
|
|
25
|
+
#
|
|
26
|
+
# <tt>:length</tt>, <tt>:percentage</tt>, <tt>:min</tt>, <tt>:max</tt>, <tt>:fill</tt>, or <tt>:ratio</tt>.
|
|
27
|
+
|
|
28
|
+
##
|
|
29
|
+
# :attr_reader: value
|
|
30
|
+
# The numeric value (or array for ratio) associated with the rule.
|
|
31
|
+
|
|
32
|
+
# Requests a fixed size.
|
|
33
|
+
#
|
|
34
|
+
# Constraint.length(10) # 10 characters wide/high
|
|
13
35
|
#
|
|
14
|
-
# [v]
|
|
36
|
+
# [v] Number of cells (Integer).
|
|
15
37
|
def self.length(v)
|
|
16
|
-
new(type: :length, value: v)
|
|
38
|
+
new(type: :length, value: Integer(v))
|
|
17
39
|
end
|
|
18
40
|
|
|
19
|
-
#
|
|
41
|
+
# Requests a percentage of available space.
|
|
42
|
+
#
|
|
43
|
+
# Constraint.percentage(25) # 25% of the area
|
|
20
44
|
#
|
|
21
|
-
# [v]
|
|
45
|
+
# [v] Percentage 0-100 (Integer).
|
|
22
46
|
def self.percentage(v)
|
|
23
|
-
new(type: :percentage, value: v)
|
|
47
|
+
new(type: :percentage, value: Integer(v))
|
|
24
48
|
end
|
|
25
49
|
|
|
26
|
-
#
|
|
50
|
+
# Enforces a minimum size.
|
|
27
51
|
#
|
|
28
|
-
#
|
|
52
|
+
# Constraint.min(5) # At least 5 cells
|
|
53
|
+
#
|
|
54
|
+
# This section will grow if space permits, but never shrink below +v+.
|
|
55
|
+
#
|
|
56
|
+
# [v] Minimum cells (Integer).
|
|
29
57
|
def self.min(v)
|
|
30
|
-
new(type: :min, value: v)
|
|
58
|
+
new(type: :min, value: Integer(v))
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Enforces a maximum size.
|
|
62
|
+
#
|
|
63
|
+
# Constraint.max(10) # At most 10 cells
|
|
64
|
+
#
|
|
65
|
+
# [v] Maximum cells (Integer).
|
|
66
|
+
def self.max(v)
|
|
67
|
+
new(type: :max, value: Integer(v))
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Fills remaining space proportionally.
|
|
71
|
+
#
|
|
72
|
+
# Constraint.fill(1) # Equal share
|
|
73
|
+
# Constraint.fill(2) # Double share
|
|
74
|
+
#
|
|
75
|
+
# Fill constraints distribute any space left after satisfying strict rules.
|
|
76
|
+
# They behave like flex-grow. A fill(2) takes twice as much space as a fill(1).
|
|
77
|
+
#
|
|
78
|
+
# [v] Proportional weight (Integer, default: 1).
|
|
79
|
+
def self.fill(v = 1)
|
|
80
|
+
new(type: :fill, value: Integer(v))
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Requests a specific ratio of the total space.
|
|
84
|
+
#
|
|
85
|
+
# Constraint.ratio(1, 3) # 1/3rd of the area
|
|
86
|
+
#
|
|
87
|
+
# [numerator] Top part of fraction (Integer).
|
|
88
|
+
# [denominator] Bottom part of fraction (Integer).
|
|
89
|
+
def self.ratio(numerator, denominator)
|
|
90
|
+
new(type: :ratio, value: [Integer(numerator), Integer(denominator)])
|
|
31
91
|
end
|
|
32
92
|
end
|
|
33
93
|
end
|
|
@@ -4,14 +4,32 @@
|
|
|
4
4
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
5
5
|
|
|
6
6
|
module RatatuiRuby
|
|
7
|
-
#
|
|
7
|
+
# Controls the terminal cursor position.
|
|
8
8
|
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
9
|
+
# Interfaces are not just output; they require input. Users need a visual cue—a blinking block or line—to know where their keystrokes will appear.
|
|
10
|
+
#
|
|
11
|
+
# This widget renders a ghost. It does not draw a character but instructs the terminal to place the hardware cursor at specific coordinates.
|
|
12
|
+
#
|
|
13
|
+
# Use it for text editors, input fields, or command prompts.
|
|
14
|
+
#
|
|
15
|
+
# === Examples
|
|
16
|
+
#
|
|
17
|
+
# Cursor.new(x: 10, y: 5)
|
|
11
18
|
class Cursor < Data.define(:x, :y)
|
|
19
|
+
##
|
|
20
|
+
# :attr_reader: x
|
|
21
|
+
# X coordinate (column).
|
|
22
|
+
|
|
23
|
+
##
|
|
24
|
+
# :attr_reader: y
|
|
25
|
+
# Y coordinate (row).
|
|
26
|
+
|
|
12
27
|
# Creates a new Cursor.
|
|
13
28
|
#
|
|
14
|
-
# [x]
|
|
15
|
-
# [y]
|
|
29
|
+
# [x] Integer.
|
|
30
|
+
# [y] Integer.
|
|
31
|
+
def initialize(x:, y:)
|
|
32
|
+
super(x: Integer(x), y: Integer(y))
|
|
33
|
+
end
|
|
16
34
|
end
|
|
17
35
|
end
|
|
@@ -0,0 +1,53 @@
|
|
|
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
|
+
module RatatuiRuby
|
|
7
|
+
# Draw commands for custom widgets.
|
|
8
|
+
#
|
|
9
|
+
# Custom widgets return an array of Draw commands instead of writing directly to a buffer.
|
|
10
|
+
# This keeps all pointers safely inside Rust while Ruby works with pure data.
|
|
11
|
+
#
|
|
12
|
+
# === Example
|
|
13
|
+
#
|
|
14
|
+
# class MyWidget
|
|
15
|
+
# def render(area)
|
|
16
|
+
# [
|
|
17
|
+
# RatatuiRuby::Draw.string(area.x, area.y, "Hello", {fg: :red}),
|
|
18
|
+
# RatatuiRuby::Draw.cell(area.x + 6, area.y, RatatuiRuby::Cell.char("!"))
|
|
19
|
+
# ]
|
|
20
|
+
# end
|
|
21
|
+
# end
|
|
22
|
+
module Draw
|
|
23
|
+
# Command to draw a string at the given coordinates.
|
|
24
|
+
#
|
|
25
|
+
# [x] X coordinate (absolute).
|
|
26
|
+
# [y] Y coordinate (absolute).
|
|
27
|
+
# [string] The text to draw.
|
|
28
|
+
# [style] Style hash or Style object.
|
|
29
|
+
StringCmd = Data.define(:x, :y, :string, :style)
|
|
30
|
+
|
|
31
|
+
# Command to draw a cell at the given coordinates.
|
|
32
|
+
#
|
|
33
|
+
# [x] X coordinate (absolute).
|
|
34
|
+
# [y] Y coordinate (absolute).
|
|
35
|
+
# [cell] The Cell to draw.
|
|
36
|
+
CellCmd = Data.define(:x, :y, :cell)
|
|
37
|
+
|
|
38
|
+
# Creates a string draw command.
|
|
39
|
+
#
|
|
40
|
+
# [x] X coordinate (Integer, duck-typed via +to_int+).
|
|
41
|
+
# [y] Y coordinate (Integer, duck-typed via +to_int+).
|
|
42
|
+
# [string] Text to draw.
|
|
43
|
+
# [style] Optional style (Hash or Style).
|
|
44
|
+
def self.string(x, y, string, style = {}) = StringCmd.new(x: Integer(x), y: Integer(y), string:, style:)
|
|
45
|
+
|
|
46
|
+
# Creates a cell draw command.
|
|
47
|
+
#
|
|
48
|
+
# [x] X coordinate (Integer, duck-typed via +to_int+).
|
|
49
|
+
# [y] Y coordinate (Integer, duck-typed via +to_int+).
|
|
50
|
+
# [cell] Cell to draw.
|
|
51
|
+
def self.cell(x, y, cell) = CellCmd.new(x: Integer(x), y: Integer(y), cell:)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -4,21 +4,65 @@
|
|
|
4
4
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
5
5
|
|
|
6
6
|
module RatatuiRuby
|
|
7
|
-
#
|
|
7
|
+
# Displays a standard progress bar.
|
|
8
8
|
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
|
|
9
|
+
# Long-running tasks create anxiety. Users need to know that the system is working and how much is left to do.
|
|
10
|
+
#
|
|
11
|
+
# This widget visualizes completion. It fills a bar based on a percentage.
|
|
12
|
+
#
|
|
13
|
+
# Use it for downloads, installations, or processing jobs.
|
|
14
|
+
#
|
|
15
|
+
# {rdoc-image:/doc/images/widget_gauge_demo.png}[link:/examples/widget_gauge_demo/app_rb.html]
|
|
16
|
+
#
|
|
17
|
+
# === Example
|
|
18
|
+
#
|
|
19
|
+
# Run the interactive demo from the terminal:
|
|
20
|
+
#
|
|
21
|
+
# ruby examples/widget_gauge_demo/app.rb
|
|
22
|
+
class Gauge < Data.define(:ratio, :label, :style, :gauge_style, :block, :use_unicode)
|
|
23
|
+
##
|
|
24
|
+
# :attr_reader: ratio
|
|
25
|
+
# Progress ratio from 0.0 to 1.0.
|
|
26
|
+
|
|
27
|
+
##
|
|
28
|
+
# :attr_reader: label
|
|
29
|
+
# Text label to display (optional).
|
|
30
|
+
#
|
|
31
|
+
# If nil, it often displays the percentage automatically depending on renderer logic,
|
|
32
|
+
# but explicit labels are preferred.
|
|
33
|
+
|
|
34
|
+
##
|
|
35
|
+
# :attr_reader: style
|
|
36
|
+
# Base style applied to the entire gauge background (optional).
|
|
37
|
+
|
|
38
|
+
##
|
|
39
|
+
# :attr_reader: gauge_style
|
|
40
|
+
# Style applied specifically to the filled bar portion (optional).
|
|
41
|
+
|
|
42
|
+
##
|
|
43
|
+
# :attr_reader: block
|
|
44
|
+
# Optional wrapping block.
|
|
45
|
+
|
|
46
|
+
##
|
|
47
|
+
# :attr_reader: use_unicode
|
|
48
|
+
# Whether to use Unicode block characters (true) or ASCII characters (false).
|
|
49
|
+
# Default is false (ASCII) to be conservative, though Ratatui defaults to true.
|
|
50
|
+
|
|
14
51
|
# Creates a new Gauge.
|
|
15
52
|
#
|
|
16
|
-
# [ratio]
|
|
17
|
-
# [
|
|
18
|
-
# [
|
|
19
|
-
# [
|
|
20
|
-
|
|
21
|
-
|
|
53
|
+
# [ratio] Float (0.0 - 1.0).
|
|
54
|
+
# [percent] Integer (0 - 100), alternative to ratio.
|
|
55
|
+
# [label] String (optional).
|
|
56
|
+
# [style] Style object for the background (optional).
|
|
57
|
+
# [gauge_style] Style object for the filled bar (optional).
|
|
58
|
+
# [block] Block widget (optional).
|
|
59
|
+
# [use_unicode] Boolean (default: true).
|
|
60
|
+
def initialize(ratio: nil, percent: nil, label: nil, style: nil, gauge_style: nil, block: nil, use_unicode: true)
|
|
61
|
+
if percent
|
|
62
|
+
ratio = Float(percent) / 100.0
|
|
63
|
+
end
|
|
64
|
+
ratio = Float(ratio || 0.0)
|
|
65
|
+
super(ratio:, label:, style:, gauge_style:, block:, use_unicode:)
|
|
22
66
|
end
|
|
23
67
|
end
|
|
24
68
|
end
|
|
@@ -4,19 +4,101 @@
|
|
|
4
4
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
5
5
|
|
|
6
6
|
module RatatuiRuby
|
|
7
|
-
#
|
|
7
|
+
# Divides an area into smaller chunks.
|
|
8
8
|
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
|
|
9
|
+
# Terminal screens vary in size. Hardcoded positions break when the window resizes. You need a way to organize space dynamically.
|
|
10
|
+
#
|
|
11
|
+
# This class manages geometry. It splits a given area into multiple sections based on a list of constraints.
|
|
12
|
+
#
|
|
13
|
+
# Use layouts to build responsive grids. Stack sections vertically for a sidebar-main structure. Partition them horizontally for headers and footers. Let the layout engine do the math.
|
|
14
|
+
#
|
|
15
|
+
# {rdoc-image:/doc/images/widget_layout_split.png}[link:/examples/widget_layout_split/app_rb.html]
|
|
16
|
+
#
|
|
17
|
+
# === Example
|
|
18
|
+
#
|
|
19
|
+
# Run the interactive demo from the terminal:
|
|
20
|
+
#
|
|
21
|
+
# ruby examples/widget_layout_split/app.rb
|
|
22
|
+
class Layout < Data.define(:direction, :constraints, :children, :flex)
|
|
23
|
+
##
|
|
24
|
+
# :attr_reader: direction
|
|
25
|
+
# Direction of the split.
|
|
26
|
+
#
|
|
27
|
+
# Either <tt>:vertical</tt> (top to bottom) or <tt>:horizontal</tt> (left to right).
|
|
28
|
+
#
|
|
29
|
+
# layout.direction # => :vertical
|
|
30
|
+
|
|
31
|
+
##
|
|
32
|
+
# :attr_reader: constraints
|
|
33
|
+
# Array of rules defining section sizes.
|
|
34
|
+
#
|
|
35
|
+
# See RatatuiRuby::Constraint.
|
|
36
|
+
|
|
37
|
+
##
|
|
38
|
+
# :attr_reader: children
|
|
39
|
+
# Widgets to render in each section (optional).
|
|
40
|
+
#
|
|
41
|
+
# If provided, `children[i]` is rendered into the area defined by `constraints[i]`.
|
|
42
|
+
|
|
43
|
+
##
|
|
44
|
+
# :attr_reader: flex
|
|
45
|
+
# Strategy for distributing extra space.
|
|
46
|
+
#
|
|
47
|
+
# One of <tt>:legacy</tt>, <tt>:start</tt>, <tt>:center</tt>, <tt>:end</tt>, <tt>:space_between</tt>, <tt>:space_around</tt>.
|
|
48
|
+
|
|
49
|
+
# :nodoc:
|
|
50
|
+
FLEX_MODES = %i[legacy start center end space_between space_around space_evenly].freeze
|
|
51
|
+
|
|
13
52
|
# Creates a new Layout.
|
|
14
53
|
#
|
|
15
|
-
# [direction]
|
|
16
|
-
#
|
|
17
|
-
# [
|
|
18
|
-
|
|
54
|
+
# [direction]
|
|
55
|
+
# <tt>:vertical</tt> or <tt>:horizontal</tt> (default: <tt>:vertical</tt>).
|
|
56
|
+
# [constraints]
|
|
57
|
+
# list of Constraint objects.
|
|
58
|
+
# [children]
|
|
59
|
+
# List of widgets to render (optional).
|
|
60
|
+
# [flex]
|
|
61
|
+
# Flex mode for spacing (default: <tt>:legacy</tt>).
|
|
62
|
+
def initialize(direction: :vertical, constraints: [], children: [], flex: :legacy)
|
|
19
63
|
super
|
|
20
64
|
end
|
|
65
|
+
|
|
66
|
+
# Splits an area into multiple rectangles.
|
|
67
|
+
#
|
|
68
|
+
# This is a pure calculation helper for hit testing. It computes where
|
|
69
|
+
# widgets *would* be placed without actually rendering them.
|
|
70
|
+
#
|
|
71
|
+
# rects = Layout.split(
|
|
72
|
+
# area,
|
|
73
|
+
# direction: :horizontal,
|
|
74
|
+
# constraints: [Constraint.percentage(50), Constraint.percentage(50)]
|
|
75
|
+
# )
|
|
76
|
+
# left, right = rects
|
|
77
|
+
#
|
|
78
|
+
# [area]
|
|
79
|
+
# The area to split. Can be a <tt>Rect</tt> or a <tt>Hash</tt> containing <tt>:x</tt>, <tt>:y</tt>, <tt>:width</tt>, and <tt>:height</tt>.
|
|
80
|
+
# [direction]
|
|
81
|
+
# <tt>:vertical</tt> or <tt>:horizontal</tt> (default: <tt>:vertical</tt>).
|
|
82
|
+
# [constraints]
|
|
83
|
+
# Array of <tt>Constraint</tt> objects defining section sizes.
|
|
84
|
+
# [flex]
|
|
85
|
+
# Flex mode for spacing (default: <tt>:legacy</tt>).
|
|
86
|
+
#
|
|
87
|
+
# Returns an Array of <tt>Rect</tt> objects.
|
|
88
|
+
def self.split(area, direction: :vertical, constraints:, flex: :legacy)
|
|
89
|
+
# Duck-typing: If it lacks geometry methods but can be a Hash, convert it.
|
|
90
|
+
if !area.respond_to?(:x) && area.respond_to?(:to_h)
|
|
91
|
+
# Assume it's a Hash-like object with :x, :y, etc.
|
|
92
|
+
hash = area.to_h
|
|
93
|
+
area = Rect.new(
|
|
94
|
+
x: hash.fetch(:x, 0),
|
|
95
|
+
y: hash.fetch(:y, 0),
|
|
96
|
+
width: hash.fetch(:width, 0),
|
|
97
|
+
height: hash.fetch(:height, 0)
|
|
98
|
+
)
|
|
99
|
+
end
|
|
100
|
+
raw_rects = _split(area, direction, constraints, flex)
|
|
101
|
+
raw_rects.map { |r| Rect.new(x: r[:x], y: r[:y], width: r[:width], height: r[:height]) }
|
|
102
|
+
end
|
|
21
103
|
end
|
|
22
104
|
end
|
|
@@ -0,0 +1,78 @@
|
|
|
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
|
+
module RatatuiRuby
|
|
7
|
+
# Displays a compact, single-line progress bar.
|
|
8
|
+
#
|
|
9
|
+
# Screen space is precious. Standard block gauges are bulky and consume multiple rows.
|
|
10
|
+
#
|
|
11
|
+
# This widget compresses the feedback. It draws a progress bar using line characters, fitting perfectly into tight layouts or lists.
|
|
12
|
+
#
|
|
13
|
+
# Use it when you need to show status without stealing focus or space.
|
|
14
|
+
#
|
|
15
|
+
# {rdoc-image:/doc/images/widget_line_gauge_demo.png}[link:/examples/widget_line_gauge_demo/app_rb.html]
|
|
16
|
+
#
|
|
17
|
+
# === Example
|
|
18
|
+
#
|
|
19
|
+
# Run the interactive demo from the terminal:
|
|
20
|
+
#
|
|
21
|
+
# ruby examples/widget_line_gauge_demo/app.rb
|
|
22
|
+
class LineGauge < Data.define(:ratio, :label, :style, :filled_style, :unfilled_style, :block, :filled_symbol, :unfilled_symbol)
|
|
23
|
+
##
|
|
24
|
+
# :attr_reader: ratio
|
|
25
|
+
# Progress ratio from 0.0 to 1.0.
|
|
26
|
+
|
|
27
|
+
##
|
|
28
|
+
# :attr_reader: label
|
|
29
|
+
# Optional label.
|
|
30
|
+
|
|
31
|
+
##
|
|
32
|
+
# :attr_reader: style
|
|
33
|
+
# Base style applied to the entire gauge.
|
|
34
|
+
|
|
35
|
+
##
|
|
36
|
+
# :attr_reader: filled_style
|
|
37
|
+
# Style for the completed portion.
|
|
38
|
+
|
|
39
|
+
##
|
|
40
|
+
# :attr_reader: unfilled_style
|
|
41
|
+
# Style for the remainder.
|
|
42
|
+
|
|
43
|
+
##
|
|
44
|
+
# :attr_reader: block
|
|
45
|
+
# Optional wrapping block.
|
|
46
|
+
|
|
47
|
+
##
|
|
48
|
+
# :attr_reader: filled_symbol
|
|
49
|
+
# Character for filled segments.
|
|
50
|
+
|
|
51
|
+
##
|
|
52
|
+
# :attr_reader: unfilled_symbol
|
|
53
|
+
# Character for empty segments.
|
|
54
|
+
|
|
55
|
+
# Creates a new LineGauge.
|
|
56
|
+
#
|
|
57
|
+
# [ratio] Float (0.0 - 1.0).
|
|
58
|
+
# [label] String (optional).
|
|
59
|
+
# [style] Style (optional, base style for the gauge).
|
|
60
|
+
# [filled_style] Style.
|
|
61
|
+
# [unfilled_style] Style.
|
|
62
|
+
# [block] Block.
|
|
63
|
+
# [filled_symbol] String (default: <tt>"█"</tt>).
|
|
64
|
+
# [unfilled_symbol] String (default: <tt>"░"</tt>).
|
|
65
|
+
def initialize(ratio: 0.0, label: nil, style: nil, filled_style: nil, unfilled_style: nil, block: nil, filled_symbol: "█", unfilled_symbol: "░")
|
|
66
|
+
super(
|
|
67
|
+
ratio: Float(ratio),
|
|
68
|
+
label:,
|
|
69
|
+
style:,
|
|
70
|
+
filled_style:,
|
|
71
|
+
unfilled_style:,
|
|
72
|
+
block:,
|
|
73
|
+
filled_symbol:,
|
|
74
|
+
unfilled_symbol:
|
|
75
|
+
)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -4,25 +4,101 @@
|
|
|
4
4
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
5
5
|
|
|
6
6
|
module RatatuiRuby
|
|
7
|
-
#
|
|
7
|
+
# Displays a selectable list of items.
|
|
8
8
|
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
|
|
9
|
+
# Users need to choose from options. Menus, file explorers, and selectors are everywhere.
|
|
10
|
+
# Implementing navigation, highlighting, and scrolling state from scratch is tedious.
|
|
11
|
+
#
|
|
12
|
+
# This widget manages the list. It renders the items. It highlights the selection. It handles the scrolling window.
|
|
13
|
+
#
|
|
14
|
+
# Use it to build main menus, navigation sidebars, or logs.
|
|
15
|
+
#
|
|
16
|
+
# {rdoc-image:/doc/images/widget_list_demo.png}[link:/examples/widget_list_demo/app_rb.html]
|
|
17
|
+
#
|
|
18
|
+
# === Examples
|
|
19
|
+
#
|
|
20
|
+
# # Basic List
|
|
21
|
+
# List.new(items: ["Item 1", "Item 2"])
|
|
22
|
+
#
|
|
23
|
+
# # Navigation Menu
|
|
24
|
+
# List.new(
|
|
25
|
+
# items: ["New Game", "Load Game", "Options", "Quit"],
|
|
26
|
+
# selected_index: 0,
|
|
27
|
+
# highlight_style: Style.new(bg: :blue),
|
|
28
|
+
# highlight_symbol: ">> "
|
|
29
|
+
# )
|
|
30
|
+
class List < Data.define(:items, :selected_index, :style, :highlight_style, :highlight_symbol, :repeat_highlight_symbol, :highlight_spacing, :direction, :scroll_padding, :block)
|
|
31
|
+
##
|
|
32
|
+
# :attr_reader: items
|
|
33
|
+
# The items to display (Array of Strings).
|
|
34
|
+
|
|
35
|
+
##
|
|
36
|
+
# :attr_reader: selected_index
|
|
37
|
+
# Index of the active selection (Integer or nil).
|
|
38
|
+
|
|
39
|
+
##
|
|
40
|
+
# :attr_reader: style
|
|
41
|
+
# Base style for unselected items.
|
|
42
|
+
|
|
43
|
+
##
|
|
44
|
+
# :attr_reader: highlight_style
|
|
45
|
+
# Style for the selected item.
|
|
46
|
+
|
|
47
|
+
##
|
|
48
|
+
# :attr_reader: highlight_symbol
|
|
49
|
+
# Symbol drawn before the selected item.
|
|
50
|
+
|
|
51
|
+
##
|
|
52
|
+
# :attr_reader: repeat_highlight_symbol
|
|
53
|
+
# Whether to repeat the highlight symbol for each line of the selected item.
|
|
54
|
+
|
|
55
|
+
##
|
|
56
|
+
# :attr_reader: highlight_spacing
|
|
57
|
+
# When to show the highlight symbol column.
|
|
58
|
+
#
|
|
59
|
+
# <tt>:always</tt>, <tt>:when_selected</tt>, or <tt>:never</tt>.
|
|
60
|
+
|
|
61
|
+
##
|
|
62
|
+
# :attr_reader: direction
|
|
63
|
+
# Render direction.
|
|
64
|
+
#
|
|
65
|
+
# <tt>:top_to_bottom</tt> or <tt>:bottom_to_top</tt>.
|
|
66
|
+
|
|
67
|
+
##
|
|
68
|
+
# :attr_reader: scroll_padding
|
|
69
|
+
# Number of items to keep visible above/below the selected item when scrolling (Integer or nil).
|
|
70
|
+
|
|
71
|
+
##
|
|
72
|
+
# :attr_reader: block
|
|
73
|
+
# Optional wrapping block.
|
|
74
|
+
|
|
16
75
|
# Creates a new List.
|
|
17
76
|
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
# [
|
|
21
|
-
# [
|
|
22
|
-
# [
|
|
23
|
-
# [
|
|
24
|
-
|
|
25
|
-
|
|
77
|
+
# Integer parameters accept any object responding to +to_int+ or +to_i+ (duck-typed).
|
|
78
|
+
#
|
|
79
|
+
# [items] Array of Strings.
|
|
80
|
+
# [selected_index] Numeric (nullable, coerced to Integer).
|
|
81
|
+
# [style] Style object.
|
|
82
|
+
# [highlight_style] Style object.
|
|
83
|
+
# [highlight_symbol] String (default: <tt>"> "</tt>).
|
|
84
|
+
# [repeat_highlight_symbol] Boolean (default: <tt>false</tt>).
|
|
85
|
+
# [highlight_spacing] Symbol (default: <tt>:when_selected</tt>).
|
|
86
|
+
# [direction] Symbol (default: <tt>:top_to_bottom</tt>).
|
|
87
|
+
# [scroll_padding] Numeric (nullable, coerced to Integer, default: <tt>nil</tt>).
|
|
88
|
+
# [block] Block (optional).
|
|
89
|
+
def initialize(items: [], selected_index: nil, style: nil, highlight_style: nil, highlight_symbol: "> ", repeat_highlight_symbol: false, highlight_spacing: :when_selected, direction: :top_to_bottom, scroll_padding: nil, block: nil)
|
|
90
|
+
super(
|
|
91
|
+
items:,
|
|
92
|
+
selected_index: selected_index.nil? ? nil : Integer(selected_index),
|
|
93
|
+
style:,
|
|
94
|
+
highlight_style:,
|
|
95
|
+
highlight_symbol:,
|
|
96
|
+
repeat_highlight_symbol:,
|
|
97
|
+
highlight_spacing:,
|
|
98
|
+
direction:,
|
|
99
|
+
scroll_padding: scroll_padding.nil? ? nil : Integer(scroll_padding),
|
|
100
|
+
block:
|
|
101
|
+
)
|
|
26
102
|
end
|
|
27
103
|
end
|
|
28
104
|
end
|
|
@@ -4,12 +4,38 @@
|
|
|
4
4
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
5
5
|
|
|
6
6
|
module RatatuiRuby
|
|
7
|
-
#
|
|
7
|
+
# Stacks widgets on top of each other.
|
|
8
8
|
#
|
|
9
|
-
#
|
|
9
|
+
# Terminal interfaces are 2D grids, but complex UIs require depth. You need to float modals over text,
|
|
10
|
+
# or place a status bar on top of a map.
|
|
11
|
+
#
|
|
12
|
+
# This widget manages the Z-axis. It renders a list of widgets sequentially into the same area.
|
|
13
|
+
# Later widgets draw over earlier ones (Painter's Algorithm).
|
|
14
|
+
#
|
|
15
|
+
# Use overlays to compose complex scenes. Combine backgrounds, main content, and floating elements.
|
|
16
|
+
#
|
|
17
|
+
# === Examples
|
|
18
|
+
#
|
|
19
|
+
# Overlay.new(
|
|
20
|
+
# layers: [
|
|
21
|
+
# BackgroundMap.new,
|
|
22
|
+
# StatusBar.new, # Draws over map
|
|
23
|
+
# ModalDialog.new # Draws over everything
|
|
24
|
+
# ]
|
|
25
|
+
# )
|
|
10
26
|
class Overlay < Data.define(:layers)
|
|
27
|
+
##
|
|
28
|
+
# :attr_reader: layers
|
|
29
|
+
# The stack of widgets to render.
|
|
30
|
+
#
|
|
31
|
+
# Rendered from index 0 to N. Index N is the top-most layer.
|
|
32
|
+
|
|
11
33
|
# Creates a new Overlay.
|
|
12
34
|
#
|
|
13
|
-
# [layers]
|
|
35
|
+
# [layers]
|
|
36
|
+
# Array of widgets.
|
|
37
|
+
def initialize(layers: [])
|
|
38
|
+
super
|
|
39
|
+
end
|
|
14
40
|
end
|
|
15
41
|
end
|