From fd9cd36d01673d9c04a93847f41fda8e6386028f Mon Sep 17 00:00:00 2001 From: ttibsi Date: Sun, 23 Nov 2025 11:26:56 +0000 Subject: [PATCH 1/6] borders now accept a span --- examples/borders.cpp | 4 ++-- rawterm/extras/border.h | 23 +++++++++++------------ 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/examples/borders.cpp b/examples/borders.cpp index d91b8a5..3b433a4 100644 --- a/examples/borders.cpp +++ b/examples/borders.cpp @@ -19,14 +19,14 @@ int main() { std::vector text = {}; rawterm::Region region = rawterm::Region(rawterm::Pos(3, 3), rawterm::Pos(10, 25)); auto border = rawterm::Border(region).set_padding(1).set_title("Hello world"); - border.draw(cur, &text); + border.draw(cur, text); rawterm::Region region2 = rawterm::Region(rawterm::Pos(13, 3), rawterm::Pos(20, 40)); text = {"Hello world", "foo", "bar", "some text again and again"}; auto color = rawterm::Color(109, 192, 35); auto border2 = rawterm::Border(region2, '#').set_title("This is my title").set_color(color); - border2.draw(cur, &text); + border2.draw(cur, text); std::ignore = rawterm::wait_for_input(); rawterm::Cursor::cursor_show(); diff --git a/rawterm/extras/border.h b/rawterm/extras/border.h index cb3d343..429e3f9 100644 --- a/rawterm/extras/border.h +++ b/rawterm/extras/border.h @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -63,17 +64,15 @@ namespace rawterm { "..."; } - [[nodiscard]] std::vector render(const std::vector* text) const { + [[nodiscard]] std::vector render(std::span text) const { auto trunc_title = truncated_title(); std::vector render = {""}; - std::size_t longest_txt = text->empty() - ? 0 - : std::max_element( - text->begin(), text->end(), - [](const std::string& a, const std::string& b) { - return a.size() < b.size(); - })->size() + - std::size_t(border_padding); + std::size_t longest_txt = + std::max_element( + text.begin(), text.end(), + [](const std::string& a, const std::string& b) { return a.size() < b.size(); }) + ->size() + + std::size_t(border_padding); if (longest_txt > size.width()) { longest_txt = size.width() - 2; @@ -94,8 +93,8 @@ namespace rawterm { } // Drawing text - if (!text->empty()) { - for (const auto& line : *text) { + if (!text.empty()) { + for (const auto& line : text) { std::string rendered_line = ""; if (border_char.has_value()) { rendered_line.push_back(border_char.value()); @@ -139,7 +138,7 @@ namespace rawterm { return render; }; - void draw(Cursor& cur, const std::vector* text) const { + void draw(Cursor& cur, std::span text) const { // Disable if rawterm_debug if (detail::is_debug()) { return; From aeb2ae2d3daec382a1fd940ac1522cb47d32b992 Mon Sep 17 00:00:00 2001 From: ttibsi Date: Sun, 23 Nov 2025 12:33:59 +0000 Subject: [PATCH 2/6] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13e451c..d61e014 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ * Add new Cursor::move overload to accept two integers * Handle bug in border rendering crashing with no lines of text * Removed zig build system +* borders now accept spans instead of enforcing vectors ### v4.0.7 * Added unit testing in `tests/` directory From d783348d639b2a89f9564557457239505418de97 Mon Sep 17 00:00:00 2001 From: ttibsi Date: Sun, 23 Nov 2025 12:48:43 +0000 Subject: [PATCH 3/6] Resolve warnings --- tests/menu_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/menu_test.cpp b/tests/menu_test.cpp index 399ca1f..64be131 100644 --- a/tests/menu_test.cpp +++ b/tests/menu_test.cpp @@ -60,7 +60,7 @@ boost::ut::suite<"Menu"> menu_suite = [] { "vertical render"_test = [&menu, &options] { std::string render = menu.render(); - const int nl_count = std::count(render.begin(), render.end(), '\n'); - expect(nl_count == options.size() + 1); + const long nl_count = std::count(render.begin(), render.end(), '\n'); + expect(nl_count == long(options.size()) + 1); }; }; From 755bb662337914ddbb164c6d71b1b2d8a15399ba Mon Sep 17 00:00:00 2001 From: ttibsi Date: Sun, 23 Nov 2025 12:48:56 +0000 Subject: [PATCH 4/6] Ensure tests work with changes --- tests/border_test.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/border_test.cpp b/tests/border_test.cpp index acaa82b..af90e61 100644 --- a/tests/border_test.cpp +++ b/tests/border_test.cpp @@ -19,7 +19,7 @@ boost::ut::suite<"Border"> border_suite = [] { std::vector expected = {"┌─────────┐", "│Lorem i│", "│consect│", "│Morbi i│", "│placera│", "└─────────┘"}; - auto rendered = b.render(&text); + auto rendered = b.render(text); expect(rendered == expected); // either end is a box drawing char, which is 3 bytes expect(rendered.at(1).size() == 13); @@ -35,7 +35,7 @@ boost::ut::suite<"Border"> border_suite = [] { std::vector expected = {"┌────────┐", "│ Lorem i│", "│ consect│", "│ Morbi i│", "│ placera│", "└────────┘"}; - auto rendered = b.render(&text); + auto rendered = b.render(text); expect(rendered == expected); // either end is a box drawing char, which is 3 bytes @@ -45,7 +45,7 @@ boost::ut::suite<"Border"> border_suite = [] { "render without passed text"_test = [&b] { std::vector expected = {"┌────────┐", "└────────┘"}; std::vector given = {}; - auto rendered = b.render(&given); + auto rendered = b.render(given); expect(rendered == expected); }; @@ -63,14 +63,14 @@ boost::ut::suite<"Border"> border_suite = [] { }; "render with padding and title"_test = [&b, &text] { - auto rendered = b.render(&text); + auto rendered = b.render(text); std::string expected = "┌Super...┐"; expect(rendered.at(0) == expected); }; "render with title"_test = [&b2, &text] { - auto rendered = b2.render(&text); + auto rendered = b2.render(text); std::string expected = "#Test#####"; expect(rendered.at(0) == expected); @@ -87,7 +87,7 @@ boost::ut::suite<"Border"> border_suite = [] { }; "render with padding, title, color"_test = [&b, &text] { - auto rendered = b.render(&text); + auto rendered = b.render(text); std::string expected = "┌Super...┐"; expect(rendered.at(0) == expected) << rendered.at(0); From ca06095a2f73f280ad49e5cecd683e44dadf08ee Mon Sep 17 00:00:00 2001 From: ttibsi Date: Sun, 23 Nov 2025 12:49:17 +0000 Subject: [PATCH 5/6] Handle an empty span --- rawterm/extras/border.h | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/rawterm/extras/border.h b/rawterm/extras/border.h index 429e3f9..1f741b9 100644 --- a/rawterm/extras/border.h +++ b/rawterm/extras/border.h @@ -67,12 +67,18 @@ namespace rawterm { [[nodiscard]] std::vector render(std::span text) const { auto trunc_title = truncated_title(); std::vector render = {""}; - std::size_t longest_txt = - std::max_element( - text.begin(), text.end(), - [](const std::string& a, const std::string& b) { return a.size() < b.size(); }) - ->size() + - std::size_t(border_padding); + + std::size_t longest_txt = 0; + if (text.size()) { + longest_txt = std::max_element( + text.begin(), text.end(), + [](const std::string& a, const std::string& b) { + return a.size() < b.size(); + }) + ->size(); + } + + longest_txt += std::size_t(border_padding); if (longest_txt > size.width()) { longest_txt = size.width() - 2; From 628c86ddbea6d5de4df11e964db19190c25ecfbf Mon Sep 17 00:00:00 2001 From: ttibsi Date: Sun, 23 Nov 2025 13:19:57 +0000 Subject: [PATCH 6/6] Pad border line using raw length of string --- rawterm/extras/border.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rawterm/extras/border.h b/rawterm/extras/border.h index 1f741b9..f42ad54 100644 --- a/rawterm/extras/border.h +++ b/rawterm/extras/border.h @@ -11,6 +11,7 @@ #include #include #include +#include namespace rawterm { struct Border { @@ -113,7 +114,7 @@ namespace rawterm { drawable_text = line.substr(0, static_cast(longest_txt)); } const std::size_t line_buffer = - size.width() - drawable_text.size() - border_padding - 2; + size.width() - raw_size(drawable_text) - border_padding - 2; rendered_line += std::string(border_padding, ' ') + drawable_text + std::string(border_padding + line_buffer, ' ');