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