21using Charset = std::array<std::string, 2>;
22using Charsets = std::array<Charset, 6>;
24const Charsets charsets = {
33class Separator :
public Node {
35 explicit Separator(std::string value) :
value_(std::move(value)) {}
37 void ComputeRequirement()
override {
38 requirement_.min_x = 1;
39 requirement_.min_y = 1;
42 void Render(Screen& screen)
override {
43 for (
int y = box_.y_min; y <= box_.y_max; ++y) {
44 for (
int x = box_.x_min; x <= box_.x_max; ++x) {
45 Cell& pixel = screen.CellAt(x, y);
47 pixel.automerge =
true;
55class SeparatorAuto :
public Node {
59 void ComputeRequirement()
override {
60 requirement_.min_x = 1;
61 requirement_.min_y = 1;
64 void Render(Screen& screen)
override {
65 const bool is_column = (box_.x_max == box_.x_min);
66 const bool is_line = (box_.y_min == box_.y_max);
69 charsets[
style_][int(is_line && !is_column)];
71 for (
int y = box_.y_min; y <= box_.y_max; ++y) {
72 for (
int x = box_.x_min; x <= box_.x_max; ++x) {
73 Cell& pixel = screen.CellAt(x, y);
75 pixel.automerge =
true;
83class SeparatorWithCell :
public SeparatorAuto {
85 explicit SeparatorWithCell(Cell pixel)
86 : SeparatorAuto(
LIGHT), pixel_(std::move(pixel)) {
87 pixel_.automerge =
true;
89 void Render(Screen& screen)
override {
90 for (
int y = box_.y_min; y <= box_.y_max; ++y) {
91 for (
int x = box_.x_min; x <= box_.x_max; ++x) {
92 screen.CellAt(x, y) = pixel_;
136 return std::make_shared<SeparatorAuto>(
LIGHT);
174 return std::make_shared<SeparatorAuto>(style);
211 return std::make_shared<SeparatorAuto>(
LIGHT);
248 return std::make_shared<SeparatorAuto>(
DASHED);
285 return std::make_shared<SeparatorAuto>(
HEAVY);
322 return std::make_shared<SeparatorAuto>(
DOUBLE);
359 return std::make_shared<SeparatorAuto>(
EMPTY);
397 return std::make_shared<Separator>(std::string(value));
428 return std::make_shared<SeparatorWithCell>(std::move(pixel));
445 Color unselected_color,
446 Color selected_color) {
447 class Impl :
public Node {
452 unselected_color_(unselected_color),
453 selected_color_(selected_color) {}
454 void ComputeRequirement()
override {
455 requirement_.min_x = 1;
456 requirement_.min_y = 1;
459 void Render(
Screen& screen)
override {
460 if (box_.y_max < box_.y_min) {
465 int demi_cell_left = int(left_ * 2.F - 1.F);
466 int demi_cell_right = int(right_ * 2.F + 2.F);
468 const int y = box_.y_min;
469 for (
int x = box_.x_min; x <= box_.x_max; ++x) {
472 const int a = (x - box_.x_min) * 2;
474 const bool a_empty = demi_cell_left == a || demi_cell_right == a;
475 const bool b_empty = demi_cell_left == b || demi_cell_right == b;
477 if (!a_empty && !b_empty) {
485 if (demi_cell_left <= a && b <= demi_cell_right) {
495 Color unselected_color_;
496 Color selected_color_;
498 return std::make_shared<Impl>(
left,
right, unselected_color, selected_color);
515 Color unselected_color,
516 Color selected_color) {
517 class Impl :
public Node {
519 Impl(
float up,
float down,
Color unselected_color,
Color selected_color)
522 unselected_color_(unselected_color),
523 selected_color_(selected_color) {}
524 void ComputeRequirement()
override {
525 requirement_.min_x = 1;
526 requirement_.min_y = 1;
529 void Render(
Screen& screen)
override {
530 if (box_.x_max < box_.x_min) {
535 const int demi_cell_up = int(up_ * 2 - 1);
536 const int demi_cell_down = int(down_ * 2 + 2);
538 const int x = box_.x_min;
539 for (
int y = box_.y_min; y <= box_.y_max; ++y) {
542 const int a = (y - box_.y_min) * 2;
544 const bool a_empty = demi_cell_up == a || demi_cell_down == a;
545 const bool b_empty = demi_cell_up == b || demi_cell_down == b;
547 if (!a_empty && !b_empty) {
555 if (demi_cell_up <= a && b <= demi_cell_down) {
565 Color unselected_color_;
566 Color selected_color_;
568 return std::make_shared<Impl>(up,
down, unselected_color, selected_color);
Node is the base class for all elements in the DOM tree.
Element separatorStyled(BorderStyle)
Draw a vertical or horizontal separation in between two other elements.
Element separatorEmpty()
Draw a vertical or horizontal separation in between two other elements, using the EMPTY style.
Element separatorLight()
Draw a vertical or horizontal separation in between two other elements, using the LIGHT style.
Element separatorDashed()
Draw a vertical or horizontal separation in between two other elements, using the DASHED style.
Element separator()
Draw a vertical or horizontal separation in between two other elements.
Element separatorCharacter(std::string_view)
Draw a vertical or horizontal separation in between two other elements.
void Render(Screen &screen, const Element &element)
Display an element on a ftxui::Screen.
Element separatorDouble()
Draw a vertical or horizontal separation in between two other elements, using the DOUBLE style.
Element separatorHeavy()
Draw a vertical or horizontal separation in between two other elements, using the HEAVY style.
BorderStyle
BorderStyle is an enumeration that represents the different styles of borders that can be applied to ...
Cell & CellAt(int x, int y)
Access a cell (Cell) at a given position.
Color is a class that represents a color in the terminal user interface.
A rectangular grid of Cell.
A Unicode character and its associated style.
The FTXUI ftxui:: namespace.
Element separatorVSelector(float up, float down, Color unselected_color, Color selected_color)
Draw an vertical bar, with the area in between up/downcolored differently.
std::shared_ptr< Node > Element
Element separatorHSelector(float left, float right, Color unselected_color, Color selected_color)
Draw a horizontal bar, with the area in between left/right colored differently.
std::function< void(Cell &)> style_