FTXUI 6.1.9
C++ functional terminal UI.
Loading...
Searching...
No Matches
screen_interactive.hpp
Go to the documentation of this file.
1// Copyright 2020 Arthur Sonzogni. All rights reserved.
2// Use of this source code is governed by the MIT license that can be found in
3// the LICENSE file.
4#ifndef FTXUI_COMPONENT_SCREEN_INTERACTIVE_HPP
5#define FTXUI_COMPONENT_SCREEN_INTERACTIVE_HPP
6
7#include <atomic> // for atomic
8#include <functional> // for function
9#include <memory> // for shared_ptr
10#include <string> // for string
11
12#include "ftxui/component/animation.hpp" // for TimePoint
13#include "ftxui/component/captured_mouse.hpp" // for CapturedMouse
14#include "ftxui/component/event.hpp" // for Event
15#include "ftxui/component/task.hpp" // for Task, Closure
16#include "ftxui/dom/selection.hpp" // for SelectionOption
17#include "ftxui/screen/screen.hpp" // for Screen
18
19namespace ftxui {
20class ComponentBase;
21class Loop;
22struct Event;
23
24using Component = std::shared_ptr<ComponentBase>;
25class ScreenInteractivePrivate;
26
27namespace task {
28class TaskRunner;
29}
30
31/// @brief ScreenInteractive is a `Screen` that can handle events, run a main
32/// loop, and manage components.
33///
34/// @ingroup component
35class ScreenInteractive : public Screen {
36 public:
37 // Constructors:
38 static ScreenInteractive FixedSize(int dimx, int dimy);
44
45 // Destructor.
47
48 // Options. Must be called before Loop().
49 void TrackMouse(bool enable = true);
50 void HandlePipedInput(bool enable = true);
51
52 // Return the currently active screen, nullptr if none.
53 static ScreenInteractive* Active();
54
55 // Start/Stop the main loop.
56 void Loop(Component);
57 void Exit();
59
60 // Post tasks to be executed by the loop.
61 void Post(Task task);
62 void PostEvent(Event event);
64
66
67 // Decorate a function. The outputted one will execute similarly to the
68 // inputted one, but with the currently active screen terminal hooks
69 // temporarily uninstalled.
71
72 // FTXUI implements handlers for Ctrl-C and Ctrl-Z. By default, these handlers
73 // are executed, even if the component catches the event. This avoid users
74 // handling every event to be trapped in the application. However, in some
75 // cases, the application may want to handle these events itself. In this
76 // case, the application can force FTXUI to not handle these events by calling
77 // the following functions with force=true.
78 void ForceHandleCtrlC(bool force);
79 void ForceHandleCtrlZ(bool force);
80
81 // Selection API.
82 std::string GetSelection();
83 void SelectionChange(std::function<void()> callback);
84
85 private:
86 void ExitNow();
87
88 void Install();
89 void Uninstall();
90
91 void PreMain();
92 void PostMain();
93
94 bool HasQuitted();
95 void RunOnce(Component component);
96 void RunOnceBlocking(Component component);
97
98 void HandleTask(Component component, Task& task);
99 bool HandleSelection(bool handled, Event event);
100 void RefreshSelection();
101 void Draw(Component component);
102 void ResetCursorPosition();
103
104 void InstallPipedInputHandling();
105
106 void Signal(int signal);
107
108 void FetchTerminalEvents();
109
110 void PostAnimationTask();
111
112 ScreenInteractive* suspended_screen_ = nullptr;
113 enum class Dimension {
115 Fixed,
118 };
120 int dimx,
121 int dimy,
122 bool use_alternative_screen);
123
124 const Dimension dimension_;
125 const bool use_alternative_screen_;
126
127 bool track_mouse_ = true;
128
129 std::string set_cursor_position;
130 std::string reset_cursor_position;
131
132 std::atomic<bool> quit_{false};
133 bool animation_requested_ = false;
134 animation::TimePoint previous_animation_time_;
135
136 int cursor_x_ = 1;
137 int cursor_y_ = 1;
138
139 std::uint64_t frame_count_ = 0;
140 bool mouse_captured = false;
141 bool previous_frame_resized_ = false;
142
143 bool frame_valid_ = false;
144
145 bool force_handle_ctrl_c_ = true;
146 bool force_handle_ctrl_z_ = true;
147
148 // Piped input handling state (POSIX only)
149 bool handle_piped_input_ = true;
150 // File descriptor for /dev/tty, used for piped input handling.
151 int tty_fd_ = -1;
152
153 // The style of the cursor to restore on exit.
154 int cursor_reset_shape_ = 1;
155
156 // Selection API:
157 CapturedMouse selection_pending_;
158 struct SelectionData {
159 int start_x = -1;
160 int start_y = -1;
161 int end_x = -2;
162 int end_y = -2;
163 bool empty = true;
164 bool operator==(const SelectionData& other) const;
165 bool operator!=(const SelectionData& other) const;
166 };
167 SelectionData selection_data_;
168 SelectionData selection_data_previous_;
169 std::unique_ptr<Selection> selection_;
170 std::function<void()> selection_on_change_;
171
172 // PIMPL private implementation idiom (Pimpl).
173 struct Internal;
174 std::unique_ptr<Internal> internal_;
175
176 friend class Loop;
177
178 Component component_;
179
180 public:
181 class Private {
182 public:
183 static void Signal(ScreenInteractive& s, int signal) { s.Signal(signal); }
184 };
185 friend Private;
186};
187
188} // namespace ftxui
189
190#endif /* end of include guard: FTXUI_COMPONENT_SCREEN_INTERACTIVE_HPP */
static void Signal(ScreenInteractive &s, int signal)
static ScreenInteractive TerminalOutput()
void HandlePipedInput(bool enable=true)
Enable or disable automatic piped input handling. When enabled, FTXUI will detect piped input and red...
void Exit()
Exit the main loop.
static ScreenInteractive FixedSize(int dimx, int dimy)
void PostEvent(Event event)
Add an event to the main loop. It will be executed later, after every other scheduled events.
void Post(Task task)
Add a task to the main loop. It will be executed later, after every other scheduled tasks.
static ScreenInteractive FitComponent()
static ScreenInteractive Fullscreen()
static ScreenInteractive FullscreenPrimaryScreen()
static ScreenInteractive * Active()
Return the currently active screen, or null if none.
CapturedMouse CaptureMouse()
Try to get the unique lock about behing able to capture the mouse.
std::string GetSelection()
Returns the content of the current selection.
static ScreenInteractive FullscreenAlternateScreen()
void TrackMouse(bool enable=true)
Set whether mouse is tracked and events reported. called outside of the main loop....
void SelectionChange(std::function< void()> callback)
void RequestAnimationFrame()
Add a task to draw the screen one more time, until all the animations are done.
Closure ExitLoopClosure()
Return a function to exit the main loop.
void ForceHandleCtrlC(bool force)
Force FTXUI to handle or not handle Ctrl-C, even if the component catches the Event::CtrlC.
void ForceHandleCtrlZ(bool force)
Force FTXUI to handle or not handle Ctrl-Z, even if the component catches the Event::CtrlZ.
Closure WithRestoredIO(Closure)
Decorate a function. It executes the same way, but with the currently active screen terminal hooks te...
Loop is a class that manages the event loop for a component.
Definition loop.hpp:56
ScreenInteractive is a Screen that can handle events, run a main loop, and manage components.
Represent an event. It can be key press event, a terminal resize, or more ...
Definition event.hpp:29
int dimy() const
Definition image.hpp:36
int dimx() const
Definition image.hpp:35
A rectangular grid of Pixel.
Definition screen.hpp:26
The FTXUI ftxui::Dimension:: namespace.
std::chrono::time_point< Clock > TimePoint
Definition animation.hpp:29
The FTXUI ftxui:: namespace.
Definition animation.hpp:10
std::unique_ptr< CapturedMouseInterface > CapturedMouse
std::variant< Event, Closure, AnimationTask > Task
Definition task.hpp:14
std::function< void()> Closure
Definition task.hpp:13
std::shared_ptr< ComponentBase > Component