22using Charset = std::array<std::string, 6>;
23using Charsets = std::array<Charset, 6>;
26 Charset{
"┌",
"┐",
"└",
"┘",
"─",
"│"},
27 Charset{
"┏",
"┓",
"┗",
"┛",
"╍",
"╏"},
28 Charset{
"┏",
"┓",
"┗",
"┛",
"━",
"┃"},
29 Charset{
"╔",
"╗",
"╚",
"╝",
"═",
"║"},
30 Charset{
"╭",
"╮",
"╰",
"╯",
"─",
"│"},
31 Charset{
" ",
" ",
" ",
" ",
" ",
" "},
35class Border :
public Node {
39 std::optional<Color> foreground_color = std::nullopt)
42 foreground_color_(foreground_color) {}
45 std::optional<Color> foreground_color_;
47 void ComputeRequirement()
override {
49 requirement_ = children_[0]->requirement();
50 requirement_.min_x += 2;
51 requirement_.min_y += 2;
52 if (children_.size() == 2) {
54 std::max(requirement_.min_x, children_[1]->requirement().min_x + 2);
56 requirement_.selected_box.x_min++;
57 requirement_.selected_box.x_max++;
58 requirement_.selected_box.y_min++;
59 requirement_.selected_box.y_max++;
62 void SetBox(Box
box)
override {
64 if (children_.size() == 2) {
76 children_[0]->SetBox(
box);
81 children_[0]->Render(
screen);
84 if (box_.x_min >= box_.x_max || box_.y_min >= box_.y_max) {
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 {
138 void ComputeRequirement()
override {
140 requirement_ = children_[0]->requirement();
141 requirement_.min_x += 2;
142 requirement_.min_y += 2;
143 if (children_.size() == 2) {
145 std::max(requirement_.min_x, children_[1]->requirement().min_x + 2);
147 requirement_.selected_box.x_min++;
148 requirement_.selected_box.x_max++;
149 requirement_.selected_box.y_min++;
150 requirement_.selected_box.y_max++;
153 void SetBox(Box
box)
override {
155 if (children_.size() == 2) {
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_;