FTXUI 7.0.3
C++ functional terminal UI.
Loading...
Searching...
No Matches
src/ftxui/dom/separator.cpp
Go to the documentation of this file.
1#include <string_view>
2// Copyright 2020 Arthur Sonzogni. All rights reserved.
3// Use of this source code is governed by the MIT license that can be found in
4// the LICENSE file.
5#include <array> // for array, array<>::value_type
6#include <memory> // for make_shared, allocator
7#include <string> // for basic_string, string
8#include <utility> // for move
9
10#include "ftxui/dom/elements.hpp" // for Element, BorderStyle, LIGHT, separator, DOUBLE, EMPTY, HEAVY, separatorCharacter, separatorDouble, separatorEmpty, separatorHSelector, separatorHeavy, separatorLight, separatorStyled, separatorVSelector
11#include "ftxui/dom/node.hpp" // for Node
12#include "ftxui/dom/requirement.hpp" // for Requirement
13#include "ftxui/screen/box.hpp" // for Box
14#include "ftxui/screen/cell.hpp" // for Cell
15#include "ftxui/screen/color.hpp" // for Color
16#include "ftxui/screen/screen.hpp" // for Cell, Screen
17
18namespace ftxui {
19
20namespace {
21using SeparatorCharset = std::array<std::string, 2>; // NOLINT
22using SeparatorCharsets = std::array<SeparatorCharset, 6>; // NOLINT
23
24const SeparatorCharsets charsets = {
25 // NOLINT
26 SeparatorCharset{"│", "─"}, // LIGHT
27 SeparatorCharset{"╏", "╍"}, // DASHED
28 SeparatorCharset{"┃", "━"}, // HEAVY
29 SeparatorCharset{"║", "═"}, // DOUBLE
30 SeparatorCharset{"│", "─"}, // ROUNDED
31 SeparatorCharset{" ", " "}, // EMPTY
32};
33
34class Separator : public Node {
35 public:
36 explicit Separator(std::string value) : value_(std::move(value)) {}
37
38 void ComputeRequirement() override {
39 requirement_.min_x = 1;
40 requirement_.min_y = 1;
41 }
42
43 void Render(Screen& screen) override {
44 for (int y = box_.y_min; y <= box_.y_max; ++y) {
45 for (int x = box_.x_min; x <= box_.x_max; ++x) {
46 Cell& pixel = screen.CellAt(x, y);
47 pixel.character = value_;
48 pixel.automerge = true;
49 }
50 }
51 }
52
53 std::string value_;
54};
55
56class SeparatorAuto : public Node {
57 public:
58 explicit SeparatorAuto(BorderStyle style) : style_(style) {}
59
60 void ComputeRequirement() override {
61 requirement_.min_x = 1;
62 requirement_.min_y = 1;
63 }
64
65 void Render(Screen& screen) override {
66 const bool is_column = (box_.x_max == box_.x_min);
67 const bool is_line = (box_.y_min == box_.y_max);
68
69 const std::string c =
70 charsets[style_][int(is_line && !is_column)]; // NOLINT
71
72 for (int y = box_.y_min; y <= box_.y_max; ++y) {
73 for (int x = box_.x_min; x <= box_.x_max; ++x) {
74 Cell& pixel = screen.CellAt(x, y);
75 pixel.character = c;
76 pixel.automerge = true;
77 }
78 }
79 }
80
82};
83
84class SeparatorWithCell : public SeparatorAuto {
85 public:
86 explicit SeparatorWithCell(Cell pixel)
87 : SeparatorAuto(LIGHT), pixel_(std::move(pixel)) {
88 pixel_.automerge = true;
89 }
90 void Render(Screen& screen) override {
91 for (int y = box_.y_min; y <= box_.y_max; ++y) {
92 for (int x = box_.x_min; x <= box_.x_max; ++x) {
93 screen.CellAt(x, y) = pixel_;
94 }
95 }
96 }
97
98 private:
99 Cell pixel_;
100};
101} // namespace
102
103/// @brief 在兩個元素之間繪製垂直或水平分隔線。
104/// @ingroup dom
105/// @see separator
106/// @see separatorLight
107/// @see separatorDashed
108/// @see separatorDouble
109/// @see separatorHeavy
110/// @see separatorEmpty
111/// @see separatorRounded
112/// @see separatorStyled
113/// @see separatorCharacter
114///
115/// 在兩個元素之間添加視覺分隔。
116///
117/// ### 範例
118///
119/// ```cpp
120/// // 使用 'border' 作為函式...
121/// Element document = vbox({
122/// text("up"),
123/// separator(),
124/// text("down"),
125/// });
126/// ```
127///
128/// ### 輸出
129///
130/// ```bash
131/// up
132/// ────
133/// down
134/// ```
136 return std::make_shared<SeparatorAuto>(LIGHT);
137}
138
139/// @brief 在兩個元素之間繪製垂直或水平分隔線。
140/// @param style 分隔線的樣式。
141/// @ingroup dom
142/// @see separator
143/// @see separatorLight
144/// @see separatorDashed
145/// @see separatorDouble
146/// @see separatorHeavy
147/// @see separatorEmpty
148/// @see separatorRounded
149/// @see separatorStyled
150/// @see separatorCharacter
151///
152/// 在兩個元素之間添加視覺分隔。
153///
154/// ### 範例
155///
156/// ```cpp
157/// // 使用 'border' 作為函式...
158/// Element document = vbox({
159/// text("up"),
160/// separatorStyled(DOUBLE),
161/// text("down"),
162/// });
163/// ```
164///
165/// ### 輸出
166///
167/// ```bash
168/// up
169/// ════
170/// down
171/// ```
173 return std::make_shared<SeparatorAuto>(style);
174}
175
176/// @brief 使用 LIGHT 樣式在兩個元素之間繪製垂直或水平分隔線。
177/// @ingroup dom
178/// @see separator
179/// @see separatorLight
180/// @see separatorDashed
181/// @see separatorDouble
182/// @see separatorHeavy
183/// @see separatorEmpty
184/// @see separatorRounded
185/// @see separatorStyled
186/// @see separatorCharacter
187///
188/// 在兩個元素之間添加視覺分隔。
189///
190/// ### 範例
191///
192/// ```cpp
193/// // 使用 'border' 作為函式...
194/// Element document = vbox({
195/// text("up"),
196/// separatorLight(),
197/// text("down"),
198/// });
199/// ```
200///
201/// ### 輸出
202///
203/// ```bash
204/// up
205/// ────
206/// down
207/// ```
209 return std::make_shared<SeparatorAuto>(LIGHT);
210}
211
212/// @brief 使用 DASHED 樣式在兩個元素之間繪製垂直或水平分隔線。
213/// @ingroup dom
214/// @see separator
215/// @see separatorLight
216/// @see separatorDashed
217/// @see separatorDouble
218/// @see separatorHeavy
219/// @see separatorEmpty
220/// @see separatorRounded
221/// @see separatorStyled
222/// @see separatorCharacter
223///
224/// 在兩個元素之間添加視覺分隔。
225///
226/// ### 範例
227///
228/// ```cpp
229/// // 使用 'border' 作為函式...
230/// Element document = vbox({
231/// text("up"),
232/// separatorLight(),
233/// text("down"),
234/// });
235/// ```
236///
237/// ### 輸出
238///
239/// ```bash
240/// up
241/// ╍╍╍╍
242/// down
243/// ```
245 return std::make_shared<SeparatorAuto>(DASHED);
246}
247
248/// @brief 使用 HEAVY 樣式在兩個元素之間繪製垂直或水平分隔線。
249/// @ingroup dom
250/// @see separator
251/// @see separatorLight
252/// @see separatorDashed
253/// @see separatorDouble
254/// @see separatorHeavy
255/// @see separatorEmpty
256/// @see separatorRounded
257/// @see separatorStyled
258/// @see separatorCharacter
259///
260/// 在兩個元素之間添加視覺分隔。
261///
262/// ### 範例
263///
264/// ```cpp
265/// // 使用 'border' 作為函式...
266/// Element document = vbox({
267/// text("up"),
268/// separatorHeavy(),
269/// text("down"),
270/// });
271/// ```
272///
273/// ### 輸出
274///
275/// ```bash
276/// up
277/// ━━━━
278/// down
279/// ```
281 return std::make_shared<SeparatorAuto>(HEAVY);
282}
283
284/// @brief 使用 DOUBLE 樣式在兩個元素之間繪製垂直或水平分隔線。
285/// @ingroup dom
286/// @see separator
287/// @see separatorLight
288/// @see separatorDashed
289/// @see separatorDouble
290/// @see separatorHeavy
291/// @see separatorEmpty
292/// @see separatorRounded
293/// @see separatorStyled
294/// @see separatorCharacter
295///
296/// 在兩個元素之間添加視覺分隔。
297///
298/// ### 範例
299///
300/// ```cpp
301/// // 使用 'border' 作為函式...
302/// Element document = vbox({
303/// text("up"),
304/// separatorDouble(),
305/// text("down"),
306/// });
307/// ```
308///
309/// ### 輸出
310///
311/// ```bash
312/// up
313/// ════
314/// down
315/// ```
317 return std::make_shared<SeparatorAuto>(DOUBLE);
318}
319
320/// @brief 使用 EMPTY 樣式在兩個元素之間繪製垂直或水平分隔線。
321/// @ingroup dom
322/// @see separator
323/// @see separatorLight
324/// @see separatorDashed
325/// @see separatorDouble
326/// @see separatorHeavy
327/// @see separatorEmpty
328/// @see separatorRounded
329/// @see separatorStyled
330/// @see separatorCharacter
331///
332/// 在兩個元素之間添加視覺分隔。
333///
334/// ### 範例
335///
336/// ```cpp
337/// // 使用 'border' 作為函式...
338/// Element document = vbox({
339/// text("up"),
340/// separator(),
341/// text("down"),
342/// });
343/// ```
344///
345/// ### 輸出
346///
347/// ```bash
348/// up
349///
350/// down
351/// ```
353 return std::make_shared<SeparatorAuto>(EMPTY);
354}
355
356/// @brief 在兩個元素之間繪製垂直或水平分隔線。
357/// @param value 用於填充分隔線區域的字元。
358/// @ingroup dom
359/// @see separator
360/// @see separatorLight
361/// @see separatorDashed
362/// @see separatorDouble
363/// @see separatorHeavy
364/// @see separatorEmpty
365/// @see separatorRounded
366/// @see separatorStyled
367/// @see separatorCharacter
368///
369/// 在兩個元素之間添加視覺分隔。
370///
371/// ### 範例
372///
373/// ```cpp
374/// // 使用 'border' 作為函式...
375/// Element document = vbox({
376/// text("up"),
377/// separator(),
378/// text("down"),
379/// });
380/// ```
381///
382/// ### 輸出
383///
384/// ```bash
385/// up
386/// ────
387/// down
388/// ```
390 return std::make_shared<Separator>(std::string(value));
391}
392
393/// @brief 用指定的 pixel 填滿並在兩個元素之間繪製一條分隔線。
394/// @ingroup dom
395/// @see separator
396/// @see separatorLight
397/// @see separatorDashed
398/// @see separatorHeavy
399/// @see separatorDouble
400/// @see separatorStyled
401///
402/// ### 範例
403///
404/// ```cpp
405/// Cell empty;
406/// Element document = vbox({
407/// text("Up"),
408/// separator(empty),
409/// text("Down"),
410/// })
411/// ```
412///
413/// ### 輸出
414///
415/// ```bash
416/// Up
417///
418/// Down
419/// ```
420Element separator(Cell pixel) {
421 return std::make_shared<SeparatorWithCell>(std::move(pixel));
422}
423
424/// @brief 繪製一個水平條,其中左右兩側之間的區域以不同顏色顯示。
425/// @param left 活躍區域的左限。
426/// @param right 活躍區域的右限。
427/// @param selected_color 選定區域的顏色。
428/// @param unselected_color 未選定區域的顏色。
429///
430/// ### 範例
431///
432/// ```cpp
433/// Element document = separatorHSelector(2,5, Color::White, Color::Blue);
434/// ```
436 float right,
437 Color unselected_color,
438 Color selected_color) {
439 class Impl : public Node {
440 public:
441 Impl(float left, float right, Color selected_color, Color unselected_color)
442 : left_(left),
443 right_(right),
444 unselected_color_(unselected_color),
445 selected_color_(selected_color) {}
446 void ComputeRequirement() override {
447 requirement_.min_x = 1;
448 requirement_.min_y = 1;
449 }
450
451 void Render(Screen& screen) override {
452 if (box_.y_max < box_.y_min) {
453 return;
454 }
455
456 // 這是有著空半格儲存格的兩個位置。
457 int demi_cell_left = int(left_ * 2.F - 1.F); // NOLINT
458 int demi_cell_right = int(right_ * 2.F + 2.F); // NOLINT
459
460 const int y = box_.y_min;
461 for (int x = box_.x_min; x <= box_.x_max; ++x) {
462 Cell& pixel = screen.CellAt(x, y);
463
464 const int a = (x - box_.x_min) * 2;
465 const int b = a + 1;
466 const bool a_empty = demi_cell_left == a || demi_cell_right == a;
467 const bool b_empty = demi_cell_left == b || demi_cell_right == b;
468
469 if (!a_empty && !b_empty) {
470 pixel.character = "─";
471 pixel.automerge = true;
472 } else {
473 pixel.character = a_empty ? "╶" : "╴"; // NOLINT
474 pixel.automerge = false;
475 }
476
477 if (demi_cell_left <= a && b <= demi_cell_right) {
478 pixel.foreground_color = selected_color_;
479 } else {
480 pixel.foreground_color = unselected_color_;
481 }
482 }
483 }
484
485 float left_;
486 float right_;
487 Color unselected_color_;
488 Color selected_color_;
489 };
490 return std::make_shared<Impl>(left, right, unselected_color, selected_color);
491}
492
493/// @brief 繪製一個垂直條,其中上方/下方之間的區域以不同顏色顯示。
494/// @param up 活躍區域的上限。
495/// @param down 活躍區域的下限。
496/// @param selected_color 選定區域的顏色。
497/// @param unselected_color 未選定區域的顏色。
498///
499/// ### 範例
500///
501/// ```cpp
502/// Element document = separatorHSelector(2,5, Color::White, Color::Blue);
503/// ```
505 float down,
506 Color unselected_color,
507 Color selected_color) {
508 class Impl : public Node {
509 public:
510 Impl(float up, float down, Color unselected_color, Color selected_color)
511 : up_(up),
512 down_(down),
513 unselected_color_(unselected_color),
514 selected_color_(selected_color) {}
515 void ComputeRequirement() override {
516 requirement_.min_x = 1;
517 requirement_.min_y = 1;
518 }
519
520 void Render(Screen& screen) override {
521 if (box_.x_max < box_.x_min) {
522 return;
523 }
524
525 // 這是有著空半格儲存格的兩個位置。
526 const int demi_cell_up = int(up_ * 2 - 1);
527 const int demi_cell_down = int(down_ * 2 + 2);
528
529 const int x = box_.x_min;
530 for (int y = box_.y_min; y <= box_.y_max; ++y) {
531 Cell& pixel = screen.CellAt(x, y);
532
533 const int a = (y - box_.y_min) * 2;
534 const int b = a + 1;
535 const bool a_empty = demi_cell_up == a || demi_cell_down == a;
536 const bool b_empty = demi_cell_up == b || demi_cell_down == b;
537
538 if (!a_empty && !b_empty) {
539 pixel.character = "│";
540 pixel.automerge = true;
541 } else {
542 pixel.character = a_empty ? "╷" : "╵"; // NOLINT
543 pixel.automerge = false;
544 }
545
546 if (demi_cell_up <= a && b <= demi_cell_down) {
547 pixel.foreground_color = selected_color_;
548 } else {
549 pixel.foreground_color = unselected_color_;
550 }
551 }
552 }
553
554 float up_;
555 float down_;
556 Color unselected_color_;
557 Color selected_color_;
558 };
559 return std::make_shared<Impl>(up, down, unselected_color, selected_color);
560}
561
562} // namespace ftxui
Element separatorStyled(BorderStyle style)
在兩個元素之間繪製垂直或水平分隔線。
Element separatorEmpty()
使用 EMPTY 樣式在兩個元素之間繪製垂直或水平分隔線。
Element separatorLight()
使用 LIGHT 樣式在兩個元素之間繪製垂直或水平分隔線。
BorderStyle
BorderStyle 是一個列舉,表示可以應用於終端機 UI 元素的不同邊框樣式。
Definition elements.hpp:35
Element separatorDashed()
使用 DASHED 樣式在兩個元素之間繪製垂直或水平分隔線。
Element separator()
在兩個元素之間繪製垂直或水平分隔線。
Element separatorCharacter(std::string_view value)
在兩個元素之間繪製垂直或水平分隔線。
Element separatorDouble()
使用 DOUBLE 樣式在兩個元素之間繪製垂直或水平分隔線。
Element separatorHeavy()
使用 HEAVY 樣式在兩個元素之間繪製垂直或水平分隔線。
@ EMPTY
Definition elements.hpp:41
@ DOUBLE
Definition elements.hpp:39
@ HEAVY
Definition elements.hpp:38
@ DASHED
Definition elements.hpp:37
@ LIGHT
Definition elements.hpp:36
FTXUI ftxui:: 命名空間
Definition animation.hpp:11
Element separatorVSelector(float up, float down, Color unselected_color, Color selected_color)
繪製一個垂直條,其中上方/下方之間的區域以不同顏色顯示。
std::shared_ptr< Node > Element
Definition elements.hpp:25
FTXUI_EXPORT(DOM) Element separatorCharacter(std Element separatorHSelector(float left, float right, Color unselected_color, Color selected_color)
繪製一個水平條,其中左右兩側之間的區域以不同顏色顯示。
int y
Definition elements.hpp:131
void Render(Screen &screen, Node *node, Selection &selection)
Definition node.cpp:105
int value
Definition elements.hpp:192
std::uint8_t left
Definition screen.cpp:147
std::uint8_t down
Definition screen.cpp:150
std::uint8_t right
Definition screen.cpp:149
std::function< void(Cell &)> style_
std::string value_