20using Charset = std::array<std::string, 2>;
21using Charsets = std::array<Charset, 6>;
23const Charsets charsets = {
32class Separator :
public Node {
34 explicit Separator(std::string value) :
value_(std::move(value)) {}
36 void ComputeRequirement()
override {
37 requirement_.min_x = 1;
38 requirement_.min_y = 1;
41 void Render(Screen& screen)
override {
42 for (
int y = box_.y_min; y <= box_.y_max; ++y) {
43 for (
int x = box_.x_min; x <= box_.x_max; ++x) {
44 Pixel& pixel = screen.PixelAt(x, y);
46 pixel.automerge =
true;
54class SeparatorAuto :
public Node {
58 void ComputeRequirement()
override {
59 requirement_.min_x = 1;
60 requirement_.min_y = 1;
63 void Render(Screen& screen)
override {
64 const bool is_column = (box_.x_max == box_.x_min);
65 const bool is_line = (box_.y_min == box_.y_max);
68 charsets[
style_][int(is_line && !is_column)];
70 for (
int y = box_.y_min; y <= box_.y_max; ++y) {
71 for (
int x = box_.x_min; x <= box_.x_max; ++x) {
72 Pixel& pixel = screen.PixelAt(x, y);
74 pixel.automerge =
true;
82class SeparatorWithPixel :
public SeparatorAuto {
84 explicit SeparatorWithPixel(Pixel pixel)
85 : SeparatorAuto(
LIGHT), pixel_(std::move(pixel)) {
86 pixel_.automerge =
true;
88 void Render(Screen& screen)
override {
89 for (
int y = box_.y_min; y <= box_.y_max; ++y) {
90 for (
int x = box_.x_min; x <= box_.x_max; ++x) {
91 screen.PixelAt(x, y) = pixel_;
125 return std::make_shared<SeparatorAuto>(
LIGHT);
153 return std::make_shared<SeparatorAuto>(style);
180 return std::make_shared<SeparatorAuto>(
LIGHT);
207 return std::make_shared<SeparatorAuto>(
DASHED);
234 return std::make_shared<SeparatorAuto>(
HEAVY);
261 return std::make_shared<SeparatorAuto>(
DOUBLE);
297 return std::make_shared<SeparatorAuto>(
EMPTY);
333 return std::make_shared<Separator>(std::move(value));
364 return std::make_shared<SeparatorWithPixel>(std::move(pixel));
380 Color unselected_color,
381 Color selected_color) {
382 class Impl :
public Node {
384 Impl(
float left,
float right, Color selected_color, Color unselected_color)
387 unselected_color_(unselected_color),
388 selected_color_(selected_color) {}
389 void ComputeRequirement()
override {
390 requirement_.min_x = 1;
391 requirement_.min_y = 1;
394 void Render(Screen& screen)
override {
395 if (box_.y_max < box_.y_min) {
400 int demi_cell_left = int(left_ * 2.F - 1.F);
401 int demi_cell_right = int(right_ * 2.F + 2.F);
403 const int y = box_.y_min;
404 for (
int x = box_.x_min; x <= box_.x_max; ++x) {
405 Pixel& pixel = screen.PixelAt(x, y);
407 const int a = (x - box_.x_min) * 2;
409 const bool a_empty = demi_cell_left == a || demi_cell_right == a;
410 const bool b_empty = demi_cell_left == b || demi_cell_right == b;
412 if (!a_empty && !b_empty) {
413 pixel.character =
"─";
414 pixel.automerge =
true;
416 pixel.character = a_empty ?
"╶" :
"╴";
417 pixel.automerge =
false;
420 if (demi_cell_left <= a && b <= demi_cell_right) {
421 pixel.foreground_color = selected_color_;
423 pixel.foreground_color = unselected_color_;
430 Color unselected_color_;
431 Color selected_color_;
433 return std::make_shared<Impl>(
left,
right, unselected_color, selected_color);
449 Color unselected_color,
450 Color selected_color) {
451 class Impl :
public Node {
453 Impl(
float up,
float down, Color unselected_color, Color selected_color)
456 unselected_color_(unselected_color),
457 selected_color_(selected_color) {}
458 void ComputeRequirement()
override {
459 requirement_.min_x = 1;
460 requirement_.min_y = 1;
463 void Render(Screen& screen)
override {
464 if (box_.x_max < box_.x_min) {
469 const int demi_cell_up = int(up_ * 2 - 1);
470 const int demi_cell_down = int(down_ * 2 + 2);
472 const int x = box_.x_min;
473 for (
int y = box_.y_min; y <= box_.y_max; ++y) {
474 Pixel& pixel = screen.PixelAt(x, y);
476 const int a = (y - box_.y_min) * 2;
478 const bool a_empty = demi_cell_up == a || demi_cell_down == a;
479 const bool b_empty = demi_cell_up == b || demi_cell_down == b;
481 if (!a_empty && !b_empty) {
482 pixel.character =
"│";
483 pixel.automerge =
true;
485 pixel.character = a_empty ?
"╷" :
"╵";
486 pixel.automerge =
false;
489 if (demi_cell_up <= a && b <= demi_cell_down) {
490 pixel.foreground_color = selected_color_;
492 pixel.foreground_color = unselected_color_;
499 Color unselected_color_;
500 Color selected_color_;
502 return std::make_shared<Impl>(up,
down, unselected_color, selected_color);
Element separatorStyled(BorderStyle)
他の2つの要素の間に垂直または水平の区切り線を描画します。
Element separatorEmpty()
他の2つの要素の間にEMPTYスタイルで垂直または水平の区切り線を描画します。
Element separatorDashed()
他の2つの要素の間にLIGHTスタイルで垂直または水平の区切り線を描画します。
void Render(Screen &screen, const Element &element)
要素をftxui::Screenに表示します。
Element separatorDouble()
他の2つの要素の間にHEAVYスタイルで垂直または水平の区切り線を描画します。
BorderStyle
BorderStyleは、ターミナルUIの要素に適用できる様々なボーダースタイルを表す列挙型です。
Color
Colorは、ターミナルの色サポートを表す列挙型です。
Element separatorVSelector(float up, float down, Color unselected_color, Color selected_color)
std::shared_ptr< Node > Element
Element separatorHSelector(float left, float right, Color unselected_color, Color selected_color)
Element separatorCharacter(std::string)
std::function< void(Pixel &)> style_