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