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