FTXUI  4.0.0
C++ functional terminal UI.
Loading...
Searching...
No Matches
table.cpp
Go to the documentation of this file.
1#include "ftxui/dom/table.hpp"
2
3#include <algorithm> // for max
4#include <memory> // for allocator, shared_ptr, allocator_traits<>::value_type
5#include <utility> // for move, swap
6
7#include "ftxui/dom/elements.hpp" // for Element, operator|, text, separatorCharacter, Elements, BorderStyle, Decorator, emptyElement, size, gridbox, EQUAL, flex, flex_shrink, HEIGHT, WIDTH
8
9namespace ftxui {
10namespace {
11
12bool IsCell(int x, int y) {
13 return x % 2 == 1 && y % 2 == 1;
14}
15
16// NOLINTNEXTLINE
17static std::string charset[5][6] = {
18 {"┌", "┐", "└", "┘", "─", "│"}, //
19 {"┏", "┓", "┗", "┛", "━", "┃"}, //
20 {"╔", "╗", "╚", "╝", "═", "║"}, //
21 {"╭", "╮", "╰", "╯", "─", "│"}, //
22 {" ", " ", " ", " ", " ", " "}, //
23};
24
25int Wrap(int input, int modulo) {
26 input %= modulo;
27 input += modulo;
28 input %= modulo;
29 return input;
30}
31
32void Order(int& a, int& b) {
33 if (a >= b) {
34 std::swap(a, b);
35 }
36}
37
38} // namespace
39
41 Initialize({});
42}
43
44Table::Table(std::vector<std::vector<std::string>> input) {
45 std::vector<std::vector<Element>> output;
46 for (auto& row : input) {
47 output.emplace_back();
48 auto& output_row = output.back();
49 for (auto& cell : row) {
50 output_row.push_back(text(std::move(cell)));
51 }
52 }
53 Initialize(std::move(output));
54}
55
56Table::Table(std::vector<std::vector<Element>> input) {
57 Initialize(std::move(input));
58}
59
60void Table::Initialize(std::vector<std::vector<Element>> input) {
61 input_dim_y_ = (int)input.size();
62 input_dim_x_ = 0;
63 for (auto& row : input) {
64 input_dim_x_ = std::max(input_dim_x_, (int)row.size());
65 }
66
67 dim_y_ = 2 * input_dim_y_ + 1;
68 dim_x_ = 2 * input_dim_x_ + 1;
69
70 // Reserve space.
71 elements_.resize(dim_y_);
72 for (int y = 0; y < dim_y_; ++y) {
73 elements_[y].resize(dim_x_);
74 }
75
76 // Transfert elements_ from |input| toward |elements_|.
77 {
78 int y = 1;
79 for (auto& row : input) {
80 int x = 1;
81 for (auto& cell : row) {
82 elements_[y][x] = std::move(cell);
83 x += 2;
84 }
85 y += 2;
86 }
87 }
88
89 // Add empty element for the border.
90 for (int y = 0; y < dim_y_; ++y) {
91 for (int x = 0; x < dim_x_; ++x) {
92 auto& element = elements_[y][x];
93
94 if (IsCell(x, y)) {
95 if (!element) {
96 element = emptyElement();
97 }
98 continue;
99 }
100
101 element = emptyElement();
102 }
103 }
104}
105
107 return SelectRectangle(0, -1, index, index);
108}
109
110TableSelection Table::SelectRows(int row_min, int row_max) {
111 return SelectRectangle(0, -1, row_min, row_max);
112}
113
115 return SelectRectangle(index, index, 0, -1);
116}
117
118TableSelection Table::SelectColumns(int column_min, int column_max) {
119 return SelectRectangle(column_min, column_max, 0, -1);
120}
121
122TableSelection Table::SelectCell(int column, int row) {
123 return SelectRectangle(column, column, row, row);
124}
125
127 int column_max,
128 int row_min,
129 int row_max) {
130 column_min = Wrap(column_min, input_dim_x_);
131 column_max = Wrap(column_max, input_dim_x_);
132 Order(column_min, column_max);
133 row_min = Wrap(row_min, input_dim_y_);
134 row_max = Wrap(row_max, input_dim_y_);
135 Order(row_min, row_max);
136
137 TableSelection output; // NOLINT
138 output.table_ = this;
139 output.x_min_ = 2 * column_min;
140 output.x_max_ = 2 * column_max + 2;
141 output.y_min_ = 2 * row_min;
142 output.y_max_ = 2 * row_max + 2;
143 return output;
144}
145
147 TableSelection output; // NOLINT
148 output.table_ = this;
149 output.x_min_ = 0;
150 output.x_max_ = dim_x_ - 1;
151 output.y_min_ = 0;
152 output.y_max_ = dim_y_ - 1;
153 return output;
154}
155
157 for (int y = 0; y < dim_y_; ++y) {
158 for (int x = 0; x < dim_x_; ++x) {
159 auto& it = elements_[y][x];
160
161 // Line
162 if ((x + y) % 2 == 1) {
163 it = std::move(it) | flex;
164 continue;
165 }
166
167 // Cells
168 if ((x % 2) == 1 && (y % 2) == 1) {
169 it = std::move(it) | flex_shrink;
170 continue;
171 }
172
173 // Corners
174 it = std::move(it) | size(WIDTH, EQUAL, 0) | size(HEIGHT, EQUAL, 0);
175 }
176 }
177 dim_x_ = 0;
178 dim_y_ = 0;
179 return gridbox(std::move(elements_));
180}
181
182// NOLINTNEXTLINE
184 for (int y = y_min_; y <= y_max_; ++y) {
185 for (int x = x_min_; x <= x_max_; ++x) {
186 Element& e = table_->elements_[y][x];
187 e = std::move(e) | decorator;
188 }
189 }
190}
191
192// NOLINTNEXTLINE
194 for (int y = y_min_; y <= y_max_; ++y) {
195 for (int x = x_min_; x <= x_max_; ++x) {
196 if (y % 2 == 1 && x % 2 == 1) {
197 Element& e = table_->elements_[y][x];
198 e = std::move(e) | decorator;
199 }
200 }
201 }
202}
203
204// NOLINTNEXTLINE
206 int modulo,
207 int shift) {
208 for (int y = y_min_; y <= y_max_; ++y) {
209 for (int x = x_min_; x <= x_max_; ++x) {
210 if (y % 2 == 1 && (x / 2) % modulo == shift) {
211 Element& e = table_->elements_[y][x];
212 e = std::move(e) | decorator;
213 }
214 }
215 }
216}
217
218// NOLINTNEXTLINE
220 int modulo,
221 int shift) {
222 for (int y = y_min_ + 1; y <= y_max_ - 1; ++y) {
223 for (int x = x_min_; x <= x_max_; ++x) {
224 if (y % 2 == 1 && (y / 2) % modulo == shift) {
225 Element& e = table_->elements_[y][x];
226 e = std::move(e) | decorator;
227 }
228 }
229 }
230}
231
232// NOLINTNEXTLINE
234 int modulo,
235 int shift) {
236 for (int y = y_min_; y <= y_max_; ++y) {
237 for (int x = x_min_; x <= x_max_; ++x) {
238 if (y % 2 == 1 && x % 2 == 1 && ((x / 2) % modulo == shift)) {
239 Element& e = table_->elements_[y][x];
240 e = std::move(e) | decorator;
241 }
242 }
243 }
244}
245
246// NOLINTNEXTLINE
248 int modulo,
249 int shift) {
250 for (int y = y_min_; y <= y_max_; ++y) {
251 for (int x = x_min_; x <= x_max_; ++x) {
252 if (y % 2 == 1 && x % 2 == 1 && ((y / 2) % modulo == shift)) {
253 Element& e = table_->elements_[y][x];
254 e = std::move(e) | decorator;
255 }
256 }
257 }
258}
259
265
266 // NOLINTNEXTLINE
267 table_->elements_[y_min_][x_min_] = text(charset[border][0]) | automerge;
268 // NOLINTNEXTLINE
269 table_->elements_[y_min_][x_max_] = text(charset[border][1]) | automerge;
270 // NOLINTNEXTLINE
271 table_->elements_[y_max_][x_min_] = text(charset[border][2]) | automerge;
272 // NOLINTNEXTLINE
273 table_->elements_[y_max_][x_max_] = text(charset[border][3]) | automerge;
274}
275
277 for (int y = y_min_ + 1; y <= y_max_ - 1; ++y) {
278 for (int x = x_min_ + 1; x <= x_max_ - 1; ++x) {
279 if (y % 2 == 0 || x % 2 == 0) {
280 Element& e = table_->elements_[y][x];
281 e = (y % 2 == 1)
282 ? separatorCharacter(charset[border][5]) | automerge // NOLINT
283 : separatorCharacter(charset[border][4]) | automerge; // NOLINT
284 }
285 }
286 }
287}
288
290 for (int y = y_min_ + 1; y <= y_max_ - 1; ++y) {
291 for (int x = x_min_ + 1; x <= x_max_ - 1; ++x) {
292 if (x % 2 == 0) {
293 table_->elements_[y][x] =
294 separatorCharacter(charset[border][5]) | automerge; // NOLINT
295 }
296 }
297 }
298}
299
301 for (int y = y_min_ + 1; y <= y_max_ - 1; ++y) {
302 for (int x = x_min_ + 1; x <= x_max_ - 1; ++x) {
303 if (y % 2 == 0) {
304 table_->elements_[y][x] =
305 separatorCharacter(charset[border][4]) | automerge; // NOLINT
306 }
307 }
308 }
309}
310
312 for (int y = y_min_; y <= y_max_; y++) {
313 table_->elements_[y][x_min_] =
314 separatorCharacter(charset[border][5]) | automerge; // NOLINT
315 }
316}
317
319 for (int y = y_min_; y <= y_max_; y++) {
320 table_->elements_[y][x_max_] =
321 separatorCharacter(charset[border][5]) | automerge; // NOLINT
322 }
323}
324
326 for (int x = x_min_; x <= x_max_; x++) {
327 table_->elements_[y_min_][x] =
328 separatorCharacter(charset[border][4]) | automerge; // NOLINT
329 }
330}
331
333 for (int x = x_min_; x <= x_max_; x++) {
334 table_->elements_[y_max_][x] =
335 separatorCharacter(charset[border][4]) | automerge; // NOLINT
336 }
337}
338
339} // namespace ftxui
340
341// Copyright 2021 Arthur Sonzogni. All rights reserved.
342// Use of this source code is governed by the MIT license that can be found in
343// the LICENSE file.
void DecorateAlternateColumn(Decorator, int modulo=2, int shift=0)
Definition table.cpp:205
void SeparatorVertical(BorderStyle border=LIGHT)
Definition table.cpp:289
void DecorateCells(Decorator)
Definition table.cpp:193
void BorderLeft(BorderStyle border=LIGHT)
Definition table.cpp:311
void DecorateCellsAlternateColumn(Decorator, int modulo=2, int shift=0)
Definition table.cpp:233
void Decorate(Decorator)
Definition table.cpp:183
void DecorateAlternateRow(Decorator, int modulo=2, int shift=0)
Definition table.cpp:219
void BorderTop(BorderStyle border=LIGHT)
Definition table.cpp:325
void Separator(BorderStyle border=LIGHT)
Definition table.cpp:276
void BorderBottom(BorderStyle border=LIGHT)
Definition table.cpp:332
void DecorateCellsAlternateRow(Decorator, int modulo=2, int shift=0)
Definition table.cpp:247
void BorderRight(BorderStyle border=LIGHT)
Definition table.cpp:318
void Border(BorderStyle border=LIGHT)
Definition table.cpp:260
void SeparatorHorizontal(BorderStyle border=LIGHT)
Definition table.cpp:300
Element Render()
Definition table.cpp:156
TableSelection SelectCell(int column, int row)
Definition table.cpp:122
TableSelection SelectColumn(int column_index)
Definition table.cpp:114
TableSelection SelectRow(int row_index)
Definition table.cpp:106
TableSelection SelectColumns(int column_min, int column_max)
Definition table.cpp:118
TableSelection SelectRows(int row_min, int row_max)
Definition table.cpp:110
TableSelection SelectAll()
Definition table.cpp:146
TableSelection SelectRectangle(int column_min, int column_max, int row_min, int row_max)
Definition table.cpp:126
std::function< Element(Element)> Decorator
Definition elements.hpp:20
Element flex(Element)
Make a child element to expand proportionnally to the space left in a container.
Definition flex.cpp:120
std::shared_ptr< Node > Element
Definition elements.hpp:18
Element emptyElement()
Definition util.cpp:131
Element flex_shrink(Element)
Minimize if needed.
Definition flex.cpp:156
Element text(std::wstring text)
Display a piece of unicode text.
Definition text.cpp:111
Element separatorCharacter(std::string)
Draw a vertical or horizontal separation in between two other elements.
Element gridbox(std::vector< Elements > lines)
A container displaying a grid of elements.
Definition gridbox.cpp:178
Element automerge(Element child)
Enable character to be automatically merged with others nearby.
Definition automerge.cpp:14
Decorator size(Direction, Constraint, int value)
Apply a constraint on the size of an element.
Definition size.cpp:85
Element border(Element)
Draw a border around the element.
Definition border.cpp:200
BorderStyle
Definition elements.hpp:23