FTXUI  5.0.0
C++ functional terminal UI.
Loading...
Searching...
No Matches
text.cpp
Go to the documentation of this file.
1// Copyright 2020 Arthur Sonzogni. All rights reserved.
2// Use of this source code is governed by the MIT license that can be found in
3// the LICENSE file.
4#include <algorithm> // for min
5#include <memory> // for make_shared
6#include <sstream>
7#include <string> // for string, wstring
8#include <utility> // for move
9
10#include "ftxui/dom/deprecated.hpp" // for text, vtext
11#include "ftxui/dom/elements.hpp" // for Element, text, vtext
12#include "ftxui/dom/node.hpp" // for Node
13#include "ftxui/dom/requirement.hpp" // for Requirement
14#include "ftxui/screen/box.hpp" // for Box
15#include "ftxui/screen/screen.hpp" // for Pixel, Screen
16#include "ftxui/screen/string.hpp" // for string_width, Utf8ToGlyphs, to_string
17
18namespace ftxui {
19
20namespace {
21using ftxui::Screen;
22
23class Text : public Node {
24 public:
25 explicit Text(std::string text) : text_(std::move(text)) {}
26
27 void ComputeRequirement() override {
28 requirement_.min_x = string_width(text_);
29 requirement_.min_y = 1;
30 has_selection = false;
31 }
32
33 void Select(Selection& selection) override {
34 if (Box::Intersection(selection.GetBox(), box_).IsEmpty()) {
35 return;
36 }
37
38 Selection selection_saturated = selection.SaturateHorizontal(box_);
39
40 has_selection = true;
41 selection_start_ = selection_saturated.GetBox().x_min;
42 selection_end_ = selection_saturated.GetBox().x_max;
43
44 std::stringstream ss;
45 int x = box_.x_min;
46 for (const auto& cell : Utf8ToGlyphs(text_)) {
47 if (cell == "\n") {
48 continue;
49 }
50 if (selection_start_ <= x && x <= selection_end_) {
51 ss << cell;
52 }
53 x++;
54 }
55 selection.AddPart(ss.str(), box_.y_min, selection_start_, selection_end_);
56 }
57
58 void Render(Screen& screen) override {
59 int x = box_.x_min;
60 const int y = box_.y_min;
61
62 if (y > box_.y_max) {
63 return;
64 }
65
66 for (const auto& cell : Utf8ToGlyphs(text_)) {
67 if (x > box_.x_max) {
68 break;
69 }
70 if (cell == "\n") {
71 continue;
72 }
73 screen.PixelAt(x, y).character = cell;
74
75 if (has_selection) {
76 auto selectionTransform = screen.GetSelectionStyle();
77 if ((x >= selection_start_) && (x <= selection_end_)) {
78 selectionTransform(screen.PixelAt(x, y));
79 }
80 }
81
82 ++x;
83 }
84 }
85
86 private:
87 std::string text_;
88 bool has_selection = false;
89 int selection_start_ = 0;
90 int selection_end_ = -1;
91};
92
93class VText : public Node {
94 public:
95 explicit VText(std::string text)
96 : text_(std::move(text)), width_{std::min(string_width(text_), 1)} {}
97
98 void ComputeRequirement() override {
99 requirement_.min_x = width_;
100 requirement_.min_y = string_width(text_);
101 }
102
103 void Render(Screen& screen) override {
104 const int x = box_.x_min;
105 int y = box_.y_min;
106 if (x + width_ - 1 > box_.x_max) {
107 return;
108 }
109 for (const auto& it : Utf8ToGlyphs(text_)) {
110 if (y > box_.y_max) {
111 return;
112 }
113 screen.PixelAt(x, y).character = it;
114 y += 1;
115 }
116 }
117
118 private:
119 std::string text_;
120 int width_ = 1;
121};
122
123} // namespace
124
125/// @brief Display a piece of UTF8 encoded unicode text.
126/// @ingroup dom
127/// @see ftxui::to_wstring
128///
129/// ### Example
130///
131/// ```cpp
132/// Element document = text("Hello world!");
133/// ```
134///
135/// ### Output
136///
137/// ```bash
138/// Hello world!
139/// ```
140Element text(std::string text) {
141 return std::make_shared<Text>(std::move(text));
142}
143
144/// @brief Display a piece of unicode text.
145/// @ingroup dom
146/// @see ftxui::to_wstring
147///
148/// ### Example
149///
150/// ```cpp
151/// Element document = text(L"Hello world!");
152/// ```
153///
154/// ### Output
155///
156/// ```bash
157/// Hello world!
158/// ```
159Element text(std::wstring text) { // NOLINT
160 return std::make_shared<Text>(to_string(text));
161}
162
163/// @brief Display a piece of unicode text vertically.
164/// @ingroup dom
165/// @see ftxui::to_wstring
166///
167/// ### Example
168///
169/// ```cpp
170/// Element document = vtext("Hello world!");
171/// ```
172///
173/// ### Output
174///
175/// ```bash
176/// H
177/// e
178/// l
179/// l
180/// o
181///
182/// w
183/// o
184/// r
185/// l
186/// d
187/// !
188/// ```
189Element vtext(std::string text) {
190 return std::make_shared<VText>(std::move(text));
191}
192
193/// @brief Display a piece unicode text vertically.
194/// @ingroup dom
195/// @see ftxui::to_wstring
196///
197/// ### Example
198///
199/// ```cpp
200/// Element document = vtext(L"Hello world!");
201/// ```
202///
203/// ### Output
204///
205/// ```bash
206/// H
207/// e
208/// l
209/// l
210/// o
211///
212/// w
213/// o
214/// r
215/// l
216/// d
217/// !
218/// ```
219Element vtext(std::wstring text) { // NOLINT
220 return std::make_shared<VText>(to_string(text));
221}
222
223} // namespace ftxui
A rectangular grid of Pixel.
Definition screen.hpp:27
std::shared_ptr< Node > Element
Definition elements.hpp:22
std::shared_ptr< T > Make(Args &&... args)
Definition component.hpp:26
std::vector< std::string > Utf8ToGlyphs(const std::string &input)
Definition string.cpp:1357
int string_width(const std::string &)
Definition string.cpp:1330
std::string to_string(const std::wstring &s)
Convert a UTF8 std::string into a std::wstring.
Definition string.cpp:1565
Element text(std::wstring text)
Display a piece of unicode text.
Definition text.cpp:159
Element vtext(std::wstring text)
Display a piece unicode text vertically.
Definition text.cpp:219
void Render(Screen &screen, const Element &element)
Display an element on a ftxui::Screen.
Definition node.cpp:72
static auto Intersection(Box a, Box b) -> Box
Definition box.cpp:12