mirror of
				https://github.com/ArthurSonzogni/FTXUI.git
				synced 2025-10-31 18:48:11 +08:00 
			
		
		
		
	Feature: the Modal component. (#418)
				
					
				
			This commit is contained in:
		| @@ -25,6 +25,7 @@ example(menu_multiple) | ||||
| example(menu_style) | ||||
| example(menu_underline_animated_gallery) | ||||
| example(modal_dialog) | ||||
| example(modal_dialog_custom) | ||||
| example(nested_screen) | ||||
| example(print_key_press) | ||||
| example(radiobox) | ||||
|   | ||||
| @@ -1,94 +1,83 @@ | ||||
| #include <memory>  // for allocator, shared_ptr, __shared_ptr_access | ||||
| #include <string>  // for string, basic_string, char_traits, operator+ | ||||
| #include <vector>  // for vector | ||||
| #include <ftxui/component/component_options.hpp>  // for ButtonOption | ||||
| #include <functional>                             // for function | ||||
| #include <memory>                                 // for allocator, shared_ptr | ||||
|  | ||||
| #include "ftxui/component/captured_mouse.hpp"  // for ftxui | ||||
| #include "ftxui/component/component.hpp"  // for Button, Renderer, Horizontal, Tab | ||||
| #include "ftxui/component/component_base.hpp"      // for ComponentBase | ||||
| #include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive | ||||
| #include "ftxui/dom/elements.hpp"  // for operator|, Element, filler, text, hbox, separator, center, vbox, bold, border, clear_under, dbox, size, GREATER_THAN, HEIGHT | ||||
| #include "ftxui/component/component.hpp"  // for Button, operator|=, Renderer, Vertical, Modal | ||||
| #include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive, Component | ||||
| #include "ftxui/dom/elements.hpp"  // for operator|, separator, text, size, Element, vbox, border, GREATER_THAN, WIDTH, center, HEIGHT | ||||
|  | ||||
| using namespace ftxui; | ||||
|  | ||||
| auto button_style = ButtonOption::Animated(); | ||||
|  | ||||
| // Definition of the main component. The details are not important. | ||||
| Component MainComponent(std::function<void()> show_modal, | ||||
|                         std::function<void()> exit) { | ||||
|   auto component = Container::Vertical({ | ||||
|       Button("Show modal", show_modal, button_style), | ||||
|       Button("Quit", exit, button_style), | ||||
|   }); | ||||
|   // Polish how the two buttons are rendered: | ||||
|   component |= Renderer([&](Element inner) { | ||||
|     return vbox({ | ||||
|                text("Main component"), | ||||
|                separator(), | ||||
|                inner, | ||||
|            })                                // | ||||
|            | size(WIDTH, GREATER_THAN, 15)   // | ||||
|            | size(HEIGHT, GREATER_THAN, 15)  // | ||||
|            | border                          // | ||||
|            | center;                         // | ||||
|   }); | ||||
|   return component; | ||||
| } | ||||
|  | ||||
| // Definition of the modal component. The details are not important. | ||||
| Component ModalComponent(std::function<void()> do_nothing, | ||||
|                          std::function<void()> hide_modal) { | ||||
|   auto component = Container::Vertical({ | ||||
|       Button("Do nothing", do_nothing, button_style), | ||||
|       Button("Quit modal", hide_modal, button_style), | ||||
|   }); | ||||
|   // Polish how the two buttons are rendered: | ||||
|   component |= Renderer([&](Element inner) { | ||||
|     return vbox({ | ||||
|                text("Modal component "), | ||||
|                separator(), | ||||
|                inner, | ||||
|            })                               // | ||||
|            | size(WIDTH, GREATER_THAN, 30)  // | ||||
|            | border;                        // | ||||
|   }); | ||||
|   return component; | ||||
| } | ||||
|  | ||||
| int main(int argc, const char* argv[]) { | ||||
|   using namespace ftxui; | ||||
|   auto screen = ScreenInteractive::TerminalOutput(); | ||||
|  | ||||
|   // There are two layers. One at depth = 0 and the modal window at depth = 1; | ||||
|   int depth = 0; | ||||
|   // State of the application: | ||||
|   bool modal_shown = false; | ||||
|  | ||||
|   // The current rating of FTXUI. | ||||
|   std::string rating = "3/5 stars"; | ||||
|   // Some actions modifying the state: | ||||
|   auto show_modal = [&] { modal_shown = true; }; | ||||
|   auto hide_modal = [&] { modal_shown = false; }; | ||||
|   auto exit = screen.ExitLoopClosure(); | ||||
|   auto do_nothing = [&] {}; | ||||
|  | ||||
|   // At depth=0, two buttons. One for rating FTXUI and one for quitting. | ||||
|   auto button_rate_ftxui = Button("Rate FTXUI", [&] { depth = 1; }); | ||||
|   auto button_quit = Button("Quit", screen.ExitLoopClosure()); | ||||
|   // Instanciate the main and modal components: | ||||
|   auto main_component = MainComponent(show_modal, exit); | ||||
|   auto modal_component = ModalComponent(do_nothing, hide_modal); | ||||
|  | ||||
|   auto depth_0_container = Container::Horizontal({ | ||||
|       button_rate_ftxui, | ||||
|       button_quit, | ||||
|   }); | ||||
|   auto depth_0_renderer = Renderer(depth_0_container, [&] { | ||||
|     return vbox({ | ||||
|                text("Modal dialog example"), | ||||
|                separator(), | ||||
|                text("☆☆☆ FTXUI:" + rating + " ☆☆☆") | bold, | ||||
|                filler(), | ||||
|                hbox({ | ||||
|                    button_rate_ftxui->Render(), | ||||
|                    filler(), | ||||
|                    button_quit->Render(), | ||||
|                }), | ||||
|            }) | | ||||
|            border | size(HEIGHT, GREATER_THAN, 18) | center; | ||||
|   }); | ||||
|   // Use the `Modal` function to use together the main component and its modal | ||||
|   // window. The |modal_shown| boolean controls whether the modal is shown or | ||||
|   // not. | ||||
|   main_component |= Modal(modal_component, &modal_shown); | ||||
|  | ||||
|   // At depth=1, The "modal" window. | ||||
|   std::vector<std::string> rating_labels = { | ||||
|       "1/5 stars", "2/5 stars", "3/5 stars", "4/5 stars", "5/5 stars", | ||||
|   }; | ||||
|   auto on_rating = [&](std::string new_rating) { | ||||
|     rating = new_rating; | ||||
|     depth = 0; | ||||
|   }; | ||||
|   auto depth_1_container = Container::Horizontal({ | ||||
|       Button(&rating_labels[0], [&] { on_rating(rating_labels[0]); }), | ||||
|       Button(&rating_labels[1], [&] { on_rating(rating_labels[1]); }), | ||||
|       Button(&rating_labels[2], [&] { on_rating(rating_labels[2]); }), | ||||
|       Button(&rating_labels[3], [&] { on_rating(rating_labels[3]); }), | ||||
|       Button(&rating_labels[4], [&] { on_rating(rating_labels[4]); }), | ||||
|   }); | ||||
|  | ||||
|   auto depth_1_renderer = Renderer(depth_1_container, [&] { | ||||
|     return vbox({ | ||||
|                text("Do you like FTXUI?"), | ||||
|                separator(), | ||||
|                hbox(depth_1_container->Render()), | ||||
|            }) | | ||||
|            border; | ||||
|   }); | ||||
|  | ||||
|   auto main_container = Container::Tab( | ||||
|       { | ||||
|           depth_0_renderer, | ||||
|           depth_1_renderer, | ||||
|       }, | ||||
|       &depth); | ||||
|  | ||||
|   auto main_renderer = Renderer(main_container, [&] { | ||||
|     Element document = depth_0_renderer->Render(); | ||||
|  | ||||
|     if (depth == 1) { | ||||
|       document = dbox({ | ||||
|           document, | ||||
|           depth_1_renderer->Render() | clear_under | center, | ||||
|       }); | ||||
|     } | ||||
|     return document; | ||||
|   }); | ||||
|  | ||||
|   screen.Loop(main_renderer); | ||||
|   screen.Loop(main_component); | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| // Copyright 2020 Arthur Sonzogni. All rights reserved. | ||||
| // Copyright 2022 Arthur Sonzogni. All rights reserved. | ||||
| // Use of this source code is governed by the MIT license that can be found in | ||||
| // the LICENSE file. | ||||
|   | ||||
							
								
								
									
										94
									
								
								examples/component/modal_dialog_custom.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								examples/component/modal_dialog_custom.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | ||||
| #include <memory>  // for allocator, shared_ptr, __shared_ptr_access | ||||
| #include <string>  // for string, basic_string, char_traits, operator+ | ||||
| #include <vector>  // for vector | ||||
|  | ||||
| #include "ftxui/component/captured_mouse.hpp"  // for ftxui | ||||
| #include "ftxui/component/component.hpp"  // for Button, Renderer, Horizontal, Tab | ||||
| #include "ftxui/component/component_base.hpp"      // for ComponentBase | ||||
| #include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive | ||||
| #include "ftxui/dom/elements.hpp"  // for operator|, Element, filler, text, hbox, separator, center, vbox, bold, border, clear_under, dbox, size, GREATER_THAN, HEIGHT | ||||
|  | ||||
| int main(int argc, const char* argv[]) { | ||||
|   using namespace ftxui; | ||||
|   auto screen = ScreenInteractive::TerminalOutput(); | ||||
|  | ||||
|   // There are two layers. One at depth = 0 and the modal window at depth = 1; | ||||
|   int depth = 0; | ||||
|  | ||||
|   // The current rating of FTXUI. | ||||
|   std::string rating = "3/5 stars"; | ||||
|  | ||||
|   // At depth=0, two buttons. One for rating FTXUI and one for quitting. | ||||
|   auto button_rate_ftxui = Button("Rate FTXUI", [&] { depth = 1; }); | ||||
|   auto button_quit = Button("Quit", screen.ExitLoopClosure()); | ||||
|  | ||||
|   auto depth_0_container = Container::Horizontal({ | ||||
|       button_rate_ftxui, | ||||
|       button_quit, | ||||
|   }); | ||||
|   auto depth_0_renderer = Renderer(depth_0_container, [&] { | ||||
|     return vbox({ | ||||
|                text("Modal dialog example"), | ||||
|                separator(), | ||||
|                text("☆☆☆ FTXUI:" + rating + " ☆☆☆") | bold, | ||||
|                filler(), | ||||
|                hbox({ | ||||
|                    button_rate_ftxui->Render(), | ||||
|                    filler(), | ||||
|                    button_quit->Render(), | ||||
|                }), | ||||
|            }) | | ||||
|            border | size(HEIGHT, GREATER_THAN, 18) | center; | ||||
|   }); | ||||
|  | ||||
|   // At depth=1, The "modal" window. | ||||
|   std::vector<std::string> rating_labels = { | ||||
|       "1/5 stars", "2/5 stars", "3/5 stars", "4/5 stars", "5/5 stars", | ||||
|   }; | ||||
|   auto on_rating = [&](std::string new_rating) { | ||||
|     rating = new_rating; | ||||
|     depth = 0; | ||||
|   }; | ||||
|   auto depth_1_container = Container::Horizontal({ | ||||
|       Button(&rating_labels[0], [&] { on_rating(rating_labels[0]); }), | ||||
|       Button(&rating_labels[1], [&] { on_rating(rating_labels[1]); }), | ||||
|       Button(&rating_labels[2], [&] { on_rating(rating_labels[2]); }), | ||||
|       Button(&rating_labels[3], [&] { on_rating(rating_labels[3]); }), | ||||
|       Button(&rating_labels[4], [&] { on_rating(rating_labels[4]); }), | ||||
|   }); | ||||
|  | ||||
|   auto depth_1_renderer = Renderer(depth_1_container, [&] { | ||||
|     return vbox({ | ||||
|                text("Do you like FTXUI?"), | ||||
|                separator(), | ||||
|                hbox(depth_1_container->Render()), | ||||
|            }) | | ||||
|            border; | ||||
|   }); | ||||
|  | ||||
|   auto main_container = Container::Tab( | ||||
|       { | ||||
|           depth_0_renderer, | ||||
|           depth_1_renderer, | ||||
|       }, | ||||
|       &depth); | ||||
|  | ||||
|   auto main_renderer = Renderer(main_container, [&] { | ||||
|     Element document = depth_0_renderer->Render(); | ||||
|  | ||||
|     if (depth == 1) { | ||||
|       document = dbox({ | ||||
|           document, | ||||
|           depth_1_renderer->Render() | clear_under | center, | ||||
|       }); | ||||
|     } | ||||
|     return document; | ||||
|   }); | ||||
|  | ||||
|   screen.Loop(main_renderer); | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| // 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
	 Arthur Sonzogni
					Arthur Sonzogni