25using Charset = std::array<std::string, 6>;
26using Charsets = std::array<Charset, 6>;
28static Charsets simple_border_charset = {
29 Charset{
"┌",
"┐",
"└",
"┘",
"─",
"│"},
30 Charset{
"┏",
"┓",
"┗",
"┛",
"╍",
"╏"},
31 Charset{
"┏",
"┓",
"┗",
"┛",
"━",
"┃"},
32 Charset{
"╔",
"╗",
"╚",
"╝",
"═",
"║"},
33 Charset{
"╭",
"╮",
"╰",
"╯",
"─",
"│"},
34 Charset{
" ",
" ",
" ",
" ",
" ",
" "},
39class Border :
public Node {
43 std::optional<Color> foreground_color = std::nullopt)
44 : Node(std::move(children)),
45 charset_(simple_border_charset[style])
52 void ComputeRequirement()
override {
54 requirement_ = children_[0]->requirement();
55 requirement_.min_x += 2;
56 requirement_.min_y += 2;
57 if (children_.size() == 2) {
59 std::max(requirement_.min_x, children_[1]->requirement().min_x + 2);
61 requirement_.focused.box.x_min++;
62 requirement_.focused.box.x_max++;
63 requirement_.focused.box.y_min++;
64 requirement_.focused.box.y_max++;
67 void SetBox(Box box)
override {
69 if (children_.size() == 2) {
71 title_box.x_min = box.x_min + 1;
72 title_box.x_max = std::min(box.x_max - 1,
73 box.x_min + children_[1]->requirement().min_x);
74 title_box.y_min = box.y_min;
75 title_box.y_max = box.y_min;
76 children_[1]->SetBox(title_box);
82 children_[0]->SetBox(box);
88 children_[0]->Render(
screen);
92 if (box_.x_min >= box_.x_max || box_.y_min >= box_.y_max) {
101 for (
int x = box_.x_min + 1; x < box_.x_max; ++x) {
102 Pixel& p1 =
screen.PixelAt(x, box_.y_min);
103 Pixel& p2 =
screen.PixelAt(x, box_.y_max);
109 for (
int y = box_.y_min + 1; y < box_.y_max; ++y) {
110 Pixel& p3 =
screen.PixelAt(box_.x_min, y);
111 Pixel& p4 =
screen.PixelAt(box_.x_max, y);
120 if (children_.size() == 2) {
121 children_[1]->Render(
screen);
126 if (foreground_color_) {
127 for (
int x = box_.x_min; x <= box_.x_max; ++x) {
131 for (
int y = box_.y_min; y <= box_.y_max; ++y) {
141class BorderPixel :
public Node {
143 BorderPixel(
Elements children, Pixel pixel)
144 : Node(std::move(children)), pixel_(std::move(pixel)) {}
149 void ComputeRequirement()
override {
151 requirement_ = children_[0]->requirement();
152 requirement_.min_x += 2;
153 requirement_.min_y += 2;
154 if (children_.size() == 2) {
156 std::max(requirement_.min_x, children_[1]->requirement().min_x + 2);
159 requirement_.focused.box.Shift(1, 1);
162 void SetBox(Box box)
override {
164 if (children_.size() == 2) {
166 title_box.x_min = box.x_min + 1;
167 title_box.x_max = box.x_max - 1;
168 title_box.y_min = box.y_min;
169 title_box.y_max = box.y_min;
170 children_[1]->SetBox(title_box);
176 children_[0]->SetBox(box);
182 children_[0]->Render(
screen);
186 if (box_.x_min >= box_.x_max || box_.y_min >= box_.y_max) {
190 screen.PixelAt(box_.x_min, box_.y_min) = pixel_;
191 screen.PixelAt(box_.x_max, box_.y_min) = pixel_;
192 screen.PixelAt(box_.x_min, box_.y_max) = pixel_;
193 screen.PixelAt(box_.x_max, box_.y_max) = pixel_;
195 for (
int x = box_.x_min + 1; x < box_.x_max; ++x) {
196 screen.PixelAt(x, box_.y_min) = pixel_;
197 screen.PixelAt(x, box_.y_max) = pixel_;
199 for (
int y = box_.y_min + 1; y < box_.y_max; ++y) {
200 screen.PixelAt(box_.x_min, y) = pixel_;
201 screen.PixelAt(box_.x_max, y) = pixel_;
245 return std::make_shared<Border>(unpack(std::move(child)),
ROUNDED);
253 return [pixel](
Element child) {
254 return std::make_shared<BorderPixel>(unpack(std::move(child)), pixel);
263 return [style](
Element child) {
264 return std::make_shared<Border>(unpack(std::move(child)), style);
273 return [foreground_color](
Element child) {
274 return std::make_shared<Border>(unpack(std::move(child)),
ROUNDED,
284 return [style, foreground_color](
Element child) {
285 return std::make_shared<Border>(unpack(std::move(child)), style,
328 return std::make_shared<Border>(unpack(std::move(child)),
DASHED);
369 return std::make_shared<Border>(unpack(std::move(child)),
LIGHT);
410 return std::make_shared<Border>(unpack(std::move(child)),
HEAVY);
451 return std::make_shared<Border>(unpack(std::move(child)),
DOUBLE);
492 return std::make_shared<Border>(unpack(std::move(child)),
ROUNDED);
533 return std::make_shared<Border>(unpack(std::move(child)),
EMPTY);
572 return std::make_shared<Border>(unpack(std::move(content), std::move(
title)),
virtual void SetBox(Box box)
Asigna una posición y una dimensión a un elemento para dibujarlo.
virtual void ComputeRequirement()
Calcula cuánto espacio necesita un elemento.
Element window(Element title, Element content, BorderStyle border=ROUNDED)
Draw window with a title and a border around the element.
Element borderDouble(Element)
Draw a double border around the element.
Element borderDashed(Element)
Draw a dashed border around the element.
Element borderRounded(Element)
Draw a rounded border around the element.
Element borderHeavy(Element)
Draw a heavy border around the element.
Element borderLight(Element)
Draw a light border around the element.
Decorator borderWith(const Pixel &)
Same as border but with a constant Pixel around the element.
Decorator borderStyled(BorderStyle)
Same as border but with different styles.
void Render(Screen &screen, const Element &element)
Muestra un elemento en un ftxui::Screen.
Element border(Element)
Draw a border around the element.
Element borderEmpty(Element)
Draw an empty border around the element.
BorderStyle
BorderStyle es una enumeración que representa los diferentes estilos de bordes que se pueden aplicar ...
Color es una clase que representa un color en la interfaz de usuario de la terminal.
Un carácter Unicode y su estilo asociado.
El espacio de nombres ftxui:: de FTXUI.
std::function< Element(Element)> Decorator
std::shared_ptr< Node > Element
std::vector< Element > Elements
std::optional< Color > foreground_color_