21using Charset = std::array<std::string, 6>;
22using Charsets = std::array<Charset, 6>;
24static Charsets simple_border_charset = {
25 Charset{
"┌",
"┐",
"└",
"┘",
"─",
"│"},
26 Charset{
"┏",
"┓",
"┗",
"┛",
"╍",
"╏"},
27 Charset{
"┏",
"┓",
"┗",
"┛",
"━",
"┃"},
28 Charset{
"╔",
"╗",
"╚",
"╝",
"═",
"║"},
29 Charset{
"╭",
"╮",
"╰",
"╯",
"─",
"│"},
30 Charset{
" ",
" ",
" ",
" ",
" ",
" "},
37 std::optional<Color> foreground_color = std::nullopt)
38 : Node(std::move(children)),
39 charset_(simple_border_charset[style])
41 foreground_color_(foreground_color) {}
43 const Charset& charset_;
44 std::optional<Color> foreground_color_;
46 void ComputeRequirement()
override {
48 requirement_ = children_[0]->requirement();
49 requirement_.min_x += 2;
50 requirement_.min_y += 2;
51 if (children_.size() == 2) {
53 std::max(requirement_.min_x, children_[1]->requirement().min_x + 2);
55 requirement_.focused.box.x_min++;
56 requirement_.focused.box.x_max++;
57 requirement_.focused.box.y_min++;
58 requirement_.focused.box.y_max++;
61 void SetBox(Box box)
override {
63 if (children_.size() == 2) {
65 title_box.x_min = box.x_min + 1;
66 title_box.x_max = std::min(box.x_max - 1,
67 box.x_min + children_[1]->requirement().min_x);
68 title_box.y_min = box.y_min;
69 title_box.y_max = box.y_min;
70 children_[1]->SetBox(title_box);
76 children_[0]->SetBox(box);
79 void Render(Screen& screen)
override {
81 children_[0]->Render(screen);
88 screen.at(box_.
x_min, box_.
y_min) = charset_[0];
89 screen.at(box_.
x_max, box_.
y_min) = charset_[1];
90 screen.at(box_.
x_min, box_.
y_max) = charset_[2];
91 screen.at(box_.
x_max, box_.
y_max) = charset_[3];
93 for (
int x = box_.
x_min + 1; x < box_.
x_max; ++x) {
94 Pixel& p1 = screen.PixelAt(x, box_.
y_min);
95 Pixel& p2 = screen.PixelAt(x, box_.
y_max);
96 p1.character = charset_[4];
97 p2.character = charset_[4];
101 for (
int y = box_.
y_min + 1; y < box_.
y_max; ++y) {
102 Pixel& p3 = screen.PixelAt(box_.
x_min, y);
103 Pixel& p4 = screen.PixelAt(box_.
x_max, y);
104 p3.character = charset_[5];
105 p4.character = charset_[5];
111 if (children_.size() == 2) {
112 children_[1]->Render(screen);
116 if (foreground_color_) {
117 for (
int x = box_.
x_min; x <= box_.
x_max; ++x) {
118 screen.PixelAt(x, box_.
y_min).foreground_color = *foreground_color_;
119 screen.PixelAt(x, box_.
y_max).foreground_color = *foreground_color_;
121 for (
int y = box_.
y_min; y <= box_.
y_max; ++y) {
122 screen.PixelAt(box_.
x_min, y).foreground_color = *foreground_color_;
123 screen.PixelAt(box_.
x_max, y).foreground_color = *foreground_color_;
130class BorderPixel :
public Node {
132 BorderPixel(
Elements children, Pixel pixel)
133 :
Node(std::move(children)), pixel_(std::move(pixel)) {}
138 void ComputeRequirement()
override {
151 void SetBox(Box box)
override {
155 title_box.x_min = box.x_min + 1;
156 title_box.x_max = box.x_max - 1;
157 title_box.y_min = box.y_min;
158 title_box.y_max = box.y_min;
168 void Render(Screen& screen)
override {
226 return std::make_shared<Border>(unpack(std::move(child)), ROUNDED);
233 return [pixel](Element child) {
234 return std::make_shared<BorderPixel>(unpack(std::move(child)), pixel);
242 return [style](Element child) {
243 return std::make_shared<Border>(unpack(std::move(child)), style);
251 return [foreground_color](Element child) {
252 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);
507Element
window(Element title, Element content, BorderStyle border) {
508 return std::make_shared<Border>(unpack(std::move(content), std::move(title)),
virtual void SetBox(Box box)
为绘图元素分配位置和尺寸。
virtual void ComputeRequirement()
计算元素所需的空间。
friend void Render(Screen &screen, Node *node, Selection &selection)
Element window(Element title, Element content, BorderStyle border)
绘制带有标题和边框的窗口。
Element borderDouble(Element child)
在元素周围绘制双线边框。
Element borderDashed(Element child)
在元素周围绘制虚线边框。
Element borderRounded(Element child)
在元素周围绘制圆角边框。
Element borderHeavy(Element child)
在元素周围绘制粗边框。
Element borderLight(Element child)
在元素周围绘制细边框。
Decorator borderWith(const Pixel &pixel)
与 border 相同,但在元素周围使用一个常量像素。
Decorator borderStyled(BorderStyle style)
与 border 相同,但具有不同的样式。
void Render(Screen &screen, const Element &element)
在 ftxui::Screen 上显示元素。
Element border(Element child)
在元素周围绘制边框。
Element borderEmpty(Element child)
在元素周围绘制一个空边框。
BorderStyle
BorderStyle 是一个枚举,表示可应用于终端 UI 中元素的不同边框样式。
#include "ftxui/component/component_base.hpp" // 用于 ComponentBase
std::vector< Element > Elements