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 {
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);
83 children_[0]->Render(
screen);
86 if (box_.x_min >= box_.x_max || box_.y_min >= box_.y_max) {
95 for (
int x = box_.x_min + 1; x < box_.x_max; ++x) {
96 Pixel& p1 =
screen.PixelAt(x, box_.y_min);
97 Pixel& p2 =
screen.PixelAt(x, box_.y_max);
103 for (
int y = box_.y_min + 1; y < box_.y_max; ++y) {
104 Pixel& p3 =
screen.PixelAt(box_.x_min, y);
105 Pixel& p4 =
screen.PixelAt(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 BorderPixel :
public Node {
134 BorderPixel(
Elements children, Pixel pixel)
135 : Node(std::move(children)), pixel_(std::move(pixel)) {}
140 void ComputeRequirement()
override {
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);
172 children_[0]->Render(
screen);
175 if (box_.x_min >= box_.x_max || box_.y_min >= box_.y_max) {
179 screen.PixelAt(box_.x_min, box_.y_min) = pixel_;
180 screen.PixelAt(box_.x_max, box_.y_min) = pixel_;
181 screen.PixelAt(box_.x_min, box_.y_max) = pixel_;
182 screen.PixelAt(box_.x_max, box_.y_max) = pixel_;
184 for (
int x = box_.x_min + 1; x < box_.x_max; ++x) {
185 screen.PixelAt(x, box_.y_min) = pixel_;
186 screen.PixelAt(x, box_.y_max) = pixel_;
188 for (
int y = box_.y_min + 1; y < box_.y_max; ++y) {
189 screen.PixelAt(box_.x_min, y) = pixel_;
190 screen.PixelAt(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<BorderPixel>(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)),
virtual void SetBox(Box box)
Assigne une position et une dimension à un élément pour le dessin.
virtual void ComputeRequirement()
Calcule l'espace nécessaire à un élément.
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)
Dessine une double bordure autour de l'élément.
Element borderDashed(Element)
Dessine une bordure en pointillés autour de l'élément.
Element borderRounded(Element)
Dessine une bordure arrondie autour de l'élément.
Element borderHeavy(Element)
Dessine une bordure épaisse autour de l'élément.
Element borderLight(Element)
Dessine une bordure fine autour de l'élément.
Decorator borderWith(const Pixel &)
Identique à border mais avec un Pixel constant autour de l'élément.
Decorator borderStyled(BorderStyle)
Identique à border mais avec différents styles.
Element border(Element)
Dessine une bordure autour de l'élément.
Element borderEmpty(Element)
Dessine une bordure vide autour de l'élément.
BorderStyle
BorderStyle est une énumération qui représente les différents styles de bordures pouvant être appliqu...
Color est une classe qui représente une couleur dans l'interface utilisateur du terminal.
Un caractère Unicode et son style associé.
L'espace de noms FTXUI ftxui::
std::function< Element(Element)> Decorator
std::shared_ptr< Node > Element
std::vector< Element > Elements
void Render(Screen &screen, const Element &element)
std::optional< Color > foreground_color_