26class Text :
public Node {
28 explicit Text(
const std::string& text) : glyphs_(Utf8ToGlyphs(text)) {}
29 explicit Text(std::string_view sv) :
Text(std::string(sv)) {}
31 void ComputeRequirement()
override {
33 int current_width = 0;
35 has_selection_ =
false;
36 selection_rows_.clear();
37 lines_offsets_.clear();
38 lines_offsets_.push_back(0);
40 for (
size_t i = 0; i < glyphs_.size(); ++i) {
41 if (glyphs_[i] ==
"\n") {
42 max_width = std::max(max_width, current_width);
45 lines_offsets_.push_back((
int)i + 1);
50 max_width = std::max(max_width, current_width);
51 lines_offsets_.push_back((
int)glyphs_.size() + 1);
53 requirement_.min_x = max_width;
54 requirement_.min_y = lines_count;
57 void Select(Selection& selection)
override {
62 has_selection_ =
true;
63 selection_rows_.assign(lines_offsets_.size() - 1, {-1, -1});
65 for (
size_t i = 0; i < lines_offsets_.size() - 1; ++i) {
66 const int y = box_.y_min + (int)i;
71 const Box row_box{box_.x_min, box_.x_max, y, y};
76 const Selection row_sel = selection.SaturateHorizontal(row_box);
77 const int sel_start = row_sel.GetBox().x_min;
78 const int sel_end = row_sel.GetBox().x_max;
79 selection_rows_[i] = {sel_start, sel_end};
83 const int start = lines_offsets_[i];
84 const int end = lines_offsets_[i + 1] - 1;
85 for (
int j = start; j < end; ++j) {
86 if (sel_start <= x && x <= sel_end) {
91 selection.AddPart(std::move(part), y, sel_start, sel_end);
95 void Render(Screen& screen)
override {
100 if (y > box_.y_max) {
104 for (
const auto& cell : glyphs_) {
109 if (y > box_.y_max) {
115 if (x <= box_.x_max) {
116 screen.CellAt(x, y).character = cell;
118 if (has_selection_ && line < selection_rows_.size()) {
119 const auto& [sel_start, sel_end] = selection_rows_[line];
120 if (sel_start != -1 && x >= sel_start && x <= sel_end) {
121 screen.GetSelectionStyle()(screen.CellAt(x, y));
130 std::vector<std::string> glyphs_;
131 std::vector<int> lines_offsets_;
132 bool has_selection_ =
false;
133 std::vector<std::pair<int, int>> selection_rows_;
136class VText :
public Node {
138 explicit VText(
const std::string& text) : glyphs_(Utf8ToGlyphs(text)) {
139 for (
const auto& g : glyphs_) {
146 explicit VText(std::string_view sv) : VText(std::string(sv)) {}
148 void ComputeRequirement()
override {
150 int current_height = 0;
153 for (
const auto& cell : glyphs_) {
155 max_height = std::max(max_height, current_height);
162 max_height = std::max(max_height, current_height);
164 requirement_.min_x = width_ * columns;
165 requirement_.min_y = max_height;
168 void Render(Screen& screen)
override {
171 if (x + width_ - 1 > box_.x_max) {
174 for (
const auto& it : glyphs_) {
178 if (x + width_ - 1 > box_.x_max) {
183 if (y > box_.y_max) {
186 screen.CellAt(x, y).character = it;
192 std::vector<std::string> glyphs_;
214 return std::make_shared<Text>(std::string(text));
263 return std::make_shared<VText>(std::string(text));
Element text(std::wstring_view text)
Display a piece of unicode text.
Element vtext(std::wstring_view text)
Display a piece unicode text vertically.
void Render(Screen &screen, const Element &element)
Display an element on a ftxui::Screen.
static auto Intersection(Box a, Box b) -> Box
A rectangular grid of Cell.
The FTXUI ftxui:: namespace.
std::shared_ptr< Node > Element
std::string to_string(std::wstring_view s)
Convert a std::wstring into a UTF8 std::string.