12bool IsCell(
int x,
int y) {
13 return x % 2 == 1 && y % 2 == 1;
17static std::string charset[6][6] = {
18 {
"┌",
"┐",
"└",
"┘",
"─",
"│"},
19 {
"┏",
"┓",
"┗",
"┛",
"╍",
"╏"},
20 {
"┏",
"┓",
"┗",
"┛",
"━",
"┃"},
21 {
"╔",
"╗",
"╚",
"╝",
"═",
"║"},
22 {
"╭",
"╮",
"╰",
"╯",
"─",
"│"},
23 {
" ",
" ",
" ",
" ",
" ",
" "},
26int Wrap(
int input,
int modulo) {
33void Order(
int& a,
int& b) {
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)));
54 Initialize(std::move(output));
58 Initialize(std::move(input));
61void Table::Initialize(std::vector<std::vector<Element>> input) {
62 input_dim_y_ = (int)input.size();
64 for (
auto& row : input) {
65 input_dim_x_ = std::max(input_dim_x_, (
int)row.size());
68 dim_y_ = 2 * input_dim_y_ + 1;
69 dim_x_ = 2 * input_dim_x_ + 1;
72 elements_.resize(dim_y_);
73 for (
int y = 0; y < dim_y_; ++y) {
74 elements_[y].resize(dim_x_);
80 for (
auto& row : input) {
82 for (
auto& cell : row) {
83 elements_[y][x] = std::move(cell);
91 for (
int y = 0; y < dim_y_; ++y) {
92 for (
int x = 0; x < dim_x_; ++x) {
93 auto& element = elements_[y][x];
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);
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;
149 output.table_ =
this;
151 output.x_max_ = dim_x_ - 1;
153 output.y_max_ = dim_y_ - 1;
158 for (
int y = 0; y < dim_y_; ++y) {
159 for (
int x = 0; x < dim_x_; ++x) {
160 auto& it = elements_[y][x];
163 if ((x + y) % 2 == 1) {
164 it = std::move(it) |
flex;
169 if ((x % 2) == 1 && (y % 2) == 1) {
180 return gridbox(std::move(elements_));
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;
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;
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;
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;
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;
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;
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];
291 for (
int y = y_min_ + 1; y <= y_max_ - 1; ++y) {
292 for (
int x = x_min_ + 1; x <= x_max_ - 1; ++x) {
294 table_->elements_[y][x] =
302 for (
int y = y_min_ + 1; y <= y_max_ - 1; ++y) {
303 for (
int x = x_min_ + 1; x <= x_max_ - 1; ++x) {
305 table_->elements_[y][x] =
313 for (
int y = y_min_; y <= y_max_; y++) {
314 table_->elements_[y][x_min_] =
320 for (
int y = y_min_; y <= y_max_; y++) {
321 table_->elements_[y][x_max_] =
327 for (
int x = x_min_; x <= x_max_; x++) {
328 table_->elements_[y_min_][x] =
334 for (
int x = x_min_; x <= x_max_; x++) {
335 table_->elements_[y_max_][x] =
void DecorateAlternateColumn(Decorator, int modulo=2, int shift=0)
void SeparatorVertical(BorderStyle border=LIGHT)
void DecorateCells(Decorator)
void BorderLeft(BorderStyle border=LIGHT)
void DecorateCellsAlternateColumn(Decorator, int modulo=2, int shift=0)
void DecorateAlternateRow(Decorator, int modulo=2, int shift=0)
void BorderTop(BorderStyle border=LIGHT)
void Separator(BorderStyle border=LIGHT)
void BorderBottom(BorderStyle border=LIGHT)
void DecorateCellsAlternateRow(Decorator, int modulo=2, int shift=0)
void BorderRight(BorderStyle border=LIGHT)
void Border(BorderStyle border=LIGHT)
void SeparatorHorizontal(BorderStyle border=LIGHT)
TableSelection SelectCell(int column, int row)
TableSelection SelectColumn(int column_index)
TableSelection SelectRow(int row_index)
TableSelection SelectColumns(int column_min, int column_max)
TableSelection SelectRows(int row_min, int row_max)
TableSelection SelectAll()
TableSelection SelectRectangle(int column_min, int column_max, int row_min, int row_max)
std::function< Element(Element)> Decorator
Element flex(Element)
Make a child element to expand proportionnally to the space left in a container.
std::shared_ptr< Node > Element
Element flex_shrink(Element)
Minimize if needed.
Element text(std::wstring text)
Display a piece of unicode text.
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.
Element automerge(Element child)
Enable character to be automatically merged with others nearby.
Decorator size(Direction, Constraint, int value)
Apply a constraint on the size of an element.
Element border(Element)
Draw a border around the element.