-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathselectionPrompt.cpp
161 lines (138 loc) Β· 4.47 KB
/
selectionPrompt.cpp
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include <iostream>
#include <string>
#include <vector>
#ifdef _WIN32
#include <windows.h>
#include <conio.h>
#else
#include <termios.h>
#include <unistd.h>
#endif
using std::cout;
using std::endl;
using std::vector;
using std::string;
#ifdef _WIN32
// Define ENABLE_VIRTUAL_TERMINAL_PROCESSING if not already defined
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#endif
void enableANSI() {
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hOut == INVALID_HANDLE_VALUE) return;
DWORD dwMode = 0;
if (!GetConsoleMode(hOut, &dwMode)) return;
dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
if (!SetConsoleMode(hOut, dwMode)) return;
}
#endif
void setRawMode(bool enable) {
#ifdef _WIN32
static DWORD oldM, newM;
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
if (enable){
GetConsoleMode(hStdin, &oldM);
newM = oldM & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);
if(!SetConsoleMode(hStdin, newM)){
std::cerr << "Unable to set console mode" << std::endl;
}
} else {
SetConsoleMode(hStdin, oldM);
}
#else
static struct termios oldt, newt;
if (enable) {
tcgetattr(STDIN_FILENO, &oldt); // Get current terminal attributes
newt = oldt; // Copy them to modify
newt.c_lflag &= ~(ICANON | ECHO); // Disable canonical mode and echo
tcsetattr(STDIN_FILENO, TCSANOW, &newt); // Apply changes immediately
} else {
tcsetattr(STDIN_FILENO, TCSANOW, &oldt); // Restore original attributes
}
#endif
}
char getCommand(){
#ifdef _WIN32
int key = _getch();
if (key == 3) // Ctrl+C - Exit program
exit(0);
else if (key == 13) // Enter key
return '\n';
else if (key == 0 || key == 224) { // Arrow keys are a two-part code
key = _getch(); // Get the second part
switch (key) {
case 72: return 'A';
case 80: return 'B';
default: return '\0';
}
}
return '\0';
#else
char key = getchar(); // Read a single character
if (key == '\n') { // Enter key
return key;
} else if (key == '\033') { // Escape sequence for arrow keys
getchar(); // Skip the '['
key = getchar();
if (key != 'A' && key != 'B')
key = '\0';
}
else{
key = '\0';
}
return key;
#endif
}
int main (){
#ifdef _WIN32
enableANSI();
#endif
cout << "\033[2J\033[3J\033[H";
vector<string> food {"Pizza", "Burger", "Pasta", "Chicken", "Meat"};
string styleStart = "\033[31m";
string styleEnd = "\033[0m";
int selectedIndex = 0;
setRawMode(true);
std::cout << "\0337";
do {
cout << "Which food do you prefer the most?" << endl;
for (size_t i = 0; i < food.size(); i++){
if (selectedIndex == i){
cout << styleStart << " > " << food[i] << styleEnd << endl;
}
else {
cout << " " << food[i] << endl;
}
}
cout << "\033[?25l\033[0m"; // hide cursor
char key = getCommand();
while (key == '\0')
key = getCommand();
if (key == '\n'){
// delete the selections and the question
// return the selected item/index in the vector
std::cout << "\0338";
cout << "\033[J";
setRawMode(false);
cout << "\033[?25h\033[0m"; // view cursor again
break;
}
else if (key == 'A'){
if (selectedIndex == 0)
selectedIndex = food.size() - 1;
else
selectedIndex--;
}
else if (key == 'B'){
if (selectedIndex == food.size() - 1)
selectedIndex = 0;
else
selectedIndex++;
}
//cout << "\033[" << food.size() << "A"; // move the cursor up according to the size of the vector
std::cout << "\0338";
cout << "\033[J"; // clear everything from the current position till the end of the screen
} while (true);
cout << "\033[32m \n \n You choose " << food[selectedIndex] << styleEnd << endl << endl;
return 0;
}