mirror of
				https://github.com/ArthurSonzogni/FTXUI.git
				synced 2025-10-31 10:38:09 +08:00 
			
		
		
		
	Add the Renderer component.
This commit is contained in:
		| @@ -1,43 +1,36 @@ | ||||
| #include <string>  // for operator+, to_wstring, allocator, wstring | ||||
|  | ||||
| #include "ftxui/component/captured_mouse.hpp"      // for ftxui | ||||
| #include "ftxui/component/component.hpp"           // for Button, Make | ||||
| #include "ftxui/component/component_base.hpp"      // for ComponentBase | ||||
| #include "ftxui/component/container.hpp"           // for Container | ||||
| #include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive | ||||
| #include "ftxui/dom/elements.hpp"  // for separator, Element, gauge, text, operator|, vbox, border | ||||
|  | ||||
| using namespace ftxui; | ||||
|  | ||||
| class MyComponent : public ComponentBase { | ||||
|  private: | ||||
|   std::wstring label_add = L"Increase"; | ||||
|   std::wstring label_rm = L"Decrease"; | ||||
|   int value_ = 50; | ||||
| int main(int argc, const char* argv[]) { | ||||
|   int value = 50; | ||||
|   std::wstring label_dec = L"decrease"; | ||||
|   std::wstring label_inc = L"increase"; | ||||
|  | ||||
|  public: | ||||
|   MyComponent() { | ||||
|     Add(Container::Horizontal({ | ||||
|         Button(&label_rm, [&] { value_--; }), | ||||
|         Button(&label_add, [&] { value_++; }), | ||||
|     })); | ||||
|   } | ||||
|   // The tree of components. This defines how to navigate using the keyboard. | ||||
|   auto buttons = Container::Horizontal({ | ||||
|       Button(&label_dec, [&] { value--; }), | ||||
|       Button(&label_inc, [&] { value++; }), | ||||
|   }); | ||||
|  | ||||
|   Element Render() override { | ||||
|   // Modify the way to render them on screen: | ||||
|   auto component = Renderer(buttons, [&] { | ||||
|     return vbox({ | ||||
|                text(L"Value = " + std::to_wstring(value_)), | ||||
|                text(L"value = " + std::to_wstring(value)), | ||||
|                separator(), | ||||
|                gauge(value_ * 0.01f), | ||||
|                gauge(value * 0.01f), | ||||
|                separator(), | ||||
|                ComponentBase::Render(), | ||||
|                buttons->Render(), | ||||
|            }) | | ||||
|            border; | ||||
|   } | ||||
| }; | ||||
|   }); | ||||
|  | ||||
| int main(int argc, const char* argv[]) { | ||||
|   auto screen = ScreenInteractive::FitComponent(); | ||||
|   screen.Loop(Make<MyComponent>()); | ||||
|   screen.Loop(component); | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -6,8 +6,7 @@ | ||||
|  | ||||
| using namespace ftxui; | ||||
|  | ||||
| class MyComponent : public ComponentBase { | ||||
|  private: | ||||
| int main(int argc, const char* argv[]) { | ||||
|   std::wstring build_examples_label = L"Build examples"; | ||||
|   std::wstring build_tests_label = L"Build tests"; | ||||
|   std::wstring use_webassembly_label = L"Use WebAssembly"; | ||||
| @@ -16,19 +15,14 @@ class MyComponent : public ComponentBase { | ||||
|   bool build_tests_state = false; | ||||
|   bool use_webassembly_state = true; | ||||
|  | ||||
|   Component container = Container::Vertical({ | ||||
|   auto component = Container::Vertical({ | ||||
|       Checkbox(&build_examples_label, &build_examples_state), | ||||
|       Checkbox(&build_tests_label, &build_tests_state), | ||||
|       Checkbox(&use_webassembly_label, &use_webassembly_state), | ||||
|   }); | ||||
|  | ||||
|  public: | ||||
|   MyComponent() { Add(container); } | ||||
| }; | ||||
|  | ||||
| int main(int argc, const char* argv[]) { | ||||
|   auto screen = ScreenInteractive::TerminalOutput(); | ||||
|   screen.Loop(Make<MyComponent>()); | ||||
|   screen.Loop(component); | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,9 +1,7 @@ | ||||
| #include <ext/alloc_traits.h>  // for __alloc_traits<>::value_type | ||||
| #include <memory>  // for unique_ptr, make_unique, __shared_ptr_access | ||||
| #include <string>  // for operator+, wstring | ||||
| #include <vector>  // for vector | ||||
|  | ||||
| #include "ftxui/component/captured_mouse.hpp"  // for ftxui | ||||
| #include "ftxui/component/component.hpp"       // for Checkbox, Make | ||||
| #include "ftxui/component/component_base.hpp"  // for ComponentBase | ||||
| #include "ftxui/component/container.hpp"       // for Container | ||||
| @@ -13,49 +11,28 @@ | ||||
|  | ||||
| using namespace ftxui; | ||||
|  | ||||
| struct CheckboxAndState { | ||||
| struct CheckboxState { | ||||
|   std::wstring label; | ||||
|   bool state; | ||||
|   Component component; | ||||
| }; | ||||
|  | ||||
| std::unique_ptr<CheckboxAndState> MakeCheckbox(std::wstring label) { | ||||
|   auto out = std::make_unique<CheckboxAndState>(); | ||||
|   out->label = label; | ||||
|   out->state = false; | ||||
|   out->component = Checkbox(&out->label, &out->state); | ||||
|   return out; | ||||
| } | ||||
|  | ||||
| class MyComponent : public ComponentBase { | ||||
|  public: | ||||
|   MyComponent() { | ||||
|     Add(container); | ||||
|     checkbox.resize(30); | ||||
|     for (int i = 0; i < checkbox.size(); ++i) { | ||||
|       checkbox[i] = MakeCheckbox(L"CheckBox " + to_wstring(i)); | ||||
|       container->Add(checkbox[i]->component); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // clang-format off | ||||
|   Element Render() override { | ||||
|     Elements content; | ||||
|     return vbox(container->Render()) | ||||
|       | frame | ||||
|       | size(HEIGHT, LESS_THAN, 10) | ||||
|       | border; | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   std::vector<std::unique_ptr<CheckboxAndState>> checkbox; | ||||
|   Component container = Container::Vertical(); | ||||
|   bool checked; | ||||
| }; | ||||
|  | ||||
| int main(int argc, const char* argv[]) { | ||||
|   int size = 30; | ||||
|   std::vector<CheckboxState> states(size); | ||||
|   auto container = Container::Vertical({}); | ||||
|   for(int i = 0; i<size; ++i) { | ||||
|     states[i].checked = false; | ||||
|     states[i].label = L"Checkbox " + to_wstring(i); | ||||
|     container->Add(Checkbox(&states[i].label, &states[i].checked)); | ||||
|   } | ||||
|  | ||||
|   auto component = Renderer(container, [&] { | ||||
|     return container->Render() | frame | ftxui::size(HEIGHT, LESS_THAN, 10) | | ||||
|            border; | ||||
|   }); | ||||
|  | ||||
|   auto screen = ScreenInteractive::FitComponent(); | ||||
|   auto my_component = Make<MyComponent>(); | ||||
|   screen.Loop(my_component); | ||||
|   screen.Loop(component); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|   | ||||
| @@ -12,111 +12,117 @@ | ||||
|  | ||||
| using namespace ftxui; | ||||
|  | ||||
| class MyComponent : public ComponentBase { | ||||
|   const std::vector<std::wstring> menu_entries_ = { | ||||
| // Display a component nicely with a title on the left. | ||||
| Component Wrap(std::wstring name, Component component) { | ||||
|   return Renderer(component, [name, component] { | ||||
|     return hbox({ | ||||
|                text(name) | size(WIDTH, EQUAL, 8), | ||||
|                separator(), | ||||
|                component->Render() | xflex, | ||||
|            }) | | ||||
|            xflex; | ||||
|   }); | ||||
| } | ||||
|  | ||||
| int main(int argc, const char* argv[]) { | ||||
|   auto screen = ScreenInteractive::FitComponent(); | ||||
|  | ||||
|   // -- Menu ---------------------------------------------------------------------- | ||||
|   const std::vector<std::wstring> menu_entries = { | ||||
|       L"Menu 1", | ||||
|       L"Menu 2", | ||||
|       L"Menu 3", | ||||
|       L"Menu 4", | ||||
|   }; | ||||
|   int menu_selected_ = 0; | ||||
|   Component menu_ = Menu(&menu_entries_, &menu_selected_); | ||||
|   int menu_selected = 0; | ||||
|   auto menu = Menu(&menu_entries, &menu_selected); | ||||
|   menu = Wrap(L"Menu", menu); | ||||
|  | ||||
|   int toggle_selected_ = 0; | ||||
|   std::vector<std::wstring> toggle_entries_ = { | ||||
|   // -- Toggle------------------------------------------------------------------ | ||||
|   int toggle_selected = 0; | ||||
|   std::vector<std::wstring> toggle_entries = { | ||||
|       L"Toggle_1", | ||||
|       L"Toggle_2", | ||||
|   }; | ||||
|   Component toggle_ = Toggle(&toggle_entries_, &toggle_selected_); | ||||
|   auto toggle = Toggle(&toggle_entries, &toggle_selected); | ||||
|   toggle = Wrap(L"Toggle", toggle); | ||||
|  | ||||
|   std::wstring checkbox_1_label_ = L"checkbox1"; | ||||
|   std::wstring checkbox_2_label_ = L"checkbox2"; | ||||
|   bool checkbox_1_selected_ = false; | ||||
|   bool checkbox_2_selected_ = false; | ||||
|   // -- Checkbox --------------------------------------------------------------- | ||||
|   std::wstring checkbox_1_label = L"checkbox1"; | ||||
|   std::wstring checkbox_2_label = L"checkbox2"; | ||||
|   bool checkbox_1_selected = false; | ||||
|   bool checkbox_2_selected = false; | ||||
|  | ||||
|   Component checkbox_container_ = Container::Vertical({ | ||||
|       Checkbox(&checkbox_1_label_, &checkbox_1_selected_), | ||||
|       Checkbox(&checkbox_2_label_, &checkbox_2_selected_), | ||||
|   auto checkboxes = Container::Vertical({ | ||||
|       Checkbox(&checkbox_1_label, &checkbox_1_selected), | ||||
|       Checkbox(&checkbox_2_label, &checkbox_2_selected), | ||||
|   }); | ||||
|   checkboxes = Wrap(L"Checkbox", checkboxes); | ||||
|  | ||||
|   int radiobox_selected_ = 0; | ||||
|   std::vector<std::wstring> radiobox_entries_ = { | ||||
|   // -- Radiobox --------------------------------------------------------------- | ||||
|   int radiobox_selected = 0; | ||||
|   std::vector<std::wstring> radiobox_entries = { | ||||
|       L"Radiobox 1", | ||||
|       L"Radiobox 2", | ||||
|       L"Radiobox 3", | ||||
|       L"Radiobox 4", | ||||
|   }; | ||||
|   Component radiobox_ = Radiobox(&radiobox_entries_, &radiobox_selected_); | ||||
|   auto radiobox = Radiobox(&radiobox_entries, &radiobox_selected); | ||||
|   radiobox = Wrap(L"Radiobox", radiobox); | ||||
|  | ||||
|   std::wstring input_label_; | ||||
|   std::wstring input_placeholder_ = L"input"; | ||||
|   Component input_ = Input(&input_label_, &input_placeholder_); | ||||
|   // -- Input ------------------------------------------------------------------ | ||||
|   std::wstring input_label; | ||||
|   std::wstring input_placeholder = L"input"; | ||||
|   auto input = Input(&input_label, &input_placeholder); | ||||
|   input = Wrap(L"Input", input); | ||||
|  | ||||
|   std::wstring button_label_ = L"Quit"; | ||||
|   // -- Button ----------------------------------------------------------------- | ||||
|   std::wstring button_label = L"Quit"; | ||||
|   std::function<void()> on_button_clicked_; | ||||
|   Component button_ = Button(&button_label_, [this] { on_button_clicked_(); }); | ||||
|   auto button = Button(&button_label, screen.ExitLoopClosure()); | ||||
|   button = Wrap(L"Button", button); | ||||
|  | ||||
|   int slider_value_1_ = 12; | ||||
|   int slider_value_2_ = 56; | ||||
|   int slider_value_3_ = 128; | ||||
|   Component slider_container_ = Container::Vertical({ | ||||
|       Slider(L"R:", &slider_value_1_, 0, 256, 1), | ||||
|       Slider(L"G:", &slider_value_2_, 0, 256, 1), | ||||
|       Slider(L"B:", &slider_value_3_, 0, 256, 1), | ||||
|   // -- Slider ----------------------------------------------------------------- | ||||
|   int slider_value_1 = 12; | ||||
|   int slider_value_2 = 56; | ||||
|   int slider_value_3 = 128; | ||||
|   auto sliders = Container::Vertical({ | ||||
|       Slider(L"R:", &slider_value_1, 0, 256, 1), | ||||
|       Slider(L"G:", &slider_value_2, 0, 256, 1), | ||||
|       Slider(L"B:", &slider_value_3, 0, 256, 1), | ||||
|   }); | ||||
|   sliders = Wrap(L"Slider", sliders); | ||||
|  | ||||
|   // -- Layout ----------------------------------------------------------------- | ||||
|   auto layout = Container::Vertical({ | ||||
|       menu, | ||||
|       toggle, | ||||
|       checkboxes, | ||||
|       radiobox, | ||||
|       input, | ||||
|       sliders, | ||||
|       button, | ||||
|   }); | ||||
|  | ||||
|  public: | ||||
|   MyComponent(std::function<void(void)> on_quit) : on_quit_(on_quit) { | ||||
|     Add(Container::Vertical({ | ||||
|         menu_, | ||||
|         toggle_, | ||||
|         checkbox_container_, | ||||
|         radiobox_, | ||||
|         input_, | ||||
|         slider_container_, | ||||
|         button_, | ||||
|     })); | ||||
|   } | ||||
|  | ||||
|   Element Render(std::wstring name, Element element) { | ||||
|     return hbox({ | ||||
|                text(name) | size(WIDTH, EQUAL, 8), | ||||
|   auto component = Renderer(layout, [&] { | ||||
|     return vbox({ | ||||
|                menu->Render(), | ||||
|                separator(), | ||||
|                element | xflex, | ||||
|                toggle->Render(), | ||||
|                separator(), | ||||
|                checkboxes->Render(), | ||||
|                separator(), | ||||
|                radiobox->Render(), | ||||
|                separator(), | ||||
|                input->Render(), | ||||
|                separator(), | ||||
|                sliders->Render(), | ||||
|                separator(), | ||||
|                button->Render(), | ||||
|            }) | | ||||
|            xflex; | ||||
|   } | ||||
|            xflex | size(WIDTH, GREATER_THAN, 40) | border; | ||||
|   }); | ||||
|  | ||||
|   Element Render(std::wstring name, Component& component) { | ||||
|     return Render(name, component->Render()); | ||||
|   } | ||||
|  | ||||
|   Element Render() override { | ||||
|     return  // | ||||
|         vbox({ | ||||
|             Render(L"menu", menu_), | ||||
|             separator(), | ||||
|             Render(L"toggle", toggle_), | ||||
|             separator(), | ||||
|             Render(L"checkbox", checkbox_container_), | ||||
|             separator(), | ||||
|             Render(L"radiobox", radiobox_), | ||||
|             separator(), | ||||
|             Render(L"input", input_) | size(WIDTH, LESS_THAN, 50), | ||||
|             separator(), | ||||
|             Render(L"slider", slider_container_), | ||||
|             separator(), | ||||
|             Render(L"button", button_), | ||||
|         }) | | ||||
|         xflex | size(WIDTH, GREATER_THAN, 40) | border; | ||||
|   } | ||||
|  | ||||
|   std::function<void()> on_quit_; | ||||
| }; | ||||
|  | ||||
| int main(int argc, const char* argv[]) { | ||||
|   auto screen = ScreenInteractive::FitComponent(); | ||||
|   auto component = Make<MyComponent>(screen.ExitLoopClosure()); | ||||
|   screen.Loop(component); | ||||
|  | ||||
|   return 0; | ||||
|   | ||||
| @@ -20,32 +20,32 @@ | ||||
|  | ||||
| using namespace ftxui; | ||||
|  | ||||
| int shift = 0; | ||||
| class Graph { | ||||
|  public: | ||||
|   std::vector<int> operator()(int width, int height) { | ||||
|     std::vector<int> output(width); | ||||
|     for (int i = 0; i < width; ++i) { | ||||
|       float v = 0; | ||||
|       v += 0.1f * sin((i + shift) * 0.1f); | ||||
|       v += 0.2f * sin((i + shift + 10) * 0.15f); | ||||
|       v += 0.1f * sin((i + shift) * 0.03f); | ||||
|       v *= height; | ||||
|       v += 0.5f * height; | ||||
|       output[i] = (int)v; | ||||
| int main(int argc, const char* argv[]) { | ||||
|   auto screen = ScreenInteractive::Fullscreen(); | ||||
|  | ||||
|   int shift = 0; | ||||
|  | ||||
|   class Graph { | ||||
|    public: | ||||
|     Graph(int* shift) : shift_(shift) {} | ||||
|     std::vector<int> operator()(int width, int height) { | ||||
|       std::vector<int> output(width); | ||||
|       for (int i = 0; i < width; ++i) { | ||||
|         float v = 0; | ||||
|         v += 0.1f * sin((i + *shift_) * 0.1f); | ||||
|         v += 0.2f * sin((i + *shift_ + 10) * 0.15f); | ||||
|         v += 0.1f * sin((i + *shift_) * 0.03f); | ||||
|         v *= height; | ||||
|         v += 0.5f * height; | ||||
|         output[i] = (int)v; | ||||
|       } | ||||
|       return output; | ||||
|     } | ||||
|     return output; | ||||
|   } | ||||
| }; | ||||
|     int* shift_; | ||||
|   }; | ||||
|  | ||||
| class HTopComponent : public ComponentBase { | ||||
|   Graph my_graph; | ||||
|  | ||||
|  public: | ||||
|   HTopComponent() {} | ||||
|   ~HTopComponent() override {} | ||||
|  | ||||
|   Element Render() override { | ||||
|   Graph my_graph(&shift); | ||||
|   auto htop = Renderer([&] { | ||||
|     auto frequency = vbox({ | ||||
|         text(L"Frequency [Mhz]") | hcenter, | ||||
|         hbox({ | ||||
| @@ -98,52 +98,50 @@ class HTopComponent : public ComponentBase { | ||||
|                ram | flex, | ||||
|            }) | | ||||
|            flex | border; | ||||
|   } | ||||
| }; | ||||
|   }); | ||||
|  | ||||
| const std::vector<std::wstring> compiler_entries = { | ||||
|     L"gcc", | ||||
|     L"clang", | ||||
|     L"emcc", | ||||
|     L"game_maker", | ||||
|     L"Ada compilers", | ||||
|     L"ALGOL 60 compilers", | ||||
|     L"ALGOL 68 compilers", | ||||
|     L"Assemblers (Intel *86)", | ||||
|     L"Assemblers (Motorola 68*)", | ||||
|     L"Assemblers (Zilog Z80)", | ||||
|     L"Assemblers (other)", | ||||
|     L"BASIC Compilers", | ||||
|     L"BASIC interpreters", | ||||
|     L"Batch compilers", | ||||
|     L"C compilers", | ||||
|     L"Source-to-source compilers", | ||||
|     L"C++ compilers", | ||||
|     L"C# compilers", | ||||
|     L"COBOL compilers", | ||||
|     L"Common Lisp compilers", | ||||
|     L"D compilers", | ||||
|     L"DIBOL/DBL compilers", | ||||
|     L"ECMAScript interpreters", | ||||
|     L"Eiffel compilers", | ||||
|     L"Fortran compilers", | ||||
|     L"Go compilers", | ||||
|     L"Haskell compilers", | ||||
|     L"Java compilers", | ||||
|     L"Pascal compilers", | ||||
|     L"Perl Interpreters", | ||||
|     L"PHP compilers", | ||||
|     L"PL/I compilers", | ||||
|     L"Python compilers", | ||||
|     L"Scheme compilers and interpreters", | ||||
|     L"Smalltalk compilers", | ||||
|     L"Tcl Interpreters", | ||||
|     L"VMS Interpreters", | ||||
|     L"Rexx Interpreters", | ||||
|     L"CLI compilers", | ||||
| }; | ||||
|   const std::vector<std::wstring> compiler_entries = { | ||||
|       L"gcc", | ||||
|       L"clang", | ||||
|       L"emcc", | ||||
|       L"game_maker", | ||||
|       L"Ada compilers", | ||||
|       L"ALGOL 60 compilers", | ||||
|       L"ALGOL 68 compilers", | ||||
|       L"Assemblers (Intel *86)", | ||||
|       L"Assemblers (Motorola 68*)", | ||||
|       L"Assemblers (Zilog Z80)", | ||||
|       L"Assemblers (other)", | ||||
|       L"BASIC Compilers", | ||||
|       L"BASIC interpreters", | ||||
|       L"Batch compilers", | ||||
|       L"C compilers", | ||||
|       L"Source-to-source compilers", | ||||
|       L"C++ compilers", | ||||
|       L"C# compilers", | ||||
|       L"COBOL compilers", | ||||
|       L"Common Lisp compilers", | ||||
|       L"D compilers", | ||||
|       L"DIBOL/DBL compilers", | ||||
|       L"ECMAScript interpreters", | ||||
|       L"Eiffel compilers", | ||||
|       L"Fortran compilers", | ||||
|       L"Go compilers", | ||||
|       L"Haskell compilers", | ||||
|       L"Java compilers", | ||||
|       L"Pascal compilers", | ||||
|       L"Perl Interpreters", | ||||
|       L"PHP compilers", | ||||
|       L"PL/I compilers", | ||||
|       L"Python compilers", | ||||
|       L"Scheme compilers and interpreters", | ||||
|       L"Smalltalk compilers", | ||||
|       L"Tcl Interpreters", | ||||
|       L"VMS Interpreters", | ||||
|       L"Rexx Interpreters", | ||||
|       L"CLI compilers", | ||||
|   }; | ||||
|  | ||||
| class CompilerComponent : public ComponentBase { | ||||
|   int compiler_selected = 0; | ||||
|   Component compiler = Radiobox(&compiler_entries, &compiler_selected); | ||||
|  | ||||
| @@ -178,28 +176,48 @@ class CompilerComponent : public ComponentBase { | ||||
|       Checkbox(&options_label[3], &options_state[3]), | ||||
|   }); | ||||
|  | ||||
|  public: | ||||
|   ~CompilerComponent() override {} | ||||
|   CompilerComponent() { | ||||
|     Add(Container::Horizontal({ | ||||
|         compiler, | ||||
|         flags, | ||||
|         Container::Vertical({ | ||||
|             executable_, | ||||
|             Container::Horizontal({ | ||||
|                 input_add, | ||||
|                 input, | ||||
|             }), | ||||
|         }), | ||||
|     })); | ||||
|   auto compiler_component = Container::Horizontal({ | ||||
|       compiler, | ||||
|       flags, | ||||
|       Container::Vertical({ | ||||
|           executable_, | ||||
|           Container::Horizontal({ | ||||
|               input_add, | ||||
|               input, | ||||
|           }), | ||||
|       }), | ||||
|   }); | ||||
|  | ||||
|     InputBase::From(input_add)->on_enter = [this] { | ||||
|       input_entries.push_back(input_add_content); | ||||
|       input_add_content = L""; | ||||
|     }; | ||||
|   } | ||||
|   InputBase::From(input_add)->on_enter = [&] { | ||||
|     input_entries.push_back(input_add_content); | ||||
|     input_add_content = L""; | ||||
|   }; | ||||
|  | ||||
|   Element Render() override { | ||||
|   auto render_command = [&] { | ||||
|     Elements line; | ||||
|     // Compiler | ||||
|     line.push_back(text(compiler_entries[compiler_selected]) | bold); | ||||
|     // flags | ||||
|     for (int i = 0; i < 4; ++i) { | ||||
|       if (options_state[i]) { | ||||
|         line.push_back(text(L" ")); | ||||
|         line.push_back(text(options_label[i]) | dim); | ||||
|       } | ||||
|     } | ||||
|     // Executable | ||||
|     if (!executable_content_.empty()) { | ||||
|       line.push_back(text(L" -O ") | bold); | ||||
|       line.push_back(text(executable_content_) | color(Color::BlueLight) | | ||||
|                      bold); | ||||
|     } | ||||
|     // Input | ||||
|     for (auto& it : input_entries) { | ||||
|       line.push_back(text(L" " + it) | color(Color::RedLight)); | ||||
|     } | ||||
|     return line; | ||||
|   }; | ||||
|  | ||||
|   auto compiler_renderer = Renderer(compiler_component, [&] { | ||||
|     auto compiler_win = window(text(L"Compiler"), compiler->Render() | frame); | ||||
|     auto flags_win = window(text(L"Flags"), flags->Render()); | ||||
|     auto executable_win = window(text(L"Executable:"), executable_->Render()); | ||||
| @@ -227,50 +245,21 @@ class CompilerComponent : public ComponentBase { | ||||
|                    }), | ||||
|                    filler(), | ||||
|                }), | ||||
|                hflow(RenderCommandLine()) | flex_grow, | ||||
|                hflow(render_command()) | flex_grow, | ||||
|            }) | | ||||
|            flex_grow | border; | ||||
|   } | ||||
|   }); | ||||
|  | ||||
|   Elements RenderCommandLine() { | ||||
|     Elements line; | ||||
|     // Compiler | ||||
|     line.push_back(text(compiler_entries[compiler_selected]) | bold); | ||||
|     // flags | ||||
|     for (int i = 0; i < 4; ++i) { | ||||
|       if (options_state[i]) { | ||||
|         line.push_back(text(L" ")); | ||||
|         line.push_back(text(options_label[i]) | dim); | ||||
|       } | ||||
|     } | ||||
|     // Executable | ||||
|     if (!executable_content_.empty()) { | ||||
|       line.push_back(text(L" -O ") | bold); | ||||
|       line.push_back(text(executable_content_) | color(Color::BlueLight) | | ||||
|                      bold); | ||||
|     } | ||||
|     // Input | ||||
|     for (auto& it : input_entries) { | ||||
|       line.push_back(text(L" " + it) | color(Color::RedLight)); | ||||
|     } | ||||
|     return line; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| class SpinnerComponent : public ComponentBase { | ||||
|   Element Render() override { | ||||
|   auto spinner_tab_renderer = Renderer([&] { | ||||
|     Elements entries; | ||||
|     for (int i = 0; i < 22; ++i) { | ||||
|       if (i != 0) | ||||
|         entries.push_back(spinner(i, shift / 2) | bold | | ||||
|                           size(WIDTH, GREATER_THAN, 2) | border); | ||||
|       entries.push_back(spinner(i, shift / 2) | bold | | ||||
|                         size(WIDTH, GREATER_THAN, 2) | border); | ||||
|     } | ||||
|     return hflow(std::move(entries)) | border; | ||||
|   } | ||||
| }; | ||||
|   }); | ||||
|  | ||||
| class ColorComponent : public ComponentBase { | ||||
|   Element Render() override { | ||||
|   auto color_tab_renderer = Renderer([] { | ||||
|     return hbox({ | ||||
|                vbox({ | ||||
|                    color(Color::Default, text(L"Default")), | ||||
| @@ -312,79 +301,67 @@ class ColorComponent : public ComponentBase { | ||||
|                }), | ||||
|            }) | | ||||
|            hcenter | border; | ||||
|   } | ||||
| }; | ||||
|   }); | ||||
|  | ||||
| class GaugeComponent : public ComponentBase { | ||||
|   Element RenderGauge(int delta) { | ||||
|   auto render_gauge = [&shift](int delta) { | ||||
|     float progress = (shift + delta) % 1000 / 1000.f; | ||||
|     return hbox({ | ||||
|         text(std::to_wstring(int(progress * 100)) + L"% ") | | ||||
|             size(WIDTH, EQUAL, 5), | ||||
|         gauge(progress), | ||||
|     }); | ||||
|   } | ||||
|   Element Render() override { | ||||
|   }; | ||||
|  | ||||
|   auto gauge_component = Renderer([render_gauge] { | ||||
|     return vbox({ | ||||
|                RenderGauge(0) | color(Color::Black), | ||||
|                RenderGauge(100) | color(Color::GrayDark), | ||||
|                RenderGauge(50) | color(Color::GrayLight), | ||||
|                RenderGauge(6894) | color(Color::White), | ||||
|                render_gauge(0) | color(Color::Black), | ||||
|                render_gauge(100) | color(Color::GrayDark), | ||||
|                render_gauge(50) | color(Color::GrayLight), | ||||
|                render_gauge(6894) | color(Color::White), | ||||
|                separator(), | ||||
|                RenderGauge(6841) | color(Color::Blue), | ||||
|                RenderGauge(9813) | color(Color::BlueLight), | ||||
|                RenderGauge(98765) | color(Color::Cyan), | ||||
|                RenderGauge(98) | color(Color::CyanLight), | ||||
|                RenderGauge(9846) | color(Color::Green), | ||||
|                RenderGauge(1122) | color(Color::GreenLight), | ||||
|                RenderGauge(84) | color(Color::Magenta), | ||||
|                RenderGauge(645) | color(Color::MagentaLight), | ||||
|                RenderGauge(568) | color(Color::Red), | ||||
|                RenderGauge(2222) | color(Color::RedLight), | ||||
|                RenderGauge(220) | color(Color::Yellow), | ||||
|                RenderGauge(348) | color(Color::YellowLight), | ||||
|                render_gauge(6841) | color(Color::Blue), | ||||
|                render_gauge(9813) | color(Color::BlueLight), | ||||
|                render_gauge(98765) | color(Color::Cyan), | ||||
|                render_gauge(98) | color(Color::CyanLight), | ||||
|                render_gauge(9846) | color(Color::Green), | ||||
|                render_gauge(1122) | color(Color::GreenLight), | ||||
|                render_gauge(84) | color(Color::Magenta), | ||||
|                render_gauge(645) | color(Color::MagentaLight), | ||||
|                render_gauge(568) | color(Color::Red), | ||||
|                render_gauge(2222) | color(Color::RedLight), | ||||
|                render_gauge(220) | color(Color::Yellow), | ||||
|                render_gauge(348) | color(Color::YellowLight), | ||||
|            }) | | ||||
|            border; | ||||
|   }; | ||||
| }; | ||||
|   }); | ||||
|  | ||||
| class Tab : public ComponentBase { | ||||
|  public: | ||||
|   int tab_index = 0; | ||||
|   std::vector<std::wstring> tab_entries = { | ||||
|       L"htop", L"color", L"spinner", L"gauge", L"compiler", | ||||
|   }; | ||||
|   Component tab_selection = Toggle(&tab_entries, &tab_index); | ||||
|   Component container = | ||||
|       Container::Tab(&tab_index, | ||||
|                      { | ||||
|                          std::make_shared<HTopComponent>(), | ||||
|                          std::make_shared<ColorComponent>(), | ||||
|                          std::make_shared<SpinnerComponent>(), | ||||
|                          std::make_shared<GaugeComponent>(), | ||||
|                          std::make_shared<CompilerComponent>(), | ||||
|                      }); | ||||
|   auto tab_selection = Toggle(&tab_entries, &tab_index); | ||||
|   auto tab_content = Container::Tab(&tab_index, { | ||||
|                                                     htop, | ||||
|                                                     color_tab_renderer, | ||||
|                                                     spinner_tab_renderer, | ||||
|                                                     gauge_component, | ||||
|                                                     compiler_renderer, | ||||
|                                                 }); | ||||
|  | ||||
|   Component main_container = Container::Vertical({ | ||||
|   auto main_container = Container::Vertical({ | ||||
|       tab_selection, | ||||
|       container, | ||||
|       tab_content, | ||||
|   }); | ||||
|  | ||||
|   Tab() { Add(main_container); } | ||||
|  | ||||
|   Element Render() override { | ||||
|   auto main_renderer = Renderer(main_container, [&] { | ||||
|     return vbox({ | ||||
|         text(L"FTXUI Demo") | bold | hcenter, | ||||
|         tab_selection->Render() | hcenter, | ||||
|         container->Render() | flex, | ||||
|         tab_content->Render() | flex, | ||||
|     }); | ||||
|   } | ||||
| }; | ||||
|   }); | ||||
|  | ||||
| int main(int argc, const char* argv[]) { | ||||
|   auto screen = ScreenInteractive::Fullscreen(); | ||||
|  | ||||
|   std::thread update([&screen]() { | ||||
|   std::thread update([&screen, &shift]() { | ||||
|     for (;;) { | ||||
|       using namespace std::chrono_literals; | ||||
|       std::this_thread::sleep_for(0.05s); | ||||
| @@ -393,8 +370,7 @@ int main(int argc, const char* argv[]) { | ||||
|     } | ||||
|   }); | ||||
|  | ||||
|   Component tab = std::make_shared<Tab>(); | ||||
|   screen.Loop(tab); | ||||
|   screen.Loop(main_renderer); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|   | ||||
							
								
								
									
										83
									
								
								examples/component/slider_rgb.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								examples/component/slider_rgb.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| #include <functional>  // for function | ||||
| #include <memory>      // for allocator, __shared_ptr_access | ||||
| #include <string>      // for operator+, to_wstring, char_traits | ||||
|  | ||||
| #include "ftxui/component/captured_mouse.hpp"  // for ftxui | ||||
| #include "ftxui/component/component.hpp"       // for Slider, Make | ||||
| #include "ftxui/component/component_base.hpp"  // for ComponentBase | ||||
| #include "ftxui/component/container.hpp"       // for Container | ||||
| #include "ftxui/component/event.hpp"  // for Event, Event::Escape, Event::Return | ||||
| #include "ftxui/component/screen_interactive.hpp"  // for Component, ScreenInteractive | ||||
| #include "ftxui/dom/elements.hpp"  // for separator, operator|, Element, size, text, vbox, xflex, bgcolor, hbox, GREATER_THAN, WIDTH, border, HEIGHT, LESS_THAN | ||||
| #include "ftxui/screen/color.hpp"  // for Color | ||||
|  | ||||
| using namespace ftxui; | ||||
|  | ||||
| Element ColorTile(int red, int green, int blue) { | ||||
|   return text(L"") | size(WIDTH, GREATER_THAN, 14) | | ||||
|          size(HEIGHT, GREATER_THAN, 7) | bgcolor(Color::RGB(red, green, blue)); | ||||
| } | ||||
|  | ||||
| Element ColorString(int red, int green, int blue) { | ||||
|   return text(L"RGB = (" +                     // | ||||
|               std::to_wstring(red) + L"," +    // | ||||
|               std::to_wstring(green) + L"," +  // | ||||
|               std::to_wstring(blue) + L")"     // | ||||
|   ); | ||||
| } | ||||
|  | ||||
| class MyComponent : public ComponentBase { | ||||
|  private: | ||||
|   int* red_; | ||||
|   int* green_; | ||||
|   int* blue_; | ||||
|   Component slider_red_ = Slider(L"Red  :", red_, 0, 255, 1); | ||||
|   Component slider_green_ = Slider(L"Green:", green_, 0, 255, 1); | ||||
|   Component slider_blue_ = Slider(L"Blue :", blue_, 0, 255, 1); | ||||
|   std::function<void(void)> quit_; | ||||
|  | ||||
|  public: | ||||
|   MyComponent(int* red, int* green, int* blue, std::function<void(void)> quit) | ||||
|       : red_(red), green_(green), blue_(blue), quit_(quit) { | ||||
|     Add(Container::Vertical({ | ||||
|         slider_red_, | ||||
|         slider_green_, | ||||
|         slider_blue_, | ||||
|     })); | ||||
|   } | ||||
|  | ||||
|   Element Render() { | ||||
|     return hbox({ | ||||
|                ColorTile(*red_, *green_, *blue_), | ||||
|                separator(), | ||||
|                vbox({ | ||||
|                    slider_red_->Render(), | ||||
|                    separator(), | ||||
|                    slider_green_->Render(), | ||||
|                    separator(), | ||||
|                    slider_blue_->Render(), | ||||
|                    separator(), | ||||
|                    ColorString(*red_, *green_, *blue_), | ||||
|                }) | xflex, | ||||
|            }) | | ||||
|            border | size(WIDTH, LESS_THAN, 80); | ||||
|   } | ||||
|  | ||||
|   bool OnEvent(Event event) { | ||||
|     if (event == Event::Return || event == Event::Escape) | ||||
|       quit_(); | ||||
|     return ComponentBase::OnEvent(event); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| int main(int argc, const char* argv[]) { | ||||
|   auto screen = ScreenInteractive::TerminalOutput(); | ||||
|   int red = 128; | ||||
|   int green = 25; | ||||
|   int blue = 100; | ||||
|   screen.Loop(Make<MyComponent>(&red, &green, &blue, screen.ExitLoopClosure())); | ||||
| } | ||||
|  | ||||
| // Copyright 2020 Arthur Sonzogni. All rights reserved. | ||||
| // Use of this source code is governed by the MIT license that can be found in | ||||
| // the LICENSE file. | ||||
		Reference in New Issue
	
	Block a user
	 ArthurSonzogni
					ArthurSonzogni