ratatui_ruby 0.4.0 → 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 +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 +87 -171
- data/CHANGELOG.md +38 -1
- data/README.md +8 -3
- data/REUSE.toml +20 -0
- data/doc/application_architecture.md +105 -45
- data/doc/application_testing.md +5 -3
- data/doc/contributors/design/ruby_frontend.md +9 -5
- data/doc/contributors/developing_examples.md +76 -18
- data/doc/contributors/documentation_style.md +7 -0
- data/doc/contributors/index.md +2 -0
- data/doc/event_handling.md +10 -4
- data/doc/images/app_all_events.png +0 -0
- data/doc/images/app_color_picker.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_ratatui_logo_demo.png +0 -0
- data/doc/images/widget_ratatui_mascot_demo.png +0 -0
- data/doc/images/widget_render.png +0 -0
- data/doc/images/widget_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/interactive_design.md +25 -30
- data/doc/quickstart.md +147 -120
- 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/examples/app_all_events/view.rb +7 -0
- 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/{login_form → app_login_form}/app.rb +39 -42
- data/examples/{map_demo → app_map_demo}/app.rb +24 -21
- data/examples/{table_select → app_table_select}/app.rb +68 -65
- data/examples/{quickstart_dsl → verify_quickstart_dsl}/app.rb +15 -6
- data/examples/verify_quickstart_layout/app.rb +69 -0
- data/examples/{quickstart_lifecycle → verify_quickstart_lifecycle}/app.rb +19 -10
- data/examples/verify_readme_usage/app.rb +34 -0
- data/examples/widget_barchart_demo/app.rb +238 -0
- data/examples/{block_padding → widget_block_padding}/app.rb +17 -13
- data/examples/{block_titles → widget_block_titles}/app.rb +25 -17
- data/examples/{box_demo → widget_box_demo}/app.rb +99 -65
- 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 +19 -21
- data/examples/widget_table_flex/app.rb +95 -0
- data/examples/widget_tabs_demo/app.rb +167 -0
- data/ext/ratatui_ruby/Cargo.lock +1 -1
- data/ext/ratatui_ruby/Cargo.toml +1 -1
- data/ext/ratatui_ruby/src/events.rs +121 -36
- data/ext/ratatui_ruby/src/frame.rs +115 -0
- data/ext/ratatui_ruby/src/lib.rs +79 -26
- data/ext/ratatui_ruby/src/rendering.rs +8 -4
- data/ext/ratatui_ruby/src/style.rs +138 -57
- data/ext/ratatui_ruby/src/terminal.rs +5 -9
- data/ext/ratatui_ruby/src/text.rs +13 -6
- data/ext/ratatui_ruby/src/widgets/barchart.rs +56 -54
- data/ext/ratatui_ruby/src/widgets/block.rs +7 -6
- data/ext/ratatui_ruby/src/widgets/canvas.rs +21 -3
- data/ext/ratatui_ruby/src/widgets/chart.rs +20 -10
- data/ext/ratatui_ruby/src/widgets/layout.rs +9 -4
- data/ext/ratatui_ruby/src/widgets/list.rs +32 -9
- data/ext/ratatui_ruby/src/widgets/overlay.rs +2 -1
- data/ext/ratatui_ruby/src/widgets/paragraph.rs +1 -1
- data/ext/ratatui_ruby/src/widgets/ratatui_logo.rs +19 -8
- data/ext/ratatui_ruby/src/widgets/ratatui_mascot.rs +17 -10
- data/ext/ratatui_ruby/src/widgets/scrollbar.rs +4 -2
- data/ext/ratatui_ruby/src/widgets/sparkline.rs +14 -11
- data/ext/ratatui_ruby/src/widgets/table.rs +8 -4
- data/ext/ratatui_ruby/src/widgets/tabs.rs +11 -11
- data/lib/ratatui_ruby/cell.rb +3 -3
- data/lib/ratatui_ruby/event/key.rb +1 -1
- data/lib/ratatui_ruby/event/none.rb +43 -0
- data/lib/ratatui_ruby/event.rb +56 -4
- data/lib/ratatui_ruby/frame.rb +87 -0
- data/lib/ratatui_ruby/schema/bar_chart/bar.rb +11 -11
- data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +1 -5
- data/lib/ratatui_ruby/schema/bar_chart.rb +217 -217
- data/lib/ratatui_ruby/schema/block.rb +163 -168
- data/lib/ratatui_ruby/schema/calendar.rb +66 -67
- data/lib/ratatui_ruby/schema/canvas.rb +63 -63
- data/lib/ratatui_ruby/schema/center.rb +46 -46
- data/lib/ratatui_ruby/schema/chart.rb +135 -143
- data/lib/ratatui_ruby/schema/clear.rb +42 -42
- data/lib/ratatui_ruby/schema/constraint.rb +76 -76
- data/lib/ratatui_ruby/schema/cursor.rb +25 -25
- data/lib/ratatui_ruby/schema/gauge.rb +53 -53
- data/lib/ratatui_ruby/schema/layout.rb +87 -87
- data/lib/ratatui_ruby/schema/line_gauge.rb +62 -62
- data/lib/ratatui_ruby/schema/list.rb +86 -84
- data/lib/ratatui_ruby/schema/overlay.rb +31 -31
- data/lib/ratatui_ruby/schema/paragraph.rb +80 -80
- data/lib/ratatui_ruby/schema/ratatui_logo.rb +10 -6
- data/lib/ratatui_ruby/schema/ratatui_mascot.rb +10 -5
- data/lib/ratatui_ruby/schema/rect.rb +60 -60
- data/lib/ratatui_ruby/schema/scrollbar.rb +119 -119
- data/lib/ratatui_ruby/schema/shape/label.rb +1 -1
- data/lib/ratatui_ruby/schema/sparkline.rb +111 -110
- data/lib/ratatui_ruby/schema/style.rb +46 -46
- data/lib/ratatui_ruby/schema/table.rb +112 -119
- data/lib/ratatui_ruby/schema/tabs.rb +66 -67
- data/lib/ratatui_ruby/session/autodoc.rb +417 -0
- data/lib/ratatui_ruby/session.rb +40 -23
- data/lib/ratatui_ruby/test_helper.rb +185 -19
- data/lib/ratatui_ruby/version.rb +1 -1
- data/lib/ratatui_ruby.rb +65 -39
- data/{examples/sparkline_demo → sig/examples/app_all_events}/app.rbs +3 -2
- data/sig/examples/app_all_events/model/event_entry.rbs +16 -0
- data/sig/examples/app_all_events/model/events.rbs +15 -0
- data/sig/examples/app_all_events/model/timestamp.rbs +11 -0
- data/sig/examples/app_all_events/view/app_view.rbs +8 -0
- data/sig/examples/app_all_events/view/controls_view.rbs +6 -0
- data/sig/examples/app_all_events/view/counts_view.rbs +6 -0
- data/sig/examples/app_all_events/view/live_view.rbs +6 -0
- data/sig/examples/app_all_events/view/log_view.rbs +6 -0
- data/sig/examples/app_all_events/view.rbs +8 -0
- data/sig/examples/app_all_events/view_state.rbs +15 -0
- data/{examples/list_demo → sig/examples/app_color_picker}/app.rbs +2 -2
- data/sig/examples/app_login_form/app.rbs +11 -0
- data/sig/examples/app_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/{examples/gauge_demo → sig/examples/widget_gauge_demo}/app.rbs +4 -0
- data/sig/examples/widget_layout_split/app.rbs +10 -0
- data/sig/examples/widget_line_gauge_demo/app.rbs +11 -0
- data/sig/examples/widget_list_demo/app.rbs +12 -0
- data/sig/examples/widget_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/{examples → sig/examples}/widget_style_colors/app.rbs +1 -1
- data/sig/examples/widget_table_flex/app.rbs +11 -0
- data/sig/ratatui_ruby/frame.rbs +9 -0
- data/sig/ratatui_ruby/ratatui_ruby.rbs +3 -2
- data/sig/ratatui_ruby/schema/draw.rbs +4 -0
- data/sig/ratatui_ruby/schema/layout.rbs +1 -1
- 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/index.html.erb +6 -0
- data/tasks/sourcehut.rake +4 -4
- data/tasks/terminal_preview/app_screenshot.rb +1 -3
- data/tasks/terminal_preview/crash_report.rb +7 -9
- data/tasks/terminal_preview/launcher_script.rb +4 -6
- data/tasks/terminal_preview/preview_collection.rb +4 -6
- data/tasks/terminal_preview/safety_confirmation.rb +3 -5
- data/tasks/terminal_preview/saved_screenshot.rb +7 -9
- data/tasks/terminal_preview/terminal_window.rb +7 -9
- data/tasks/test.rake +1 -1
- data/tasks/website/index_page.rb +3 -3
- data/tasks/website/version.rb +10 -10
- data/tasks/website/version_menu.rb +10 -12
- data/tasks/website/versioned_documentation.rb +49 -17
- data/tasks/website/website.rb +6 -8
- data/tasks/website.rake +4 -4
- metadata +156 -125
- data/LICENSES/BSD-2-Clause.txt +0 -9
- data/doc/contributors/better_dx.md +0 -543
- data/doc/contributors/example_analysis.md +0 -82
- data/doc/images/all_events.png +0 -0
- data/doc/images/block_padding.png +0 -0
- data/doc/images/block_titles.png +0 -0
- data/doc/images/box_demo.png +0 -0
- data/doc/images/calendar_demo.png +0 -0
- data/doc/images/cell_demo.png +0 -0
- data/doc/images/chart_demo.png +0 -0
- data/doc/images/flex_layout.png +0 -0
- data/doc/images/gauge_demo.png +0 -0
- data/doc/images/line_gauge_demo.png +0 -0
- data/doc/images/list_demo.png +0 -0
- data/doc/images/readme_usage.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/examples/all_events/app.rb +0 -169
- data/examples/all_events/app.rbs +0 -7
- data/examples/all_events/test_app.rb +0 -139
- data/examples/analytics/app.rb +0 -258
- data/examples/analytics/app.rbs +0 -7
- data/examples/analytics/test_app.rb +0 -132
- data/examples/block_padding/app.rbs +0 -7
- data/examples/block_padding/test_app.rb +0 -31
- data/examples/block_titles/app.rbs +0 -7
- data/examples/block_titles/test_app.rb +0 -34
- data/examples/box_demo/app.rbs +0 -7
- data/examples/box_demo/test_app.rb +0 -88
- data/examples/calendar_demo/app.rb +0 -101
- data/examples/calendar_demo/app.rbs +0 -7
- data/examples/calendar_demo/test_app.rb +0 -108
- data/examples/cell_demo/app.rb +0 -108
- data/examples/cell_demo/app.rbs +0 -7
- data/examples/cell_demo/test_app.rb +0 -36
- data/examples/chart_demo/app.rb +0 -203
- data/examples/chart_demo/app.rbs +0 -7
- data/examples/chart_demo/test_app.rb +0 -102
- data/examples/custom_widget/app.rb +0 -51
- data/examples/custom_widget/app.rbs +0 -7
- data/examples/custom_widget/test_app.rb +0 -30
- data/examples/flex_layout/app.rb +0 -156
- data/examples/flex_layout/app.rbs +0 -7
- data/examples/flex_layout/test_app.rb +0 -65
- data/examples/gauge_demo/app.rb +0 -182
- data/examples/gauge_demo/test_app.rb +0 -120
- data/examples/hit_test/app.rb +0 -175
- data/examples/hit_test/app.rbs +0 -7
- data/examples/hit_test/test_app.rb +0 -102
- data/examples/line_gauge_demo/app.rb +0 -190
- data/examples/line_gauge_demo/app.rbs +0 -7
- data/examples/line_gauge_demo/test_app.rb +0 -129
- data/examples/list_demo/app.rb +0 -253
- data/examples/list_demo/test_app.rb +0 -237
- data/examples/list_styles/app.rb +0 -140
- data/examples/list_styles/app.rbs +0 -7
- data/examples/list_styles/test_app.rb +0 -157
- data/examples/login_form/app.rbs +0 -7
- data/examples/login_form/test_app.rb +0 -51
- data/examples/map_demo/app.rbs +0 -7
- data/examples/map_demo/test_app.rb +0 -149
- data/examples/mouse_events/app.rb +0 -97
- data/examples/mouse_events/app.rbs +0 -7
- data/examples/mouse_events/test_app.rb +0 -53
- data/examples/popup_demo/app.rb +0 -103
- data/examples/popup_demo/app.rbs +0 -7
- data/examples/popup_demo/test_app.rb +0 -54
- data/examples/quickstart_dsl/app.rbs +0 -7
- data/examples/quickstart_dsl/test_app.rb +0 -29
- data/examples/quickstart_lifecycle/app.rbs +0 -7
- data/examples/quickstart_lifecycle/test_app.rb +0 -29
- data/examples/ratatui_logo_demo/app.rb +0 -79
- data/examples/ratatui_logo_demo/app.rbs +0 -7
- data/examples/ratatui_logo_demo/test_app.rb +0 -51
- data/examples/ratatui_mascot_demo/app.rb +0 -84
- data/examples/ratatui_mascot_demo/app.rbs +0 -7
- data/examples/ratatui_mascot_demo/test_app.rb +0 -47
- data/examples/readme_usage/app.rb +0 -29
- data/examples/readme_usage/app.rbs +0 -7
- data/examples/readme_usage/test_app.rb +0 -29
- data/examples/rich_text/app.rb +0 -141
- data/examples/rich_text/app.rbs +0 -7
- data/examples/rich_text/test_app.rb +0 -166
- data/examples/scroll_text/app.rb +0 -103
- data/examples/scroll_text/app.rbs +0 -7
- data/examples/scroll_text/test_app.rb +0 -110
- data/examples/scrollbar_demo/app.rb +0 -143
- data/examples/scrollbar_demo/app.rbs +0 -7
- data/examples/scrollbar_demo/test_app.rb +0 -77
- data/examples/sparkline_demo/app.rb +0 -240
- data/examples/sparkline_demo/test_app.rb +0 -107
- data/examples/table_flex/app.rb +0 -65
- data/examples/table_flex/app.rbs +0 -7
- data/examples/table_flex/test_app.rb +0 -36
- data/examples/table_select/app.rbs +0 -7
- data/examples/table_select/test_app.rb +0 -180
- data/examples/widget_style_colors/test_app.rb +0 -48
- /data/doc/images/{analytics.png → app_analytics.png} +0 -0
- /data/doc/images/{custom_widget.png → app_custom_widget.png} +0 -0
- /data/doc/images/{login_form.png → app_login_form.png} +0 -0
- /data/doc/images/{map_demo.png → app_map_demo.png} +0 -0
- /data/doc/images/{mouse_events.png → app_mouse_events.png} +0 -0
- /data/doc/images/{table_select.png → app_table_select.png} +0 -0
- /data/doc/images/{quickstart_dsl.png → verify_quickstart_dsl.png} +0 -0
- /data/doc/images/{ratatui_logo_demo.png → verify_quickstart_layout.png} +0 -0
- /data/doc/images/{quickstart_lifecycle.png → verify_quickstart_lifecycle.png} +0 -0
- /data/doc/images/{list_styles.png → widget_list_styles.png} +0 -0
- /data/doc/images/{popup_demo.png → widget_popup_demo.png} +0 -0
- /data/doc/images/{hit_test.png → widget_rect.png} +0 -0
- /data/doc/images/{rich_text.png → widget_rich_text.png} +0 -0
- /data/doc/images/{scroll_text.png → widget_scroll_text.png} +0 -0
|
@@ -1,19 +1,23 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
4
|
+
|
|
5
|
+
use bumpalo::Bump;
|
|
1
6
|
use magnus::{prelude::*, Error, Symbol, Value};
|
|
2
7
|
use ratatui::{
|
|
8
|
+
layout::Alignment,
|
|
3
9
|
style::{Color, Modifier, Style},
|
|
10
|
+
symbols,
|
|
4
11
|
text::Line,
|
|
5
12
|
widgets::{Block, BorderType, Borders, Padding},
|
|
6
|
-
layout::Alignment,
|
|
7
|
-
symbols,
|
|
8
13
|
};
|
|
9
|
-
use bumpalo::Bump;
|
|
10
14
|
|
|
11
15
|
pub fn parse_color(color_str: &str) -> Option<Color> {
|
|
12
16
|
// Try standard ratatui parsing first (named colors, indexed, etc.)
|
|
13
17
|
if let Ok(color) = color_str.parse::<Color>() {
|
|
14
18
|
return Some(color);
|
|
15
19
|
}
|
|
16
|
-
|
|
20
|
+
|
|
17
21
|
// Try hex parsing manually: #RRGGBB
|
|
18
22
|
let hex_str = color_str.trim();
|
|
19
23
|
if hex_str.starts_with('#') && hex_str.len() == 7 {
|
|
@@ -24,7 +28,7 @@ pub fn parse_color(color_str: &str) -> Option<Color> {
|
|
|
24
28
|
return Some(Color::Rgb(r, g, b));
|
|
25
29
|
}
|
|
26
30
|
}
|
|
27
|
-
|
|
31
|
+
|
|
28
32
|
None
|
|
29
33
|
}
|
|
30
34
|
|
|
@@ -61,9 +65,12 @@ pub fn parse_style(style_val: Value) -> Result<Style, Error> {
|
|
|
61
65
|
|
|
62
66
|
let (fg, bg, modifiers_val) = if let Some(hash) = magnus::RHash::from_value(style_val) {
|
|
63
67
|
(
|
|
64
|
-
hash.lookup(ruby.to_symbol("fg"))
|
|
65
|
-
|
|
66
|
-
hash.lookup(ruby.to_symbol("
|
|
68
|
+
hash.lookup(ruby.to_symbol("fg"))
|
|
69
|
+
.unwrap_or_else(|_| ruby.qnil().as_value()),
|
|
70
|
+
hash.lookup(ruby.to_symbol("bg"))
|
|
71
|
+
.unwrap_or_else(|_| ruby.qnil().as_value()),
|
|
72
|
+
hash.lookup(ruby.to_symbol("modifiers"))
|
|
73
|
+
.unwrap_or_else(|_| ruby.qnil().as_value()),
|
|
67
74
|
)
|
|
68
75
|
} else {
|
|
69
76
|
(
|
|
@@ -92,7 +99,8 @@ pub fn parse_style(style_val: Value) -> Result<Style, Error> {
|
|
|
92
99
|
if !modifiers_val.is_nil() {
|
|
93
100
|
if let Some(modifiers_array) = magnus::RArray::from_value(modifiers_val) {
|
|
94
101
|
for i in 0..modifiers_array.len() {
|
|
95
|
-
let index = isize::try_from(i)
|
|
102
|
+
let index = isize::try_from(i)
|
|
103
|
+
.map_err(|e| Error::new(ruby.exception_range_error(), e.to_string()))?;
|
|
96
104
|
if let Ok(sym) = modifiers_array.entry::<Symbol>(index) {
|
|
97
105
|
if let Some(m) = parse_modifier_str(&sym.to_string()) {
|
|
98
106
|
style = style.add_modifier(m);
|
|
@@ -105,16 +113,22 @@ pub fn parse_style(style_val: Value) -> Result<Style, Error> {
|
|
|
105
113
|
Ok(style)
|
|
106
114
|
}
|
|
107
115
|
|
|
108
|
-
pub fn parse_border_set<'a>(
|
|
116
|
+
pub fn parse_border_set<'a>(
|
|
117
|
+
set_val: Value,
|
|
118
|
+
bump: &'a Bump,
|
|
119
|
+
) -> Result<symbols::border::Set<'a>, Error> {
|
|
109
120
|
let ruby = magnus::Ruby::get().unwrap();
|
|
110
|
-
let hash = magnus::RHash::from_value(set_val)
|
|
111
|
-
Error::new(ruby.exception_type_error(), "expected hash for border_set")
|
|
112
|
-
})?;
|
|
121
|
+
let hash = magnus::RHash::from_value(set_val)
|
|
122
|
+
.ok_or_else(|| Error::new(ruby.exception_type_error(), "expected hash for border_set"))?;
|
|
113
123
|
|
|
114
124
|
let get_char = |key: &str| -> Result<Option<&'a str>, Error> {
|
|
115
|
-
let mut val: Value = hash
|
|
125
|
+
let mut val: Value = hash
|
|
126
|
+
.lookup(ruby.to_symbol(key))
|
|
127
|
+
.unwrap_or_else(|_| ruby.qnil().as_value());
|
|
116
128
|
if val.is_nil() {
|
|
117
|
-
val = hash
|
|
129
|
+
val = hash
|
|
130
|
+
.lookup(ruby.str_new(key))
|
|
131
|
+
.unwrap_or_else(|_| ruby.qnil().as_value());
|
|
118
132
|
}
|
|
119
133
|
if val.is_nil() {
|
|
120
134
|
Ok(None)
|
|
@@ -125,28 +139,47 @@ pub fn parse_border_set<'a>(set_val: Value, bump: &'a Bump) -> Result<symbols::b
|
|
|
125
139
|
};
|
|
126
140
|
|
|
127
141
|
let mut set = symbols::border::Set::default();
|
|
128
|
-
if let Some(s) = get_char("top_left")? {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
if let Some(s) = get_char("
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if let Some(s) = get_char("
|
|
135
|
-
|
|
142
|
+
if let Some(s) = get_char("top_left")? {
|
|
143
|
+
set.top_left = s;
|
|
144
|
+
}
|
|
145
|
+
if let Some(s) = get_char("top_right")? {
|
|
146
|
+
set.top_right = s;
|
|
147
|
+
}
|
|
148
|
+
if let Some(s) = get_char("bottom_left")? {
|
|
149
|
+
set.bottom_left = s;
|
|
150
|
+
}
|
|
151
|
+
if let Some(s) = get_char("bottom_right")? {
|
|
152
|
+
set.bottom_right = s;
|
|
153
|
+
}
|
|
154
|
+
if let Some(s) = get_char("vertical_left")? {
|
|
155
|
+
set.vertical_left = s;
|
|
156
|
+
}
|
|
157
|
+
if let Some(s) = get_char("vertical_right")? {
|
|
158
|
+
set.vertical_right = s;
|
|
159
|
+
}
|
|
160
|
+
if let Some(s) = get_char("horizontal_top")? {
|
|
161
|
+
set.horizontal_top = s;
|
|
162
|
+
}
|
|
163
|
+
if let Some(s) = get_char("horizontal_bottom")? {
|
|
164
|
+
set.horizontal_bottom = s;
|
|
165
|
+
}
|
|
136
166
|
|
|
137
167
|
Ok(set)
|
|
138
168
|
}
|
|
139
169
|
|
|
140
170
|
pub fn parse_bar_set<'a>(set_val: Value, bump: &'a Bump) -> Result<symbols::bar::Set<'a>, Error> {
|
|
141
171
|
let ruby = magnus::Ruby::get().unwrap();
|
|
142
|
-
let hash = magnus::RHash::from_value(set_val)
|
|
143
|
-
Error::new(ruby.exception_type_error(), "expected hash for bar_set")
|
|
144
|
-
})?;
|
|
172
|
+
let hash = magnus::RHash::from_value(set_val)
|
|
173
|
+
.ok_or_else(|| Error::new(ruby.exception_type_error(), "expected hash for bar_set"))?;
|
|
145
174
|
|
|
146
175
|
let get_char = |key: &str| -> Result<Option<&'a str>, Error> {
|
|
147
|
-
let mut val: Value = hash
|
|
176
|
+
let mut val: Value = hash
|
|
177
|
+
.lookup(ruby.to_symbol(key))
|
|
178
|
+
.unwrap_or_else(|_| ruby.qnil().as_value());
|
|
148
179
|
if val.is_nil() {
|
|
149
|
-
val = hash
|
|
180
|
+
val = hash
|
|
181
|
+
.lookup(ruby.str_new(key))
|
|
182
|
+
.unwrap_or_else(|_| ruby.qnil().as_value());
|
|
150
183
|
}
|
|
151
184
|
if val.is_nil() {
|
|
152
185
|
Ok(None)
|
|
@@ -157,33 +190,57 @@ pub fn parse_bar_set<'a>(set_val: Value, bump: &'a Bump) -> Result<symbols::bar:
|
|
|
157
190
|
};
|
|
158
191
|
|
|
159
192
|
let mut set = symbols::bar::Set::default();
|
|
160
|
-
if let Some(s) = get_char("empty")? {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
if let Some(s) = get_char("
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
if let Some(s) = get_char("
|
|
167
|
-
|
|
168
|
-
|
|
193
|
+
if let Some(s) = get_char("empty")? {
|
|
194
|
+
set.empty = s;
|
|
195
|
+
}
|
|
196
|
+
if let Some(s) = get_char("one_eighth")? {
|
|
197
|
+
set.one_eighth = s;
|
|
198
|
+
}
|
|
199
|
+
if let Some(s) = get_char("one_quarter")? {
|
|
200
|
+
set.one_quarter = s;
|
|
201
|
+
}
|
|
202
|
+
if let Some(s) = get_char("three_eighths")? {
|
|
203
|
+
set.three_eighths = s;
|
|
204
|
+
}
|
|
205
|
+
if let Some(s) = get_char("half")? {
|
|
206
|
+
set.half = s;
|
|
207
|
+
}
|
|
208
|
+
if let Some(s) = get_char("five_eighths")? {
|
|
209
|
+
set.five_eighths = s;
|
|
210
|
+
}
|
|
211
|
+
if let Some(s) = get_char("three_quarters")? {
|
|
212
|
+
set.three_quarters = s;
|
|
213
|
+
}
|
|
214
|
+
if let Some(s) = get_char("seven_eighths")? {
|
|
215
|
+
set.seven_eighths = s;
|
|
216
|
+
}
|
|
217
|
+
if let Some(s) = get_char("full")? {
|
|
218
|
+
set.full = s;
|
|
219
|
+
}
|
|
169
220
|
|
|
170
221
|
Ok(set)
|
|
171
222
|
}
|
|
172
223
|
|
|
173
224
|
pub fn parse_block(block_val: Value, bump: &Bump) -> Result<Block<'_>, Error> {
|
|
174
|
-
if block_val.is_nil() {
|
|
225
|
+
if block_val.is_nil() {
|
|
226
|
+
return Ok(Block::default());
|
|
227
|
+
}
|
|
175
228
|
|
|
176
229
|
let mut block = Block::default();
|
|
177
230
|
if let Ok(v) = block_val.funcall::<&str, _, Value>("style", ()) {
|
|
178
|
-
if !v.is_nil() {
|
|
231
|
+
if !v.is_nil() {
|
|
232
|
+
block = block.style(parse_style(v)?);
|
|
233
|
+
}
|
|
179
234
|
}
|
|
180
235
|
|
|
181
236
|
if let Ok(v) = block_val.funcall::<&str, _, Value>("title_style", ()) {
|
|
182
|
-
if !v.is_nil() {
|
|
237
|
+
if !v.is_nil() {
|
|
238
|
+
block = block.title_style(parse_style(v)?);
|
|
239
|
+
}
|
|
183
240
|
}
|
|
184
241
|
|
|
185
242
|
if let Ok(title) = block_val.funcall::<&str, _, Value>("title", ()) {
|
|
186
|
-
if !title.is_nil() {
|
|
243
|
+
if !title.is_nil() {
|
|
187
244
|
let s: String = title.funcall("to_s", ())?;
|
|
188
245
|
block = block.title(Line::from(s));
|
|
189
246
|
}
|
|
@@ -208,11 +265,14 @@ pub fn parse_block(block_val: Value, bump: &Bump) -> Result<Block<'_>, Error> {
|
|
|
208
265
|
|
|
209
266
|
fn parse_titles(block_val: Value, mut block: Block<'_>) -> Result<Block<'_>, Error> {
|
|
210
267
|
if let Ok(titles_val) = block_val.funcall::<&str, _, Value>("titles", ()) {
|
|
211
|
-
if titles_val.is_nil() {
|
|
268
|
+
if titles_val.is_nil() {
|
|
269
|
+
return Ok(block);
|
|
270
|
+
}
|
|
212
271
|
if let Some(titles_array) = magnus::RArray::from_value(titles_val) {
|
|
213
272
|
for i in 0..titles_array.len() {
|
|
214
273
|
let ruby = magnus::Ruby::get().unwrap();
|
|
215
|
-
let index = isize::try_from(i)
|
|
274
|
+
let index = isize::try_from(i)
|
|
275
|
+
.map_err(|e| Error::new(ruby.exception_range_error(), e.to_string()))?;
|
|
216
276
|
let title_item: Value = titles_array.entry(index)?;
|
|
217
277
|
let mut content = String::new();
|
|
218
278
|
let mut alignment = Alignment::Left;
|
|
@@ -220,8 +280,10 @@ fn parse_titles(block_val: Value, mut block: Block<'_>) -> Result<Block<'_>, Err
|
|
|
220
280
|
let mut style = Style::default();
|
|
221
281
|
|
|
222
282
|
if let Some(hash) = magnus::RHash::from_value(title_item) {
|
|
223
|
-
if let Ok(v) = hash.lookup::<_, Value>(ruby.to_symbol("content")) {
|
|
224
|
-
if !v.is_nil() {
|
|
283
|
+
if let Ok(v) = hash.lookup::<_, Value>(ruby.to_symbol("content")) {
|
|
284
|
+
if !v.is_nil() {
|
|
285
|
+
content = v.funcall("to_s", ())?;
|
|
286
|
+
}
|
|
225
287
|
}
|
|
226
288
|
if let Ok(v) = hash.lookup::<_, Value>(ruby.to_symbol("alignment")) {
|
|
227
289
|
if let Some(s) = Symbol::from_value(v) {
|
|
@@ -234,25 +296,37 @@ fn parse_titles(block_val: Value, mut block: Block<'_>) -> Result<Block<'_>, Err
|
|
|
234
296
|
}
|
|
235
297
|
if let Ok(v) = hash.lookup::<_, Value>(ruby.to_symbol("position")) {
|
|
236
298
|
if let Some(s) = Symbol::from_value(v) {
|
|
237
|
-
if s.to_string().as_str() == "bottom" {
|
|
299
|
+
if s.to_string().as_str() == "bottom" {
|
|
300
|
+
is_bottom = true;
|
|
301
|
+
}
|
|
238
302
|
}
|
|
239
303
|
}
|
|
240
|
-
if let Ok(v) = hash.lookup::<_, Value>(ruby.to_symbol("style")) {
|
|
241
|
-
if !v.is_nil() {
|
|
304
|
+
if let Ok(v) = hash.lookup::<_, Value>(ruby.to_symbol("style")) {
|
|
305
|
+
if !v.is_nil() {
|
|
306
|
+
style = parse_style(v)?;
|
|
307
|
+
}
|
|
242
308
|
}
|
|
243
309
|
} else {
|
|
244
310
|
content = title_item.funcall("to_s", ())?;
|
|
245
311
|
}
|
|
246
312
|
|
|
247
313
|
let line = Line::from(content).alignment(alignment).style(style);
|
|
248
|
-
block = if is_bottom {
|
|
314
|
+
block = if is_bottom {
|
|
315
|
+
block.title_bottom(line)
|
|
316
|
+
} else {
|
|
317
|
+
block.title_top(line)
|
|
318
|
+
};
|
|
249
319
|
}
|
|
250
320
|
}
|
|
251
321
|
}
|
|
252
322
|
Ok(block)
|
|
253
323
|
}
|
|
254
324
|
|
|
255
|
-
fn parse_borders<'a>(
|
|
325
|
+
fn parse_borders<'a>(
|
|
326
|
+
block_val: Value,
|
|
327
|
+
mut block: Block<'a>,
|
|
328
|
+
bump: &'a Bump,
|
|
329
|
+
) -> Result<Block<'a>, Error> {
|
|
256
330
|
if let Ok(borders_val) = block_val.funcall::<&str, _, Value>("borders", ()) {
|
|
257
331
|
if !borders_val.is_nil() {
|
|
258
332
|
let mut ratatui_borders = Borders::NONE;
|
|
@@ -268,7 +342,8 @@ fn parse_borders<'a>(block_val: Value, mut block: Block<'a>, bump: &'a Bump) ->
|
|
|
268
342
|
} else if let Some(arr) = magnus::RArray::from_value(borders_val) {
|
|
269
343
|
for i in 0..arr.len() {
|
|
270
344
|
let ruby = magnus::Ruby::get().unwrap();
|
|
271
|
-
let index = isize::try_from(i)
|
|
345
|
+
let index = isize::try_from(i)
|
|
346
|
+
.map_err(|e| Error::new(ruby.exception_range_error(), e.to_string()))?;
|
|
272
347
|
let sym: Symbol = arr.entry(index)?;
|
|
273
348
|
match sym.to_string().as_str() {
|
|
274
349
|
"all" => ratatui_borders |= Borders::ALL,
|
|
@@ -285,19 +360,23 @@ fn parse_borders<'a>(block_val: Value, mut block: Block<'a>, bump: &'a Bump) ->
|
|
|
285
360
|
}
|
|
286
361
|
|
|
287
362
|
if let Ok(v) = block_val.funcall::<&str, _, Value>("border_style", ()) {
|
|
288
|
-
if !v.is_nil() {
|
|
289
|
-
|
|
363
|
+
if !v.is_nil() {
|
|
364
|
+
block = block.border_style(parse_style(v)?);
|
|
365
|
+
} else if let Ok(color_val) = block_val.funcall::<&str, _, Value>("border_color", ()) {
|
|
290
366
|
if !color_val.is_nil() {
|
|
291
367
|
if let Ok(s) = color_val.funcall::<&str, _, String>("to_s", ()) {
|
|
292
|
-
if let Some(c) = parse_color(&s) {
|
|
368
|
+
if let Some(c) = parse_color(&s) {
|
|
369
|
+
block = block.border_style(Style::default().fg(c));
|
|
370
|
+
}
|
|
293
371
|
}
|
|
294
372
|
}
|
|
295
373
|
}
|
|
296
374
|
}
|
|
297
375
|
|
|
298
376
|
if let Ok(v) = block_val.funcall::<&str, _, Value>("border_set", ()) {
|
|
299
|
-
if !v.is_nil() {
|
|
300
|
-
|
|
377
|
+
if !v.is_nil() {
|
|
378
|
+
block = block.border_set(parse_border_set(v, bump)?);
|
|
379
|
+
} else if let Ok(v) = block_val.funcall::<&str, _, Value>("border_type", ()) {
|
|
301
380
|
if let Some(sym) = Symbol::from_value(v) {
|
|
302
381
|
match sym.to_string().as_str() {
|
|
303
382
|
"rounded" => block = block.border_type(BorderType::Rounded),
|
|
@@ -315,7 +394,9 @@ fn parse_borders<'a>(block_val: Value, mut block: Block<'a>, bump: &'a Bump) ->
|
|
|
315
394
|
|
|
316
395
|
fn parse_padding(block_val: Value, block: Block<'_>) -> Block<'_> {
|
|
317
396
|
if let Ok(padding_val) = block_val.funcall::<&str, _, Value>("padding", ()) {
|
|
318
|
-
if padding_val.is_nil() {
|
|
397
|
+
if padding_val.is_nil() {
|
|
398
|
+
return block;
|
|
399
|
+
}
|
|
319
400
|
if let Ok(p) = u16::try_convert(padding_val) {
|
|
320
401
|
return block.padding(Padding::uniform(p));
|
|
321
402
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
2
2
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
3
3
|
|
|
4
|
-
use magnus::Error;
|
|
5
4
|
use magnus::value::ReprValue;
|
|
5
|
+
use magnus::Error;
|
|
6
6
|
use ratatui::{
|
|
7
7
|
backend::{CrosstermBackend, TestBackend},
|
|
8
8
|
Terminal,
|
|
@@ -121,15 +121,11 @@ pub fn resize_terminal(width: u16, height: u16) -> Result<(), Error> {
|
|
|
121
121
|
let mut term_lock = TERMINAL.lock().unwrap();
|
|
122
122
|
if let Some(wrapper) = term_lock.as_mut() {
|
|
123
123
|
match wrapper {
|
|
124
|
-
TerminalWrapper::Crossterm(_) => {
|
|
125
|
-
}
|
|
124
|
+
TerminalWrapper::Crossterm(_) => {}
|
|
126
125
|
TerminalWrapper::Test(terminal) => {
|
|
127
126
|
terminal.backend_mut().resize(width, height);
|
|
128
127
|
if let Err(e) = terminal.resize(ratatui::layout::Rect::new(0, 0, width, height)) {
|
|
129
|
-
return Err(Error::new(
|
|
130
|
-
ruby.exception_runtime_error(),
|
|
131
|
-
e.to_string(),
|
|
132
|
-
));
|
|
128
|
+
return Err(Error::new(ruby.exception_runtime_error(), e.to_string()));
|
|
133
129
|
}
|
|
134
130
|
}
|
|
135
131
|
}
|
|
@@ -195,7 +191,7 @@ fn color_to_value(color: ratatui::style::Color) -> Value {
|
|
|
195
191
|
fn modifiers_to_value(modifier: ratatui::style::Modifier) -> Value {
|
|
196
192
|
let ruby = magnus::Ruby::get().unwrap();
|
|
197
193
|
let ary = ruby.ary_new();
|
|
198
|
-
|
|
194
|
+
|
|
199
195
|
if modifier.contains(ratatui::style::Modifier::BOLD) {
|
|
200
196
|
let _ = ary.push(ruby.str_new("bold"));
|
|
201
197
|
}
|
|
@@ -223,6 +219,6 @@ fn modifiers_to_value(modifier: ratatui::style::Modifier) -> Value {
|
|
|
223
219
|
if modifier.contains(ratatui::style::Modifier::RAPID_BLINK) {
|
|
224
220
|
let _ = ary.push(ruby.str_new("rapid_blink"));
|
|
225
221
|
}
|
|
226
|
-
|
|
222
|
+
|
|
227
223
|
ary.as_value()
|
|
228
224
|
}
|
|
@@ -23,7 +23,10 @@ pub fn parse_text(value: Value) -> Result<Vec<Line<'static>>, Error> {
|
|
|
23
23
|
if let Ok(s) = String::try_convert(value) {
|
|
24
24
|
// Split on newlines and create a Line for each.
|
|
25
25
|
// We need to own the strings, so we convert each line string to a String
|
|
26
|
-
let lines: Vec<Line> = s
|
|
26
|
+
let lines: Vec<Line> = s
|
|
27
|
+
.split('\n')
|
|
28
|
+
.map(|line| Line::from(line.to_string()))
|
|
29
|
+
.collect();
|
|
27
30
|
return if lines.is_empty() {
|
|
28
31
|
Ok(vec![Line::from("")])
|
|
29
32
|
} else {
|
|
@@ -36,7 +39,8 @@ pub fn parse_text(value: Value) -> Result<Vec<Line<'static>>, Error> {
|
|
|
36
39
|
let mut lines = Vec::new();
|
|
37
40
|
for i in 0..arr.len() {
|
|
38
41
|
let ruby = magnus::Ruby::get().unwrap();
|
|
39
|
-
let index = isize::try_from(i)
|
|
42
|
+
let index = isize::try_from(i)
|
|
43
|
+
.map_err(|e| Error::new(ruby.exception_range_error(), e.to_string()))?;
|
|
40
44
|
let elem: Value = arr.entry(index)?;
|
|
41
45
|
|
|
42
46
|
// Try to convert to String
|
|
@@ -68,7 +72,10 @@ pub fn parse_text(value: Value) -> Result<Vec<Line<'static>>, Error> {
|
|
|
68
72
|
// Fallback: try to convert to string
|
|
69
73
|
match String::try_convert(value) {
|
|
70
74
|
Ok(s) => {
|
|
71
|
-
let lines: Vec<Line> = s
|
|
75
|
+
let lines: Vec<Line> = s
|
|
76
|
+
.split('\n')
|
|
77
|
+
.map(|line| Line::from(line.to_string()))
|
|
78
|
+
.collect();
|
|
72
79
|
if lines.is_empty() {
|
|
73
80
|
Ok(vec![Line::from("")])
|
|
74
81
|
} else {
|
|
@@ -139,7 +146,8 @@ pub fn parse_line(value: Value) -> Result<Line<'static>, Error> {
|
|
|
139
146
|
let mut spans = Vec::new();
|
|
140
147
|
for i in 0..spans_array.len() {
|
|
141
148
|
let ruby = magnus::Ruby::get().unwrap();
|
|
142
|
-
let index = isize::try_from(i)
|
|
149
|
+
let index = isize::try_from(i)
|
|
150
|
+
.map_err(|e| Error::new(ruby.exception_range_error(), e.to_string()))?;
|
|
143
151
|
let span_elem: Value = spans_array.entry(index)?;
|
|
144
152
|
|
|
145
153
|
// If it's a string, convert to span without style
|
|
@@ -166,6 +174,5 @@ pub fn parse_line(value: Value) -> Result<Line<'static>, Error> {
|
|
|
166
174
|
#[cfg(test)]
|
|
167
175
|
mod tests {
|
|
168
176
|
#[test]
|
|
169
|
-
fn test_parse_plain_string() {
|
|
170
|
-
}
|
|
177
|
+
fn test_parse_plain_string() {}
|
|
171
178
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
use crate::style::{parse_bar_set, parse_block, parse_style};
|
|
5
5
|
use bumpalo::Bump;
|
|
6
|
-
use magnus::{prelude::*, Error, Symbol, Value
|
|
6
|
+
use magnus::{prelude::*, Error, RArray, Symbol, Value};
|
|
7
7
|
use ratatui::{
|
|
8
8
|
layout::{Direction, Rect},
|
|
9
9
|
text::Line,
|
|
@@ -41,59 +41,61 @@ pub fn render(frame: &mut Frame, area: Rect, node: Value) -> Result<(), Error> {
|
|
|
41
41
|
let ruby = magnus::Ruby::get().unwrap();
|
|
42
42
|
if let Some(array) = RArray::from_value(data_val) {
|
|
43
43
|
for i in 0..array.len() {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
44
|
+
let index = isize::try_from(i)
|
|
45
|
+
.map_err(|e| Error::new(ruby.exception_range_error(), e.to_string()))?;
|
|
46
|
+
let group_obj: Value = array.entry(index)?;
|
|
47
|
+
|
|
48
|
+
let label_val: Value = group_obj.funcall("label", ())?;
|
|
49
|
+
let label_str: String = if label_val.is_nil() {
|
|
50
|
+
String::new()
|
|
51
|
+
} else {
|
|
52
|
+
label_val.funcall("to_s", ())?
|
|
53
|
+
};
|
|
54
|
+
let label_ref = bump.alloc_str(&label_str) as &str;
|
|
55
|
+
|
|
56
|
+
let bars_array: RArray = group_obj.funcall("bars", ())?;
|
|
57
|
+
let mut bars: Vec<Bar> = Vec::new();
|
|
58
|
+
|
|
59
|
+
for j in 0..bars_array.len() {
|
|
60
|
+
let bar_idx = isize::try_from(j)
|
|
61
|
+
.map_err(|e| Error::new(ruby.exception_range_error(), e.to_string()))?;
|
|
62
|
+
let bar_obj: Value = bars_array.entry(bar_idx)?;
|
|
63
|
+
|
|
64
|
+
let value: u64 = bar_obj.funcall("value", ())?;
|
|
65
|
+
let mut bar = Bar::default().value(value);
|
|
66
|
+
|
|
67
|
+
let label_val: Value = bar_obj.funcall("label", ())?;
|
|
68
|
+
if !label_val.is_nil() {
|
|
69
|
+
let s: String = label_val.funcall("to_s", ())?;
|
|
70
|
+
let s_ref = bump.alloc_str(&s) as &str;
|
|
71
|
+
bar = bar.label(Line::from(s_ref));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
let text_val: Value = bar_obj.funcall("text_value", ())?;
|
|
75
|
+
if !text_val.is_nil() {
|
|
76
|
+
let s: String = text_val.funcall("to_s", ())?;
|
|
77
|
+
let s_ref = bump.alloc_str(&s) as &str;
|
|
78
|
+
bar = bar.text_value(s_ref);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
let style_val: Value = bar_obj.funcall("style", ())?;
|
|
82
|
+
if !style_val.is_nil() {
|
|
83
|
+
bar = bar.style(parse_style(style_val)?);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
let val_style_val: Value = bar_obj.funcall("value_style", ())?;
|
|
87
|
+
if !val_style_val.is_nil() {
|
|
88
|
+
bar = bar.value_style(parse_style(val_style_val)?);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
bars.push(bar);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
let mut group = BarGroup::new(bars);
|
|
95
|
+
if !label_ref.is_empty() {
|
|
96
|
+
group = group.label(Line::from(label_ref));
|
|
97
|
+
}
|
|
98
|
+
bar_chart = bar_chart.data(group);
|
|
97
99
|
}
|
|
98
100
|
}
|
|
99
101
|
|
|
@@ -11,23 +11,24 @@ pub fn render(frame: &mut Frame, area: Rect, node: Value) -> Result<(), Error> {
|
|
|
11
11
|
let bump = Bump::new();
|
|
12
12
|
let block = parse_block(node, &bump)?;
|
|
13
13
|
let block_clone = block.clone();
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
// Render the block itself (borders, styling)
|
|
16
16
|
block_clone.render(area, frame.buffer_mut());
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
// Get children and render them within the block's inner area
|
|
19
19
|
let children_val: Value = node.funcall("children", ())?;
|
|
20
20
|
let children_array = magnus::RArray::from_value(children_val);
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
if let Some(arr) = children_array {
|
|
23
23
|
if !arr.is_empty() {
|
|
24
24
|
// Calculate the inner area of the block (excluding borders and padding)
|
|
25
25
|
let inner = block.inner(area);
|
|
26
|
-
|
|
26
|
+
|
|
27
27
|
// Render each child in the block's inner area
|
|
28
28
|
for i in 0..arr.len() {
|
|
29
29
|
let ruby = magnus::Ruby::get().unwrap();
|
|
30
|
-
let index = isize::try_from(i)
|
|
30
|
+
let index = isize::try_from(i)
|
|
31
|
+
.map_err(|e| Error::new(ruby.exception_range_error(), e.to_string()))?;
|
|
31
32
|
let child: Value = arr.entry(index)?;
|
|
32
33
|
if let Err(e) = render_node(frame, inner, child) {
|
|
33
34
|
eprintln!("Error rendering block child {i}: {e:?}");
|
|
@@ -35,6 +36,6 @@ pub fn render(frame: &mut Frame, area: Rect, node: Value) -> Result<(), Error> {
|
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
}
|
|
38
|
-
|
|
39
|
+
|
|
39
40
|
Ok(())
|
|
40
41
|
}
|
|
@@ -11,6 +11,7 @@ use ratatui::{
|
|
|
11
11
|
Frame,
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
+
#[allow(clippy::too_many_lines)]
|
|
14
15
|
pub fn render(frame: &mut Frame, area: ratatui::layout::Rect, node: Value) -> Result<(), Error> {
|
|
15
16
|
let bump = Bump::new();
|
|
16
17
|
let shapes_val: RArray = node.funcall("shapes", ())?;
|
|
@@ -64,7 +65,13 @@ pub fn render(frame: &mut Frame, area: ratatui::layout::Rect, node: Value) -> Re
|
|
|
64
65
|
let color_val: Value = shape_val.funcall("color", ()).unwrap();
|
|
65
66
|
let color =
|
|
66
67
|
parse_color(&color_val.to_string()).unwrap_or(ratatui::style::Color::Reset);
|
|
67
|
-
ctx.draw(&Line {
|
|
68
|
+
ctx.draw(&Line {
|
|
69
|
+
x1,
|
|
70
|
+
y1,
|
|
71
|
+
x2,
|
|
72
|
+
y2,
|
|
73
|
+
color,
|
|
74
|
+
});
|
|
68
75
|
}
|
|
69
76
|
"RatatuiRuby::Shape::Rectangle" => {
|
|
70
77
|
let x: f64 = shape_val.funcall("x", ()).unwrap_or(0.0);
|
|
@@ -74,7 +81,13 @@ pub fn render(frame: &mut Frame, area: ratatui::layout::Rect, node: Value) -> Re
|
|
|
74
81
|
let color_val: Value = shape_val.funcall("color", ()).unwrap();
|
|
75
82
|
let color =
|
|
76
83
|
parse_color(&color_val.to_string()).unwrap_or(ratatui::style::Color::Reset);
|
|
77
|
-
ctx.draw(&Rectangle {
|
|
84
|
+
ctx.draw(&Rectangle {
|
|
85
|
+
x,
|
|
86
|
+
y,
|
|
87
|
+
width,
|
|
88
|
+
height,
|
|
89
|
+
color,
|
|
90
|
+
});
|
|
78
91
|
}
|
|
79
92
|
"RatatuiRuby::Shape::Circle" => {
|
|
80
93
|
let x: f64 = shape_val.funcall("x", ()).unwrap_or(0.0);
|
|
@@ -83,7 +96,12 @@ pub fn render(frame: &mut Frame, area: ratatui::layout::Rect, node: Value) -> Re
|
|
|
83
96
|
let color_val: Value = shape_val.funcall("color", ()).unwrap();
|
|
84
97
|
let color =
|
|
85
98
|
parse_color(&color_val.to_string()).unwrap_or(ratatui::style::Color::Reset);
|
|
86
|
-
ctx.draw(&Circle {
|
|
99
|
+
ctx.draw(&Circle {
|
|
100
|
+
x,
|
|
101
|
+
y,
|
|
102
|
+
radius,
|
|
103
|
+
color,
|
|
104
|
+
});
|
|
87
105
|
}
|
|
88
106
|
"RatatuiRuby::Shape::Map" => {
|
|
89
107
|
let color_val: Value = shape_val.funcall("color", ()).unwrap();
|