CB100

Notas, resueltos y tps de la materia Algoritmos y Estructuras de Datos
Index Commits Files Refs README
guias/1/ej11.cpp (4055B)
   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 }