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