20using Charset = std::array<std::string, 2>;
21using Charsets = std::array<Charset, 6>;
23const Charsets charsets = {
32class Separator :
public Node {
34 explicit Separator(std::string value) :
value_(std::move(value)) {}
36 void ComputeRequirement()
override {
37 requirement_.min_x = 1;
38 requirement_.min_y = 1;
41 void Render(Screen& screen)
override {
42 for (
int y = box_.y_min; y <= box_.y_max; ++y) {
43 for (
int x = box_.x_min; x <= box_.x_max; ++x) {
44 Pixel& pixel = screen.PixelAt(x, y);
46 pixel.automerge =
true;
54class SeparatorAuto :
public Node {
58 void ComputeRequirement()
override {
59 requirement_.min_x = 1;
60 requirement_.min_y = 1;
63 void Render(Screen& screen)
override {
64 const bool is_column = (box_.x_max == box_.x_min);
65 const bool is_line = (box_.y_min == box_.y_max);
68 charsets[
style_][int(is_line && !is_column)];
70 for (
int y = box_.y_min; y <= box_.y_max; ++y) {
71 for (
int x = box_.x_min; x <= box_.x_max; ++x) {
72 Pixel& pixel = screen.PixelAt(x, y);
74 pixel.automerge =
true;
82class SeparatorWithPixel :
public SeparatorAuto {
84 explicit SeparatorWithPixel(Pixel pixel)
85 : SeparatorAuto(
LIGHT), pixel_(std::move(pixel)) {
86 pixel_.automerge =
true;
88 void Render(Screen& screen)
override {
89 for (
int y = box_.y_min; y <= box_.y_max; ++y) {
90 for (
int x = box_.x_min; x <= box_.x_max; ++x) {
91 screen.PixelAt(x, y) = pixel_;
135 return std::make_shared<SeparatorAuto>(
LIGHT);
173 return std::make_shared<SeparatorAuto>(style);
210 return std::make_shared<SeparatorAuto>(
LIGHT);
247 return std::make_shared<SeparatorAuto>(
DASHED);
284 return std::make_shared<SeparatorAuto>(
HEAVY);
321 return std::make_shared<SeparatorAuto>(
DOUBLE);
358 return std::make_shared<SeparatorAuto>(
EMPTY);
396 return std::make_shared<Separator>(std::move(value));
427 return std::make_shared<SeparatorWithPixel>(std::move(pixel));
444 Color unselected_color,
445 Color selected_color) {
446 class Impl :
public Node {
451 unselected_color_(unselected_color),
452 selected_color_(selected_color) {}
453 void ComputeRequirement()
override {
454 requirement_.min_x = 1;
455 requirement_.min_y = 1;
458 void Render(
Screen& screen)
override {
459 if (box_.y_max < box_.y_min) {
464 int demi_cell_left = int(left_ * 2.F - 1.F);
465 int demi_cell_right = int(right_ * 2.F + 2.F);
467 const int y = box_.y_min;
468 for (
int x = box_.x_min; x <= box_.x_max; ++x) {
471 const int a = (x - box_.x_min) * 2;
473 const bool a_empty = demi_cell_left == a || demi_cell_right == a;
474 const bool b_empty = demi_cell_left == b || demi_cell_right == b;
476 if (!a_empty && !b_empty) {
484 if (demi_cell_left <= a && b <= demi_cell_right) {
494 Color unselected_color_;
495 Color selected_color_;
497 return std::make_shared<Impl>(
left,
right, unselected_color, selected_color);
514 Color unselected_color,
515 Color selected_color) {
516 class Impl :
public Node {
518 Impl(
float up,
float down,
Color unselected_color,
Color selected_color)
521 unselected_color_(unselected_color),
522 selected_color_(selected_color) {}
523 void ComputeRequirement()
override {
524 requirement_.min_x = 1;
525 requirement_.min_y = 1;
528 void Render(
Screen& screen)
override {
529 if (box_.x_max < box_.x_min) {
534 const int demi_cell_up = int(up_ * 2 - 1);
535 const int demi_cell_down = int(down_ * 2 + 2);
537 const int x = box_.x_min;
538 for (
int y = box_.y_min; y <= box_.y_max; ++y) {
541 const int a = (y - box_.y_min) * 2;
543 const bool a_empty = demi_cell_up == a || demi_cell_down == a;
544 const bool b_empty = demi_cell_up == b || demi_cell_down == b;
546 if (!a_empty && !b_empty) {
554 if (demi_cell_up <= a && b <= demi_cell_down) {
564 Color unselected_color_;
565 Color selected_color_;
567 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 separatorCharacter(std::string)
Draw a vertical or horizontal separation in between two other elements.
Element separator()
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 ...
Pixel & PixelAt(int x, int y)
Access a cell (Pixel) at a given position.
Color is a class that represents a color in the terminal user interface.
A rectangular grid of Pixel.
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(Pixel &)> style_