FTXUI 7.1.0
C++ functional terminal UI.
Loading...
Searching...
No Matches
app.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_APP_HPP
5#define FTXUI_COMPONENT_APP_HPP
6
7#include <atomic> // for atomic
8#include <chrono> // for steady_clock, time_point
9#include <functional> // for function
10#include <memory> // for shared_ptr, unique_ptr
11#include <string> // for string, basic_string, allocator
12#include <vector> // for vector
13
14#include "ftxui/component/animation.hpp" // for TimePoint
16#include "ftxui/component/task.hpp" // for Task, Closure
17#include "ftxui/screen/screen.hpp" // for Screen
18#include "ftxui/screen/terminal.hpp" // for Dimensions
19#include "ftxui/util/export.hpp"
20
21namespace ftxui {
22class ComponentBase;
23using Component = std::shared_ptr<ComponentBase>;
24class Node;
25using Element = std::shared_ptr<Node>;
26struct Event;
27class Selection;
28class TaskRunner;
29
30/// @brief App is a class that manages the application lifecycle.
31/// It is responsible for initializing the terminal, running the main loop,
32/// and cleaning up on exit.
33///
34/// @note This class was previously named ScreenInteractive.
35///
36/// @ingroup component
37class FTXUI_EXPORT(COMPONENT) App : public Screen {
38 public:
39 // Constructors:
40
41 /// @brief Create an App with a fixed size.
42 /// @param dimx The width of the app.
43 /// @param dimy The height of the app.
44 static App FixedSize(int dimx, int dimy);
45
46 /// @brief Create an App taking the full terminal size. This is using the
47 /// alternate screen buffer to avoid messing with the terminal content.
48 /// @note This is the same as `App::FullscreenAlternateScreen()`
49 static App Fullscreen();
50
51 /// @brief Create an App taking the full terminal size. The primary screen
52 /// buffer is being used. It means if the terminal is resized, the previous
53 /// content might mess up with the terminal content.
54 static App FullscreenPrimaryScreen();
55
56 /// @brief Create an App taking the full terminal size. This is using the
57 /// alternate screen buffer to avoid messing with the terminal content.
58 static App FullscreenAlternateScreen();
59
60 /// @brief Create an App whose width and height match the component being
61 /// drawn.
62 static App FitComponent();
63
64 /// @brief Create an App whose width match the terminal output width and
65 /// the height matches the component being drawn.
66 static App TerminalOutput();
67
68 // Destructor.
69 ~App() override;
70
71 App(App&&) noexcept;
72 App& operator=(App&&) noexcept;
73 App(const App&) = delete;
74 App& operator=(const App&) = delete;
75
76 // Options. Must be called before Loop().
77
78 /// @brief Set whether mouse is tracked and events reported.
79 /// @param enable Whether to enable mouse event tracking.
80 /// @note Mouse tracking is enabled by default.
81 /// @note Mouse tracking is only supported on terminals that supports it.
82 /// @note This must be called before calling `App::Loop`.
83 void TrackMouse(bool enable = true);
84
85 /// @brief Enable or disable automatic piped input handling.
86 /// When enabled, FTXUI will detect piped input and redirect stdin from
87 /// /dev/tty for keyboard input, allowing applications to read piped data
88 /// while still receiving interactive keyboard events.
89 /// @param enable Whether to enable piped input handling. Default is true.
90 /// @note This must be called before Loop().
91 /// @note This feature is enabled by default.
92 /// @note This feature is only available on POSIX systems (Linux/macOS).
93 void HandlePipedInput(bool enable = true);
94
95 /// @brief Return the currently active app, nullptr if none.
96 static App* Active();
97
98 // Start/Stop the main loop.
99
100 /// @brief Execute the main loop.
101 /// @param component The component to draw.
102 void Loop(Component component);
103
104 /// @brief Exit the main loop.
105 void Exit();
106
107 /// @brief Return a function to exit the main loop.
108 Closure ExitLoopClosure();
109
110 /// @brief Decorate a function. The outputted one will execute similarly to
111 /// the inputted one, but with the currently active app terminal hooks
112 /// temporarily uninstalled.
113 Closure WithRestoredIO(Closure fn);
114
115 /// @brief FTXUI implements handlers for Ctrl-C and Ctrl-Z. By default, these
116 /// handlers are executed, even if the component catches the event. This avoid
117 /// users handling every event to be trapped in the application. However, in
118 /// some cases, the application may want to handle these events itself. In
119 /// this case, the application can force FTXUI to not handle these events by
120 /// calling the following functions with force=true.
121 void ForceHandleCtrlC(bool force = true);
122
123 /// @brief Force FTXUI to handle or not handle Ctrl-Z, even if the component
124 /// catches the Event::CtrlZ.
125 void ForceHandleCtrlZ(bool force = true);
126
127 // Post tasks to be executed by the loop.
128
129 /// @brief Add a task to the main loop.
130 /// It will be executed later, after every other scheduled tasks.
131 void Post(Task task);
132
133 /// @brief Add an event to the main loop.
134 /// It will be executed later, after every other scheduled events.
135 void PostEvent(Event event);
136
137 /// @brief Add a task to the main loop.
138 /// It will be executed later, after every other scheduled tasks.
139 static void PostEventOrExecute(Closure closure);
140
141 /// @brief Add a task to draw the screen one more time, until all the
142 /// animations are done.
143 void RequestAnimationFrame();
144
145 /// @brief Print an element above the app. It is printed once, and becomes
146 /// part of the terminal scrollback. The app keeps being drawn below.
147 /// @param element The element to print. Its width is the terminal width.
148 /// @note This is meant for apps not using the alternate screen, such as
149 /// `App::TerminalOutput()`.
150 void PrintAbove(Element element);
151
152 // Selection API:
153
154 /// @brief Try to get the unique lock about being able to capture the mouse.
155 /// @return A unique lock if the mouse is not already captured, otherwise a
156 /// null.
157 CapturedMouse CaptureMouse();
158
159 /// @brief Returns the content of the current selection.
160 std::string GetSelection();
161
162 /// @brief Set a callback that will be called when the selection changes.
163 void SelectionChange(std::function<void()> callback);
164
165 // Terminal info.
166
167 /// @brief Return the terminal name.
168 const std::string& TerminalName() const;
169
170 /// @brief Return the terminal version.
171 int TerminalVersion() const;
172
173 /// @brief Return the terminal emulator name.
174 const std::string& TerminalEmulatorName() const;
175
176 /// @brief Return the terminal emulator version.
177 const std::string& TerminalEmulatorVersion() const;
178
179 /// @brief Return the terminal capabilities.
180 const std::vector<int>& TerminalCapabilities() const;
181
182 /// @brief Return the names of the terminal capabilities.
183 std::vector<std::string> TerminalCapabilityNames() const;
184
185 private:
186 void ExitNow();
187 void Install();
188 void Uninstall();
189
190 void PreMain();
191 void PostMain();
192
193 /// @brief Return whether the main loop has been quit.
194 bool HasQuitted();
195 void RunOnce(const Component& component);
196 void RunOnceBlocking(Component component);
197
198 void HandleTask(Component component, Task& task);
199 bool HandleSelection(bool handled, Event event);
200 void Draw(Component component);
201 std::string ResetCursorPosition();
202
203 void RequestCursorPosition(bool force = false);
204
205 void TerminalSend(std::string_view);
206 void TerminalFlush();
207
208 void InstallPipedInputHandling();
209 void InstallTerminalInfo();
210
211 void Signal(int signal);
212
213 size_t FetchTerminalEvents();
214
215 void PostAnimationTask();
216
217 struct Internal;
218 explicit App(std::unique_ptr<Internal> internal, int dimx, int dimy);
219
220 std::unique_ptr<Internal> internal_;
221
222 friend class Loop;
223
224 public:
225 class Private {
226 public:
227 static void Signal(App& s, int signal) { s.Signal(signal); }
228 };
229 friend Private;
230};
231
232} // namespace ftxui
233
234#endif /* end of include guard: FTXUI_COMPONENT_APP_HPP */
The FTXUI ftxui:: namespace.
Definition animation.hpp:11
std::unique_ptr< CapturedMouseInterface > CapturedMouse
std::shared_ptr< Node > Element
Definition app.hpp:25
std::variant< Event, Closure, AnimationTask > Task
Definition task.hpp:14
std::function< void()> Closure
Definition task.hpp:13
std::shared_ptr< ComponentBase > Component
Definition app.hpp:23