ratatui_ruby 0.5.0 → 0.7.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 +10 -4
- data/CHANGELOG.md +79 -7
- data/README.md +37 -5
- data/REUSE.toml +2 -7
- data/doc/application_architecture.md +96 -22
- data/doc/application_testing.md +76 -30
- data/doc/contributors/architectural_overhaul/chat_conversations.md +4952 -0
- data/doc/contributors/architectural_overhaul/implementation_plan.md +60 -0
- data/doc/contributors/architectural_overhaul/task.md +37 -0
- data/doc/contributors/design/ruby_frontend.md +288 -56
- data/doc/contributors/design/rust_backend.md +349 -54
- data/doc/contributors/developing_examples.md +134 -49
- data/doc/contributors/index.md +7 -5
- data/doc/contributors/v1.0.0_blockers.md +1729 -0
- data/doc/event_handling.md +11 -3
- 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_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_list_demo.png +0 -0
- data/doc/images/widget_overlay_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_sparkline_demo.png +0 -0
- data/doc/images/widget_table_demo.png +0 -0
- data/doc/images/widget_tabs_demo.png +0 -0
- data/doc/images/widget_text_width.png +0 -0
- data/doc/index.md +11 -6
- data/doc/interactive_design.md +2 -2
- data/doc/quickstart.md +127 -165
- data/doc/terminal_limitations.md +92 -0
- data/doc/v0.7.0_migration.md +236 -0
- data/doc/why.md +93 -0
- data/examples/app_all_events/README.md +47 -27
- data/examples/app_all_events/app.rb +38 -35
- data/examples/app_all_events/model/app_model.rb +157 -0
- data/examples/app_all_events/model/event_entry.rb +17 -0
- data/examples/app_all_events/model/msg.rb +37 -0
- data/examples/app_all_events/update.rb +73 -0
- data/examples/app_all_events/view/app_view.rb +9 -9
- data/examples/app_all_events/view/controls_view.rb +9 -7
- data/examples/app_all_events/view/counts_view.rb +13 -9
- data/examples/app_all_events/view/live_view.rb +9 -8
- data/examples/app_all_events/view/log_view.rb +11 -16
- data/examples/app_color_picker/README.md +84 -42
- data/examples/app_color_picker/app.rb +24 -62
- data/examples/app_color_picker/controls.rb +90 -0
- data/examples/app_color_picker/copy_dialog.rb +45 -49
- data/examples/app_color_picker/export_pane.rb +126 -0
- data/examples/app_color_picker/input.rb +99 -67
- data/examples/app_color_picker/main_container.rb +178 -0
- data/examples/app_color_picker/palette.rb +55 -26
- data/examples/app_login_form/README.md +49 -0
- data/examples/app_login_form/app.rb +2 -3
- data/examples/app_stateful_interaction/README.md +33 -0
- data/examples/app_stateful_interaction/app.rb +272 -0
- data/examples/timeout_demo.rb +43 -0
- data/examples/verify_quickstart_dsl/README.md +49 -0
- data/examples/verify_quickstart_dsl/app.rb +2 -0
- data/examples/verify_quickstart_layout/README.md +71 -0
- data/examples/verify_quickstart_layout/app.rb +2 -0
- data/examples/verify_quickstart_lifecycle/README.md +56 -0
- data/examples/verify_quickstart_lifecycle/app.rb +10 -4
- data/examples/verify_readme_usage/README.md +43 -0
- data/examples/verify_readme_usage/app.rb +8 -2
- data/examples/widget_barchart_demo/README.md +50 -0
- data/examples/widget_barchart_demo/app.rb +5 -5
- data/examples/widget_block_demo/README.md +36 -0
- data/examples/widget_block_demo/app.rb +256 -0
- data/examples/widget_box_demo/README.md +45 -0
- data/examples/widget_calendar_demo/README.md +39 -0
- data/examples/widget_calendar_demo/app.rb +5 -1
- 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 +31 -24
- 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 +7 -2
- data/examples/widget_gauge_demo/README.md +41 -0
- data/examples/widget_layout_split/README.md +44 -0
- data/examples/widget_line_gauge_demo/README.md +41 -0
- data/examples/widget_list_demo/README.md +49 -0
- data/examples/widget_list_demo/app.rb +91 -107
- data/examples/widget_map_demo/README.md +39 -0
- data/examples/{app_map_demo → widget_map_demo}/app.rb +4 -4
- data/examples/widget_overlay_demo/README.md +36 -0
- data/examples/widget_overlay_demo/app.rb +248 -0
- data/examples/widget_popup_demo/README.md +36 -0
- data/examples/widget_ratatui_logo_demo/README.md +34 -0
- data/examples/widget_ratatui_logo_demo/app.rb +1 -1
- data/examples/widget_ratatui_mascot_demo/README.md +34 -0
- data/examples/widget_rect/README.md +38 -0
- data/examples/widget_render/README.md +37 -0
- data/examples/widget_render/app.rb +3 -3
- data/examples/widget_rich_text/README.md +35 -0
- data/examples/widget_rich_text/app.rb +62 -33
- data/examples/widget_scroll_text/README.md +37 -0
- data/examples/widget_scroll_text/app.rb +0 -1
- data/examples/widget_scrollbar_demo/README.md +37 -0
- data/examples/widget_sparkline_demo/README.md +42 -0
- data/examples/widget_sparkline_demo/app.rb +4 -3
- data/examples/widget_style_colors/README.md +34 -0
- data/examples/widget_table_demo/README.md +48 -0
- data/examples/{app_table_select → widget_table_demo}/app.rb +65 -12
- data/examples/widget_tabs_demo/README.md +41 -0
- data/examples/widget_tabs_demo/app.rb +15 -1
- data/examples/widget_text_width/README.md +35 -0
- data/examples/widget_text_width/app.rb +113 -0
- data/exe/.gitkeep +0 -0
- data/ext/ratatui_ruby/Cargo.lock +11 -4
- data/ext/ratatui_ruby/Cargo.toml +2 -1
- data/ext/ratatui_ruby/src/events.rs +238 -26
- data/ext/ratatui_ruby/src/frame.rs +116 -3
- data/ext/ratatui_ruby/src/lib.rs +37 -6
- data/ext/ratatui_ruby/src/rendering.rs +22 -21
- data/ext/ratatui_ruby/src/string_width.rs +101 -0
- data/ext/ratatui_ruby/src/terminal.rs +39 -15
- data/ext/ratatui_ruby/src/text.rs +13 -4
- data/ext/ratatui_ruby/src/widgets/barchart.rs +24 -6
- data/ext/ratatui_ruby/src/widgets/canvas.rs +5 -5
- data/ext/ratatui_ruby/src/widgets/gauge.rs +9 -2
- data/ext/ratatui_ruby/src/widgets/line_gauge.rs +9 -2
- data/ext/ratatui_ruby/src/widgets/list.rs +179 -3
- 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/scrollbar.rs +93 -1
- data/ext/ratatui_ruby/src/widgets/scrollbar_state.rs +169 -0
- data/ext/ratatui_ruby/src/widgets/table.rs +191 -34
- data/ext/ratatui_ruby/src/widgets/table_state.rs +121 -0
- data/lib/ratatui_ruby/buffer/cell.rb +168 -0
- data/lib/ratatui_ruby/buffer.rb +15 -0
- data/lib/ratatui_ruby/cell.rb +4 -4
- 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 +111 -51
- data/lib/ratatui_ruby/event/mouse.rb +3 -3
- data/lib/ratatui_ruby/event/paste.rb +1 -1
- data/lib/ratatui_ruby/frame.rb +100 -4
- data/lib/ratatui_ruby/layout/constraint.rb +95 -0
- data/lib/ratatui_ruby/layout/layout.rb +106 -0
- data/lib/ratatui_ruby/layout/rect.rb +118 -0
- data/lib/ratatui_ruby/layout.rb +19 -0
- data/lib/ratatui_ruby/list_state.rb +88 -0
- data/lib/ratatui_ruby/schema/bar_chart/bar.rb +2 -2
- data/lib/ratatui_ruby/schema/cursor.rb +5 -0
- data/lib/ratatui_ruby/schema/gauge.rb +3 -1
- data/lib/ratatui_ruby/schema/layout.rb +1 -1
- data/lib/ratatui_ruby/schema/line_gauge.rb +2 -2
- data/lib/ratatui_ruby/schema/list.rb +25 -4
- data/lib/ratatui_ruby/schema/list_item.rb +41 -0
- data/lib/ratatui_ruby/schema/rect.rb +43 -0
- data/lib/ratatui_ruby/schema/row.rb +66 -0
- data/lib/ratatui_ruby/schema/style.rb +24 -4
- data/lib/ratatui_ruby/schema/table.rb +29 -11
- data/lib/ratatui_ruby/schema/text.rb +96 -3
- data/lib/ratatui_ruby/scrollbar_state.rb +112 -0
- data/lib/ratatui_ruby/style/style.rb +81 -0
- data/lib/ratatui_ruby/style.rb +15 -0
- 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 +414 -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 +65 -358
- data/lib/ratatui_ruby/tui/buffer_factories.rb +20 -0
- data/lib/ratatui_ruby/tui/canvas_factories.rb +44 -0
- data/lib/ratatui_ruby/tui/core.rb +38 -0
- data/lib/ratatui_ruby/tui/layout_factories.rb +74 -0
- data/lib/ratatui_ruby/tui/state_factories.rb +33 -0
- data/lib/ratatui_ruby/tui/style_factories.rb +20 -0
- data/lib/ratatui_ruby/tui/text_factories.rb +44 -0
- data/lib/ratatui_ruby/tui/widget_factories.rb +195 -0
- data/lib/ratatui_ruby/tui.rb +75 -0
- data/lib/ratatui_ruby/version.rb +1 -1
- data/lib/ratatui_ruby/widgets/bar_chart/bar.rb +47 -0
- data/lib/ratatui_ruby/widgets/bar_chart/bar_group.rb +25 -0
- data/lib/ratatui_ruby/widgets/bar_chart.rb +239 -0
- data/lib/ratatui_ruby/widgets/block.rb +192 -0
- data/lib/ratatui_ruby/widgets/calendar.rb +84 -0
- data/lib/ratatui_ruby/widgets/canvas.rb +231 -0
- data/lib/ratatui_ruby/widgets/cell.rb +47 -0
- data/lib/ratatui_ruby/widgets/center.rb +59 -0
- data/lib/ratatui_ruby/widgets/chart.rb +185 -0
- data/lib/ratatui_ruby/widgets/clear.rb +54 -0
- data/lib/ratatui_ruby/widgets/cursor.rb +42 -0
- data/lib/ratatui_ruby/widgets/gauge.rb +72 -0
- data/lib/ratatui_ruby/widgets/line_gauge.rb +80 -0
- data/lib/ratatui_ruby/widgets/list.rb +127 -0
- data/lib/ratatui_ruby/widgets/list_item.rb +43 -0
- data/lib/ratatui_ruby/widgets/overlay.rb +43 -0
- data/lib/ratatui_ruby/widgets/paragraph.rb +99 -0
- data/lib/ratatui_ruby/widgets/ratatui_logo.rb +31 -0
- data/lib/ratatui_ruby/widgets/ratatui_mascot.rb +36 -0
- data/lib/ratatui_ruby/widgets/row.rb +68 -0
- data/lib/ratatui_ruby/widgets/scrollbar.rb +143 -0
- data/lib/ratatui_ruby/widgets/shape/label.rb +68 -0
- data/lib/ratatui_ruby/widgets/sparkline.rb +134 -0
- data/lib/ratatui_ruby/widgets/table.rb +141 -0
- data/lib/ratatui_ruby/widgets/tabs.rb +85 -0
- data/lib/ratatui_ruby/widgets.rb +40 -0
- data/lib/ratatui_ruby.rb +64 -57
- data/sig/examples/app_all_events/view.rbs +1 -1
- data/sig/examples/app_all_events/view_state.rbs +1 -1
- data/sig/examples/app_stateful_interaction/app.rbs +33 -0
- data/sig/examples/widget_block_demo/app.rbs +32 -0
- data/sig/examples/{app_map_demo → widget_map_demo}/app.rbs +2 -2
- data/sig/examples/{app_table_select → widget_table_demo}/app.rbs +2 -2
- data/sig/examples/{widget_table_flex → widget_text_width}/app.rbs +2 -3
- data/sig/ratatui_ruby/event.rbs +11 -1
- data/sig/ratatui_ruby/frame.rbs +2 -0
- data/sig/ratatui_ruby/list_state.rbs +13 -0
- data/sig/ratatui_ruby/ratatui_ruby.rbs +2 -2
- data/sig/ratatui_ruby/schema/bar_chart/bar.rbs +3 -3
- data/sig/ratatui_ruby/schema/gauge.rbs +2 -2
- 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/row.rbs +22 -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 +9 -6
- data/sig/ratatui_ruby/scrollbar_state.rbs +18 -0
- data/sig/ratatui_ruby/session.rbs +41 -48
- 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/sig/ratatui_ruby/tui/buffer_factories.rbs +10 -0
- data/sig/ratatui_ruby/tui/canvas_factories.rbs +14 -0
- data/sig/ratatui_ruby/tui/core.rbs +14 -0
- data/sig/ratatui_ruby/tui/layout_factories.rbs +19 -0
- data/sig/ratatui_ruby/tui/state_factories.rbs +12 -0
- data/sig/ratatui_ruby/tui/style_factories.rbs +10 -0
- data/sig/ratatui_ruby/tui/text_factories.rbs +14 -0
- data/sig/ratatui_ruby/tui/widget_factories.rbs +39 -0
- data/sig/ratatui_ruby/tui.rbs +19 -0
- data/tasks/autodoc/examples.rb +79 -0
- data/tasks/autodoc.rake +7 -35
- data/tasks/bump/changelog.rb +3 -3
- data/tasks/bump/links.rb +67 -0
- data/tasks/sourcehut.rake +64 -21
- data/tasks/terminal_preview/app_screenshot.rb +13 -3
- data/tasks/terminal_preview/saved_screenshot.rb +4 -3
- metadata +169 -48
- data/doc/contributors/dwim_dx.md +0 -366
- data/doc/images/app_analytics.png +0 -0
- data/doc/images/app_custom_widget.png +0 -0
- data/doc/images/app_mouse_events.png +0 -0
- data/doc/images/app_table_select.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_list_styles.png +0 -0
- data/doc/images/widget_table_flex.png +0 -0
- data/examples/app_all_events/model/events.rb +0 -180
- data/examples/app_all_events/model/highlight.rb +0 -57
- data/examples/app_all_events/test/snapshots/after_focus_lost.txt +0 -24
- data/examples/app_all_events/test/snapshots/after_focus_regained.txt +0 -24
- data/examples/app_all_events/test/snapshots/after_horizontal_resize.txt +0 -24
- data/examples/app_all_events/test/snapshots/after_key_a.txt +0 -24
- data/examples/app_all_events/test/snapshots/after_key_ctrl_x.txt +0 -24
- data/examples/app_all_events/test/snapshots/after_mouse_click.txt +0 -24
- data/examples/app_all_events/test/snapshots/after_mouse_drag.txt +0 -24
- data/examples/app_all_events/test/snapshots/after_multiple_events.txt +0 -24
- data/examples/app_all_events/test/snapshots/after_paste.txt +0 -24
- data/examples/app_all_events/test/snapshots/after_resize.txt +0 -24
- data/examples/app_all_events/test/snapshots/after_right_click.txt +0 -24
- data/examples/app_all_events/test/snapshots/after_vertical_resize.txt +0 -24
- data/examples/app_all_events/test/snapshots/initial_state.txt +0 -24
- data/examples/app_all_events/view_state.rb +0 -42
- data/examples/app_color_picker/scene.rb +0 -201
- data/examples/widget_block_padding/app.rb +0 -67
- data/examples/widget_block_titles/app.rb +0 -69
- data/examples/widget_list_styles/app.rb +0 -141
- data/examples/widget_table_flex/app.rb +0 -95
- data/lib/ratatui_ruby/session/autodoc.rb +0 -417
- data/lib/ratatui_ruby/session.rb +0 -163
- data/sig/examples/widget_block_padding/app.rbs +0 -11
- data/sig/examples/widget_block_titles/app.rbs +0 -11
- data/sig/examples/widget_list_styles/app.rbs +0 -11
- data/tasks/autodoc/inventory.rb +0 -61
- data/tasks/autodoc/notice.rb +0 -26
- data/tasks/autodoc/rbs.rb +0 -38
- data/tasks/autodoc/rdoc.rb +0 -45
- data/tasks/bump/comparison_links.rb +0 -41
- /data/doc/images/{app_map_demo.png → widget_map_demo.png} +0 -0
|
@@ -0,0 +1,141 @@
|
|
|
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
|
+
module Widgets
|
|
8
|
+
# Displays structured data in rows and columns.
|
|
9
|
+
#
|
|
10
|
+
# Data is often multidimensional. You need to show relationships between fields (Name, Age, ID).
|
|
11
|
+
# Aligning columns manually in a monospaced environment is painful and error-prone.
|
|
12
|
+
#
|
|
13
|
+
# This widget creates a grid. It enforces column widths using constraints. It renders headers, rows, and footers aligned perfectly.
|
|
14
|
+
#
|
|
15
|
+
# Use it to display database records, logs, or file lists.
|
|
16
|
+
#
|
|
17
|
+
# {rdoc-image:/doc/images/widget_table_flex.png}[link:/examples/widget_table_flex/app_rb.html]
|
|
18
|
+
#
|
|
19
|
+
# === Example
|
|
20
|
+
#
|
|
21
|
+
# Run the interactive demo from the terminal:
|
|
22
|
+
#
|
|
23
|
+
# ruby examples/widget_table_flex/app.rb
|
|
24
|
+
class Table < Data.define(:header, :rows, :widths, :row_highlight_style, :highlight_symbol, :highlight_spacing, :column_highlight_style, :cell_highlight_style, :selected_row, :selected_column, :offset, :block, :footer, :flex, :style, :column_spacing)
|
|
25
|
+
##
|
|
26
|
+
# :attr_reader: header
|
|
27
|
+
# Header row content (Array of Strings, Text::Spans, Text::Lines, or Paragraphs).
|
|
28
|
+
|
|
29
|
+
##
|
|
30
|
+
# :attr_reader: rows
|
|
31
|
+
# Data rows (Array of Arrays). Each cell can be String, Text::Span, Text::Line, Paragraph, or Cell.
|
|
32
|
+
|
|
33
|
+
##
|
|
34
|
+
# :attr_reader: widths
|
|
35
|
+
# Column width constraints (Array of Constraint).
|
|
36
|
+
|
|
37
|
+
##
|
|
38
|
+
# :attr_reader: row_highlight_style
|
|
39
|
+
# Style for the selected row.
|
|
40
|
+
|
|
41
|
+
##
|
|
42
|
+
# :attr_reader: highlight_symbol
|
|
43
|
+
# Symbol for the selected row.
|
|
44
|
+
|
|
45
|
+
##
|
|
46
|
+
# :attr_reader: highlight_spacing
|
|
47
|
+
# When to show the highlight symbol column (<tt>:always</tt>, <tt>:when_selected</tt>, <tt>:never</tt>).
|
|
48
|
+
|
|
49
|
+
##
|
|
50
|
+
# :attr_reader: column_highlight_style
|
|
51
|
+
# Style for the selected column.
|
|
52
|
+
|
|
53
|
+
##
|
|
54
|
+
# :attr_reader: cell_highlight_style
|
|
55
|
+
# Style for the selected cell (intersection of row and column).
|
|
56
|
+
|
|
57
|
+
##
|
|
58
|
+
# :attr_reader: selected_row
|
|
59
|
+
# Index of the selected row (Integer or nil).
|
|
60
|
+
|
|
61
|
+
##
|
|
62
|
+
# :attr_reader: selected_column
|
|
63
|
+
# Index of the selected column (Integer or nil).
|
|
64
|
+
|
|
65
|
+
##
|
|
66
|
+
# :attr_reader: offset
|
|
67
|
+
# Scroll offset (Integer or nil).
|
|
68
|
+
#
|
|
69
|
+
# Controls the viewport's starting row position in the table.
|
|
70
|
+
#
|
|
71
|
+
# When +nil+ (default), Ratatui auto-scrolls to keep the selection visible ("natural scrolling").
|
|
72
|
+
#
|
|
73
|
+
# When set, forces the viewport to start at this row index. Use this for:
|
|
74
|
+
# - **Passive scrolling**: Scroll through a log table without selecting rows.
|
|
75
|
+
# - **Click-to-select math**: Calculate which row index corresponds to a click coordinate.
|
|
76
|
+
#
|
|
77
|
+
# *Important*: When both +offset+ and +selected_row+ are set, Ratatui may still adjust
|
|
78
|
+
# the viewport during rendering to ensure the selection stays visible. Set +selected_row+
|
|
79
|
+
# to +nil+ for fully manual scroll control.
|
|
80
|
+
|
|
81
|
+
##
|
|
82
|
+
# :attr_reader: block
|
|
83
|
+
# Optional wrapping block.
|
|
84
|
+
|
|
85
|
+
##
|
|
86
|
+
# :attr_reader: footer
|
|
87
|
+
# Footer row content (Array of Strings, Text::Spans, Text::Lines, or Paragraphs).
|
|
88
|
+
|
|
89
|
+
##
|
|
90
|
+
# :attr_reader: flex
|
|
91
|
+
# Flex mode for column distribution.
|
|
92
|
+
|
|
93
|
+
##
|
|
94
|
+
# :attr_reader: style
|
|
95
|
+
# Base style for the entire table.
|
|
96
|
+
|
|
97
|
+
##
|
|
98
|
+
# :attr_reader: column_spacing
|
|
99
|
+
# Spacing between columns (Integer, default 1).
|
|
100
|
+
|
|
101
|
+
# Creates a new Table.
|
|
102
|
+
#
|
|
103
|
+
# [header] Array of strings, Text::Spans, Text::Lines, or paragraphs.
|
|
104
|
+
# [rows] 2D Array where each cell is String, Text::Span, Text::Line, Paragraph, or Cell.
|
|
105
|
+
# [widths] Array of Constraints.
|
|
106
|
+
# [row_highlight_style] Style object.
|
|
107
|
+
# [highlight_symbol] String.
|
|
108
|
+
# [highlight_spacing] Symbol (optional, default: <tt>:when_selected</tt>).
|
|
109
|
+
# [column_highlight_style] Style object.
|
|
110
|
+
# [cell_highlight_style] Style object.
|
|
111
|
+
# [selected_row] Integer (nullable).
|
|
112
|
+
# [selected_column] Integer (nullable).
|
|
113
|
+
# [offset] Numeric (nullable, coerced to Integer). Forces scroll position when set.
|
|
114
|
+
# [block] Block (optional).
|
|
115
|
+
# [footer] Array of strings/paragraphs (optional).
|
|
116
|
+
# [flex] Symbol (optional, default: <tt>:legacy</tt>).
|
|
117
|
+
# [style] Style object or Hash (optional).
|
|
118
|
+
# [column_spacing] Integer (optional, default: 1).
|
|
119
|
+
def initialize(header: nil, rows: [], widths: [], row_highlight_style: nil, highlight_symbol: "> ", highlight_spacing: :when_selected, column_highlight_style: nil, cell_highlight_style: nil, selected_row: nil, selected_column: nil, offset: nil, block: nil, footer: nil, flex: :legacy, style: nil, column_spacing: 1)
|
|
120
|
+
super(
|
|
121
|
+
header:,
|
|
122
|
+
rows:,
|
|
123
|
+
widths:,
|
|
124
|
+
row_highlight_style:,
|
|
125
|
+
highlight_symbol:,
|
|
126
|
+
highlight_spacing:,
|
|
127
|
+
column_highlight_style:,
|
|
128
|
+
cell_highlight_style:,
|
|
129
|
+
selected_row: selected_row.nil? ? nil : Integer(selected_row),
|
|
130
|
+
selected_column: selected_column.nil? ? nil : Integer(selected_column),
|
|
131
|
+
offset: offset.nil? ? nil : Integer(offset),
|
|
132
|
+
block:,
|
|
133
|
+
footer:,
|
|
134
|
+
flex:,
|
|
135
|
+
style:,
|
|
136
|
+
column_spacing: Integer(column_spacing)
|
|
137
|
+
)
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
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
|
+
module Widgets
|
|
8
|
+
# Displays a tab bar for navigation.
|
|
9
|
+
#
|
|
10
|
+
# Screen real estate is limited. You cannot show everything at once. Segregating content into views is necessary for complex apps.
|
|
11
|
+
#
|
|
12
|
+
# This widget separates dimensions. It displays a row of titles, indicating which view is active.
|
|
13
|
+
#
|
|
14
|
+
# Use it at the top of your interface to switch between major modes or contexts.
|
|
15
|
+
#
|
|
16
|
+
# {rdoc-image:/doc/images/widget_tabs_demo.png}[link:/examples/widget_tabs_demo/app_rb.html]
|
|
17
|
+
#
|
|
18
|
+
# === Example
|
|
19
|
+
#
|
|
20
|
+
# Run the interactive demo from the terminal:
|
|
21
|
+
#
|
|
22
|
+
# ruby examples/widget_tabs_demo/app.rb
|
|
23
|
+
class Tabs < Data.define(:titles, :selected_index, :block, :divider, :highlight_style, :style, :padding_left, :padding_right)
|
|
24
|
+
##
|
|
25
|
+
# :attr_reader: titles
|
|
26
|
+
# Tab titles (Array of Strings).
|
|
27
|
+
|
|
28
|
+
##
|
|
29
|
+
# :attr_reader: selected_index
|
|
30
|
+
# Index of the active tab.
|
|
31
|
+
|
|
32
|
+
##
|
|
33
|
+
# :attr_reader: block
|
|
34
|
+
# Optional wrapping block.
|
|
35
|
+
|
|
36
|
+
##
|
|
37
|
+
# :attr_reader: divider
|
|
38
|
+
# Separator string between tabs.
|
|
39
|
+
|
|
40
|
+
##
|
|
41
|
+
# :attr_reader: highlight_style
|
|
42
|
+
# Style for the selected tab title.
|
|
43
|
+
|
|
44
|
+
##
|
|
45
|
+
# :attr_reader: style
|
|
46
|
+
# Base style for the tabs area.
|
|
47
|
+
|
|
48
|
+
##
|
|
49
|
+
# :attr_reader: padding_left
|
|
50
|
+
# Left padding for the tabs area (Integer, default: 0).
|
|
51
|
+
|
|
52
|
+
##
|
|
53
|
+
# :attr_reader: padding_right
|
|
54
|
+
# Right padding for the tabs area (Integer, default: 0).
|
|
55
|
+
|
|
56
|
+
# Creates a new Tabs widget.
|
|
57
|
+
#
|
|
58
|
+
# [titles] Array of Strings/Lines.
|
|
59
|
+
# [selected_index] Integer (default: 0).
|
|
60
|
+
# [block] Block (optional).
|
|
61
|
+
# [divider] String (optional).
|
|
62
|
+
# [highlight_style] Style (optional).
|
|
63
|
+
# [style] Style (optional).
|
|
64
|
+
# [padding_left] Integer (default: 0).
|
|
65
|
+
# [padding_right] Integer (default: 0).
|
|
66
|
+
def initialize(titles: [], selected_index: 0, block: nil, divider: nil, highlight_style: nil, style: nil, padding_left: 0, padding_right: 0)
|
|
67
|
+
super(
|
|
68
|
+
titles:,
|
|
69
|
+
selected_index: Integer(selected_index),
|
|
70
|
+
block:,
|
|
71
|
+
divider:,
|
|
72
|
+
highlight_style:,
|
|
73
|
+
style:,
|
|
74
|
+
padding_left: Integer(padding_left),
|
|
75
|
+
padding_right: Integer(padding_right)
|
|
76
|
+
)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Returns the total width of the tabs.
|
|
80
|
+
def width
|
|
81
|
+
RatatuiRuby._tabs_width(self)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
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
|
+
# Widget classes for building terminal UIs.
|
|
8
|
+
#
|
|
9
|
+
# This module mirrors +ratatui::widgets+ and contains all renderable
|
|
10
|
+
# widget types: Block, Paragraph, List, Table, Gauge, Chart, etc.
|
|
11
|
+
module Widgets
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Core widgets
|
|
16
|
+
require_relative "widgets/block"
|
|
17
|
+
require_relative "widgets/paragraph"
|
|
18
|
+
require_relative "widgets/list"
|
|
19
|
+
require_relative "widgets/list_item"
|
|
20
|
+
require_relative "widgets/table"
|
|
21
|
+
require_relative "widgets/row"
|
|
22
|
+
require_relative "widgets/cell"
|
|
23
|
+
require_relative "widgets/tabs"
|
|
24
|
+
require_relative "widgets/gauge"
|
|
25
|
+
require_relative "widgets/line_gauge"
|
|
26
|
+
require_relative "widgets/sparkline"
|
|
27
|
+
require_relative "widgets/bar_chart"
|
|
28
|
+
require_relative "widgets/bar_chart/bar"
|
|
29
|
+
require_relative "widgets/bar_chart/bar_group"
|
|
30
|
+
require_relative "widgets/chart"
|
|
31
|
+
require_relative "widgets/scrollbar"
|
|
32
|
+
require_relative "widgets/calendar"
|
|
33
|
+
require_relative "widgets/canvas"
|
|
34
|
+
require_relative "widgets/clear"
|
|
35
|
+
require_relative "widgets/cursor"
|
|
36
|
+
require_relative "widgets/overlay"
|
|
37
|
+
require_relative "widgets/center"
|
|
38
|
+
require_relative "widgets/ratatui_logo"
|
|
39
|
+
require_relative "widgets/ratatui_mascot"
|
|
40
|
+
require_relative "widgets/shape/label"
|
data/lib/ratatui_ruby.rb
CHANGED
|
@@ -4,37 +4,26 @@
|
|
|
4
4
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
5
5
|
|
|
6
6
|
require_relative "ratatui_ruby/version"
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
require_relative "ratatui_ruby/
|
|
10
|
-
require_relative "ratatui_ruby/
|
|
11
|
-
require_relative "ratatui_ruby/
|
|
12
|
-
require_relative "ratatui_ruby/
|
|
13
|
-
require_relative "ratatui_ruby/schema/
|
|
14
|
-
require_relative "ratatui_ruby/schema/
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
require_relative "ratatui_ruby/schema/tabs"
|
|
18
|
-
require_relative "ratatui_ruby/schema/bar_chart"
|
|
19
|
-
require_relative "ratatui_ruby/schema/bar_chart/bar"
|
|
20
|
-
require_relative "ratatui_ruby/schema/bar_chart/bar_group"
|
|
21
|
-
require_relative "ratatui_ruby/schema/sparkline"
|
|
22
|
-
require_relative "ratatui_ruby/schema/chart"
|
|
23
|
-
require_relative "ratatui_ruby/schema/clear"
|
|
24
|
-
require_relative "ratatui_ruby/schema/cursor"
|
|
25
|
-
require_relative "ratatui_ruby/schema/overlay"
|
|
26
|
-
require_relative "ratatui_ruby/schema/center"
|
|
27
|
-
require_relative "ratatui_ruby/schema/scrollbar"
|
|
28
|
-
require_relative "ratatui_ruby/schema/canvas"
|
|
29
|
-
require_relative "ratatui_ruby/schema/shape/label"
|
|
30
|
-
require_relative "ratatui_ruby/schema/calendar"
|
|
31
|
-
require_relative "ratatui_ruby/schema/ratatui_logo"
|
|
32
|
-
require_relative "ratatui_ruby/schema/ratatui_mascot"
|
|
33
|
-
require_relative "ratatui_ruby/schema/text"
|
|
34
|
-
require_relative "ratatui_ruby/schema/draw"
|
|
7
|
+
|
|
8
|
+
# New modularized structure (mirrors ratatui Rust crate)
|
|
9
|
+
require_relative "ratatui_ruby/layout" # Layout::Rect, Layout::Constraint, Layout::Layout
|
|
10
|
+
require_relative "ratatui_ruby/style" # Style::Style
|
|
11
|
+
require_relative "ratatui_ruby/widgets" # Widgets::Block, Widgets::Paragraph, etc.
|
|
12
|
+
require_relative "ratatui_ruby/buffer" # Buffer::Cell (for inspection)
|
|
13
|
+
require_relative "ratatui_ruby/schema/text" # Text::Span, Text::Line
|
|
14
|
+
require_relative "ratatui_ruby/schema/draw" # Draw commands
|
|
15
|
+
|
|
16
|
+
# Event types
|
|
35
17
|
require_relative "ratatui_ruby/event"
|
|
36
|
-
|
|
18
|
+
|
|
19
|
+
# Frame and state objects
|
|
37
20
|
require_relative "ratatui_ruby/frame"
|
|
21
|
+
require_relative "ratatui_ruby/list_state"
|
|
22
|
+
require_relative "ratatui_ruby/table_state"
|
|
23
|
+
require_relative "ratatui_ruby/scrollbar_state"
|
|
24
|
+
|
|
25
|
+
# TUI facade (for external instantiation and caching)
|
|
26
|
+
require_relative "ratatui_ruby/tui"
|
|
38
27
|
|
|
39
28
|
begin
|
|
40
29
|
require "ratatui_ruby/ratatui_ruby"
|
|
@@ -52,7 +41,13 @@ end
|
|
|
52
41
|
# Use `RatatuiRuby.run` to start your application.
|
|
53
42
|
module RatatuiRuby
|
|
54
43
|
# Generic error class for RatatuiRuby.
|
|
55
|
-
class Error < StandardError
|
|
44
|
+
class Error < StandardError
|
|
45
|
+
# Raised when a terminal operation fails (e.g., I/O error, backend failure).
|
|
46
|
+
class Terminal < Error; end
|
|
47
|
+
|
|
48
|
+
# Raised when an API safety contract is violated (e.g., accessing a Frame outside its valid scope).
|
|
49
|
+
class Safety < Error; end
|
|
50
|
+
end
|
|
56
51
|
|
|
57
52
|
##
|
|
58
53
|
# Initializes the terminal for TUI mode.
|
|
@@ -119,19 +114,19 @@ module RatatuiRuby
|
|
|
119
114
|
# pass a block to manipulate the frame directly. The block receives a
|
|
120
115
|
# {Frame} object for imperative drawing.
|
|
121
116
|
#
|
|
122
|
-
# [tree] A widget tree (Paragraph, Layout, etc.) to render. Optional if
|
|
117
|
+
# [tree] A widget tree (Widgets::Paragraph, Layout::Layout, etc.) to render. Optional if
|
|
123
118
|
# a block is given.
|
|
124
119
|
#
|
|
125
120
|
# === Examples
|
|
126
121
|
#
|
|
127
122
|
# Legacy declarative style (tree-based):
|
|
128
123
|
#
|
|
129
|
-
# RatatuiRuby.draw(Paragraph.new(text: "Hello"))
|
|
124
|
+
# RatatuiRuby.draw(Widgets::Paragraph.new(text: "Hello"))
|
|
130
125
|
#
|
|
131
126
|
# New imperative style (block-based):
|
|
132
127
|
#
|
|
133
128
|
# RatatuiRuby.draw do |frame|
|
|
134
|
-
# frame.render_widget(Paragraph.new(text: "Hello"), frame.area)
|
|
129
|
+
# frame.render_widget(Widgets::Paragraph.new(text: "Hello"), frame.area)
|
|
135
130
|
# end
|
|
136
131
|
#
|
|
137
132
|
def self.draw(tree = nil, &block)
|
|
@@ -155,41 +150,54 @@ module RatatuiRuby
|
|
|
155
150
|
##
|
|
156
151
|
# Checks for user input.
|
|
157
152
|
#
|
|
158
|
-
#
|
|
159
|
-
# Returns RatatuiRuby::Event::None if the queue is empty (non-blocking).
|
|
153
|
+
# Interactive apps must respond to input. Loops need to poll without burning CPU.
|
|
160
154
|
#
|
|
161
|
-
#
|
|
155
|
+
# This method checks for an event. It returns the event if one is found. It returns {RatatuiRuby::Event::None} if the timeout expires.
|
|
162
156
|
#
|
|
157
|
+
# [timeout] Float seconds to wait (default: 0.016).
|
|
158
|
+
# Pass <tt>nil</tt> to block indefinitely (wait forever).
|
|
159
|
+
# Pass <tt>0.0</tt> for a non-blocking check.
|
|
160
|
+
#
|
|
161
|
+
# === Examples
|
|
162
|
+
#
|
|
163
|
+
# # Standard loop (approx 60 FPS)
|
|
163
164
|
# event = RatatuiRuby.poll_event
|
|
164
|
-
# if event.none?
|
|
165
|
-
# puts "No input available"
|
|
166
|
-
# elsif event.key?
|
|
167
|
-
# puts "Key pressed"
|
|
168
|
-
# end
|
|
169
165
|
#
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
166
|
+
# # Block until event (pauses execution)
|
|
167
|
+
# event = RatatuiRuby.poll_event(timeout: nil)
|
|
168
|
+
#
|
|
169
|
+
# # Non-blocking check (returns immediately)
|
|
170
|
+
# event = RatatuiRuby.poll_event(timeout: 0.0)
|
|
171
|
+
#
|
|
172
|
+
def self.poll_event(timeout: 0.016)
|
|
173
|
+
raise ArgumentError, "timeout must be non-negative" if timeout && timeout < 0
|
|
174
|
+
|
|
175
|
+
raw = _poll_event(timeout)
|
|
176
|
+
return Event::None.new.freeze if raw.nil?
|
|
173
177
|
|
|
174
178
|
case raw[:type]
|
|
175
179
|
when :key
|
|
176
|
-
Event::Key.new(
|
|
180
|
+
Event::Key.new(
|
|
181
|
+
code: raw[:code],
|
|
182
|
+
modifiers: (raw[:modifiers] || []).freeze,
|
|
183
|
+
kind: raw[:kind] || :standard
|
|
184
|
+
).freeze
|
|
177
185
|
when :mouse
|
|
178
186
|
Event::Mouse.new(
|
|
179
187
|
kind: raw[:kind].to_s,
|
|
180
188
|
x: raw[:x],
|
|
181
189
|
y: raw[:y],
|
|
182
190
|
button: raw[:button].to_s,
|
|
183
|
-
modifiers: raw[:modifiers] || []
|
|
184
|
-
)
|
|
191
|
+
modifiers: (raw[:modifiers] || []).freeze
|
|
192
|
+
).freeze
|
|
185
193
|
when :resize
|
|
186
|
-
Event::Resize.new(width: raw[:width], height: raw[:height])
|
|
194
|
+
Event::Resize.new(width: raw[:width], height: raw[:height]).freeze
|
|
187
195
|
when :paste
|
|
188
|
-
Event::Paste.new(content: raw[:content])
|
|
196
|
+
Event::Paste.new(content: raw[:content]).freeze
|
|
189
197
|
when :focus_gained
|
|
190
|
-
Event::FocusGained.new
|
|
198
|
+
Event::FocusGained.new.freeze
|
|
191
199
|
when :focus_lost
|
|
192
|
-
Event::FocusLost.new
|
|
200
|
+
Event::FocusLost.new.freeze
|
|
193
201
|
else
|
|
194
202
|
# Fallback for unknown events, though ideally we cover them all
|
|
195
203
|
nil
|
|
@@ -204,7 +212,7 @@ module RatatuiRuby
|
|
|
204
212
|
#
|
|
205
213
|
# Managing generic setup/teardown (raw mode, alternate screen) manualy is error-prone. If your app crashes, the terminal might be left in a broken state.
|
|
206
214
|
#
|
|
207
|
-
# This method handles the safety net. It initializes the terminal, yields a {
|
|
215
|
+
# This method handles the safety net. It initializes the terminal, yields a {TUI}, and ensures the terminal state is restored even if exceptions occur.
|
|
208
216
|
#
|
|
209
217
|
# === Example
|
|
210
218
|
#
|
|
@@ -213,9 +221,8 @@ module RatatuiRuby
|
|
|
213
221
|
# sleep 1
|
|
214
222
|
# end
|
|
215
223
|
def self.run(focus_events: true, bracketed_paste: true)
|
|
216
|
-
require_relative "ratatui_ruby/session"
|
|
217
224
|
init_terminal(focus_events:, bracketed_paste:)
|
|
218
|
-
yield
|
|
225
|
+
yield TUI.new
|
|
219
226
|
ensure
|
|
220
227
|
restore_terminal
|
|
221
228
|
end
|
|
@@ -226,7 +233,7 @@ module RatatuiRuby
|
|
|
226
233
|
# When writing tests, you need to verify that your widget drew the correct characters and styles.
|
|
227
234
|
# This method provides deep inspection of the cell's state (symbol, colors, modifiers).
|
|
228
235
|
#
|
|
229
|
-
# Returns a {Cell} object.
|
|
236
|
+
# Returns a {Buffer::Cell} object.
|
|
230
237
|
#
|
|
231
238
|
# Values depend on what the backend has rendered. If nothing has been rendered to a cell, it may contain defaults (empty symbol, nil colors).
|
|
232
239
|
#
|
|
@@ -239,7 +246,7 @@ module RatatuiRuby
|
|
|
239
246
|
#
|
|
240
247
|
def self.get_cell_at(x, y)
|
|
241
248
|
raw = _get_cell_at(x, y)
|
|
242
|
-
Cell.new(
|
|
249
|
+
Buffer::Cell.new(
|
|
243
250
|
char: raw["char"],
|
|
244
251
|
fg: raw["fg"],
|
|
245
252
|
bg: raw["bg"],
|
|
@@ -251,5 +258,5 @@ module RatatuiRuby
|
|
|
251
258
|
private_class_method :_get_cell_at
|
|
252
259
|
|
|
253
260
|
# Hide native Layout._split helper
|
|
254
|
-
Layout.singleton_class.__send__(:private, :_split)
|
|
261
|
+
Layout::Layout.singleton_class.__send__(:private, :_split)
|
|
255
262
|
end
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
|
|
4
4
|
module View
|
|
5
5
|
interface _View
|
|
6
|
-
def call(state: ViewState, tui: RatatuiRuby::
|
|
6
|
+
def call(state: ViewState, tui: RatatuiRuby::TUI, frame: RatatuiRuby::Frame, area: RatatuiRuby::Rect) -> void
|
|
7
7
|
end
|
|
8
8
|
end
|
|
@@ -10,6 +10,6 @@ class ViewState < Data
|
|
|
10
10
|
attr_reader border_color: Symbol
|
|
11
11
|
attr_reader area: RatatuiRuby::Rect?
|
|
12
12
|
|
|
13
|
-
def self.build(events: Events, focused: bool, tui: RatatuiRuby::
|
|
13
|
+
def self.build(events: Events, focused: bool, tui: RatatuiRuby::TUI, _resize_sub_counter: untyped) -> instance
|
|
14
14
|
def self.new: (?events: Events, ?focused: bool, ?hotkey_style: RatatuiRuby::Style, ?dimmed_style: RatatuiRuby::Style, ?lit_style: RatatuiRuby::Style, ?border_color: Symbol, ?area: RatatuiRuby::Rect | nil) -> instance
|
|
15
15
|
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
2
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
class AppStatefulInteraction
|
|
5
|
+
@tables: Array[String]
|
|
6
|
+
@data: Hash[String, Array[Array[String]]]
|
|
7
|
+
@list_state: RatatuiRuby::ListState
|
|
8
|
+
@table_state: RatatuiRuby::TableState
|
|
9
|
+
@active_pane: :list | :table
|
|
10
|
+
@tui: untyped
|
|
11
|
+
@style_active: RatatuiRuby::Style
|
|
12
|
+
@style_inactive: RatatuiRuby::Style
|
|
13
|
+
@style_highlight: RatatuiRuby::Style
|
|
14
|
+
@list_area: RatatuiRuby::Rect
|
|
15
|
+
@table_area: RatatuiRuby::Rect
|
|
16
|
+
|
|
17
|
+
# @public
|
|
18
|
+
def self.new: () -> AppStatefulInteraction
|
|
19
|
+
|
|
20
|
+
# @public
|
|
21
|
+
def run: () -> void
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def render: () -> void
|
|
26
|
+
def render_list: (untyped frame, RatatuiRuby::Rect area) -> void
|
|
27
|
+
def render_table: (untyped frame, RatatuiRuby::Rect area) -> void
|
|
28
|
+
def handle_input: () -> (:quit | nil)
|
|
29
|
+
def scroll_active: (Integer delta) -> void
|
|
30
|
+
def handle_click: (Integer x, Integer y) -> void
|
|
31
|
+
def handle_list_click: (Integer mouse_y) -> void
|
|
32
|
+
def handle_table_click: (Integer mouse_y) -> void
|
|
33
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
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
|
+
class WidgetBlockDemo
|
|
7
|
+
@tui: RatatuiRuby::Tui
|
|
8
|
+
@hotkey_style: RatatuiRuby::Style
|
|
9
|
+
@title_configs: Array[{name: String, title: String?}]
|
|
10
|
+
@title_index: Integer
|
|
11
|
+
@titles_configs: Array[{name: String, titles: Array[RatatuiRuby::Block::title_input]}]
|
|
12
|
+
@titles_index: Integer
|
|
13
|
+
@alignment_configs: Array[{name: String, alignment: RatatuiRuby::Alignment}]
|
|
14
|
+
@alignment_index: Integer
|
|
15
|
+
@title_styles: Array[{name: String, style: RatatuiRuby::Style?}]
|
|
16
|
+
@title_style_index: Integer
|
|
17
|
+
@border_configs: Array[{name: String, borders: Array[RatatuiRuby::Block::border_option]}]
|
|
18
|
+
@border_index: Integer
|
|
19
|
+
@border_type_configs: Array[{name: String, type: RatatuiRuby::Block::border_type?, set: Hash[Symbol, String]?}]
|
|
20
|
+
@border_type_index: Integer
|
|
21
|
+
@border_styles: Array[{name: String, style: RatatuiRuby::Style?}]
|
|
22
|
+
@border_style_index: Integer
|
|
23
|
+
@base_styles: Array[{name: String, style: RatatuiRuby::Style?}]
|
|
24
|
+
@base_style_index: Integer
|
|
25
|
+
@padding_configs: Array[{name: String, padding: RatatuiRuby::Block::padding_input}]
|
|
26
|
+
@padding_index: Integer
|
|
27
|
+
|
|
28
|
+
def self.new: () -> WidgetBlockDemo
|
|
29
|
+
def run: () -> void
|
|
30
|
+
private def render: () -> void
|
|
31
|
+
private def handle_input: () -> (:quit)?
|
|
32
|
+
end
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
2
|
-
#
|
|
3
2
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
4
3
|
|
|
5
|
-
class
|
|
4
|
+
class WidgetTextWidth
|
|
6
5
|
# @public
|
|
7
|
-
def self.new: () ->
|
|
6
|
+
def self.new: () -> WidgetTextWidth
|
|
8
7
|
|
|
9
8
|
# @public
|
|
10
9
|
def run: () -> void
|
data/sig/ratatui_ruby/event.rbs
CHANGED
|
@@ -11,11 +11,14 @@ module RatatuiRuby
|
|
|
11
11
|
def focus_lost?: () -> bool
|
|
12
12
|
def deconstruct_keys: (Array[Symbol]?) -> Hash[Symbol, untyped]
|
|
13
13
|
|
|
14
|
+
type key_kind = :standard | :function | :media | :modifier | :system
|
|
15
|
+
|
|
14
16
|
class Key < Event
|
|
15
17
|
attr_reader code: String
|
|
16
18
|
attr_reader modifiers: Array[String]
|
|
19
|
+
attr_reader kind: key_kind
|
|
17
20
|
|
|
18
|
-
def initialize: (code: String, modifiers: Array[String]) -> void
|
|
21
|
+
def initialize: (code: String, ?modifiers: Array[String], ?kind: key_kind) -> void
|
|
19
22
|
def ==: (untyped other) -> bool
|
|
20
23
|
def to_sym: () -> Symbol
|
|
21
24
|
def to_s: () -> String
|
|
@@ -24,6 +27,13 @@ module RatatuiRuby
|
|
|
24
27
|
def alt?: () -> bool
|
|
25
28
|
def shift?: () -> bool
|
|
26
29
|
def text?: () -> bool
|
|
30
|
+
def char: () -> String
|
|
31
|
+
def media?: () -> bool
|
|
32
|
+
def system?: () -> bool
|
|
33
|
+
def function?: () -> bool
|
|
34
|
+
def modifier?: () -> bool
|
|
35
|
+
def standard?: () -> bool
|
|
36
|
+
def unmodified?: () -> bool
|
|
27
37
|
def deconstruct_keys: (Array[Symbol]?) -> Hash[Symbol, untyped]
|
|
28
38
|
end
|
|
29
39
|
|
data/sig/ratatui_ruby/frame.rbs
CHANGED
|
@@ -5,5 +5,7 @@ module RatatuiRuby
|
|
|
5
5
|
class Frame
|
|
6
6
|
def area: () -> Rect
|
|
7
7
|
def render_widget: (widget widget, Rect area) -> nil
|
|
8
|
+
def render_stateful_widget: (widget widget, Rect area, (ListState | TableState | ScrollbarState) state) -> nil
|
|
9
|
+
def set_cursor_position: (Integer x, Integer y) -> nil
|
|
8
10
|
end
|
|
9
11
|
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
2
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
module RatatuiRuby
|
|
5
|
+
class ListState
|
|
6
|
+
def self.new: (?Integer? selected) -> ListState
|
|
7
|
+
def select: (Integer? index) -> nil
|
|
8
|
+
def selected: () -> Integer?
|
|
9
|
+
def offset: () -> Integer
|
|
10
|
+
def scroll_down_by: (Integer n) -> nil
|
|
11
|
+
def scroll_up_by: (Integer n) -> nil
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -12,7 +12,7 @@ module RatatuiRuby
|
|
|
12
12
|
def self.restore_terminal: () -> void
|
|
13
13
|
def self.draw: (widget tree) -> void
|
|
14
14
|
| () { (Frame) -> void } -> void
|
|
15
|
-
def self._poll_event: () -> Hash[Symbol, untyped]?
|
|
16
|
-
def self.poll_event: () -> Event?
|
|
15
|
+
def self._poll_event: (Float?) -> Hash[Symbol, untyped]?
|
|
16
|
+
def self.poll_event: (?timeout: Float?) -> Event?
|
|
17
17
|
def self.inject_test_event: (String, Hash[Symbol, untyped]) -> void
|
|
18
18
|
end
|