mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2025-12-16 01:48:56 +08:00
Add string view overloads (#1154)
Some checks failed
Build / Bazel, cl, windows-latest (push) Has been cancelled
Build / Bazel, clang++, macos-latest (push) Has been cancelled
Build / Bazel, clang++, ubuntu-latest (push) Has been cancelled
Build / Bazel, g++, macos-latest (push) Has been cancelled
Build / Bazel, g++, ubuntu-latest (push) Has been cancelled
Build / CMake, cl, windows-latest (push) Has been cancelled
Build / CMake, gcc, ubuntu-latest (push) Has been cancelled
Build / CMake, llvm, ubuntu-latest (push) Has been cancelled
Build / CMake, llvm, macos-latest (push) Has been cancelled
Build / Test modules (llvm, ubuntu-latest) (push) Has been cancelled
Documentation / documentation (push) Has been cancelled
Some checks failed
Build / Bazel, cl, windows-latest (push) Has been cancelled
Build / Bazel, clang++, macos-latest (push) Has been cancelled
Build / Bazel, clang++, ubuntu-latest (push) Has been cancelled
Build / Bazel, g++, macos-latest (push) Has been cancelled
Build / Bazel, g++, ubuntu-latest (push) Has been cancelled
Build / CMake, cl, windows-latest (push) Has been cancelled
Build / CMake, gcc, ubuntu-latest (push) Has been cancelled
Build / CMake, llvm, ubuntu-latest (push) Has been cancelled
Build / CMake, llvm, macos-latest (push) Has been cancelled
Build / Test modules (llvm, ubuntu-latest) (push) Has been cancelled
Documentation / documentation (push) Has been cancelled
This is better ergonomic, as `std::string_view` is lightweight and accept more conversion than `const std::string&`. Co-authored-by: ArthurSonzogni <sonzogniarthur@gmail.com>
This commit is contained in:
@@ -27,6 +27,11 @@ Next
|
||||
- Remove dependency on 'pthread'.
|
||||
- Bugfix: Bazel target @ftxui is now visible. Thanks @dskkato in #1157.
|
||||
|
||||
### General
|
||||
- Breaking. Move to `std::string_view` instead of `const std::string&` where
|
||||
applicable. This yields better interoperability with string literals and
|
||||
avoids unnecessary copies. Thanks @mikomikotaishi for PR #1154
|
||||
|
||||
### Component
|
||||
- Feature: POSIX Piped Input Handling.
|
||||
- Allows FTXUI applications to read data from stdin (when piped) while still receiving keyboard input from the terminal.
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <ftxui/component/mouse.hpp> // for Mouse
|
||||
#include <string> // for string, operator==
|
||||
#include <string_view>
|
||||
|
||||
namespace ftxui {
|
||||
|
||||
@@ -28,13 +29,13 @@ class ComponentBase;
|
||||
/// @ingroup component
|
||||
struct Event {
|
||||
// --- Constructor section ---------------------------------------------------
|
||||
static Event Character(std::string);
|
||||
static Event Character(std::string_view);
|
||||
static Event Character(char);
|
||||
static Event Character(wchar_t);
|
||||
static Event Special(std::string);
|
||||
static Event Mouse(std::string, Mouse mouse);
|
||||
static Event CursorPosition(std::string, int x, int y); // Internal
|
||||
static Event CursorShape(std::string, int shape); // Internal
|
||||
static Event Special(std::string_view);
|
||||
static Event Mouse(std::string_view, Mouse mouse);
|
||||
static Event CursorPosition(std::string_view, int x, int y); // Internal
|
||||
static Event CursorShape(std::string_view, int shape); // Internal
|
||||
|
||||
// --- Arrow ---
|
||||
static const Event ArrowLeft;
|
||||
|
||||
@@ -106,9 +106,9 @@ struct Canvas {
|
||||
// Draw using character of size 2x4 at position (x,y)
|
||||
// x is considered to be a multiple of 2.
|
||||
// y is considered to be a multiple of 4.
|
||||
void DrawText(int x, int y, const std::string& value);
|
||||
void DrawText(int x, int y, const std::string& value, const Color& color);
|
||||
void DrawText(int x, int y, const std::string& value, const Stylizer& style);
|
||||
void DrawText(int x, int y, std::string_view value);
|
||||
void DrawText(int x, int y, std::string_view value, const Color& color);
|
||||
void DrawText(int x, int y, std::string_view value, const Stylizer& style);
|
||||
|
||||
// Draw using directly pixels or images --------------------------------------
|
||||
// x is considered to be a multiple of 2.
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <string_view>
|
||||
#include "ftxui/dom/canvas.hpp"
|
||||
#include "ftxui/dom/direction.hpp"
|
||||
#include "ftxui/dom/flexbox_config.hpp"
|
||||
@@ -51,8 +52,8 @@ Elements operator|(Elements, Decorator);
|
||||
Decorator operator|(Decorator, Decorator);
|
||||
|
||||
// --- Widget ---
|
||||
Element text(std::string text);
|
||||
Element vtext(std::string text);
|
||||
Element text(std::string_view text);
|
||||
Element vtext(std::string_view text);
|
||||
Element separator();
|
||||
Element separatorLight();
|
||||
Element separatorDashed();
|
||||
@@ -61,7 +62,7 @@ Element separatorDouble();
|
||||
Element separatorEmpty();
|
||||
Element separatorStyled(BorderStyle);
|
||||
Element separator(Pixel);
|
||||
Element separatorCharacter(std::string);
|
||||
Element separatorCharacter(std::string_view);
|
||||
Element separatorHSelector(float left,
|
||||
float right,
|
||||
Color unselected_color,
|
||||
@@ -89,11 +90,11 @@ Decorator borderStyled(Color);
|
||||
Decorator borderWith(const Pixel&);
|
||||
Element window(Element title, Element content, BorderStyle border = ROUNDED);
|
||||
Element spinner(int charset_index, size_t image_index);
|
||||
Element paragraph(const std::string& text);
|
||||
Element paragraphAlignLeft(const std::string& text);
|
||||
Element paragraphAlignRight(const std::string& text);
|
||||
Element paragraphAlignCenter(const std::string& text);
|
||||
Element paragraphAlignJustify(const std::string& text);
|
||||
Element paragraph(std::string_view text);
|
||||
Element paragraphAlignLeft(std::string_view text);
|
||||
Element paragraphAlignRight(std::string_view text);
|
||||
Element paragraphAlignCenter(std::string_view text);
|
||||
Element paragraphAlignJustify(std::string_view text);
|
||||
Element graph(GraphFunction);
|
||||
Element emptyElement();
|
||||
Element canvas(ConstRef<Canvas>);
|
||||
@@ -120,8 +121,8 @@ Element bgcolor(const LinearGradient&, Element);
|
||||
Decorator focusPosition(int x, int y);
|
||||
Decorator focusPositionRelative(float x, float y);
|
||||
Element automerge(Element child);
|
||||
Decorator hyperlink(std::string link);
|
||||
Element hyperlink(std::string link, Element child);
|
||||
Decorator hyperlink(std::string_view link);
|
||||
Element hyperlink(std::string_view link, Element child);
|
||||
Element selectionStyleReset(Element);
|
||||
Decorator selectionColor(Color foreground);
|
||||
Decorator selectionBackgroundColor(Color foreground);
|
||||
|
||||
@@ -30,7 +30,7 @@ class Selection {
|
||||
Selection SaturateVertical(Box box);
|
||||
bool IsEmpty() const { return empty_; }
|
||||
|
||||
void AddPart(const std::string& part, int y, int left, int right);
|
||||
void AddPart(std::string_view part, int y, int left, int right);
|
||||
std::string GetParts() { return parts_.str(); }
|
||||
|
||||
private:
|
||||
|
||||
@@ -68,7 +68,7 @@ class Screen : public Image {
|
||||
|
||||
// Store an hyperlink in the screen. Return the id of the hyperlink. The id is
|
||||
// used to identify the hyperlink when the user click on it.
|
||||
uint8_t RegisterHyperlink(const std::string& link);
|
||||
uint8_t RegisterHyperlink(std::string_view link);
|
||||
const std::string& Hyperlink(uint8_t id) const;
|
||||
|
||||
using SelectionStyle = std::function<void(Pixel&)>;
|
||||
|
||||
@@ -4,27 +4,32 @@
|
||||
#ifndef FTXUI_SCREEN_STRING_HPP
|
||||
#define FTXUI_SCREEN_STRING_HPP
|
||||
|
||||
#include <string> // for string, wstring, to_string
|
||||
#include <vector> // for vector
|
||||
#include <string> // for string, wstring, to_string
|
||||
#include <string_view> // for string_view
|
||||
#include <vector> // for vector
|
||||
|
||||
namespace ftxui {
|
||||
std::string to_string(const std::wstring& s);
|
||||
std::wstring to_wstring(const std::string& s);
|
||||
std::string to_string(std::wstring_view s);
|
||||
std::wstring to_wstring(std::string_view s);
|
||||
|
||||
template <typename T>
|
||||
std::wstring to_wstring(T s) {
|
||||
return to_wstring(std::to_string(s));
|
||||
return to_wstring(std::string_view(std::to_string(s)));
|
||||
}
|
||||
template <>
|
||||
inline std::wstring to_wstring(const char* s) {
|
||||
return to_wstring(std::string_view(s));
|
||||
}
|
||||
|
||||
int string_width(const std::string&);
|
||||
int string_width(std::string_view);
|
||||
|
||||
// Split the string into a its glyphs. An empty one is inserted ater fullwidth
|
||||
// ones.
|
||||
std::vector<std::string> Utf8ToGlyphs(const std::string& input);
|
||||
std::vector<std::string> Utf8ToGlyphs(std::string_view input);
|
||||
|
||||
// Map every cells drawn by |input| to their corresponding Glyphs. Half-size
|
||||
// Glyphs takes one cell, full-size Glyphs take two cells.
|
||||
std::vector<int> CellToGlyphIndex(const std::string& input);
|
||||
std::vector<int> CellToGlyphIndex(std::string_view input);
|
||||
|
||||
} // namespace ftxui
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <ftxui/screen/string.hpp>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
@@ -125,13 +126,15 @@ class ConstStringListRef {
|
||||
Adapter& operator=(Adapter&&) = default;
|
||||
virtual ~Adapter() = default;
|
||||
virtual size_t size() const = 0;
|
||||
virtual std::string operator[](size_t i) const = 0;
|
||||
virtual std::string_view operator[](size_t i) const = 0;
|
||||
};
|
||||
using Variant = std::variant<const std::vector<std::string>, //
|
||||
const std::vector<std::string>*, //
|
||||
const std::vector<std::wstring>*, //
|
||||
Adapter*, //
|
||||
std::unique_ptr<Adapter> //
|
||||
using Variant = std::variant<const std::vector<std::string>, //
|
||||
const std::vector<std::string>*, //
|
||||
const std::vector<std::string_view>, //
|
||||
const std::vector<std::string_view>*, //
|
||||
const std::vector<std::wstring>*, //
|
||||
Adapter*, //
|
||||
std::unique_ptr<Adapter> //
|
||||
>;
|
||||
|
||||
ConstStringListRef() = default;
|
||||
@@ -149,6 +152,14 @@ class ConstStringListRef {
|
||||
{
|
||||
variant_ = std::make_shared<Variant>(value);
|
||||
}
|
||||
ConstStringListRef(std::vector<std::string_view> value) // NOLINT
|
||||
{
|
||||
variant_ = std::make_shared<Variant>(value);
|
||||
}
|
||||
ConstStringListRef(const std::vector<std::string_view>* value) // NOLINT
|
||||
{
|
||||
variant_ = std::make_shared<Variant>(value);
|
||||
}
|
||||
ConstStringListRef(const std::vector<std::wstring>* value) // NOLINT
|
||||
{
|
||||
variant_ = std::make_shared<Variant>(value);
|
||||
@@ -169,7 +180,62 @@ class ConstStringListRef {
|
||||
}
|
||||
|
||||
std::string operator[](size_t i) const {
|
||||
return variant_ ? std::visit(IndexedGetter(i), *variant_) : "";
|
||||
if (!variant_) {
|
||||
return "";
|
||||
}
|
||||
auto& v = *variant_;
|
||||
if (std::holds_alternative<const std::vector<std::string>>(v)) {
|
||||
return std::get<const std::vector<std::string>>(v)[i];
|
||||
}
|
||||
if (std::holds_alternative<const std::vector<std::string>*>(v)) {
|
||||
return (*std::get<const std::vector<std::string>*>(v))[i];
|
||||
}
|
||||
if (std::holds_alternative<const std::vector<std::string_view>>(v)) {
|
||||
return std::string(std::get<const std::vector<std::string_view>>(v)[i]);
|
||||
}
|
||||
if (std::holds_alternative<const std::vector<std::string_view>*>(v)) {
|
||||
return std::string(
|
||||
(*std::get<const std::vector<std::string_view>*>(v))[i]);
|
||||
}
|
||||
if (std::holds_alternative<const std::vector<std::wstring>*>(v)) {
|
||||
return to_string((*std::get<const std::vector<std::wstring>*>(v))[i]);
|
||||
}
|
||||
if (std::holds_alternative<Adapter*>(v)) {
|
||||
return std::string((*std::get<Adapter*>(v))[i]);
|
||||
}
|
||||
if (std::holds_alternative<std::unique_ptr<Adapter>>(v)) {
|
||||
return std::string((*std::get<std::unique_ptr<Adapter>>(v))[i]);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string_view at(size_t i) const {
|
||||
if (!variant_) {
|
||||
return "";
|
||||
}
|
||||
auto& v = *variant_;
|
||||
if (std::holds_alternative<const std::vector<std::string>>(v)) {
|
||||
return std::get<const std::vector<std::string>>(v)[i];
|
||||
}
|
||||
if (std::holds_alternative<const std::vector<std::string>*>(v)) {
|
||||
return (*std::get<const std::vector<std::string>*>(v))[i];
|
||||
}
|
||||
if (std::holds_alternative<const std::vector<std::string_view>>(v)) {
|
||||
return std::get<const std::vector<std::string_view>>(v)[i];
|
||||
}
|
||||
if (std::holds_alternative<const std::vector<std::string_view>*>(v)) {
|
||||
return (*std::get<const std::vector<std::string_view>*>(v))[i];
|
||||
}
|
||||
if (std::holds_alternative<const std::vector<std::wstring>*>(v)) {
|
||||
return {};
|
||||
}
|
||||
if (std::holds_alternative<Adapter*>(v)) {
|
||||
return (*std::get<Adapter*>(v))[i];
|
||||
}
|
||||
if (std::holds_alternative<std::unique_ptr<Adapter>>(v)) {
|
||||
return (*std::get<std::unique_ptr<Adapter>>(v))[i];
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -180,6 +246,12 @@ class ConstStringListRef {
|
||||
size_t operator()(const std::vector<std::string>* v) const {
|
||||
return v->size();
|
||||
}
|
||||
size_t operator()(const std::vector<std::string_view>& v) const {
|
||||
return v.size();
|
||||
}
|
||||
size_t operator()(const std::vector<std::string_view>* v) const {
|
||||
return v->size();
|
||||
}
|
||||
size_t operator()(const std::vector<std::wstring>* v) const {
|
||||
return v->size();
|
||||
}
|
||||
@@ -189,25 +261,6 @@ class ConstStringListRef {
|
||||
}
|
||||
};
|
||||
|
||||
struct IndexedGetter {
|
||||
IndexedGetter(size_t index) // NOLINT
|
||||
: index_(index) {}
|
||||
size_t index_;
|
||||
std::string operator()(const std::vector<std::string>& v) const {
|
||||
return v[index_];
|
||||
}
|
||||
std::string operator()(const std::vector<std::string>* v) const {
|
||||
return (*v)[index_];
|
||||
}
|
||||
std::string operator()(const std::vector<std::wstring>* v) const {
|
||||
return to_string((*v)[index_]);
|
||||
}
|
||||
std::string operator()(const Adapter* v) const { return (*v)[index_]; }
|
||||
std::string operator()(const std::unique_ptr<Adapter>& v) const {
|
||||
return (*v)[index_];
|
||||
}
|
||||
};
|
||||
|
||||
std::shared_ptr<Variant> variant_;
|
||||
};
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ class ButtonBase : public ComponentBase, public ButtonOption {
|
||||
}
|
||||
|
||||
const EntryState state{
|
||||
*label, false, active, focused_or_hover, Index(),
|
||||
std::string(*label), false, active, focused_or_hover, Index(),
|
||||
};
|
||||
|
||||
auto element = (transform ? transform : DefaultTransform) //
|
||||
|
||||
@@ -27,7 +27,7 @@ class CheckboxBase : public ComponentBase, public CheckboxOption {
|
||||
const bool is_focused = Focused();
|
||||
const bool is_active = Active();
|
||||
auto entry_state = EntryState{
|
||||
*label, *checked, is_active, is_focused || hovered_, -1,
|
||||
std::string(*label), *checked, is_active, is_focused || hovered_, -1,
|
||||
};
|
||||
auto element = (transform ? transform : CheckboxOption::Simple().transform)(
|
||||
entry_state);
|
||||
|
||||
@@ -25,9 +25,9 @@ namespace ftxui {
|
||||
/// @brief An event corresponding to a given typed character.
|
||||
/// @param input The character typed by the user.
|
||||
// static
|
||||
Event Event::Character(std::string input) {
|
||||
Event Event::Character(std::string_view input) {
|
||||
Event event;
|
||||
event.input_ = std::move(input);
|
||||
event.input_ = std::string(input);
|
||||
event.type_ = Type::Character;
|
||||
return event;
|
||||
}
|
||||
@@ -50,9 +50,9 @@ Event Event::Character(wchar_t c) {
|
||||
/// @param input The sequence of character send by the terminal.
|
||||
/// @param mouse The mouse state.
|
||||
// static
|
||||
Event Event::Mouse(std::string input, struct Mouse mouse) {
|
||||
Event Event::Mouse(std::string_view input, struct Mouse mouse) {
|
||||
Event event;
|
||||
event.input_ = std::move(input);
|
||||
event.input_ = std::string(input);
|
||||
event.type_ = Type::Mouse;
|
||||
event.data_.mouse = mouse; // NOLINT
|
||||
return event;
|
||||
@@ -60,9 +60,9 @@ Event Event::Mouse(std::string input, struct Mouse mouse) {
|
||||
|
||||
/// @brief An event corresponding to a terminal DCS (Device Control String).
|
||||
// static
|
||||
Event Event::CursorShape(std::string input, int shape) {
|
||||
Event Event::CursorShape(std::string_view input, int shape) {
|
||||
Event event;
|
||||
event.input_ = std::move(input);
|
||||
event.input_ = std::string(input);
|
||||
event.type_ = Type::CursorShape;
|
||||
event.data_.cursor_shape = shape; // NOLINT
|
||||
return event;
|
||||
@@ -71,17 +71,17 @@ Event Event::CursorShape(std::string input, int shape) {
|
||||
/// @brief An custom event whose meaning is defined by the user of the library.
|
||||
/// @param input An arbitrary sequence of character defined by the developer.
|
||||
// static
|
||||
Event Event::Special(std::string input) {
|
||||
Event Event::Special(std::string_view input) {
|
||||
Event event;
|
||||
event.input_ = std::move(input);
|
||||
event.input_ = std::string(input);
|
||||
return event;
|
||||
}
|
||||
|
||||
/// @internal
|
||||
// static
|
||||
Event Event::CursorPosition(std::string input, int x, int y) {
|
||||
Event Event::CursorPosition(std::string_view input, int x, int y) {
|
||||
Event event;
|
||||
event.input_ = std::move(input);
|
||||
event.input_ = std::string(input);
|
||||
event.type_ = Type::CursorPosition;
|
||||
event.data_.cursor = {x, y}; // NOLINT
|
||||
return event;
|
||||
@@ -292,12 +292,12 @@ const Event Event::ArrowLeftCtrl = Event::Special("\x1B[1;5D");
|
||||
const Event Event::ArrowRightCtrl = Event::Special("\x1B[1;5C");
|
||||
const Event Event::ArrowUpCtrl = Event::Special("\x1B[1;5A");
|
||||
const Event Event::ArrowDownCtrl = Event::Special("\x1B[1;5B");
|
||||
const Event Event::Backspace = Event::Special({127});
|
||||
const Event Event::Backspace = Event::Special(std::string({127}));
|
||||
const Event Event::Delete = Event::Special("\x1B[3~");
|
||||
const Event Event::Escape = Event::Special("\x1B");
|
||||
const Event Event::Return = Event::Special({10});
|
||||
const Event Event::Tab = Event::Special({9});
|
||||
const Event Event::TabReverse = Event::Special({27, 91, 90});
|
||||
const Event Event::Return = Event::Special(std::string({10}));
|
||||
const Event Event::Tab = Event::Special(std::string({9}));
|
||||
const Event Event::TabReverse = Event::Special(std::string({27, 91, 90}));
|
||||
|
||||
// See https://invisible-island.net/xterm/xterm-function-keys.html
|
||||
// We follow xterm-new / vterm-xf86-v4 / mgt / screen
|
||||
@@ -315,11 +315,11 @@ const Event Event::F11 = Event::Special("\x1B[23~");
|
||||
const Event Event::F12 = Event::Special("\x1B[24~");
|
||||
|
||||
const Event Event::Insert = Event::Special("\x1B[2~");
|
||||
const Event Event::Home = Event::Special({27, 91, 72});
|
||||
const Event Event::End = Event::Special({27, 91, 70});
|
||||
const Event Event::PageUp = Event::Special({27, 91, 53, 126});
|
||||
const Event Event::PageDown = Event::Special({27, 91, 54, 126});
|
||||
const Event Event::Custom = Event::Special({0});
|
||||
const Event Event::Home = Event::Special(std::string({27, 91, 72}));
|
||||
const Event Event::End = Event::Special(std::string({27, 91, 70}));
|
||||
const Event Event::PageUp = Event::Special(std::string({27, 91, 53, 126}));
|
||||
const Event Event::PageDown = Event::Special(std::string({27, 91, 54, 126}));
|
||||
const Event Event::Custom = Event::Special(std::string({0}));
|
||||
|
||||
const Event Event::a = Event::Character("a");
|
||||
const Event Event::b = Event::Character("b");
|
||||
|
||||
@@ -144,9 +144,8 @@ class MenuBase : public ComponentBase, public MenuOption {
|
||||
std::reverse(elements.begin(), elements.end());
|
||||
}
|
||||
|
||||
const Element bar = IsHorizontal()
|
||||
? hbox(std::move(elements))
|
||||
: vbox(std::move(elements));
|
||||
const Element bar =
|
||||
IsHorizontal() ? hbox(std::move(elements)) : vbox(std::move(elements));
|
||||
|
||||
if (!underline.enabled) {
|
||||
return bar | reflect(box_);
|
||||
@@ -623,7 +622,7 @@ Component MenuEntry(MenuEntryOption option) {
|
||||
UpdateAnimationTarget();
|
||||
|
||||
const EntryState state{
|
||||
label(), false, hovered_, is_focused, Index(),
|
||||
std::string(label()), false, hovered_, is_focused, Index(),
|
||||
};
|
||||
|
||||
Element element = (transform ? transform : DefaultOptionTransform) //
|
||||
|
||||
@@ -1054,7 +1054,7 @@ void ScreenInteractive::Signal(int signal) {
|
||||
}
|
||||
|
||||
if (signal == SIGWINCH) {
|
||||
Post(Event::Special({0}));
|
||||
Post(Event::Special(std::string({0})));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -21,8 +21,8 @@ class TaskRunner {
|
||||
auto PostTask(Task task) -> void;
|
||||
|
||||
/// Schedules a task to be executed after a certain duration.
|
||||
auto PostDelayedTask(Task task,
|
||||
std::chrono::steady_clock::duration duration) -> void;
|
||||
auto PostDelayedTask(Task task, std::chrono::steady_clock::duration duration)
|
||||
-> void;
|
||||
|
||||
/// Runs the tasks in the queue, return the delay until the next delayed task
|
||||
/// can be executed.
|
||||
|
||||
@@ -338,7 +338,7 @@ TEST(Event, Control) {
|
||||
EXPECT_TRUE(received_events.empty());
|
||||
} else {
|
||||
EXPECT_EQ(1, received_events.size());
|
||||
EXPECT_EQ(received_events[0], Event::Special({test.input}));
|
||||
EXPECT_EQ(received_events[0], Event::Special(std::string({test.input})));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -782,7 +782,7 @@ void Canvas::DrawBlockEllipseFilled(int x1,
|
||||
/// @param x the x coordinate of the text.
|
||||
/// @param y the y coordinate of the text.
|
||||
/// @param value the text to draw.
|
||||
void Canvas::DrawText(int x, int y, const std::string& value) {
|
||||
void Canvas::DrawText(int x, int y, std::string_view value) {
|
||||
DrawText(x, y, value, nostyle);
|
||||
}
|
||||
|
||||
@@ -793,7 +793,7 @@ void Canvas::DrawText(int x, int y, const std::string& value) {
|
||||
/// @param color the color of the text.
|
||||
void Canvas::DrawText(int x,
|
||||
int y,
|
||||
const std::string& value,
|
||||
std::string_view value,
|
||||
const Color& color) {
|
||||
DrawText(x, y, value, [color](Pixel& p) { p.foreground_color = color; });
|
||||
}
|
||||
@@ -805,7 +805,7 @@ void Canvas::DrawText(int x,
|
||||
/// @param style the style of the text.
|
||||
void Canvas::DrawText(int x,
|
||||
int y,
|
||||
const std::string& value,
|
||||
std::string_view value,
|
||||
const Stylizer& style) {
|
||||
for (const auto& it : Utf8ToGlyphs(value)) {
|
||||
if (!IsIn(x, y)) {
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
// the LICENSE file.
|
||||
#include <gtest/gtest.h> // for Test, TestInfo (ptr only), EXPECT_EQ, Message, TEST, TestPartResult
|
||||
#include <array> // for array
|
||||
#include <cstddef> // for size_t
|
||||
#include <array> // for array
|
||||
#include <cstddef> // for size_t
|
||||
#include <queue>
|
||||
#include <stack> // for stack
|
||||
#include <string> // for allocator, basic_string, string
|
||||
|
||||
@@ -48,8 +48,8 @@ class Hyperlink : public NodeDecorator {
|
||||
/// Element document =
|
||||
/// hyperlink("https://github.com/ArthurSonzogni/FTXUI", "link");
|
||||
/// ```
|
||||
Element hyperlink(std::string link, Element child) {
|
||||
return std::make_shared<Hyperlink>(std::move(child), std::move(link));
|
||||
Element hyperlink(std::string_view link, Element child) {
|
||||
return std::make_shared<Hyperlink>(std::move(child), std::string(link));
|
||||
}
|
||||
|
||||
/// @brief Decorate using a hyperlink.
|
||||
@@ -67,8 +67,10 @@ Element hyperlink(std::string link, Element child) {
|
||||
/// text("red") | hyperlink("https://github.com/Arthursonzogni/FTXUI");
|
||||
/// ```
|
||||
// NOLINTNEXTLINE
|
||||
Decorator hyperlink(std::string link) {
|
||||
return [link](Element child) { return hyperlink(link, std::move(child)); };
|
||||
Decorator hyperlink(std::string_view link) {
|
||||
return [link = std::string(link)](Element child) {
|
||||
return hyperlink(link, std::move(child));
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace ftxui
|
||||
|
||||
@@ -38,7 +38,7 @@ Element Split(const std::string& paragraph,
|
||||
/// @brief Return an element drawing the paragraph on multiple lines.
|
||||
/// @ingroup dom
|
||||
/// @see flexbox.
|
||||
Element paragraph(const std::string& the_text) {
|
||||
Element paragraph(std::string_view the_text) {
|
||||
return paragraphAlignLeft(the_text);
|
||||
}
|
||||
|
||||
@@ -46,8 +46,8 @@ Element paragraph(const std::string& the_text) {
|
||||
/// the left.
|
||||
/// @ingroup dom
|
||||
/// @see flexbox.
|
||||
Element paragraphAlignLeft(const std::string& the_text) {
|
||||
return Split(the_text, [](const std::string& line) {
|
||||
Element paragraphAlignLeft(std::string_view the_text) {
|
||||
return Split(std::string(the_text), [](const std::string& line) {
|
||||
static const auto config = FlexboxConfig().SetGap(1, 0);
|
||||
return flexbox(Split(line), config);
|
||||
});
|
||||
@@ -57,8 +57,8 @@ Element paragraphAlignLeft(const std::string& the_text) {
|
||||
/// the right.
|
||||
/// @ingroup dom
|
||||
/// @see flexbox.
|
||||
Element paragraphAlignRight(const std::string& the_text) {
|
||||
return Split(the_text, [](const std::string& line) {
|
||||
Element paragraphAlignRight(std::string_view the_text) {
|
||||
return Split(std::string(the_text), [](const std::string& line) {
|
||||
static const auto config = FlexboxConfig().SetGap(1, 0).Set(
|
||||
FlexboxConfig::JustifyContent::FlexEnd);
|
||||
return flexbox(Split(line), config);
|
||||
@@ -69,8 +69,8 @@ Element paragraphAlignRight(const std::string& the_text) {
|
||||
/// the center.
|
||||
/// @ingroup dom
|
||||
/// @see flexbox.
|
||||
Element paragraphAlignCenter(const std::string& the_text) {
|
||||
return Split(the_text, [](const std::string& line) {
|
||||
Element paragraphAlignCenter(std::string_view the_text) {
|
||||
return Split(std::string(the_text), [](const std::string& line) {
|
||||
static const auto config =
|
||||
FlexboxConfig().SetGap(1, 0).Set(FlexboxConfig::JustifyContent::Center);
|
||||
return flexbox(Split(line), config);
|
||||
@@ -82,8 +82,8 @@ Element paragraphAlignCenter(const std::string& the_text) {
|
||||
/// the center.
|
||||
/// @ingroup dom
|
||||
/// @see flexbox.
|
||||
Element paragraphAlignJustify(const std::string& the_text) {
|
||||
return Split(the_text, [](const std::string& line) {
|
||||
Element paragraphAlignJustify(std::string_view the_text) {
|
||||
return Split(std::string(the_text), [](const std::string& line) {
|
||||
static const auto config = FlexboxConfig().SetGap(1, 0).Set(
|
||||
FlexboxConfig::JustifyContent::SpaceBetween);
|
||||
Elements words = Split(line);
|
||||
|
||||
@@ -143,7 +143,7 @@ Selection Selection::SaturateVertical(Box box) {
|
||||
return {start_x, start_y, end_x, end_y, parent_};
|
||||
}
|
||||
|
||||
void Selection::AddPart(const std::string& part, int y, int left, int right) {
|
||||
void Selection::AddPart(std::string_view part, int y, int left, int right) {
|
||||
if (parent_ != this) {
|
||||
parent_->AddPart(part, y, left, right);
|
||||
return;
|
||||
|
||||
@@ -392,8 +392,8 @@ Element separatorEmpty() {
|
||||
/// ────
|
||||
/// down
|
||||
/// ```
|
||||
Element separatorCharacter(std::string value) {
|
||||
return std::make_shared<Separator>(std::move(value));
|
||||
Element separatorCharacter(std::string_view value) {
|
||||
return std::make_shared<Separator>(std::string(value));
|
||||
}
|
||||
|
||||
/// @brief Draw a separator in between two element filled with a given pixel.
|
||||
|
||||
@@ -25,12 +25,12 @@ TEST(TableTest, Empty) {
|
||||
}
|
||||
|
||||
TEST(TableTest, Basic) {
|
||||
auto table = Table({
|
||||
auto table = Table(std::initializer_list<std::vector<std::string>>({
|
||||
{"a", "b", "c", "d"},
|
||||
{"e", "f", "g", "h"},
|
||||
{"i", "j", "k", "l"},
|
||||
{"m", "n", "o", "p"},
|
||||
});
|
||||
}));
|
||||
Screen screen(10, 10);
|
||||
Render(screen, table.Render());
|
||||
EXPECT_EQ(
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
#include <algorithm> // for min
|
||||
#include <memory> // for make_shared
|
||||
#include <sstream>
|
||||
#include <string> // for string, wstring
|
||||
#include <utility> // for move
|
||||
#include <string> // for string, wstring
|
||||
#include <string_view> // for string_view
|
||||
#include <utility> // for move
|
||||
|
||||
#include "ftxui/dom/deprecated.hpp" // for text, vtext
|
||||
#include "ftxui/dom/elements.hpp" // for Element, text, vtext
|
||||
@@ -24,6 +25,7 @@ using ftxui::Screen;
|
||||
class Text : public Node {
|
||||
public:
|
||||
explicit Text(std::string text) : text_(std::move(text)) {}
|
||||
explicit Text(std::string_view sv) : Text(std::string(sv)) {}
|
||||
|
||||
void ComputeRequirement() override {
|
||||
requirement_.min_x = string_width(text_);
|
||||
@@ -96,6 +98,8 @@ class VText : public Node {
|
||||
explicit VText(std::string text)
|
||||
: text_(std::move(text)), width_{std::min(string_width(text_), 1)} {}
|
||||
|
||||
explicit VText(std::string_view sv) : VText(std::string(sv)) {}
|
||||
|
||||
void ComputeRequirement() override {
|
||||
requirement_.min_x = width_;
|
||||
requirement_.min_y = string_width(text_);
|
||||
@@ -138,8 +142,8 @@ class VText : public Node {
|
||||
/// ```bash
|
||||
/// Hello world!
|
||||
/// ```
|
||||
Element text(std::string text) {
|
||||
return std::make_shared<Text>(std::move(text));
|
||||
Element text(std::string_view text) {
|
||||
return std::make_shared<Text>(std::string(text));
|
||||
}
|
||||
|
||||
/// @brief Display a piece of unicode text.
|
||||
@@ -161,6 +165,25 @@ Element text(std::wstring text) { // NOLINT
|
||||
return std::make_shared<Text>(to_string(text));
|
||||
}
|
||||
|
||||
/// @brief Display a piece of unicode text.
|
||||
/// @ingroup dom
|
||||
/// @see ftxui::to_wstring
|
||||
///
|
||||
/// ### Example
|
||||
///
|
||||
/// ```cpp
|
||||
/// Element document = text(L"Hello world!");
|
||||
/// ```
|
||||
///
|
||||
/// ### Output
|
||||
///
|
||||
/// ```bash
|
||||
/// Hello world!
|
||||
/// ```
|
||||
Element text(std::wstring_view sv) {
|
||||
return text(std::wstring(sv));
|
||||
}
|
||||
|
||||
/// @brief Display a piece of unicode text vertically.
|
||||
/// @ingroup dom
|
||||
/// @see ftxui::to_wstring
|
||||
@@ -187,8 +210,8 @@ Element text(std::wstring text) { // NOLINT
|
||||
/// d
|
||||
/// !
|
||||
/// ```
|
||||
Element vtext(std::string text) {
|
||||
return std::make_shared<VText>(std::move(text));
|
||||
Element vtext(std::string_view text) {
|
||||
return std::make_shared<VText>(std::string(text));
|
||||
}
|
||||
|
||||
/// @brief Display a piece unicode text vertically.
|
||||
@@ -221,4 +244,34 @@ Element vtext(std::wstring text) { // NOLINT
|
||||
return std::make_shared<VText>(to_string(text));
|
||||
}
|
||||
|
||||
/// @brief Display a piece unicode text vertically.
|
||||
/// @ingroup dom
|
||||
/// @see ftxui::to_wstring
|
||||
///
|
||||
/// ### Example
|
||||
///
|
||||
/// ```cpp
|
||||
/// Element document = vtext(L"Hello world!");
|
||||
/// ```
|
||||
///
|
||||
/// ### Output
|
||||
///
|
||||
/// ```bash
|
||||
/// H
|
||||
/// e
|
||||
/// l
|
||||
/// l
|
||||
/// o
|
||||
///
|
||||
/// w
|
||||
/// o
|
||||
/// r
|
||||
/// l
|
||||
/// d
|
||||
/// !
|
||||
/// ```
|
||||
Element vtext(std::wstring_view text) { // NOLINT
|
||||
return vtext(std::wstring(text));
|
||||
}
|
||||
|
||||
} // namespace ftxui
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
// the LICENSE file.
|
||||
#include <gtest/gtest.h>
|
||||
#include <string> // for allocator, string
|
||||
#include <string> // for allocator, string
|
||||
#include <string_view> // for string_view
|
||||
|
||||
#include "ftxui/dom/elements.hpp" // for text, operator|, border, Element
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
@@ -121,5 +122,13 @@ TEST(TextTest, CombiningCharactersWithSpace) {
|
||||
EXPECT_EQ(t, screen.ToString());
|
||||
}
|
||||
|
||||
TEST(TextTest, WithStringViews) {
|
||||
const std::string_view t = "Hello, world!";
|
||||
auto element = text(t);
|
||||
Screen screen(13, 1);
|
||||
Render(screen, element);
|
||||
EXPECT_EQ(t, screen.ToString());
|
||||
}
|
||||
|
||||
} // namespace ftxui
|
||||
// NOLINTEND
|
||||
|
||||
@@ -531,7 +531,7 @@ void Screen::ApplyShader() {
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
std::uint8_t Screen::RegisterHyperlink(const std::string& link) {
|
||||
std::uint8_t Screen::RegisterHyperlink(std::string_view link) {
|
||||
for (std::size_t i = 0; i < hyperlinks_.size(); ++i) {
|
||||
if (hyperlinks_[i] == link) {
|
||||
return i;
|
||||
@@ -540,7 +540,7 @@ std::uint8_t Screen::RegisterHyperlink(const std::string& link) {
|
||||
if (hyperlinks_.size() == std::numeric_limits<std::uint8_t>::max()) {
|
||||
return 0;
|
||||
}
|
||||
hyperlinks_.push_back(link);
|
||||
hyperlinks_.push_back(std::string(link));
|
||||
return hyperlinks_.size() - 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1171,7 +1171,7 @@ namespace ftxui {
|
||||
// one codepoint. Put the codepoint into |ucs|. Start at |start| and update
|
||||
// |end| to represent the beginning of the next byte to eat for consecutive
|
||||
// executions.
|
||||
bool EatCodePoint(const std::string& input,
|
||||
bool EatCodePoint(std::string_view input,
|
||||
size_t start,
|
||||
size_t* end,
|
||||
uint32_t* ucs) {
|
||||
@@ -1241,7 +1241,7 @@ bool EatCodePoint(const std::string& input,
|
||||
// one codepoint. Put the codepoint into |ucs|. Start at |start| and update
|
||||
// |end| to represent the beginning of the next byte to eat for consecutive
|
||||
// executions.
|
||||
bool EatCodePoint(const std::wstring& input,
|
||||
bool EatCodePoint(std::wstring_view input,
|
||||
size_t start,
|
||||
size_t* end,
|
||||
uint32_t* ucs) {
|
||||
@@ -1328,7 +1328,7 @@ int wstring_width(const std::wstring& text) {
|
||||
return width;
|
||||
}
|
||||
|
||||
int string_width(const std::string& input) {
|
||||
int string_width(std::string_view input) {
|
||||
int width = 0;
|
||||
size_t start = 0;
|
||||
while (start < input.size()) {
|
||||
@@ -1355,7 +1355,7 @@ int string_width(const std::string& input) {
|
||||
return width;
|
||||
}
|
||||
|
||||
std::vector<std::string> Utf8ToGlyphs(const std::string& input) {
|
||||
std::vector<std::string> Utf8ToGlyphs(std::string_view input) {
|
||||
std::vector<std::string> out;
|
||||
out.reserve(input.size());
|
||||
size_t start = 0;
|
||||
@@ -1367,7 +1367,7 @@ std::vector<std::string> Utf8ToGlyphs(const std::string& input) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string append = input.substr(start, end - start);
|
||||
const auto append = input.substr(start, end - start);
|
||||
start = end;
|
||||
|
||||
// Ignore control characters.
|
||||
@@ -1386,18 +1386,18 @@ std::vector<std::string> Utf8ToGlyphs(const std::string& input) {
|
||||
// Fullwidth characters take two cells. The second is made of the empty
|
||||
// string to reserve the space the first is taking.
|
||||
if (IsFullWidth(codepoint)) {
|
||||
out.push_back(append);
|
||||
out.push_back(std::string(append));
|
||||
out.emplace_back("");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Normal characters:
|
||||
out.push_back(append);
|
||||
out.push_back(std::string(append));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
size_t GlyphPrevious(const std::string& input, size_t start) {
|
||||
size_t GlyphPrevious(std::string_view input, size_t start) {
|
||||
while (true) {
|
||||
if (start == 0) {
|
||||
return 0;
|
||||
@@ -1422,7 +1422,7 @@ size_t GlyphPrevious(const std::string& input, size_t start) {
|
||||
}
|
||||
}
|
||||
|
||||
size_t GlyphNext(const std::string& input, size_t start) {
|
||||
size_t GlyphNext(std::string_view input, size_t start) {
|
||||
bool glyph_found = false;
|
||||
while (start < input.size()) {
|
||||
size_t end = 0;
|
||||
@@ -1448,7 +1448,7 @@ size_t GlyphNext(const std::string& input, size_t start) {
|
||||
return static_cast<int>(input.size());
|
||||
}
|
||||
|
||||
size_t GlyphIterate(const std::string& input, int glyph_offset, size_t start) {
|
||||
size_t GlyphIterate(std::string_view input, int glyph_offset, size_t start) {
|
||||
if (glyph_offset >= 0) {
|
||||
for (int i = 0; i < glyph_offset; ++i) {
|
||||
start = GlyphNext(input, start);
|
||||
@@ -1462,7 +1462,7 @@ size_t GlyphIterate(const std::string& input, int glyph_offset, size_t start) {
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int> CellToGlyphIndex(const std::string& input) {
|
||||
std::vector<int> CellToGlyphIndex(std::string_view input) {
|
||||
int x = -1;
|
||||
std::vector<int> out;
|
||||
out.reserve(input.size());
|
||||
@@ -1503,7 +1503,7 @@ std::vector<int> CellToGlyphIndex(const std::string& input) {
|
||||
return out;
|
||||
}
|
||||
|
||||
int GlyphCount(const std::string& input) {
|
||||
int GlyphCount(std::string_view input) {
|
||||
int size = 0;
|
||||
size_t start = 0;
|
||||
size_t end = 0;
|
||||
@@ -1531,8 +1531,7 @@ int GlyphCount(const std::string& input) {
|
||||
return size;
|
||||
}
|
||||
|
||||
std::vector<WordBreakProperty> Utf8ToWordBreakProperty(
|
||||
const std::string& input) {
|
||||
std::vector<WordBreakProperty> Utf8ToWordBreakProperty(std::string_view input) {
|
||||
std::vector<WordBreakProperty> out;
|
||||
out.reserve(input.size());
|
||||
size_t start = 0;
|
||||
@@ -1563,7 +1562,7 @@ std::vector<WordBreakProperty> Utf8ToWordBreakProperty(
|
||||
}
|
||||
|
||||
/// Convert a std::wstring into a UTF8 std::string.
|
||||
std::string to_string(const std::wstring& s) {
|
||||
std::string to_string(std::wstring_view s) {
|
||||
std::string out;
|
||||
|
||||
size_t i = 0;
|
||||
@@ -1635,7 +1634,7 @@ std::string to_string(const std::wstring& s) {
|
||||
}
|
||||
|
||||
/// Convert a UTF8 std::string into a std::wstring.
|
||||
std::wstring to_wstring(const std::string& s) {
|
||||
std::wstring to_wstring(std::string_view s) {
|
||||
std::wstring out;
|
||||
|
||||
size_t i = 0;
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
|
||||
namespace ftxui {
|
||||
|
||||
bool EatCodePoint(const std::string& input,
|
||||
bool EatCodePoint(std::string_view input,
|
||||
size_t start,
|
||||
size_t* end,
|
||||
uint32_t* ucs);
|
||||
bool EatCodePoint(const std::wstring& input,
|
||||
bool EatCodePoint(std::wstring_view input,
|
||||
size_t start,
|
||||
size_t* end,
|
||||
uint32_t* ucs);
|
||||
@@ -23,17 +23,15 @@ bool IsCombining(uint32_t ucs);
|
||||
bool IsFullWidth(uint32_t ucs);
|
||||
bool IsControl(uint32_t ucs);
|
||||
|
||||
size_t GlyphPrevious(const std::string& input, size_t start);
|
||||
size_t GlyphNext(const std::string& input, size_t start);
|
||||
size_t GlyphPrevious(std::string_view input, size_t start);
|
||||
size_t GlyphNext(std::string_view input, size_t start);
|
||||
|
||||
// Return the index in the |input| string of the glyph at |glyph_offset|,
|
||||
// starting at |start|
|
||||
size_t GlyphIterate(const std::string& input,
|
||||
int glyph_offset,
|
||||
size_t start = 0);
|
||||
size_t GlyphIterate(std::string_view input, int glyph_offset, size_t start = 0);
|
||||
|
||||
// Returns the number of glyphs in |input|.
|
||||
int GlyphCount(const std::string& input);
|
||||
int GlyphCount(std::string_view input);
|
||||
|
||||
// Properties from:
|
||||
// https://www.unicode.org/Public/UCD/latest/ucd/auxiliary/WordBreakProperty.txt
|
||||
@@ -58,10 +56,9 @@ enum class WordBreakProperty : int8_t {
|
||||
ZWJ,
|
||||
};
|
||||
WordBreakProperty CodepointToWordBreakProperty(uint32_t codepoint);
|
||||
std::vector<WordBreakProperty> Utf8ToWordBreakProperty(
|
||||
const std::string& input);
|
||||
std::vector<WordBreakProperty> Utf8ToWordBreakProperty(std::string_view input);
|
||||
|
||||
bool IsWordBreakingCharacter(const std::string& input, size_t glyph_index);
|
||||
bool IsWordBreakingCharacter(std::string_view input, size_t glyph_index);
|
||||
} // namespace ftxui
|
||||
|
||||
#endif /* end of include guard: FTXUI_SCREEN_STRING_INTERNAL_HPP */
|
||||
|
||||
@@ -154,14 +154,14 @@ TEST(StringTest, to_string) {
|
||||
}
|
||||
|
||||
TEST(StringTest, to_wstring) {
|
||||
EXPECT_EQ(to_wstring(std::string("hello")), L"hello");
|
||||
EXPECT_EQ(to_wstring(std::string("€")), L"€");
|
||||
EXPECT_EQ(to_wstring(std::string("ÿ")), L"ÿ");
|
||||
EXPECT_EQ(to_wstring(std::string("߿")), L"߿");
|
||||
EXPECT_EQ(to_wstring(std::string("ɰɱ")), L"ɰɱ");
|
||||
EXPECT_EQ(to_wstring(std::string("«»")), L"«»");
|
||||
EXPECT_EQ(to_wstring(std::string("嵰嵲嵫")), L"嵰嵲嵫");
|
||||
EXPECT_EQ(to_wstring(std::string("🎅🎄")), L"🎅🎄");
|
||||
EXPECT_EQ(to_wstring("hello"), L"hello");
|
||||
EXPECT_EQ(to_wstring("€"), L"€");
|
||||
EXPECT_EQ(to_wstring("ÿ"), L"ÿ");
|
||||
EXPECT_EQ(to_wstring("߿"), L"߿");
|
||||
EXPECT_EQ(to_wstring("ɰɱ"), L"ɰɱ");
|
||||
EXPECT_EQ(to_wstring("«»"), L"«»");
|
||||
EXPECT_EQ(to_wstring("嵰嵲嵫"), L"嵰嵲嵫");
|
||||
EXPECT_EQ(to_wstring("🎅🎄"), L"🎅🎄");
|
||||
}
|
||||
|
||||
} // namespace ftxui
|
||||
|
||||
@@ -13,7 +13,7 @@ class Adapter : public ConstStringListRef::Adapter {
|
||||
public:
|
||||
Adapter(std::vector<std::string>& entries) : entries(entries) {}
|
||||
size_t size() const override { return entries.size() * 2; }
|
||||
std::string operator[](size_t index) const override {
|
||||
std::string_view operator[](size_t index) const override {
|
||||
return entries[index / 2];
|
||||
}
|
||||
std::vector<std::string>& entries;
|
||||
|
||||
Reference in New Issue
Block a user