1 /* Termios solo funciona en sistemas basados en UNIX */ 2 3 #include <iostream> 4 #include <string> 5 #include <cstdio> 6 #include <cstdlib> 7 #include <csignal> 8 #include <termios.h> 9 10 using namespace std; 11 12 enum { 13 ES, 14 EN, 15 DE, 16 PT, 17 MENU_ITEMS 18 }; 19 20 static struct termios default_attributes; 21 string *cursor = new string[MENU_ITEMS]; 22 unsigned int cursor_pos; 23 bool run_program; 24 25 string menu[MENU_ITEMS] = { 26 "Español", 27 "English", 28 "Deutsch", 29 "Português" 30 }; 31 32 void sig_handler(int signo) { 33 signal(signo, SIG_IGN); 34 if ((signo == SIGINT) || (signo == SIGQUIT)) { 35 run_program = false; 36 exit(0); 37 } 38 } 39 40 void set_input_mode (void) { 41 struct termios tattr; 42 43 if (!isatty(STDIN_FILENO)) { 44 cerr << "Not a terminal" << endl; 45 exit (EXIT_FAILURE); 46 } 47 48 tcgetattr(STDIN_FILENO, &default_attributes); 49 50 /* hide cursor */ 51 cout << "\033[?25l"; 52 53 /* Set the terminal modes. */ 54 tcgetattr(STDIN_FILENO, &tattr); 55 tattr.c_lflag &= ~(ICANON|ECHO); /* Clear ICANON and ECHO. */ 56 tattr.c_cc[VMIN] = 1; 57 tattr.c_cc[VTIME] = 0; 58 tcsetattr(STDIN_FILENO, TCSAFLUSH, &tattr); 59 } 60 61 void reset_input_mode (void) { 62 tcsetattr(STDIN_FILENO, TCSANOW, &default_attributes); 63 64 /* show cursor */ 65 cout << "\033[?25h"; 66 } 67 68 void print_menu(void) { 69 for(size_t i = 0; i < MENU_ITEMS; ++i) { 70 cursor[cursor_pos].assign(((i == cursor_pos) ? " >\033[33m" : " ")); 71 cout << cursor[cursor_pos] << menu[i] 72 << (i == MENU_ITEMS ? "\033[0m" : "\033[0m\n") << flush; 73 } 74 } 75 76 void clear_menu(void) { 77 cout << "\033[" << MENU_ITEMS << "A"; 78 } 79 80 void refresh_menu(void) { 81 clear_menu(); 82 print_menu(); 83 } 84 85 void move_cursor_up() { 86 if(cursor_pos >= 1) 87 cursor_pos--; 88 else cursor_pos = (MENU_ITEMS - 1); 89 } 90 91 void move_cursor_down() { 92 if(cursor_pos < (MENU_ITEMS - 1)) 93 cursor_pos++; 94 else cursor_pos = 0; 95 } 96 97 int main (void) { 98 char cmd; 99 unsigned int selected_item; 100 run_program = true; 101 cursor_pos = 0; 102 selected_item = MENU_ITEMS; 103 104 set_input_mode(); 105 signal(SIGINT, sig_handler); 106 signal(SIGQUIT, sig_handler); 107 signal(SIGTSTP, SIG_IGN); 108 atexit(reset_input_mode); 109 110 print_menu(); 111 while(run_program) { 112 cin.get(cmd); 113 switch(cmd) { 114 case 'w': 115 case 'k': 116 move_cursor_up(); 117 refresh_menu(); 118 break; 119 case 's': 120 case 'j': 121 move_cursor_down(); 122 refresh_menu(); 123 break; 124 case 'q': 125 run_program = false; 126 break; 127 case 10: // Enter 128 case ' ': 129 case 'l': 130 case 'f': 131 selected_item = cursor_pos; 132 run_program = false; 133 break; 134 case 27: { // Escape codes i.e. arrow keys 135 cin.get(cmd); // skip '[' 136 cin.get(cmd); 137 switch (cmd) { 138 case 'A': 139 move_cursor_up(); 140 refresh_menu(); 141 break; 142 case 'B': 143 move_cursor_down(); 144 refresh_menu(); 145 break; 146 case 'c': 147 run_program = false; 148 break; 149 default: 150 break; 151 } 152 } 153 default: 154 continue; 155 } 156 } 157 158 string mg; 159 clear_menu(); 160 if(selected_item != MENU_ITEMS) { 161 if (menu[selected_item] == menu[ES]) { 162 mg = "Usted seleccionó: `"; 163 } else if (menu[selected_item] == menu[DE]) { 164 mg = "Sie wählen: `"; 165 } else if (menu[selected_item] == menu[PT]) { 166 mg = "Você seleciona: `"; 167 } else { 168 mg = "You selected: `"; 169 } 170 cout << mg << menu[selected_item] << "`\033[0J\n"; 171 } 172 173 exit(EXIT_SUCCESS); 174 }
