22using Charset = std::array<std::string, 6>;
23using Charsets = std::array<Charset, 6>;
25static Charsets simple_border_charset = {
26 Charset{
"┌",
"┐",
"└",
"┘",
"─",
"│"},
27 Charset{
"┏",
"┓",
"┗",
"┛",
"╍",
"╏"},
28 Charset{
"┏",
"┓",
"┗",
"┛",
"━",
"┃"},
29 Charset{
"╔",
"╗",
"╚",
"╝",
"═",
"║"},
30 Charset{
"╭",
"╮",
"╰",
"╯",
"─",
"│"},
31 Charset{
" ",
" ",
" ",
" ",
" ",
" "},
35class Border :
public Node {
39 std::optional<Color> foreground_color = std::nullopt)
40 : Node(std::move(children)),
41 charset_(simple_border_charset[style])
48 void ComputeRequirement()
override {
49 Node::ComputeRequirement();
50 requirement_ = children_[0]->requirement();
51 requirement_.min_x += 2;
52 requirement_.min_y += 2;
53 if (children_.size() == 2) {
55 std::max(requirement_.min_x, children_[1]->requirement().min_x + 2);
57 requirement_.focused.box.x_min++;
58 requirement_.focused.box.x_max++;
59 requirement_.focused.box.y_min++;
60 requirement_.focused.box.y_max++;
63 void SetBox(Box box)
override {
65 if (children_.size() == 2) {
67 title_box.x_min = box.x_min + 1;
68 title_box.x_max = std::min(box.x_max - 1,
69 box.x_min + children_[1]->requirement().min_x);
70 title_box.y_min = box.y_min;
71 title_box.y_max = box.y_min;
72 children_[1]->SetBox(title_box);
78 children_[0]->SetBox(box);
81 void Render(Screen& screen)
override {
83 children_[0]->Render(screen);
86 if (box_.x_min >= box_.x_max || box_.y_min >= box_.y_max) {
90 screen.at(box_.x_min, box_.y_min) =
charset_[0];
91 screen.at(box_.x_max, box_.y_min) =
charset_[1];
92 screen.at(box_.x_min, box_.y_max) =
charset_[2];
93 screen.at(box_.x_max, box_.y_max) =
charset_[3];
95 for (
int x = box_.x_min + 1; x < box_.x_max; ++x) {
96 Cell& p1 = screen.CellAt(x, box_.y_min);
97 Cell& p2 = screen.CellAt(x, box_.y_max);
103 for (
int y = box_.y_min + 1;
y < box_.y_max; ++
y) {
104 Cell& p3 = screen.CellAt(box_.x_min,
y);
105 Cell& p4 = screen.CellAt(box_.x_max,
y);
113 if (children_.size() == 2) {
114 children_[1]->Render(screen);
118 if (foreground_color_) {
119 for (
int x = box_.x_min; x <= box_.x_max; ++x) {
123 for (
int y = box_.y_min;
y <= box_.y_max; ++
y) {
132class BorderCell :
public Node {
134 BorderCell(
Elements children, Cell pixel)
135 : Node(std::move(children)), pixel_(std::move(pixel)) {}
140 void ComputeRequirement()
override {
141 Node::ComputeRequirement();
142 requirement_ = children_[0]->requirement();
143 requirement_.min_x += 2;
144 requirement_.min_y += 2;
145 if (children_.size() == 2) {
147 std::max(requirement_.min_x, children_[1]->requirement().min_x + 2);
150 requirement_.focused.box.Shift(1, 1);
153 void SetBox(Box box)
override {
155 if (children_.size() == 2) {
157 title_box.x_min = box.x_min + 1;
158 title_box.x_max = box.x_max - 1;
159 title_box.y_min = box.y_min;
160 title_box.y_max = box.y_min;
161 children_[1]->SetBox(title_box);
167 children_[0]->SetBox(box);
170 void Render(Screen& screen)
override {
172 children_[0]->Render(screen);
175 if (box_.x_min >= box_.x_max || box_.y_min >= box_.y_max) {
179 screen.CellAt(box_.x_min, box_.y_min) = pixel_;
180 screen.CellAt(box_.x_max, box_.y_min) = pixel_;
181 screen.CellAt(box_.x_min, box_.y_max) = pixel_;
182 screen.CellAt(box_.x_max, box_.y_max) = pixel_;
184 for (
int x = box_.x_min + 1; x < box_.x_max; ++x) {
185 screen.CellAt(x, box_.y_min) = pixel_;
186 screen.CellAt(x, box_.y_max) = pixel_;
188 for (
int y = box_.y_min + 1;
y < box_.y_max; ++
y) {
189 screen.CellAt(box_.x_min,
y) = pixel_;
190 screen.CellAt(box_.x_max,
y) = pixel_;
228 return std::make_shared<Border>(unpack(std::move(child)),
ROUNDED);
235 return [pixel](
Element child) {
236 return std::make_shared<BorderCell>(unpack(std::move(child)), pixel);
244 return [style](
Element child) {
245 return std::make_shared<Border>(unpack(std::move(child)), style);
253 return [foreground_color](
Element child) {
254 return std::make_shared<Border>(unpack(std::move(child)),
ROUNDED,
263 return [style, foreground_color](
Element child) {
264 return std::make_shared<Border>(unpack(std::move(child)), style,
301 return std::make_shared<Border>(unpack(std::move(child)),
DASHED);
336 return std::make_shared<Border>(unpack(std::move(child)),
LIGHT);
371 return std::make_shared<Border>(unpack(std::move(child)),
HEAVY);
406 return std::make_shared<Border>(unpack(std::move(child)),
DOUBLE);
441 return std::make_shared<Border>(unpack(std::move(child)),
ROUNDED);
476 return std::make_shared<Border>(unpack(std::move(child)),
EMPTY);
508 return std::make_shared<Border>(unpack(std::move(content), std::move(title)),
Element window(Element title, Element content, BorderStyle border=ROUNDED)
Dessine une fenêtre avec un titre et une bordure autour de l'élément.
Element borderDouble(Element child)
Dessine une double bordure autour de l'élément.
Element borderDashed(Element child)
Dessine une bordure en pointillés autour de l'élément.
Element borderRounded(Element child)
Dessine une bordure arrondie autour de l'élément.
BorderStyle
BorderStyle est une énumération qui représente les différents styles de bordures pouvant être appliqu...
Element borderHeavy(Element child)
Dessine une bordure épaisse autour de l'élément.
Decorator borderWith(const Cell &pixel)
Identique à border mais avec une Cell constante autour de l'élément.
Element borderLight(Element child)
Dessine une bordure fine autour de l'élément.
Decorator borderStyled(BorderStyle style)
Identique à border mais avec différents styles.
Element border(Element child)
Dessine une bordure autour de l'élément.
Element borderEmpty(Element child)
Dessine une bordure vide autour de l'élément.
L'espace de noms FTXUI ftxui::
std::shared_ptr< Node > Element
std::vector< Element > Elements
std::function< Element(Element)> Decorator
void Render(Screen &screen, Node *node, Selection &selection)
std::optional< Color > foreground_color_