ratatui_ruby 0.3.1 → 0.4.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 +54 -13
- data/CHANGELOG.md +186 -1
- data/README.md +17 -15
- data/doc/application_architecture.md +116 -0
- data/doc/application_testing.md +12 -7
- data/doc/contributors/better_dx.md +543 -0
- data/doc/contributors/design/ruby_frontend.md +1 -1
- data/doc/contributors/developing_examples.md +203 -0
- data/doc/contributors/documentation_style.md +97 -0
- data/doc/contributors/dwim_dx.md +366 -0
- data/doc/contributors/example_analysis.md +82 -0
- data/doc/custom.css +14 -0
- data/doc/event_handling.md +119 -0
- data/doc/images/all_events.png +0 -0
- data/doc/images/analytics.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/custom_widget.png +0 -0
- data/doc/images/flex_layout.png +0 -0
- data/doc/images/gauge_demo.png +0 -0
- data/doc/images/hit_test.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/map_demo.png +0 -0
- data/doc/images/mouse_events.png +0 -0
- data/doc/images/popup_demo.png +0 -0
- data/doc/images/quickstart_dsl.png +0 -0
- data/doc/images/quickstart_lifecycle.png +0 -0
- data/doc/images/ratatui_logo_demo.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/doc/images/widget_style_colors.png +0 -0
- data/doc/index.md +1 -0
- data/doc/interactive_design.md +121 -0
- data/doc/quickstart.md +147 -72
- data/examples/all_events/app.rb +169 -0
- data/examples/all_events/app.rbs +7 -0
- data/examples/all_events/test_app.rb +139 -0
- data/examples/analytics/app.rb +258 -0
- data/examples/analytics/app.rbs +7 -0
- data/examples/analytics/test_app.rb +132 -0
- data/examples/block_padding/app.rb +63 -0
- data/examples/block_padding/app.rbs +7 -0
- data/examples/block_padding/test_app.rb +31 -0
- data/examples/block_titles/app.rb +61 -0
- data/examples/block_titles/app.rbs +7 -0
- data/examples/block_titles/test_app.rb +34 -0
- data/examples/box_demo/app.rb +216 -0
- data/examples/box_demo/app.rbs +7 -0
- data/examples/box_demo/test_app.rb +88 -0
- data/examples/calendar_demo/app.rb +101 -0
- data/examples/calendar_demo/app.rbs +7 -0
- data/examples/calendar_demo/test_app.rb +108 -0
- data/examples/cell_demo/app.rb +108 -0
- data/examples/cell_demo/app.rbs +7 -0
- data/examples/cell_demo/test_app.rb +36 -0
- data/examples/chart_demo/app.rb +203 -0
- data/examples/chart_demo/app.rbs +7 -0
- data/examples/chart_demo/test_app.rb +102 -0
- data/examples/custom_widget/app.rb +51 -0
- data/examples/custom_widget/app.rbs +7 -0
- data/examples/custom_widget/test_app.rb +30 -0
- data/examples/flex_layout/app.rb +156 -0
- data/examples/flex_layout/app.rbs +7 -0
- data/examples/flex_layout/test_app.rb +65 -0
- data/examples/gauge_demo/app.rb +182 -0
- data/examples/gauge_demo/app.rbs +7 -0
- data/examples/gauge_demo/test_app.rb +120 -0
- data/examples/hit_test/app.rb +175 -0
- data/examples/hit_test/app.rbs +7 -0
- data/examples/hit_test/test_app.rb +102 -0
- data/examples/line_gauge_demo/app.rb +190 -0
- data/examples/line_gauge_demo/app.rbs +7 -0
- data/examples/line_gauge_demo/test_app.rb +129 -0
- data/examples/list_demo/app.rb +253 -0
- data/examples/list_demo/app.rbs +12 -0
- data/examples/list_demo/test_app.rb +237 -0
- data/examples/list_styles/app.rb +140 -0
- data/examples/list_styles/app.rbs +7 -0
- data/examples/list_styles/test_app.rb +157 -0
- data/examples/{login_form.rb → login_form/app.rb} +12 -16
- data/examples/login_form/app.rbs +7 -0
- data/examples/login_form/test_app.rb +51 -0
- data/examples/map_demo/app.rb +90 -0
- data/examples/map_demo/app.rbs +7 -0
- data/examples/map_demo/test_app.rb +149 -0
- data/examples/{mouse_events.rb → mouse_events/app.rb} +29 -27
- data/examples/mouse_events/app.rbs +7 -0
- data/examples/mouse_events/test_app.rb +53 -0
- data/examples/{popup_demo.rb → popup_demo/app.rb} +15 -17
- data/examples/popup_demo/app.rbs +7 -0
- data/examples/{test_popup_demo.rb → popup_demo/test_app.rb} +18 -26
- data/examples/quickstart_dsl/app.rb +36 -0
- data/examples/quickstart_dsl/app.rbs +7 -0
- data/examples/quickstart_dsl/test_app.rb +29 -0
- data/examples/quickstart_lifecycle/app.rb +39 -0
- data/examples/quickstart_lifecycle/app.rbs +7 -0
- data/examples/quickstart_lifecycle/test_app.rb +29 -0
- data/examples/ratatui_logo_demo/app.rb +79 -0
- data/examples/ratatui_logo_demo/app.rbs +7 -0
- data/examples/ratatui_logo_demo/test_app.rb +51 -0
- data/examples/ratatui_mascot_demo/app.rb +84 -0
- data/examples/ratatui_mascot_demo/app.rbs +7 -0
- data/examples/ratatui_mascot_demo/test_app.rb +47 -0
- data/examples/readme_usage/app.rb +29 -0
- data/examples/readme_usage/app.rbs +7 -0
- data/examples/readme_usage/test_app.rb +29 -0
- data/examples/rich_text/app.rb +141 -0
- data/examples/rich_text/app.rbs +7 -0
- data/examples/rich_text/test_app.rb +166 -0
- data/examples/scroll_text/app.rb +103 -0
- data/examples/scroll_text/app.rbs +7 -0
- data/examples/scroll_text/test_app.rb +110 -0
- data/examples/scrollbar_demo/app.rb +143 -0
- data/examples/scrollbar_demo/app.rbs +7 -0
- data/examples/scrollbar_demo/test_app.rb +77 -0
- data/examples/sparkline_demo/app.rb +240 -0
- data/examples/sparkline_demo/app.rbs +10 -0
- data/examples/sparkline_demo/test_app.rb +107 -0
- data/examples/table_flex/app.rb +65 -0
- data/examples/table_flex/app.rbs +7 -0
- data/examples/table_flex/test_app.rb +36 -0
- data/examples/table_select/app.rb +198 -0
- data/examples/table_select/app.rbs +7 -0
- data/examples/table_select/test_app.rb +180 -0
- data/examples/widget_style_colors/app.rb +104 -0
- data/examples/widget_style_colors/app.rbs +14 -0
- data/examples/widget_style_colors/test_app.rb +48 -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 +218 -229
- data/ext/ratatui_ruby/src/lib.rs +38 -10
- data/ext/ratatui_ruby/src/rendering.rs +90 -10
- data/ext/ratatui_ruby/src/style.rs +281 -98
- data/ext/ratatui_ruby/src/terminal.rs +119 -25
- data/ext/ratatui_ruby/src/text.rs +171 -0
- data/ext/ratatui_ruby/src/widgets/barchart.rs +97 -24
- data/ext/ratatui_ruby/src/widgets/block.rs +31 -3
- data/ext/ratatui_ruby/src/widgets/calendar.rs +45 -44
- data/ext/ratatui_ruby/src/widgets/canvas.rs +46 -29
- data/ext/ratatui_ruby/src/widgets/chart.rs +69 -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 +218 -15
- data/ext/ratatui_ruby/src/widgets/line_gauge.rs +92 -0
- data/ext/ratatui_ruby/src/widgets/list.rs +91 -11
- data/ext/ratatui_ruby/src/widgets/mod.rs +3 -0
- data/ext/ratatui_ruby/src/widgets/overlay.rs +3 -2
- data/ext/ratatui_ruby/src/widgets/paragraph.rs +35 -13
- data/ext/ratatui_ruby/src/widgets/ratatui_logo.rs +29 -0
- data/ext/ratatui_ruby/src/widgets/ratatui_mascot.rs +44 -0
- data/ext/ratatui_ruby/src/widgets/scrollbar.rs +59 -7
- data/ext/ratatui_ruby/src/widgets/sparkline.rs +70 -6
- data/ext/ratatui_ruby/src/widgets/table.rs +173 -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/paste.rb +71 -0
- data/lib/ratatui_ruby/event/resize.rb +80 -0
- data/lib/ratatui_ruby/event.rb +79 -0
- data/lib/ratatui_ruby/schema/bar_chart/bar.rb +45 -0
- data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +27 -0
- data/lib/ratatui_ruby/schema/bar_chart.rb +228 -19
- data/lib/ratatui_ruby/schema/block.rb +186 -14
- data/lib/ratatui_ruby/schema/calendar.rb +74 -17
- data/lib/ratatui_ruby/schema/canvas.rb +215 -48
- data/lib/ratatui_ruby/schema/center.rb +49 -11
- data/lib/ratatui_ruby/schema/chart.rb +151 -41
- data/lib/ratatui_ruby/schema/clear.rb +41 -72
- data/lib/ratatui_ruby/schema/constraint.rb +82 -22
- data/lib/ratatui_ruby/schema/cursor.rb +27 -9
- data/lib/ratatui_ruby/schema/draw.rb +53 -0
- data/lib/ratatui_ruby/schema/gauge.rb +59 -15
- data/lib/ratatui_ruby/schema/layout.rb +95 -13
- data/lib/ratatui_ruby/schema/line_gauge.rb +78 -0
- data/lib/ratatui_ruby/schema/list.rb +93 -19
- data/lib/ratatui_ruby/schema/overlay.rb +34 -8
- data/lib/ratatui_ruby/schema/paragraph.rb +87 -30
- data/lib/ratatui_ruby/schema/ratatui_logo.rb +25 -0
- data/lib/ratatui_ruby/schema/ratatui_mascot.rb +29 -0
- data/lib/ratatui_ruby/schema/rect.rb +64 -15
- data/lib/ratatui_ruby/schema/scrollbar.rb +132 -24
- data/lib/ratatui_ruby/schema/shape/label.rb +66 -0
- data/lib/ratatui_ruby/schema/sparkline.rb +122 -15
- data/lib/ratatui_ruby/schema/style.rb +49 -21
- data/lib/ratatui_ruby/schema/table.rb +119 -21
- data/lib/ratatui_ruby/schema/tabs.rb +75 -13
- data/lib/ratatui_ruby/schema/text.rb +90 -0
- data/lib/ratatui_ruby/session.rb +146 -0
- data/lib/ratatui_ruby/test_helper.rb +156 -13
- data/lib/ratatui_ruby/version.rb +1 -1
- data/lib/ratatui_ruby.rb +143 -23
- data/sig/ratatui_ruby/event.rbs +69 -0
- data/sig/ratatui_ruby/ratatui_ruby.rbs +2 -1
- 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 +23 -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/{lib/ratatui_ruby/output.rb → sig/ratatui_ruby/schema/ratatui_logo.rbs} +3 -2
- 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/tasks/resources/build.yml.erb +13 -11
- data/tasks/terminal_preview/app_screenshot.rb +35 -0
- data/tasks/terminal_preview/crash_report.rb +54 -0
- data/tasks/terminal_preview/example_app.rb +25 -0
- data/tasks/terminal_preview/launcher_script.rb +48 -0
- data/tasks/terminal_preview/preview_collection.rb +60 -0
- data/tasks/terminal_preview/preview_timing.rb +22 -0
- data/tasks/terminal_preview/safety_confirmation.rb +58 -0
- data/tasks/terminal_preview/saved_screenshot.rb +55 -0
- data/tasks/terminal_preview/system_appearance.rb +11 -0
- data/tasks/terminal_preview/terminal_window.rb +138 -0
- data/tasks/terminal_preview/window_id.rb +14 -0
- data/tasks/terminal_preview.rake +28 -0
- data/tasks/test.rake +1 -1
- metadata +174 -53
- 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/map_demo.rb +0 -58
- 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_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
data/doc/quickstart.md
CHANGED
|
@@ -14,18 +14,21 @@ Add this line to your application's Gemfile:
|
|
|
14
14
|
gem "ratatui_ruby"
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
+
|
|
17
18
|
And then execute:
|
|
18
19
|
|
|
19
20
|
```bash
|
|
20
21
|
bundle install
|
|
21
22
|
```
|
|
22
23
|
|
|
24
|
+
|
|
23
25
|
Or install it yourself as:
|
|
24
26
|
|
|
25
27
|
```bash
|
|
26
28
|
gem install ratatui_ruby
|
|
27
29
|
```
|
|
28
30
|
|
|
31
|
+
|
|
29
32
|
## Basic Application
|
|
30
33
|
|
|
31
34
|
Here is a "Hello World" application that demonstrates the core lifecycle of a **ratatui_ruby** app.
|
|
@@ -41,13 +44,16 @@ begin
|
|
|
41
44
|
loop do
|
|
42
45
|
# 2. Create your UI (Immediate Mode)
|
|
43
46
|
# We define a Paragraph widget inside a Block with a title and borders.
|
|
47
|
+
# Other widgets include RatatuiRuby::RatatuiMascot, RatatuiRuby::RatatuiLogo, etc.
|
|
44
48
|
view = RatatuiRuby::Paragraph.new(
|
|
45
49
|
text: "Hello, Ratatui! Press 'q' to quit.",
|
|
46
|
-
|
|
50
|
+
alignment: :center,
|
|
47
51
|
block: RatatuiRuby::Block.new(
|
|
48
52
|
title: "My Ruby TUI App",
|
|
53
|
+
title_alignment: :center,
|
|
49
54
|
borders: [:all],
|
|
50
|
-
border_color: "cyan"
|
|
55
|
+
border_color: "cyan",
|
|
56
|
+
style: { fg: "white" }
|
|
51
57
|
)
|
|
52
58
|
)
|
|
53
59
|
|
|
@@ -56,9 +62,7 @@ begin
|
|
|
56
62
|
|
|
57
63
|
# 4. Poll for events
|
|
58
64
|
event = RatatuiRuby.poll_event
|
|
59
|
-
if event
|
|
60
|
-
break
|
|
61
|
-
end
|
|
65
|
+
break if event == "q" || event == :ctrl_c
|
|
62
66
|
end
|
|
63
67
|
ensure
|
|
64
68
|
# 5. Restore the terminal to its original state
|
|
@@ -66,7 +70,7 @@ ensure
|
|
|
66
70
|
end
|
|
67
71
|
```
|
|
68
72
|
|
|
69
|
-

|
|
70
74
|
|
|
71
75
|
### How it works
|
|
72
76
|
|
|
@@ -76,121 +80,192 @@ end
|
|
|
76
80
|
4. **`RatatuiRuby.poll_event`**: Checks for keyboard, mouse, or resize events.
|
|
77
81
|
5. **`RatatuiRuby.restore_terminal`**: Crucial for leaving raw mode and returning the user to their shell properly. Always wrap your loop in a `begin...ensure` block to guarantee this runs.
|
|
78
82
|
|
|
79
|
-
###
|
|
83
|
+
### Idiomatic Session
|
|
80
84
|
|
|
81
|
-
|
|
85
|
+
You can simplify your code by using `RatatuiRuby.run`. This method handles the terminal lifecycle for you, yielding a `Session` object with factory methods for widgets.
|
|
82
86
|
|
|
83
87
|
```rb
|
|
84
88
|
require "ratatui_ruby"
|
|
85
89
|
|
|
86
|
-
# 1. Initialize the terminal
|
|
87
|
-
RatatuiRuby.
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
90
|
+
# 1. Initialize the terminal and ensure it is restored.
|
|
91
|
+
RatatuiRuby.run do |tui|
|
|
92
|
+
loop do
|
|
93
|
+
# 2. Create your UI with methods instead of classes.
|
|
94
|
+
view = tui.paragraph(
|
|
95
|
+
text: "Hello, Ratatui! Press 'q' to quit.",
|
|
96
|
+
alignment: :center,
|
|
97
|
+
block: tui.block(
|
|
98
|
+
title: "My Ruby TUI App",
|
|
99
|
+
title_alignment: :center,
|
|
100
|
+
borders: [:all],
|
|
101
|
+
border_color: "cyan",
|
|
102
|
+
style: { fg: "white" }
|
|
103
|
+
)
|
|
96
104
|
)
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
if event && event[:type] == :key && event[:code] == "q"
|
|
104
|
-
break
|
|
105
|
+
|
|
106
|
+
# 3. Use RatatuiRuby methods, too.
|
|
107
|
+
tui.draw(view)
|
|
108
|
+
event = tui.poll_event
|
|
109
|
+
|
|
110
|
+
break if event == "q" || event == :ctrl_c
|
|
105
111
|
end
|
|
106
112
|
end
|
|
107
|
-
|
|
113
|
+
|
|
108
114
|
|
|
109
115
|
#### How it works
|
|
110
116
|
|
|
111
|
-
1. **`RatatuiRuby.
|
|
112
|
-
2. **Widget Shorthand**: The block yields a
|
|
113
|
-
3. **Method
|
|
117
|
+
1. **`RatatuiRuby.run`**: This context manager initializes the terminal before the block starts and ensures `restore_terminal` is called when the block exits (even if an error occurs).
|
|
118
|
+
2. **Widget Shorthand**: The block yields a `Session` object (here named `tui`). This object provides factory methods for every widget, allowing you to write `tui.paragraph(...)` instead of the more verbose `RatatuiRuby::Paragraph.new(...)`.
|
|
119
|
+
3. **Method Shorthand**: The session object also provides aliases for module functions of `RatatuiRuby`, allowing you to write `tui.draw(...)` instead of the more verbose `RatatuiRuby::draw(...)`.
|
|
120
|
+
|
|
121
|
+
For a deeper dive into the available application architectures (Manual vs Managed), see [Application Architecture](./application_architecture.md).
|
|
114
122
|
|
|
115
123
|
## Examples
|
|
116
124
|
|
|
117
125
|
To see more complex layouts and widget usage, check out the `examples/` directory in the repository.
|
|
118
126
|
|
|
119
|
-
### [Analytics](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/analytics.rb)
|
|
120
|
-
|
|
127
|
+
### [Analytics](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/analytics/app.rb)
|
|
128
|
+
|
|
129
|
+
Demonstrates the use of `Tabs` and `BarChart` widgets. Features custom highlight styles, base styles, dividers for the tabs, and dynamic width calculation. The `BarChart` showcases both standard and grouped bars (Quarterly view), highlighting features like `group_gap` spacing, toggling `BarChart::direction`, customizing label/value styles, cycling custom `BarChart::bar_set` characters, and switching between Full and Mini height modes.
|
|
130
|
+
|
|
131
|
+

|
|
121
132
|
|
|
122
|
-
|
|
133
|
+
### [All Events](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/all_events/app.rb)
|
|
123
134
|
|
|
124
|
-
|
|
125
|
-
A simple demonstration of `Block` and `Paragraph` widgets, reacting to arrow key presses to change colors.
|
|
135
|
+
A comprehensive demonstration of every event type supported by **ratatui_ruby**: Key, Mouse, Resize, Paste, and Focus events.
|
|
126
136
|
|
|
127
|
-

|
|
128
138
|
|
|
129
|
-
### [
|
|
130
|
-
A simple demo application for the `Calendar` widget.
|
|
139
|
+
### [Block Padding](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/block_padding/app.rb)
|
|
131
140
|
|
|
132
|
-
|
|
141
|
+
Demonstrates the `padding` property of the `Block` widget, supporting both uniform and directional padding.
|
|
133
142
|
|
|
134
|
-
|
|
135
|
-
Demonstrates the `Chart` widget with both scatter and line datasets, including custom axes.
|
|
143
|
+

|
|
136
144
|
|
|
137
|
-
|
|
145
|
+
### [Block Titles](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/block_titles/app.rb)
|
|
146
|
+
|
|
147
|
+
Demonstrates the `Block` widget's ability to render multiple titles with individual alignment and positioning (top/bottom).
|
|
148
|
+
|
|
149
|
+

|
|
150
|
+
|
|
151
|
+
### [Box Demo](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/box_demo/app.rb)
|
|
152
|
+
|
|
153
|
+
A simple demonstration of `Block` and `Paragraph` widgets, reacting to key presses to change colors, border types, border styles, and title styling. Features the new `border_style` parameter for applying colors and modifiers (bold, italic) to borders independently of the content background.
|
|
154
|
+
|
|
155
|
+

|
|
156
|
+
|
|
157
|
+
### [Calendar Demo](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/calendar_demo/app.rb)
|
|
158
|
+
|
|
159
|
+
Demonstrates the `Calendar` widget with interactive attribute cycling. Features event highlighting (dates with specific styles), toggleable month/weekday headers, and surrounding month visibility (with custom styling) via keyboard shortcuts. Press `h` to toggle month header, `w` to toggle weekday header, `s` to toggle surrounding month dates, and `e` to toggle events.
|
|
160
|
+
|
|
161
|
+

|
|
162
|
+
|
|
163
|
+
### [Chart Demo](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/chart_demo/app.rb)
|
|
164
|
+
|
|
165
|
+
Demonstrates the `Chart` widget with both scatter and line datasets, including custom axes. Features customizable axis label alignment and legend positioning.
|
|
166
|
+
|
|
167
|
+

|
|
168
|
+
|
|
169
|
+
### [Custom Widget (Escape Hatch)](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/custom_widget/app.rb)
|
|
138
170
|
|
|
139
|
-
### [Custom Widget (Escape Hatch)](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/custom_widget.rb)
|
|
140
171
|
Demonstrates how to define a custom widget in pure Ruby using the `render(area, buffer)` escape hatch for low-level drawing.
|
|
141
172
|
|
|
142
|
-

|
|
174
|
+
|
|
175
|
+
### [Flex Layout](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/flex_layout/app.rb)
|
|
143
176
|
|
|
144
|
-
|
|
145
|
-
Uses `Layout`, `List`, and `Paragraph` to create a classic sidebar-and-content interface.
|
|
177
|
+
Demonstrates modern layout features including `Constraint.fill` and `Constraint.ratio` for proportional space distribution and `flex: :space_between` for evenly distributing fixed-size elements.
|
|
146
178
|
|
|
147
|
-

|
|
148
180
|
|
|
149
|
-
### [
|
|
150
|
-
|
|
181
|
+
### [LineGauge Demo](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/line_gauge_demo/app.rb)
|
|
182
|
+
|
|
183
|
+
Demonstrates the `LineGauge` widget with customizable filled and unfilled symbols, base style support via the `style` parameter, independent styling for filled/unfilled portions, and interactive ratio cycling with arrow keys.
|
|
184
|
+
|
|
185
|
+

|
|
186
|
+
|
|
187
|
+
### [List Demo](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/list_demo/app.rb)
|
|
188
|
+
|
|
189
|
+
Demonstrates the `List` widget with interactive attribute cycling. Features multiple item sets to browse, customizable highlight styles and symbols, and exploration of all List options including direction, highlight spacing, repeat symbol mode, scroll padding, and base styling. The sidebar provides hotkey documentation for discovering all List features, including the new `p` key to adjust scroll padding.
|
|
190
|
+
|
|
191
|
+

|
|
192
|
+
|
|
193
|
+
### [Login Form](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/login_form/app.rb)
|
|
151
194
|
|
|
152
|
-
### [Login Form](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/login_form.rb)
|
|
153
195
|
Shows how to use `Overlay`, `Center`, and `Cursor` to build a modal login form with text input.
|
|
154
196
|
|
|
155
|
-

|
|
198
|
+
|
|
199
|
+
### [Map Demo](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/map_demo/app.rb)
|
|
156
200
|
|
|
157
|
-
|
|
158
|
-
Exhibits the `Canvas` widget's power, rendering a world map along with animated circles and lines.
|
|
201
|
+
Exhibits the `Canvas` widget's power, rendering a world map with city labels, animated circles, and lines.
|
|
159
202
|
|
|
160
|
-

|
|
204
|
+
|
|
205
|
+
### [Mouse Events](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/mouse_events/app.rb)
|
|
161
206
|
|
|
162
|
-
### [Mouse Events](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/mouse_events.rb)
|
|
163
207
|
Detailed plumbing of mouse events, including clicks, drags, and movement tracking.
|
|
164
208
|
|
|
165
|
-

|
|
210
|
+
|
|
211
|
+
### [Popup Demo](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/popup_demo/app.rb)
|
|
166
212
|
|
|
167
|
-
### [Popup Demo](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/popup_demo.rb)
|
|
168
213
|
Demonstrates the `Clear` widget and how to prevent "style bleed" when rendering opaque popups over colored backgrounds.
|
|
169
214
|
|
|
170
|
-

|
|
216
|
+
|
|
217
|
+
### [Ratatui Logo Demo](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/ratatui_logo_demo/app.rb)
|
|
218
|
+
|
|
219
|
+
Demonstrates the `RatatuiLogo` widget.
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+

|
|
223
|
+
|
|
224
|
+
### [Rich Text](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/rich_text/app.rb)
|
|
171
225
|
|
|
172
|
-
|
|
173
|
-
A simple example of integrating the `Scrollbar` widget and handling mouse wheel events for scrolling.
|
|
226
|
+
Demonstrates `Text::Span` and `Text::Line` for creating styled text with inline formatting, enabling word-level control over colors and text modifiers.
|
|
174
227
|
|
|
175
|
-

|
|
229
|
+
|
|
230
|
+
### [Scrollbar Demo](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/scrollbar_demo/app.rb)
|
|
231
|
+
|
|
232
|
+
A demonstration of the `Scrollbar` widget, featuring mouse wheel scrolling and extensive customization of symbols and styles.
|
|
233
|
+
|
|
234
|
+

|
|
235
|
+
|
|
236
|
+
### [Scroll Text](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/scroll_text/app.rb)
|
|
176
237
|
|
|
177
|
-
### [Scroll Text](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/scroll_text.rb)
|
|
178
238
|
Demonstrates the `Paragraph` widget's scroll functionality, allowing navigation through long text content using arrow keys for both horizontal and vertical scrolling.
|
|
179
239
|
|
|
180
|
-

|
|
241
|
+
|
|
242
|
+
### [Sparkline Demo](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/sparkline_demo/app.rb)
|
|
243
|
+
|
|
244
|
+
Demonstrates the `Sparkline` widget with interactive attribute cycling. Features multiple data sets with different patterns (steady growth, gaps, random, sawtooth, peaks), and explores all `Sparkline` options including direction, color, the new `absent_value_symbol` and `absent_value_style` parameters for distinguishing zero/absent values from low data, and the new `bar_set` parameter for custom bar characters.
|
|
245
|
+
|
|
246
|
+

|
|
247
|
+
|
|
248
|
+
### [Gauge Demo](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/gauge_demo/app.rb)
|
|
249
|
+
|
|
250
|
+
Demonstrates the `Gauge` widget with interactive attribute cycling. Features multiple gauge instances with customizable ratio, gauge color, background style, Unicode toggle, and label modes. The sidebar provides hotkey documentation for exploring all Gauge options, including the distinction between `style` (background) and `gauge_style` (filled bar).
|
|
251
|
+
|
|
252
|
+

|
|
253
|
+
|
|
254
|
+
### [Table Select](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/table_select/app.rb)
|
|
255
|
+
|
|
256
|
+
Demonstrates interactive row selection in the `Table` widget with keyboard navigation, highlighting selected rows with custom styles and symbols, applying a base style, and dynamically adjusting `column_spacing`. Also demonstrates `column_highlight_style` and the new `cell_highlight_style` for precise selection visualization.
|
|
257
|
+
|
|
258
|
+

|
|
181
259
|
|
|
182
|
-
### [
|
|
183
|
-
Utilizes `Sparkline` and `Chart` widgets to visualize real-time (simulated) data.
|
|
260
|
+
### [Table Flex](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/table_flex/app.rb)
|
|
184
261
|
|
|
185
|
-
|
|
262
|
+
Demonstrates different flex modes in the `Table` widget, such as `:space_between` and `:space_around`, allowing for modern, responsive table layouts.
|
|
186
263
|
|
|
187
|
-
|
|
188
|
-
Combines `Table` and `Gauge` widgets in a vertical layout to create a functional system overview.
|
|
264
|
+

|
|
189
265
|
|
|
190
|
-
|
|
266
|
+
### [Widget Style Colors](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/widget_style_colors/app.rb)
|
|
191
267
|
|
|
192
|
-
|
|
193
|
-
Demonstrates interactive row selection in the `Table` widget with keyboard navigation, highlighting selected rows with custom styles and symbols.
|
|
268
|
+
Demonstrates hexadecimal color code support in Style parameters. Renders an 80x24 color gradient using HSL-to-RGB conversion and #RRGGBB hex codes, showcasing 24-bit true color rendering on capable terminals.
|
|
194
269
|
|
|
195
|
-

|
|
196
271
|
|
|
@@ -0,0 +1,169 @@
|
|
|
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
|
+
# All Events Demo
|
|
10
|
+
# Demonstrates every event type: Key, Mouse, Resize, Paste, Focus.
|
|
11
|
+
class AllEventsApp
|
|
12
|
+
attr_reader :key_info, :mouse_info, :resize_info, :special_info, :focused
|
|
13
|
+
|
|
14
|
+
def initialize
|
|
15
|
+
@key_info = "Press any key..."
|
|
16
|
+
@mouse_info = "Click or scroll..."
|
|
17
|
+
@resize_info = "Resize the terminal..."
|
|
18
|
+
@special_info = "Paste text or change focus..."
|
|
19
|
+
@focused = true
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def run
|
|
23
|
+
RatatuiRuby.run do
|
|
24
|
+
# Capture initial terminal size
|
|
25
|
+
@resize_info = "#{terminal_width}×#{terminal_height}"
|
|
26
|
+
loop do
|
|
27
|
+
render
|
|
28
|
+
break if handle_input == :quit
|
|
29
|
+
sleep 0.016
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def terminal_width
|
|
37
|
+
80 # Approximation; actual size comes from Resize events
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def terminal_height
|
|
41
|
+
24
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def render
|
|
45
|
+
border_color = @focused ? "green" : "gray"
|
|
46
|
+
|
|
47
|
+
key_panel = RatatuiRuby::Paragraph.new(
|
|
48
|
+
text: @key_info,
|
|
49
|
+
alignment: :center,
|
|
50
|
+
block: RatatuiRuby::Block.new(
|
|
51
|
+
title: "⌨️ Key Events",
|
|
52
|
+
borders: [:all],
|
|
53
|
+
border_color: border_color
|
|
54
|
+
)
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
mouse_panel = RatatuiRuby::Paragraph.new(
|
|
58
|
+
text: @mouse_info,
|
|
59
|
+
alignment: :center,
|
|
60
|
+
block: RatatuiRuby::Block.new(
|
|
61
|
+
title: "🖱️ Mouse Events",
|
|
62
|
+
borders: [:all],
|
|
63
|
+
border_color: border_color
|
|
64
|
+
)
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
resize_panel = RatatuiRuby::Paragraph.new(
|
|
68
|
+
text: @resize_info,
|
|
69
|
+
alignment: :center,
|
|
70
|
+
block: RatatuiRuby::Block.new(
|
|
71
|
+
title: "📐 Resize Events",
|
|
72
|
+
borders: [:all],
|
|
73
|
+
border_color: border_color
|
|
74
|
+
)
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
special_panel = RatatuiRuby::Paragraph.new(
|
|
78
|
+
text: @special_info,
|
|
79
|
+
alignment: :center,
|
|
80
|
+
block: RatatuiRuby::Block.new(
|
|
81
|
+
title: "✨ Paste & Focus Events",
|
|
82
|
+
borders: [:all],
|
|
83
|
+
border_color: border_color
|
|
84
|
+
)
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
# 2x2 grid layout
|
|
88
|
+
top_row = RatatuiRuby::Layout.new(
|
|
89
|
+
direction: :horizontal,
|
|
90
|
+
constraints: [
|
|
91
|
+
RatatuiRuby::Constraint.percentage(50),
|
|
92
|
+
RatatuiRuby::Constraint.percentage(50)
|
|
93
|
+
],
|
|
94
|
+
children: [key_panel, mouse_panel]
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
bottom_row = RatatuiRuby::Layout.new(
|
|
98
|
+
direction: :horizontal,
|
|
99
|
+
constraints: [
|
|
100
|
+
RatatuiRuby::Constraint.percentage(50),
|
|
101
|
+
RatatuiRuby::Constraint.percentage(50)
|
|
102
|
+
],
|
|
103
|
+
children: [resize_panel, special_panel]
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# Header with instructions
|
|
107
|
+
header = RatatuiRuby::Paragraph.new(
|
|
108
|
+
text: "All Event Types Demo — Press 'q' or Ctrl+C to quit",
|
|
109
|
+
alignment: :center,
|
|
110
|
+
style: { fg: :cyan, modifiers: [:bold] }
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
layout = RatatuiRuby::Layout.new(
|
|
114
|
+
direction: :vertical,
|
|
115
|
+
constraints: [
|
|
116
|
+
RatatuiRuby::Constraint.length(1),
|
|
117
|
+
RatatuiRuby::Constraint.percentage(50),
|
|
118
|
+
RatatuiRuby::Constraint.percentage(50)
|
|
119
|
+
],
|
|
120
|
+
children: [header, top_row, bottom_row]
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
RatatuiRuby.draw(layout)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def handle_input
|
|
127
|
+
event = RatatuiRuby.poll_event
|
|
128
|
+
return unless event
|
|
129
|
+
|
|
130
|
+
case event
|
|
131
|
+
# Quit
|
|
132
|
+
in {type: :key, code: "q"} | {type: :key, code: "c", modifiers: ["ctrl"]}
|
|
133
|
+
return :quit
|
|
134
|
+
|
|
135
|
+
# Key events
|
|
136
|
+
in type: :key, code:, modifiers:
|
|
137
|
+
mods = modifiers.empty? ? "" : " [#{modifiers.join('+')}]"
|
|
138
|
+
@key_info = "Key: #{code}#{mods}"
|
|
139
|
+
|
|
140
|
+
# Mouse events
|
|
141
|
+
in type: :mouse, kind:, button:, x:, y:
|
|
142
|
+
@mouse_info = "#{kind}: #{button} at (#{x}, #{y})"
|
|
143
|
+
|
|
144
|
+
# Resize events
|
|
145
|
+
in type: :resize, width:, height:
|
|
146
|
+
@resize_info = "#{width}×#{height}"
|
|
147
|
+
|
|
148
|
+
# Paste events
|
|
149
|
+
in type: :paste, content:
|
|
150
|
+
display_content = content.length > 30 ? "#{content[0..27]}..." : content
|
|
151
|
+
@special_info = "Pasted: #{display_content.inspect}"
|
|
152
|
+
|
|
153
|
+
# Focus events
|
|
154
|
+
in type: :focus_gained
|
|
155
|
+
@focused = true
|
|
156
|
+
@special_info = "Focus gained! ✓"
|
|
157
|
+
|
|
158
|
+
in type: :focus_lost
|
|
159
|
+
@focused = false
|
|
160
|
+
@special_info = "Focus lost..."
|
|
161
|
+
else
|
|
162
|
+
nil
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
nil
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
AllEventsApp.new.run if __FILE__ == $PROGRAM_NAME
|
|
@@ -0,0 +1,139 @@
|
|
|
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
|
+
require "ratatui_ruby/test_helper"
|
|
9
|
+
require "minitest/autorun"
|
|
10
|
+
require_relative "app"
|
|
11
|
+
|
|
12
|
+
class TestAllEvents < Minitest::Test
|
|
13
|
+
include RatatuiRuby::TestHelper
|
|
14
|
+
|
|
15
|
+
def setup
|
|
16
|
+
@app = AllEventsApp.new
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def test_initial_state
|
|
20
|
+
with_test_terminal do
|
|
21
|
+
# Queue quit event
|
|
22
|
+
inject_key(:q)
|
|
23
|
+
|
|
24
|
+
@app.run
|
|
25
|
+
|
|
26
|
+
content = buffer_content.join("\n")
|
|
27
|
+
assert_includes content, "Press any key..."
|
|
28
|
+
assert_includes content, "Click or scroll..."
|
|
29
|
+
assert_includes content, "80×24"
|
|
30
|
+
assert_includes content, "Paste text or change focus..."
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def test_key_event_updates_panel
|
|
35
|
+
with_test_terminal do
|
|
36
|
+
inject_keys(:a, :q)
|
|
37
|
+
|
|
38
|
+
@app.run
|
|
39
|
+
|
|
40
|
+
assert_includes buffer_content.join("\n"), "Key: a"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def test_key_event_with_modifiers
|
|
45
|
+
with_test_terminal do
|
|
46
|
+
inject_keys(:ctrl_s, :q)
|
|
47
|
+
|
|
48
|
+
@app.run
|
|
49
|
+
|
|
50
|
+
assert_includes buffer_content.join("\n"), "Key: s [ctrl]"
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def test_mouse_event_updates_panel
|
|
55
|
+
with_test_terminal do
|
|
56
|
+
inject_event(RatatuiRuby::Event::Mouse.new(kind: "down", button: "left", x: 10, y: 5))
|
|
57
|
+
inject_key(:q)
|
|
58
|
+
|
|
59
|
+
@app.run
|
|
60
|
+
|
|
61
|
+
assert_includes buffer_content.join("\n"), "down: left at (10, 5)"
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def test_resize_event_updates_panel
|
|
66
|
+
with_test_terminal do
|
|
67
|
+
inject_event(RatatuiRuby::Event::Resize.new(width: 120, height: 40))
|
|
68
|
+
inject_key(:q)
|
|
69
|
+
|
|
70
|
+
@app.run
|
|
71
|
+
|
|
72
|
+
assert_includes buffer_content.join("\n"), "120×40"
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def test_paste_event_updates_panel
|
|
77
|
+
with_test_terminal do
|
|
78
|
+
inject_event(RatatuiRuby::Event::Paste.new(content: "Hello, World!"))
|
|
79
|
+
inject_key(:q)
|
|
80
|
+
|
|
81
|
+
@app.run
|
|
82
|
+
|
|
83
|
+
assert_includes buffer_content.join("\n"), 'Pasted: "Hello, World!"'
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def test_paste_event_truncates_long_content
|
|
88
|
+
with_test_terminal do
|
|
89
|
+
inject_event(RatatuiRuby::Event::Paste.new(content: "This is a very long string that should be truncated"))
|
|
90
|
+
inject_key(:q)
|
|
91
|
+
|
|
92
|
+
@app.run
|
|
93
|
+
|
|
94
|
+
content = buffer_content.join("\n")
|
|
95
|
+
assert_includes content, "Pasted: "
|
|
96
|
+
assert_includes content, "..."
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def test_focus_gained_updates_panel
|
|
101
|
+
with_test_terminal do
|
|
102
|
+
# Initial state is focused, so we lose then gain
|
|
103
|
+
@app.instance_variable_set(:@focused, false)
|
|
104
|
+
inject_event(RatatuiRuby::Event::FocusGained.new)
|
|
105
|
+
inject_key(:q)
|
|
106
|
+
|
|
107
|
+
@app.run
|
|
108
|
+
|
|
109
|
+
assert_includes buffer_content.join("\n"), "Focus gained! ✓"
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def test_focus_lost_updates_panel
|
|
114
|
+
with_test_terminal do
|
|
115
|
+
inject_event(RatatuiRuby::Event::FocusLost.new)
|
|
116
|
+
inject_key(:q)
|
|
117
|
+
|
|
118
|
+
@app.run
|
|
119
|
+
|
|
120
|
+
assert_includes buffer_content.join("\n"), "Focus lost..."
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def test_quit_on_q
|
|
125
|
+
with_test_terminal do
|
|
126
|
+
inject_key(:q)
|
|
127
|
+
# Wait... run should just return normally
|
|
128
|
+
@app.run
|
|
129
|
+
# If it returns, the test passes (no timeout/hang)
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def test_quit_on_ctrl_c
|
|
134
|
+
with_test_terminal do
|
|
135
|
+
inject_key(:ctrl_c)
|
|
136
|
+
@app.run
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|