FTXUI 6.1.9
C++ functional terminal UI.
Loading...
Searching...
No Matches
homescreen.cpp
Go to the documentation of this file.
1// Copyright 2020 Arthur Sonzogni. All rights reserved.
2// このソースコードの使用は、LICENSEファイルにあるMITライセンスによって管理されています。
3#include <stddef.h> // for size_t
4#include <array> // for array
5#include <atomic> // for atomic
6#include <chrono> // for operator""s, chrono_literals
7#include <cmath> // for sin
9#include <functional> // for ref, reference_wrapper, function
10#include <memory> // for allocator, shared_ptr, __shared_ptr_access
11#include <string> // for string, basic_string, char_traits, operator+, to_string
12#include <thread> // for sleep_for, thread
13#include <utility> // for move
14#include <vector> // for vector
15
16#include "../dom/color_info_sorted_2d.ipp" // for ColorInfoSorted2D
17#include "ftxui/component/component.hpp" // for Checkbox, Renderer, Horizontal, Vertical, Input, Menu, Radiobox, ResizableSplitLeft, Tab
18#include "ftxui/component/component_base.hpp" // for ComponentBase, Component
19#include "ftxui/component/component_options.hpp" // for MenuOption, InputOption
20#include "ftxui/component/event.hpp" // for Event, Event::Custom
21#include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive
22#include "ftxui/dom/elements.hpp" // for text, color, operator|, bgcolor, filler, Element, vbox, size, hbox, separator, flex, window, graph, EQUAL, paragraph, WIDTH, hcenter, Elements, bold, vscroll_indicator, HEIGHT, flexbox, hflow, border, frame, flex_grow, gauge, paragraphAlignCenter, paragraphAlignJustify, paragraphAlignLeft, paragraphAlignRight, dim, spinner, LESS_THAN, center, yframe, GREATER_THAN
23#include "ftxui/dom/flexbox_config.hpp" // for FlexboxConfig
24#include "ftxui/screen/color.hpp" // for Color, Color::BlueLight, Color::RedLight, Color::Black, Color::Blue, Color::Cyan, Color::CyanLight, Color::GrayDark, Color::GrayLight, Color::Green, Color::GreenLight, Color::Magenta, Color::MagentaLight, Color::Red, Color::White, Color::Yellow, Color::YellowLight, Color::Default, Color::Palette256, ftxui
25#include "ftxui/screen/color_info.hpp" // for ColorInfo
26#include "ftxui/screen/terminal.hpp" // for Size, Dimensions
27
28using namespace ftxui;
29
30int main() {
31 auto screen = ScreenInteractive::Fullscreen();
32
33 // ---------------------------------------------------------------------------
34 // HTOP
35 // ---------------------------------------------------------------------------
36 int shift = 0;
37
38 auto my_graph = [&shift](int width, int height) {
39 std::vector<int> output(width);
40 for (int i = 0; i < width; ++i) {
41 float v = 0.5f;
42 v += 0.1f * sin((i + shift) * 0.1f);
43 v += 0.2f * sin((i + shift + 10) * 0.15f);
44 v += 0.1f * sin((i + shift) * 0.03f);
45 v *= height;
46 output[i] = (int)v;
47 }
48 return output;
49 };
50
51 auto htop = Renderer([&] {
52 auto frequency = vbox({
53 text("Frequency [Mhz]") | hcenter,
54 hbox({
55 vbox({
56 text("2400 "),
57 filler(),
58 text("1200 "),
59 filler(),
60 text("0 "),
61 }),
62 graph(std::ref(my_graph)) | flex,
63 }) | flex,
64 });
65
66 auto utilization = vbox({
67 text("Utilization [%]") | hcenter,
68 hbox({
69 vbox({
70 text("100 "),
71 filler(),
72 text("50 "),
73 filler(),
74 text("0 "),
75 }),
76 graph(std::ref(my_graph)) | color(Color::RedLight),
77 }) | flex,
78 });
79
80 auto ram = vbox({
81 text("Ram [Mo]") | hcenter,
82 hbox({
83 vbox({
84 text("8192"),
85 filler(),
86 text("4096 "),
87 filler(),
88 text("0 "),
89 }),
90 graph(std::ref(my_graph)) | color(Color::BlueLight),
91 }) | flex,
92 });
93
94 return hbox({
95 vbox({
96 frequency | flex,
97 separator(),
98 utilization | flex,
99 }) | flex,
100 separator(),
101 ram | flex,
102 }) |
103 flex;
104 });
105
106 // ---------------------------------------------------------------------------
107 // コンパイラ
108 // ---------------------------------------------------------------------------
109
110 const std::vector<std::string> compiler_entries = {
111 "gcc",
112 "clang",
113 "emcc",
114 "game_maker",
115 "Ada compilers",
116 "ALGOL 60 compilers",
117 "ALGOL 68 compilers",
118 "Assemblers (Intel *86)",
119 "Assemblers (Motorola 68*)",
120 "Assemblers (Zilog Z80)",
121 "Assemblers (other)",
122 "BASIC Compilers",
123 "BASIC interpreters",
124 "Batch compilers",
125 "C compilers",
126 "Source-to-source compilers",
127 "C++ compilers",
128 "C# compilers",
129 "COBOL compilers",
130 "Common Lisp compilers",
131 "D compilers",
132 "DIBOL/DBL compilers",
133 "ECMAScript interpreters",
134 "Eiffel compilers",
135 "Fortran compilers",
136 "Go compilers",
137 "Haskell compilers",
138 "Java compilers",
139 "Pascal compilers",
140 "Perl Interpreters",
141 "PHP compilers",
142 "PL/I compilers",
143 "Python compilers",
144 "Scheme compilers and interpreters",
145 "Smalltalk compilers",
146 "Tcl Interpreters",
147 "VMS Interpreters",
148 "Rexx Interpreters",
149 "CLI compilers",
150 };
151
152 int compiler_selected = 0;
153 Component compiler = Radiobox(&compiler_entries, &compiler_selected);
154
155 std::array<std::string, 8> options_label = {
156 "-Wall",
157 "-Werror",
158 "-lpthread",
159 "-O3",
160 "-Wabi-tag",
161 "-Wno-class-conversion",
162 "-Wcomma-subscript",
163 "-Wno-conversion-null",
164 };
165 std::array<bool, 8> options_state = {
166 false, false, false, false, false, false, false, false,
167 };
168
169 std::vector<std::string> input_entries;
170 int input_selected = 0;
171 Component input = Menu(&input_entries, &input_selected);
172
173 auto input_option = InputOption();
174 std::string input_add_content;
175 input_option.on_enter = [&] {
176 input_entries.push_back(input_add_content);
177 input_add_content = "";
178 };
179 Component input_add = Input(&input_add_content, "input files", input_option);
180
181 std::string executable_content_ = "";
182 Component executable_ = Input(&executable_content_, "executable");
183
184 Component flags = Container::Vertical({
185 Checkbox(&options_label[0], &options_state[0]),
186 Checkbox(&options_label[1], &options_state[1]),
187 Checkbox(&options_label[2], &options_state[2]),
188 Checkbox(&options_label[3], &options_state[3]),
189 Checkbox(&options_label[4], &options_state[4]),
190 Checkbox(&options_label[5], &options_state[5]),
191 Checkbox(&options_label[6], &options_state[6]),
192 Checkbox(&options_label[7], &options_state[7]),
193 });
194
195 auto compiler_component = Container::Horizontal({
196 compiler,
197 flags,
198 Container::Vertical({
199 executable_,
200 Container::Horizontal({
201 input_add,
202 input,
203 }),
204 }),
205 });
206
207 auto render_command = [&] {
208 Elements line;
209 // コンパイラ
210 line.push_back(text(compiler_entries[compiler_selected]) | bold);
211 // フラグ
212 for (int i = 0; i < 8; ++i) {
213 if (options_state[i]) {
214 line.push_back(text(" "));
215 line.push_back(text(options_label[i]) | dim);
216 }
217 }
218 // 実行可能ファイル
219 if (!executable_content_.empty()) {
220 line.push_back(text(" -o ") | bold);
221 line.push_back(text(executable_content_) | color(Color::BlueLight) |
222 bold);
223 }
224 // 入力
225 for (auto& it : input_entries) {
226 line.push_back(text(" " + it) | color(Color::RedLight));
227 }
228 return line;
229 };
230
231 auto compiler_renderer = Renderer(compiler_component, [&] {
232 auto compiler_win = window(text("Compiler"),
233 compiler->Render() | vscroll_indicator | frame);
234 auto flags_win =
235 window(text("Flags"), flags->Render() | vscroll_indicator | frame);
236 auto executable_win = window(text("Executable:"), executable_->Render());
237 auto input_win =
238 window(text("Input"), hbox({
239 vbox({
240 hbox({
241 text("Add: "),
242 input_add->Render(),
243 }) | size(WIDTH, EQUAL, 20) |
244 size(HEIGHT, EQUAL, 1),
245 filler(),
246 }),
247 separator(),
248 input->Render() | vscroll_indicator | frame |
249 size(HEIGHT, EQUAL, 3) | flex,
250 }));
251 return vbox({
252 hbox({
253 compiler_win,
254 flags_win,
255 vbox({
256 executable_win | size(WIDTH, EQUAL, 20),
257 input_win | size(WIDTH, EQUAL, 60),
258 }),
259 filler(),
260 }) | size(HEIGHT, LESS_THAN, 8),
261 hflow(render_command()) | flex_grow,
262 }) |
263 flex_grow;
264 });
265
266 // ---------------------------------------------------------------------------
267 // スピナー
268 // ---------------------------------------------------------------------------
269 auto spinner_tab_renderer = Renderer([&] {
270 Elements entries;
271 for (int i = 0; i < 22; ++i) {
272 entries.push_back(spinner(i, shift / 5) | bold |
273 size(WIDTH, GREATER_THAN, 2) | border);
274 }
275 return hflow(std::move(entries));
276 });
277
278 // ---------------------------------------------------------------------------
279 // 色
280 // ---------------------------------------------------------------------------
281 auto color_tab_renderer = Renderer([] {
282 auto basic_color_display =
283 vbox({
284 text("16 color palette:"),
285 separator(),
286 hbox({
287 vbox({
288 color(Color::Default, text("Default")),
289 color(Color::Black, text("Black")),
290 color(Color::GrayDark, text("GrayDark")),
291 color(Color::GrayLight, text("GrayLight")),
292 color(Color::White, text("White")),
293 color(Color::Blue, text("Blue")),
294 color(Color::BlueLight, text("BlueLight")),
295 color(Color::Cyan, text("Cyan")),
296 color(Color::CyanLight, text("CyanLight")),
297 color(Color::Green, text("Green")),
298 color(Color::GreenLight, text("GreenLight")),
299 color(Color::Magenta, text("Magenta")),
300 color(Color::MagentaLight, text("MagentaLight")),
301 color(Color::Red, text("Red")),
302 color(Color::RedLight, text("RedLight")),
303 color(Color::Yellow, text("Yellow")),
304 color(Color::YellowLight, text("YellowLight")),
305 }),
306 vbox({
307 bgcolor(Color::Default, text("Default")),
308 bgcolor(Color::Black, text("Black")),
309 bgcolor(Color::GrayDark, text("GrayDark")),
310 bgcolor(Color::GrayLight, text("GrayLight")),
311 bgcolor(Color::White, text("White")),
312 bgcolor(Color::Blue, text("Blue")),
313 bgcolor(Color::BlueLight, text("BlueLight")),
314 bgcolor(Color::Cyan, text("Cyan")),
315 bgcolor(Color::CyanLight, text("CyanLight")),
316 bgcolor(Color::Green, text("Green")),
317 bgcolor(Color::GreenLight, text("GreenLight")),
318 bgcolor(Color::Magenta, text("Magenta")),
319 bgcolor(Color::MagentaLight, text("MagentaLight")),
320 bgcolor(Color::Red, text("Red")),
321 bgcolor(Color::RedLight, text("RedLight")),
322 bgcolor(Color::Yellow, text("Yellow")),
323 bgcolor(Color::YellowLight, text("YellowLight")),
324 }),
325 }),
326 }) |
327 border;
328
329 auto palette_256_color_display = text("256 colors palette:");
330 {
331 std::vector<std::vector<ColorInfo>> info_columns = ColorInfoSorted2D();
332 Elements columns;
333 for (auto& column : info_columns) {
334 Elements column_elements;
335 for (auto& it : column) {
336 column_elements.push_back(
337 text(" ") | bgcolor(Color(Color::Palette256(it.index_256))));
338 }
339 columns.push_back(hbox(std::move(column_elements)));
340 }
341 palette_256_color_display = vbox({
342 palette_256_color_display,
343 separator(),
344 vbox(columns),
345 }) |
346 border;
347 }
348
349 // トゥルーカラー表示。
350 auto true_color_display = text("TrueColors: 24bits:");
351 {
352 int saturation = 255;
353 Elements array;
354 for (int value = 0; value < 255; value += 16) {
355 Elements line;
356 for (int hue = 0; hue < 255; hue += 6) {
357 line.push_back(text("▀") //
358 | color(Color::HSV(hue, saturation, value)) //
359 | bgcolor(Color::HSV(hue, saturation, value + 8)));
360 }
361 array.push_back(hbox(std::move(line)));
362 }
363 true_color_display = vbox({
364 true_color_display,
365 separator(),
366 vbox(std::move(array)),
367 }) |
368 border;
369 }
370
371 return flexbox(
372 {
373 basic_color_display,
374 palette_256_color_display,
375 true_color_display,
376 },
377 FlexboxConfig().SetGap(1, 1));
378 });
379
380 // ---------------------------------------------------------------------------
381 // ゲージ
382 // ---------------------------------------------------------------------------
383 auto render_gauge = [&shift](int delta) {
384 float progress = (shift + delta) % 500 / 500.f;
385 return hbox({
386 text(std::to_string(int(progress * 100)) + "% ") |
387 size(WIDTH, EQUAL, 5),
388 gauge(progress),
389 });
390 };
391
392 auto gauge_component = Renderer([render_gauge] {
393 return vbox({
394 render_gauge(0) | color(Color::Black),
395 render_gauge(100) | color(Color::GrayDark),
396 render_gauge(50) | color(Color::GrayLight),
397 render_gauge(6894) | color(Color::White),
398 separator(),
399 render_gauge(6841) | color(Color::Blue),
400 render_gauge(9813) | color(Color::BlueLight),
401 render_gauge(98765) | color(Color::Cyan),
402 render_gauge(98) | color(Color::CyanLight),
403 render_gauge(9846) | color(Color::Green),
404 render_gauge(1122) | color(Color::GreenLight),
405 render_gauge(84) | color(Color::Magenta),
406 render_gauge(645) | color(Color::MagentaLight),
407 render_gauge(568) | color(Color::Red),
408 render_gauge(2222) | color(Color::RedLight),
409 render_gauge(220) | color(Color::Yellow),
410 render_gauge(348) | color(Color::YellowLight),
411 });
412 });
413
414 // ---------------------------------------------------------------------------
415 // 段落
416 // ---------------------------------------------------------------------------
417 auto make_box = [](size_t dimx, size_t dimy) {
418 std::string title = std::to_string(dimx) + "x" + std::to_string(dimy);
419 return window(text(title) | hcenter | bold,
420 text("content") | hcenter | dim) |
421 size(WIDTH, EQUAL, dimx) | size(HEIGHT, EQUAL, dimy);
422 };
423
424 auto paragraph_renderer_left = Renderer([&] {
425 std::string str =
426 "Lorem Ipsum is simply dummy text of the printing and typesetting "
427 "industry.\nLorem Ipsum has been the industry's standard dummy text "
428 "ever since the 1500s, when an unknown printer took a galley of type "
429 "and scrambled it to make a type specimen book.";
430 return vbox({
431 window(text("Align left:"), paragraphAlignLeft(str)),
432 window(text("Align center:"), paragraphAlignCenter(str)),
433 window(text("Align right:"), paragraphAlignRight(str)),
434 window(text("Align justify:"), paragraphAlignJustify(str)),
435 window(text("Side by side"), hbox({
436 paragraph(str),
437 separator(),
438 paragraph(str),
439 })),
440 window(text("Elements with different size:"),
441 flexbox({
442 make_box(10, 5),
443 make_box(9, 4),
444 make_box(8, 4),
445 make_box(6, 3),
446 make_box(10, 5),
447 make_box(9, 4),
448 make_box(8, 4),
449 make_box(6, 3),
450 make_box(10, 5),
451 make_box(9, 4),
452 make_box(8, 4),
453 make_box(6, 3),
454 })),
455 }) |
456 vscroll_indicator | yframe | flex;
457 });
458
459 auto paragraph_renderer_right = Renderer([] {
460 return paragraph("<--- This vertical bar is resizable using the mouse") |
461 center;
462 });
463
464 int paragraph_renderer_split_position = Terminal::Size().dimx / 2;
465 auto paragraph_renderer_group =
466 ResizableSplitLeft(paragraph_renderer_left, paragraph_renderer_right,
467 &paragraph_renderer_split_position);
468 auto paragraph_renderer_group_renderer =
469 Renderer(paragraph_renderer_group,
470 [&] { return paragraph_renderer_group->Render(); });
471
472 // ---------------------------------------------------------------------------
473 // タブ
474 // ---------------------------------------------------------------------------
475
476 int tab_index = 0;
477 std::vector<std::string> tab_entries = {
478 "htop", "color", "spinner", "gauge", "compiler", "paragraph",
479 };
480 auto tab_selection =
481 Menu(&tab_entries, &tab_index, MenuOption::HorizontalAnimated());
482 auto tab_content = Container::Tab(
483 {
484 htop,
485 color_tab_renderer,
486 spinner_tab_renderer,
487 gauge_component,
488 compiler_renderer,
489 paragraph_renderer_group_renderer,
490 },
491 &tab_index);
492
493 auto exit_button =
494 Button("Exit", [&] { screen.Exit(); }, ButtonOption::Animated());
495
496 auto main_container = Container::Vertical({
497 Container::Horizontal({
498 tab_selection,
499 exit_button,
500 }),
501 tab_content,
502 });
503
504 auto main_renderer = Renderer(main_container, [&] {
505 return vbox({
506 text("FTXUI Demo") | bold | hcenter,
507 hbox({
508 tab_selection->Render() | flex,
509 exit_button->Render(),
510 }),
511 tab_content->Render() | flex,
512 });
513 });
514
515 Loop loop(&screen, main_renderer);
516 while (!loop.HasQuitted()) {
517 // アプリケーションの状態を更新します。
518 // 新しいフレームの描画をリクエストします。
519 // イベントを実行し、次のフレームを描画します。
520 // フレームレート(60 FPS)を制御するために短い間スリープします。
521 }
522
523 return 0;
524}
std::vector< std::vector< ftxui::ColorInfo > > ColorInfoSorted2D()
Element make_box(int x, int y)
static ButtonOption Animated()
アニメーションカラーを使用するButtonOptionを作成します。
Element Render()
コンポーネントを描画します。 このftxui::ComponentBaseを表すftxui::Screen上に描画されるftxui::Elementを構築します。レンダリングを変更するにはOnRende...
static ScreenInteractive Fullscreen()
static MenuOption HorizontalAnimated()
アニメーション付き水平メニューの標準オプション。 これはタブバーの実装に役立ちます。
Loopは、コンポーネントのイベントループを管理するクラスです。
Definition loop.hpp:53
Component Menu(MenuOption options)
テキストのリスト。フォーカスされた要素が選択されます。
Component Radiobox(RadioboxOption options)
1つだけ選択できる要素のリスト。
Component Button(ButtonOption options)
Draw a button. Execute a function when clicked. (ja: ボタンを描画します。クリックされたときに機能を実行します。)
Component Renderer(Component child, std::function< Element()>)
|child|に似ていますが、|render|をComponentRender()イベントとして使用する新しいコンポーネントを返します。
Component Checkbox(CheckboxOption options)
チェック可能な要素を描画します。
Component ResizableSplitLeft(Component main, Component back, int *main_size)
2つのコンポーネント間の水平分割。マウスで設定可能。
Inputコンポーネントのオプション。
virtual void Render(Screen &screen)
要素をftxui::Screenに表示します。
Definition node.cpp:59
FlexboxConfig & SetGap(int gap_x, int gap_y)
フレックスボックスのギャップを設定します。
Decorator bgcolor(Color)
背景色を使用して装飾します。
Element flex(Element)
子要素をコンテナに残されたスペースに比例して拡大させます。
Definition flex.cpp:120
Element paragraphAlignRight(const std::string &text)
段落を複数行にわたって右揃えで描画する要素を返します。
Element spinner(int charset_index, size_t image_index)
時間やイベントの効果を表現するのに便利です。これはアスキーアートの「ビデオ」を表示します。
Element center(Element)
要素を水平方向および垂直方向に中央揃えします。
Element paragraphAlignCenter(const std::string &text)
段落を複数行にわたって中央揃えで描画する要素を返します。
Element text(std::wstring text)
ユニコードテキストを表示します。
Definition text.cpp:160
Element flex_grow(Element)
可能であれば拡大します。
Definition flex.cpp:138
Element paragraphAlignLeft(const std::string &text)
段落を複数行にわたって左揃えで描画する要素を返します。
Element filler()
コンテナに残されたスペースに比例して拡大する要素。
Definition flex.cpp:96
Element gauge(float progress)
高精細プログレスバーを描画します。
Element paragraphAlignJustify(const std::string &text)
段落を複数行にわたって両端揃えで描画する要素を返します。 中央に。
Decorator color(Color)
前景色を使用して装飾します。
Element hcenter(Element)
要素を水平方向に中央揃えします。
Element vbox(Elements)
要素を縦に一つずつ表示するコンテナ。
Definition vbox.cpp:94
FlexboxConfigは、flexboxコンテナのレイアウトプロパティを定義する構成構造体です。
static Color HSV(uint8_t hue, uint8_t saturation, uint8_t value)
HSV表現から色を構築します。 https://en.wikipedia.org/wiki/HSL_and_HSV.
Colorは、ターミナルユーザーインターフェースにおける色を表すクラスです。
Definition color.hpp:25
int main()
FTXUI ftxui:: 名前空間
Definition animation.hpp:9
Element flexbox(Elements, FlexboxConfig config=FlexboxConfig())
行/列に要素を表示し、一杯になると次の列/行に折り返すことができるコンテナ。
Definition flexbox.cpp:250
Element hflow(Elements)
要素を左から右へ行で表示するコンテナ。一杯になると、下の新しい行から開始します。
Definition flexbox.cpp:267
Element hbox(Elements)
要素を水平方向に1つずつ表示するコンテナ。
Definition hbox.cpp:93
std::vector< Element > Elements
Definition elements.hpp:22
Element window(Element title, Element content, BorderStyle border=ROUNDED)
Component Input(InputOption options={})
Element separator()
Elements paragraph(std::wstring text)
@ LESS_THAN
Definition elements.hpp:157
@ GREATER_THAN
Definition elements.hpp:157
Element graph(GraphFunction)
GraphFunctionを使用してグラフを描画します。
std::shared_ptr< ComponentBase > Component
return size
Definition string.cpp:1516