| 
									
										
										
										
											2023-08-19 13:56:36 +02:00
										 |  |  | // 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.
 | 
					
						
							| 
									
										
										
										
											2019-01-06 17:10:35 +01:00
										 |  |  | #ifndef FTXUI_COMPONENT_SCREEN_INTERACTIVE_HPP
 | 
					
						
							|  |  |  | #define FTXUI_COMPONENT_SCREEN_INTERACTIVE_HPP
 | 
					
						
							| 
									
										
										
										
											2018-10-09 19:06:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-17 11:18:25 +02:00
										 |  |  | #include <atomic>      // for atomic
 | 
					
						
							|  |  |  | #include <functional>  // for function
 | 
					
						
							|  |  |  | #include <memory>      // for shared_ptr
 | 
					
						
							|  |  |  | #include <string>      // for string
 | 
					
						
							| 
									
										
										
										
											2019-01-27 02:33:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-13 18:51:46 +01:00
										 |  |  | #include "ftxui/component/animation.hpp"       // for TimePoint
 | 
					
						
							| 
									
										
										
										
											2021-05-01 20:40:35 +02:00
										 |  |  | #include "ftxui/component/captured_mouse.hpp"  // for CapturedMouse
 | 
					
						
							| 
									
										
										
										
											2021-07-17 15:32:08 +05:30
										 |  |  | #include "ftxui/component/event.hpp"           // for Event
 | 
					
						
							| 
									
										
										
										
											2022-10-18 21:29:27 +02:00
										 |  |  | #include "ftxui/component/task.hpp"            // for Task, Closure
 | 
					
						
							| 
									
										
										
										
											2024-12-27 15:45:13 +07:00
										 |  |  | #include "ftxui/dom/selection.hpp"             // for SelectionOption
 | 
					
						
							| 
									
										
										
										
											2021-07-17 15:32:08 +05:30
										 |  |  | #include "ftxui/screen/screen.hpp"             // for Screen
 | 
					
						
							| 
									
										
										
										
											2018-10-09 19:06:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 15:00:08 +01:00
										 |  |  | namespace ftxui { | 
					
						
							| 
									
										
										
										
											2021-05-09 20:32:27 +02:00
										 |  |  | class ComponentBase; | 
					
						
							| 
									
										
										
										
											2022-10-18 21:29:27 +02:00
										 |  |  | class Loop; | 
					
						
							| 
									
										
										
										
											2021-07-17 15:32:08 +05:30
										 |  |  | struct Event; | 
					
						
							| 
									
										
										
										
											2021-05-09 20:32:27 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | using Component = std::shared_ptr<ComponentBase>; | 
					
						
							| 
									
										
										
										
											2022-02-13 11:11:34 +01:00
										 |  |  | class ScreenInteractivePrivate; | 
					
						
							| 
									
										
										
										
											2018-10-09 19:06:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-16 18:40:50 +02:00
										 |  |  | namespace task { | 
					
						
							| 
									
										
										
										
											2025-08-17 11:18:25 +02:00
										 |  |  | class TaskRunner; | 
					
						
							| 
									
										
										
										
											2025-08-16 18:40:50 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-05 11:35:14 +02:00
										 |  |  | /// @brief ScreenInteractive is a `Screen` that can handle events, run a main
 | 
					
						
							|  |  |  | /// loop, and manage components.
 | 
					
						
							|  |  |  | ///
 | 
					
						
							|  |  |  | /// @ingroup component
 | 
					
						
							| 
									
										
										
										
											2019-01-12 18:24:46 +01:00
										 |  |  | class ScreenInteractive : public Screen { | 
					
						
							| 
									
										
										
										
											2020-03-23 21:26:00 +01:00
										 |  |  |  public: | 
					
						
							| 
									
										
										
										
											2022-03-13 18:51:46 +01:00
										 |  |  |   // Constructors:
 | 
					
						
							| 
									
										
										
										
											2020-03-23 21:26:00 +01:00
										 |  |  |   static ScreenInteractive FixedSize(int dimx, int dimy); | 
					
						
							|  |  |  |   static ScreenInteractive Fullscreen(); | 
					
						
							| 
									
										
										
										
											2023-11-11 17:57:07 +01:00
										 |  |  |   static ScreenInteractive FullscreenPrimaryScreen(); | 
					
						
							|  |  |  |   static ScreenInteractive FullscreenAlternateScreen(); | 
					
						
							| 
									
										
										
										
											2020-03-23 21:26:00 +01:00
										 |  |  |   static ScreenInteractive FitComponent(); | 
					
						
							|  |  |  |   static ScreenInteractive TerminalOutput(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-16 18:40:50 +02:00
										 |  |  |   // Destructor.
 | 
					
						
							|  |  |  |   ~ScreenInteractive(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-19 10:57:50 +02:00
										 |  |  |   // Options. Must be called before Loop().
 | 
					
						
							|  |  |  |   void TrackMouse(bool enable = true); | 
					
						
							| 
									
										
										
										
											2025-08-09 20:26:37 -07:00
										 |  |  |   void HandlePipedInput(bool enable = true); | 
					
						
							| 
									
										
										
										
											2023-08-19 10:57:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-13 18:51:46 +01:00
										 |  |  |   // Return the currently active screen, nullptr if none.
 | 
					
						
							|  |  |  |   static ScreenInteractive* Active(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-18 21:29:27 +02:00
										 |  |  |   // Start/Stop the main loop.
 | 
					
						
							| 
									
										
										
										
											2021-05-09 20:32:27 +02:00
										 |  |  |   void Loop(Component); | 
					
						
							| 
									
										
										
										
											2022-10-18 21:29:27 +02:00
										 |  |  |   void Exit(); | 
					
						
							| 
									
										
										
										
											2022-02-13 11:11:34 +01:00
										 |  |  |   Closure ExitLoopClosure(); | 
					
						
							| 
									
										
										
										
											2020-03-23 21:26:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-18 21:29:27 +02:00
										 |  |  |   // Post tasks to be executed by the loop.
 | 
					
						
							| 
									
										
										
										
											2022-02-13 11:11:34 +01:00
										 |  |  |   void Post(Task task); | 
					
						
							| 
									
										
										
										
											2020-03-23 21:26:00 +01:00
										 |  |  |   void PostEvent(Event event); | 
					
						
							| 
									
										
										
										
											2022-03-13 18:51:46 +01:00
										 |  |  |   void RequestAnimationFrame(); | 
					
						
							| 
									
										
										
										
											2022-02-13 11:11:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-01 18:13:56 +02:00
										 |  |  |   CapturedMouse CaptureMouse(); | 
					
						
							| 
									
										
										
										
											2020-03-23 21:26:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-19 16:38:39 +04:00
										 |  |  |   // Decorate a function. The outputted one will execute similarly to the
 | 
					
						
							|  |  |  |   // inputted one, but with the currently active screen terminal hooks
 | 
					
						
							|  |  |  |   // temporarily uninstalled.
 | 
					
						
							| 
									
										
										
										
											2022-02-13 11:11:34 +01:00
										 |  |  |   Closure WithRestoredIO(Closure); | 
					
						
							| 
									
										
										
										
											2022-01-19 16:38:39 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-28 15:17:54 +02:00
										 |  |  |   // FTXUI implements handlers for Ctrl-C and Ctrl-Z. By default, these handlers
 | 
					
						
							|  |  |  |   // are executed, even if the component catches the event. This avoid users
 | 
					
						
							|  |  |  |   // handling every event to be trapped in the application. However, in some
 | 
					
						
							|  |  |  |   // cases, the application may want to handle these events itself. In this
 | 
					
						
							|  |  |  |   // case, the application can force FTXUI to not handle these events by calling
 | 
					
						
							|  |  |  |   // the following functions with force=true.
 | 
					
						
							|  |  |  |   void ForceHandleCtrlC(bool force); | 
					
						
							|  |  |  |   void ForceHandleCtrlZ(bool force); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-27 15:45:13 +07:00
										 |  |  |   // Selection API.
 | 
					
						
							|  |  |  |   std::string GetSelection(); | 
					
						
							|  |  |  |   void SelectionChange(std::function<void()> callback); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-23 21:26:00 +01:00
										 |  |  |  private: | 
					
						
							| 
									
										
										
										
											2022-12-01 16:56:35 -05:00
										 |  |  |   void ExitNow(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-01 17:47:48 +02:00
										 |  |  |   void Install(); | 
					
						
							|  |  |  |   void Uninstall(); | 
					
						
							| 
									
										
										
										
											2022-01-19 16:38:39 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-18 21:29:27 +02:00
										 |  |  |   void PreMain(); | 
					
						
							|  |  |  |   void PostMain(); | 
					
						
							| 
									
										
										
										
											2021-09-01 17:47:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-18 21:29:27 +02:00
										 |  |  |   bool HasQuitted(); | 
					
						
							|  |  |  |   void RunOnce(Component component); | 
					
						
							|  |  |  |   void RunOnceBlocking(Component component); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void HandleTask(Component component, Task& task); | 
					
						
							| 
									
										
										
										
											2024-12-27 15:45:13 +07:00
										 |  |  |   bool HandleSelection(bool handled, Event event); | 
					
						
							|  |  |  |   void RefreshSelection(); | 
					
						
							| 
									
										
										
										
											2021-05-09 20:32:27 +02:00
										 |  |  |   void Draw(Component component); | 
					
						
							| 
									
										
										
										
											2022-12-01 16:56:35 -05:00
										 |  |  |   void ResetCursorPosition(); | 
					
						
							| 
									
										
										
										
											2022-10-18 21:29:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-01 16:56:35 -05:00
										 |  |  |   void Signal(int signal); | 
					
						
							| 
									
										
										
										
											2020-03-23 21:26:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-16 18:40:50 +02:00
										 |  |  |   void FetchTerminalEvents(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void PostAnimationTask(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-13 11:11:34 +01:00
										 |  |  |   ScreenInteractive* suspended_screen_ = nullptr; | 
					
						
							| 
									
										
										
										
											2020-03-23 21:26:00 +01:00
										 |  |  |   enum class Dimension { | 
					
						
							|  |  |  |     FitComponent, | 
					
						
							|  |  |  |     Fixed, | 
					
						
							|  |  |  |     Fullscreen, | 
					
						
							|  |  |  |     TerminalOutput, | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2025-06-20 21:59:36 +08:00
										 |  |  |   ScreenInteractive(Dimension dimension, | 
					
						
							|  |  |  |                     int dimx, | 
					
						
							| 
									
										
										
										
											2020-05-02 20:39:56 +02:00
										 |  |  |                     int dimy, | 
					
						
							|  |  |  |                     bool use_alternative_screen); | 
					
						
							| 
									
										
										
										
											2025-06-20 21:59:36 +08:00
										 |  |  |   const Dimension dimension_; | 
					
						
							|  |  |  |   const bool use_alternative_screen_; | 
					
						
							| 
									
										
										
										
											2020-03-23 21:26:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-19 13:56:36 +02:00
										 |  |  |   bool track_mouse_ = true; | 
					
						
							| 
									
										
										
										
											2023-08-19 10:57:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-23 21:26:00 +01:00
										 |  |  |   std::string set_cursor_position; | 
					
						
							|  |  |  |   std::string reset_cursor_position; | 
					
						
							| 
									
										
										
										
											2020-03-24 23:26:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-26 15:28:05 +02:00
										 |  |  |   std::atomic<bool> quit_{false}; | 
					
						
							| 
									
										
										
										
											2022-03-26 07:55:52 +01:00
										 |  |  |   bool animation_requested_ = false; | 
					
						
							| 
									
										
										
										
											2022-10-18 21:29:27 +02:00
										 |  |  |   animation::TimePoint previous_animation_time_; | 
					
						
							| 
									
										
										
										
											2021-04-24 18:16:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-04 17:38:31 +02:00
										 |  |  |   int cursor_x_ = 1; | 
					
						
							|  |  |  |   int cursor_y_ = 1; | 
					
						
							| 
									
										
										
										
											2021-05-01 18:13:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-20 21:59:36 +08:00
										 |  |  |   std::uint64_t frame_count_ = 0; | 
					
						
							| 
									
										
										
										
											2021-05-01 18:13:56 +02:00
										 |  |  |   bool mouse_captured = false; | 
					
						
							| 
									
										
										
										
											2022-01-11 23:06:36 +01:00
										 |  |  |   bool previous_frame_resized_ = false; | 
					
						
							| 
									
										
										
										
											2022-02-13 11:11:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-18 21:29:27 +02:00
										 |  |  |   bool frame_valid_ = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-28 15:17:54 +02:00
										 |  |  |   bool force_handle_ctrl_c_ = true; | 
					
						
							|  |  |  |   bool force_handle_ctrl_z_ = true; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-09 20:26:37 -07:00
										 |  |  | #if !defined(_WIN32) && !defined(__EMSCRIPTEN__)
 | 
					
						
							|  |  |  |   // Piped input handling state (POSIX only)
 | 
					
						
							|  |  |  |   bool handle_piped_input_ = false; | 
					
						
							|  |  |  |   bool stdin_was_redirected_ = false; | 
					
						
							|  |  |  |   int original_stdin_fd_ = -1; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-17 10:24:33 +01:00
										 |  |  |   // The style of the cursor to restore on exit.
 | 
					
						
							|  |  |  |   int cursor_reset_shape_ = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-27 15:45:13 +07:00
										 |  |  |   // Selection API:
 | 
					
						
							|  |  |  |   CapturedMouse selection_pending_; | 
					
						
							|  |  |  |   struct SelectionData { | 
					
						
							|  |  |  |     int start_x = -1; | 
					
						
							|  |  |  |     int start_y = -1; | 
					
						
							|  |  |  |     int end_x = -2; | 
					
						
							|  |  |  |     int end_y = -2; | 
					
						
							|  |  |  |     bool empty = true; | 
					
						
							|  |  |  |     bool operator==(const SelectionData& other) const; | 
					
						
							|  |  |  |     bool operator!=(const SelectionData& other) const; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   SelectionData selection_data_; | 
					
						
							|  |  |  |   SelectionData selection_data_previous_; | 
					
						
							|  |  |  |   std::unique_ptr<Selection> selection_; | 
					
						
							|  |  |  |   std::function<void()> selection_on_change_; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-16 18:40:50 +02:00
										 |  |  |   // PIMPL private implementation idiom (Pimpl).
 | 
					
						
							|  |  |  |   struct Internal; | 
					
						
							|  |  |  |   std::unique_ptr<Internal> internal_; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-18 21:29:27 +02:00
										 |  |  |   friend class Loop; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-16 18:40:50 +02:00
										 |  |  |   Component component_; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-13 11:11:34 +01:00
										 |  |  |  public: | 
					
						
							|  |  |  |   class Private { | 
					
						
							|  |  |  |    public: | 
					
						
							| 
									
										
										
										
											2022-12-01 16:56:35 -05:00
										 |  |  |     static void Signal(ScreenInteractive& s, int signal) { s.Signal(signal); } | 
					
						
							| 
									
										
										
										
											2022-02-13 11:11:34 +01:00
										 |  |  |   }; | 
					
						
							|  |  |  |   friend Private; | 
					
						
							| 
									
										
										
										
											2018-10-09 19:06:03 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 15:00:08 +01:00
										 |  |  | }  // namespace ftxui
 | 
					
						
							| 
									
										
										
										
											2018-10-09 19:06:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-06 17:10:35 +01:00
										 |  |  | #endif /* end of include guard: FTXUI_COMPONENT_SCREEN_INTERACTIVE_HPP */
 |