Implement "alternative screen".

Apply this option automatically for "fullscreen" screen. Keep it
disabled for the other modes.

This fixes issue:
https://github.com/GiuseppeCesarano/just-fast/issues/2
This commit is contained in:
ArthurSonzogni 2020-05-02 20:39:56 +02:00
parent ac3db36de8
commit 76fc52441f
2 changed files with 24 additions and 7 deletions

View File

@ -43,7 +43,11 @@ class ScreenInteractive : public Screen {
TerminalOutput, TerminalOutput,
}; };
Dimension dimension_ = Dimension::Fixed; Dimension dimension_ = Dimension::Fixed;
ScreenInteractive(int dimx, int dimy, Dimension dimension); bool use_alternative_screen_ = false;
ScreenInteractive(int dimx,
int dimy,
Dimension dimension,
bool use_alternative_screen);
Sender<Event> event_sender_; Sender<Event> event_sender_;
Receiver<Event> event_receiver_; Receiver<Event> event_receiver_;

View File

@ -124,6 +124,9 @@ static const char* SHOW_CURSOR = "\x1B[?25h";
static const char* DISABLE_LINE_WRAP = "\x1B[7l"; static const char* DISABLE_LINE_WRAP = "\x1B[7l";
static const char* ENABLE_LINE_WRAP = "\x1B[7h"; static const char* ENABLE_LINE_WRAP = "\x1B[7h";
static const char* USE_ALTERNATIVE_SCREEN = "\x1B[?1049h";
static const char* USE_NORMAL_SCREEN = "\x1B[?1049l";
using SignalHandler = void(int); using SignalHandler = void(int);
std::stack<std::function<void()>> on_exit_functions; std::stack<std::function<void()>> on_exit_functions;
void OnExit(int signal) { void OnExit(int signal) {
@ -146,8 +149,13 @@ void OnResize(int /* signal */) {
on_resize(); on_resize();
} }
ScreenInteractive::ScreenInteractive(int dimx, int dimy, Dimension dimension) ScreenInteractive::ScreenInteractive(int dimx,
: Screen(dimx, dimy), dimension_(dimension) { int dimy,
Dimension dimension,
bool use_alternative_screen)
: Screen(dimx, dimy),
dimension_(dimension),
use_alternative_screen_(use_alternative_screen) {
event_receiver_ = MakeReceiver<Event>(); event_receiver_ = MakeReceiver<Event>();
event_sender_ = event_receiver_->MakeSender(); event_sender_ = event_receiver_->MakeSender();
} }
@ -156,22 +164,22 @@ ScreenInteractive::~ScreenInteractive() {}
// static // static
ScreenInteractive ScreenInteractive::FixedSize(int dimx, int dimy) { ScreenInteractive ScreenInteractive::FixedSize(int dimx, int dimy) {
return ScreenInteractive(dimx, dimy, Dimension::Fixed); return ScreenInteractive(dimx, dimy, Dimension::Fixed, false);
} }
// static // static
ScreenInteractive ScreenInteractive::Fullscreen() { ScreenInteractive ScreenInteractive::Fullscreen() {
return ScreenInteractive(0, 0, Dimension::Fullscreen); return ScreenInteractive(0, 0, Dimension::Fullscreen, true);
} }
// static // static
ScreenInteractive ScreenInteractive::TerminalOutput() { ScreenInteractive ScreenInteractive::TerminalOutput() {
return ScreenInteractive(0, 0, Dimension::TerminalOutput); return ScreenInteractive(0, 0, Dimension::TerminalOutput, false);
} }
// static // static
ScreenInteractive ScreenInteractive::FitComponent() { ScreenInteractive ScreenInteractive::FitComponent() {
return ScreenInteractive(0, 0, Dimension::FitComponent); return ScreenInteractive(0, 0, Dimension::FitComponent, false);
} }
void ScreenInteractive::PostEvent(Event event) { void ScreenInteractive::PostEvent(Event event) {
@ -257,6 +265,11 @@ void ScreenInteractive::Loop(Component* component) {
std::thread(&UnixEventListener, &quit_, std::move(char_sender)); std::thread(&UnixEventListener, &quit_, std::move(char_sender));
#endif #endif
if (use_alternative_screen_) {
std::cout << USE_ALTERNATIVE_SCREEN;
on_exit_functions.push([] { std::cout << USE_NORMAL_SCREEN; });
}
// The main loop. // The main loop.
while (!quit_) { while (!quit_) {
std::cout << reset_cursor_position << ResetPosition(); std::cout << reset_cursor_position << ResetPosition();