-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtui-clock-screen.cpp
More file actions
124 lines (94 loc) · 3.02 KB
/
Copy pathtui-clock-screen.cpp
File metadata and controls
124 lines (94 loc) · 3.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <iostream>
#include <termios.h>
#include <unistd.h>
#include <sys/ioctl.h>
#define CURSOR_TO_TOP 1
#define NO_SPACE 1
typedef struct winsize TERMSIZE;
class Screen
{
private:
struct termios raw, normal;
TERMSIZE before, after;
int error_code;
void update_terminal_size_variable(TERMSIZE* w);
void init_terminal_size_variables(TERMSIZE* source, TERMSIZE* destination);
public:
Screen();
void clear_screen(int CURSOR_TOP = 0);
void get_terminal_size(TERMSIZE* term);
void set_exit_message(int err_code);
int get_keys_press(char* key, int deciseconds_timeout = 1);
bool is_term_size_changed();
~Screen();
};
void Screen::set_exit_message(int err_code)
{
error_code = err_code;
}
void Screen::init_terminal_size_variables(TERMSIZE* source, TERMSIZE* destination)
{
destination->ws_col = source->ws_col;
destination->ws_row = source->ws_row;
destination->ws_xpixel = source->ws_xpixel;
destination->ws_ypixel = source->ws_ypixel;
}
bool Screen::is_term_size_changed()
{
get_terminal_size(&after);
if ( before.ws_col != after.ws_col || before.ws_row != after.ws_row){
init_terminal_size_variables(&after, &before);
return true;
}
return false;
}
int Screen::get_keys_press(char* key, int deciseconds_timeout)
{
raw.c_cc[VTIME] = deciseconds_timeout;
tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
return read(STDIN_FILENO, key, 1);
}
void Screen::clear_screen(int CURSOR_TOP)
{
std::cout<< "\x1B[2J" << std::flush;
if( CURSOR_TOP == CURSOR_TO_TOP ){ std::cout<< "\x1B[1;1f" << std::flush; }
}
void Screen::get_terminal_size(TERMSIZE* term)
{
update_terminal_size_variable(term);
}
void Screen::update_terminal_size_variable(TERMSIZE* w)
{
ioctl(STDOUT_FILENO, TIOCGWINSZ, w);
}
Screen::Screen()
{
get_terminal_size(&before);
tcgetattr(STDIN_FILENO, &raw);
tcgetattr(STDIN_FILENO, &normal);
std::cout << "\x1B[s"; // Save cursor location
std::cout << "\x1B[?47h"; // Save screen
std::cout << "\x1B[?25l"; // Hide cursor
std::cout << "\x1B[1049h"; // Enable alternate buffer
std::cout << "\x1B[1;1f" << std::flush; // Move cursor to the top
raw.c_lflag &= ~(ECHO | ICANON | ISIG);
raw.c_cc[VMIN] = 0;
raw.c_cc[VTIME] = 1;
tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
}
Screen::~Screen()
{
tcsetattr(STDIN_FILENO, TCSAFLUSH, &normal);
std::cout << "\x1B[1049l"; // Disable alternate buffer
std::cout << "\x1B[?25h"; // Unhide cursor
std::cout << "\x1B[?47l"; // Restore screen
std::cout << "\x1B[u" << std::flush; // Rstore cursor location
switch (error_code)
{
case 1:
std::cout<< "NO ENOUGH SPACE TO DRAW" << std::endl;
break;
default:
break;
}
}