7#include <initializer_list>
17bool IsCell(
int x,
int y) {
18 return x % 2 == 1 &&
y % 2 == 1;
22static std::string table_charset[6][6] = {
23 {
"┌",
"┐",
"└",
"┘",
"─",
"│"},
24 {
"┏",
"┓",
"┗",
"┛",
"╍",
"╏"},
25 {
"┏",
"┓",
"┗",
"┛",
"━",
"┃"},
26 {
"╔",
"╗",
"╚",
"╝",
"═",
"║"},
27 {
"╭",
"╮",
"╰",
"╯",
"─",
"│"},
28 {
" ",
" ",
" ",
" ",
" ",
" "},
31int Wrap(
int input,
int modulo) {
38void Order(
int& a,
int& b) {
53Table::Table(
const std::vector<std::vector<std::string>>& input) {
54 std::vector<std::vector<Element>> output;
55 output.reserve(input.size());
56 for (
const auto& row : input) {
57 output.emplace_back();
58 auto& output_row = output.back();
59 output_row.reserve(row.size());
60 for (
const auto& cell : row) {
61 output_row.push_back(text(std::move(cell)));
64 Initialize(std::move(output));
69Table::Table(std::vector<std::vector<Element>> input) {
70 Initialize(std::move(input));
75Table::Table(std::initializer_list<std::vector<std::string>> init) {
76 std::vector<std::vector<Element>> input;
77 for (
const auto& row : init) {
78 std::vector<Element> output_row;
79 output_row.reserve(row.size());
80 for (
const auto& cell : row) {
81 output_row.push_back(text(cell));
83 input.push_back(std::move(output_row));
85 Initialize(std::move(input));
89void Table::Initialize(std::vector<std::vector<Element>> input) {
90 input_dim_y_ =
static_cast<int>(input.size());
92 for (
auto& row : input) {
93 input_dim_x_ = std::max(input_dim_x_,
int(row.size()));
96 dim_y_ = 2 * input_dim_y_ + 1;
97 dim_x_ = 2 * input_dim_x_ + 1;
100 elements_.resize(dim_y_);
101 for (
int y = 0;
y < dim_y_; ++
y) {
102 elements_[
y].resize(dim_x_);
108 for (
auto& row : input) {
110 for (
auto& cell : row) {
111 elements_[
y][x] = std::move(cell);
119 for (
int y = 0;
y < dim_y_; ++
y) {
120 for (
int x = 0; x < dim_x_; ++x) {
138TableSelection Table::SelectRow(
int index) {
139 return SelectRectangle(0, -1, index, index);
146TableSelection Table::SelectRows(
int row_min,
int row_max) {
147 return SelectRectangle(0, -1, row_min, row_max);
153TableSelection Table::SelectColumn(
int index) {
154 return SelectRectangle(index, index, 0, -1);
161TableSelection Table::SelectColumns(
int column_min,
int column_max) {
162 return SelectRectangle(column_min, column_max, 0, -1);
169TableSelection Table::SelectCell(
int column,
int row) {
170 return SelectRectangle(column, column, row, row);
179TableSelection Table::SelectRectangle(
int column_min,
183 TableSelection output;
184 output.table_ =
this;
185 if (input_dim_x_ == 0 || input_dim_y_ == 0) {
193 column_min =
Wrap(column_min, input_dim_x_);
194 column_max =
Wrap(column_max, input_dim_x_);
195 Order(column_min, column_max);
196 row_min =
Wrap(row_min, input_dim_y_);
197 row_max =
Wrap(row_max, input_dim_y_);
198 Order(row_min, row_max);
200 output.x_min_ = 2 * column_min;
201 output.x_max_ = 2 * column_max + 2;
202 output.y_min_ = 2 * row_min;
203 output.y_max_ = 2 * row_max + 2;
208TableSelection Table::SelectAll() {
209 TableSelection output;
210 output.table_ =
this;
212 output.x_max_ = dim_x_ - 1;
214 output.y_max_ = dim_y_ - 1;
221 for (
int y = 0;
y < dim_y_; ++
y) {
222 for (
int x = 0; x < dim_x_; ++x) {
223 auto& it = elements_[
y][x];
226 if ((x + y) % 2 == 1) {
227 it = std::move(it) | flex;
232 if ((x % 2) == 1 && (y % 2) == 1) {
233 it = std::move(it) | flex_shrink;
238 it = std::move(it) | size(WIDTH, EQUAL, 0) | size(HEIGHT, EQUAL, 0);
243 return gridbox(std::move(elements_));
250void TableSelection::Decorate(
const Decorator& decorator) {
251 for (
int y = y_min_;
y <= y_max_; ++
y) {
252 for (
int x = x_min_; x <= x_max_; ++x) {
253 Element& e = table_->elements_[
y][x];
254 e = std::move(e) | decorator;
263void TableSelection::DecorateCells(
const Decorator& decorator) {
264 for (
int y = y_min_;
y <= y_max_; ++
y) {
265 for (
int x = x_min_; x <= x_max_; ++x) {
266 if (y % 2 == 1 && x % 2 == 1) {
267 Element& e = table_->elements_[
y][x];
268 e = std::move(e) | decorator;
280void TableSelection::DecorateAlternateColumn(
const Decorator& decorator,
283 for (
int y = y_min_;
y <= y_max_; ++
y) {
284 for (
int x = x_min_; x <= x_max_; ++x) {
285 if (y % 2 == 1 && (x / 2) % modulo == shift) {
286 Element& e = table_->elements_[
y][x];
287 e = std::move(e) | decorator;
299void TableSelection::DecorateAlternateRow(
const Decorator& decorator,
302 for (
int y = y_min_ + 1;
y <= y_max_ - 1; ++
y) {
303 for (
int x = x_min_; x <= x_max_; ++x) {
304 if (y % 2 == 1 && (y / 2) % modulo == shift) {
305 Element& e = table_->elements_[
y][x];
306 e = std::move(e) | decorator;
318void TableSelection::DecorateCellsAlternateColumn(
const Decorator& decorator,
321 for (
int y = y_min_;
y <= y_max_; ++
y) {
322 for (
int x = x_min_; x <= x_max_; ++x) {
323 if (y % 2 == 1 && x % 2 == 1 && ((x / 2) % modulo == shift)) {
324 Element& e = table_->elements_[
y][x];
325 e = std::move(e) | decorator;
337void TableSelection::DecorateCellsAlternateRow(
const Decorator& decorator,
340 for (
int y = y_min_;
y <= y_max_; ++
y) {
341 for (
int x = x_min_; x <= x_max_; ++x) {
342 if (y % 2 == 1 && x % 2 == 1 && ((y / 2) % modulo == shift)) {
343 Element& e = table_->elements_[
y][x];
344 e = std::move(e) | decorator;
352void TableSelection::DecorateBorder(
const Decorator& decorator) {
353 for (
int x = x_min_; x <= x_max_; ++x) {
354 table_->elements_[y_min_][x] =
355 std::move(table_->elements_[y_min_][x]) | decorator;
356 table_->elements_[y_max_][x] =
357 std::move(table_->elements_[y_max_][x]) | decorator;
359 for (
int y = y_min_ + 1;
y <= y_max_ - 1; ++
y) {
360 table_->elements_[
y][x_min_] =
361 std::move(table_->elements_[y][x_min_]) | decorator;
362 table_->elements_[
y][x_max_] =
363 std::move(table_->elements_[y][x_max_]) | decorator;
369void TableSelection::DecorateBorderLeft(
const Decorator& decorator) {
370 for (
int y = y_min_;
y <= y_max_;
y++) {
371 table_->elements_[
y][x_min_] =
372 std::move(table_->elements_[y][x_min_]) | decorator;
378void TableSelection::DecorateBorderRight(
const Decorator& decorator) {
379 for (
int y = y_min_;
y <= y_max_;
y++) {
380 table_->elements_[
y][x_max_] =
381 std::move(table_->elements_[y][x_max_]) | decorator;
387void TableSelection::DecorateBorderTop(
const Decorator& decorator) {
388 for (
int x = x_min_; x <= x_max_; x++) {
389 table_->elements_[y_min_][x] =
390 std::move(table_->elements_[y_min_][x]) | decorator;
396void TableSelection::DecorateBorderBottom(
const Decorator& decorator) {
397 for (
int x = x_min_; x <= x_max_; x++) {
398 table_->elements_[y_max_][x] =
399 std::move(table_->elements_[y_max_][x]) | decorator;
405void TableSelection::DecorateSeparator(
const Decorator& decorator) {
406 for (
int y = y_min_ + 1;
y <= y_max_ - 1; ++
y) {
407 for (
int x = x_min_ + 1; x <= x_max_ - 1; ++x) {
408 if (y % 2 == 0 || x % 2 == 0) {
409 table_->elements_[
y][x] =
410 std::move(table_->elements_[y][x]) | decorator;
418void TableSelection::DecorateSeparatorVertical(
const Decorator& decorator) {
419 for (
int y = y_min_ + 1;
y <= y_max_ - 1; ++
y) {
420 for (
int x = x_min_ + 1; x <= x_max_ - 1; ++x) {
422 table_->elements_[
y][x] =
423 std::move(table_->elements_[y][x]) | decorator;
431void TableSelection::DecorateSeparatorHorizontal(
const Decorator& decorator) {
432 for (
int y = y_min_ + 1;
y <= y_max_ - 1; ++
y) {
433 for (
int x = x_min_ + 1; x <= x_max_ - 1; ++x) {
435 table_->elements_[
y][x] =
436 std::move(table_->elements_[y][x]) | decorator;
445 if (x_min_ > x_max_ || y_min_ > y_max_) {
452 BorderBottom(border);
455 table_->elements_[y_min_][x_min_] =
456 text(table_charset[border][0]) | automerge;
458 table_->elements_[y_min_][x_max_] =
459 text(table_charset[border][1]) | automerge;
461 table_->elements_[y_max_][x_min_] =
462 text(table_charset[border][2]) | automerge;
464 table_->elements_[y_max_][x_max_] =
465 text(table_charset[border][3]) | automerge;
473 DecorateBorder(decorator);
478void TableSelection::Separator(
BorderStyle border) {
479 for (
int y = y_min_ + 1;
y <= y_max_ - 1; ++
y) {
480 for (
int x = x_min_ + 1; x <= x_max_ - 1; ++x) {
481 if (y % 2 == 0 || x % 2 == 0) {
482 Element& e = table_->elements_[
y][x];
483 e = (
y % 2 == 1) ? separatorCharacter(table_charset[border][5]) |
485 : separatorCharacter(table_charset[border][4]) |
497 DecorateSeparator(decorator);
502void TableSelection::SeparatorVertical(
BorderStyle border) {
503 for (
int y = y_min_ + 1;
y <= y_max_ - 1; ++
y) {
504 for (
int x = x_min_ + 1; x <= x_max_ - 1; ++x) {
506 table_->elements_[
y][x] =
507 separatorCharacter(table_charset[border][5]) | automerge;
516void TableSelection::SeparatorVertical(
BorderStyle border,
518 SeparatorVertical(border);
519 DecorateSeparatorVertical(decorator);
524void TableSelection::SeparatorHorizontal(
BorderStyle border) {
525 for (
int y = y_min_ + 1;
y <= y_max_ - 1; ++
y) {
526 for (
int x = x_min_ + 1; x <= x_max_ - 1; ++x) {
528 table_->elements_[
y][x] =
529 separatorCharacter(table_charset[border][4]) | automerge;
538void TableSelection::SeparatorHorizontal(
BorderStyle border,
540 SeparatorHorizontal(border);
541 DecorateSeparatorHorizontal(decorator);
546void TableSelection::BorderLeft(
BorderStyle border) {
547 for (
int y = y_min_;
y <= y_max_;
y++) {
548 table_->elements_[
y][x_min_] =
549 separatorCharacter(table_charset[border][5]) | automerge;
559 DecorateBorderLeft(decorator);
564void TableSelection::BorderRight(
BorderStyle border) {
565 for (
int y = y_min_;
y <= y_max_;
y++) {
566 table_->elements_[
y][x_max_] =
567 separatorCharacter(table_charset[border][5]) | automerge;
574void TableSelection::BorderRight(
BorderStyle border,
577 DecorateBorderRight(decorator);
582void TableSelection::BorderTop(
BorderStyle border) {
583 for (
int x = x_min_; x <= x_max_; x++) {
584 table_->elements_[y_min_][x] =
585 separatorCharacter(table_charset[border][4]) | automerge;
594 DecorateBorderTop(decorator);
599void TableSelection::BorderBottom(
BorderStyle border) {
600 for (
int x = x_min_; x <= x_max_; x++) {
601 table_->elements_[y_max_][x] =
602 separatorCharacter(table_charset[border][4]) | automerge;
609void TableSelection::BorderBottom(
BorderStyle border,
611 BorderBottom(border);
612 DecorateBorderBottom(decorator);
Component Wrap(std::string name, Component component)
BorderStyle
BorderStyle is an enumeration that represents the different styles of borders that can be applied to ...
The FTXUI ftxui:: namespace.
std::shared_ptr< Node > Element
std::function< Element(Element)> Decorator