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,
261 return [style, foreground_color](Element child) {
262 return std::make_shared<Border>(unpack(std::move(child)), style,
299 return std::make_shared<Border>(unpack(std::move(child)), DASHED);
334 return std::make_shared<Border>(unpack(std::move(child)), LIGHT);
369 return std::make_shared<Border>(unpack(std::move(child)), HEAVY);
404 return std::make_shared<Border>(unpack(std::move(child)), DOUBLE);
439 return std::make_shared<Border>(unpack(std::move(child)), ROUNDED);
474 return std::make_shared<Border>(unpack(std::move(child)), EMPTY);
505Element
window(Element title, Element content, BorderStyle border) {
506 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の要素に適用できる様々なボーダースタイルを表す列挙型です。
std::vector< Element > Elements