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 <ftxui/component/receiver.hpp> // for Receiver, Sender
9#include <functional> // for function
10#include <memory> // for shared_ptr
11#include <string> // for string
12#include <thread> // for thread
13
14#include "ftxui/component/animation.hpp" // for TimePoint
15#include "ftxui/component/captured_mouse.hpp" // for CapturedMouse
16#include "ftxui/component/event.hpp" // for Event
17#include "ftxui/component/task.hpp" // for Task, Closure
18#include "ftxui/dom/selection.hpp" // for SelectionOption
19#include "ftxui/screen/screen.hpp" // for Screen
20
21namespace ftxui {
22class ComponentBase;
23class Loop;
24struct Event;
25
26using Component = std::shared_ptr<ComponentBase>;
27class ScreenInteractivePrivate;
28
29/// @brief ScreenInteractive is a `Screen` that can handle events, run a main
30/// loop, and manage components.
31///
32/// @ingroup component
33class ScreenInteractive : public Screen {
34 public:
35 // Constructors:
36 static ScreenInteractive FixedSize(int dimx, int dimy);
42
43 // Options. Must be called before Loop().
44 void TrackMouse(bool enable = true);
45
46 // Return the currently active screen, nullptr if none.
47 static ScreenInteractive* Active();
48
49 // Start/Stop the main loop.
50 void Loop(Component);
51 void Exit();
53
54 // Post tasks to be executed by the loop.
55 void Post(Task task);
56 void PostEvent(Event event);
58
60
61 // Decorate a function. The outputted one will execute similarly to the
62 // inputted one, but with the currently active screen terminal hooks
63 // temporarily uninstalled.
65
66 // FTXUI implements handlers for Ctrl-C and Ctrl-Z. By default, these handlers
67 // are executed, even if the component catches the event. This avoid users
68 // handling every event to be trapped in the application. However, in some
69 // cases, the application may want to handle these events itself. In this
70 // case, the application can force FTXUI to not handle these events by calling
71 // the following functions with force=true.
72 void ForceHandleCtrlC(bool force);
73 void ForceHandleCtrlZ(bool force);
74
75 // Selection API.
76 std::string GetSelection();
77 void SelectionChange(std::function<void()> callback);
78
79 private:
80 void ExitNow();
81
82 void Install();
83 void Uninstall();
84
85 void PreMain();
86 void PostMain();
87
88 bool HasQuitted();
89 void RunOnce(Component component);
90 void RunOnceBlocking(Component component);
91
92 void HandleTask(Component component, Task& task);
93 bool HandleSelection(bool handled, Event event);
94 void RefreshSelection();
95 void Draw(Component component);
96 void ResetCursorPosition();
97
98 void Signal(int signal);
99
100 ScreenInteractive* suspended_screen_ = nullptr;
101 enum class Dimension {
103 Fixed,
106 };
107 ScreenInteractive(Dimension dimension,
108 int dimx,
109 int dimy,
110 bool use_alternative_screen);
111 const Dimension dimension_;
112 const bool use_alternative_screen_;
113
114 bool track_mouse_ = true;
115
116 Sender<Task> task_sender_;
117 Receiver<Task> task_receiver_;
118
119 std::string set_cursor_position;
120 std::string reset_cursor_position;
121
122 std::atomic<bool> quit_{false};
123 std::thread event_listener_;
124 std::thread animation_listener_;
125 bool animation_requested_ = false;
126 animation::TimePoint previous_animation_time_;
127
128 int cursor_x_ = 1;
129 int cursor_y_ = 1;
130
131 std::uint64_t frame_count_ = 0;
132 bool mouse_captured = false;
133 bool previous_frame_resized_ = false;
134
135 bool frame_valid_ = false;
136
137 bool force_handle_ctrl_c_ = true;
138 bool force_handle_ctrl_z_ = true;
139
140 // The style of the cursor to restore on exit.
141 int cursor_reset_shape_ = 1;
142
143 // Selection API:
144 CapturedMouse selection_pending_;
145 struct SelectionData {
146 int start_x = -1;
147 int start_y = -1;
148 int end_x = -2;
149 int end_y = -2;
150 bool empty = true;
151 bool operator==(const SelectionData& other) const;
152 bool operator!=(const SelectionData& other) const;
153 };
154 SelectionData selection_data_;
155 SelectionData selection_data_previous_;
156 std::unique_ptr<Selection> selection_;
157 std::function<void()> selection_on_change_;
158
159 friend class Loop;
160
161 public:
162 class Private {
163 public:
164 static void Signal(ScreenInteractive& s, int signal) { s.Signal(signal); }
165 };
166 friend Private;
167};
168
169} // namespace ftxui
170
171#endif /* end of include guard: FTXUI_COMPONENT_SCREEN_INTERACTIVE_HPP */
static void Signal(ScreenInteractive &s, int signal)
static ScreenInteractive TerminalOutput()
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:33
int dimx() const
Definition image.hpp:32
A rectangular grid of Pixel.
Definition screen.hpp:27
std::chrono::time_point< Clock > TimePoint
Definition animation.hpp:29
The FTXUI ftxui:: namespace.
Definition animation.hpp:10
std::unique_ptr< CapturedMouseInterface > CapturedMouse
std::unique_ptr< ReceiverImpl< T > > Receiver
Definition receiver.hpp:46
std::unique_ptr< SenderImpl< T > > Sender
Definition receiver.hpp:45
std::variant< Event, Closure, AnimationTask > Task
Definition task.hpp:14
std::function< void()> Closure
Definition task.hpp:13
std::shared_ptr< ComponentBase > Component