basicmenu.h  1.0.0
integrate a menu in your console program easily
basicmenu.h
Go to the documentation of this file.
00001 
00048 #ifndef _basicmenu_h
00049 #define _basicmenu_h
00050 
00051 #include <stdio.h>
00052 #include <stdlib.h>
00053 #include <termios.h>
00054 #include <unistd.h>
00055 #include <string.h>
00056 #include <sys/ioctl.h>
00057 
00058 
00059 /***********************************************/
00060 /*                The Menu                     */
00061 /***********************************************/
00062 
00072 typedef struct custom_Menu {    
00073         char item[255]; 
00074         int index; 
00075         struct custom_Menu * last ; 
00077 }custom_Menu;
00078 
00079 
00086 void init_new_menu (custom_Menu** mymenu);
00087 
00088 
00096 int getch(void) ;
00097 
00106 int getTouch (void) ;
00107 
00108 /*
00109  * Add new item the your menu
00110  */
00111 
00120 void addNewItem (custom_Menu ** mymenu, char newItem[]) ;
00121 
00122 /*
00123  * print the menu on the screen
00124  */
00125 
00135 int put_menu (custom_Menu * mymenu, void (*before)(void), void (*after)(void)) ;
00136 
00137 
00147 int put_menu_with (custom_Menu * mymenu /* , int a, char b, int liste[]... */ );
00148 
00149 
00154 void startBasicMenu(void) ;
00155 
00156 /*
00157  * this will be used to clear the console
00158  */
00159 static void toPosition() ;
00160 
00161 /***********************************************/
00162 /*                  COLORS                     */
00163 /***********************************************/
00164 
00173 //typedef enum _COLOR_ _COLOR_;
00174 typedef enum {
00175         BLACK,  
00176         RED,    
00177         GREEN,  
00178         YELLOW, 
00179         BLUE,   
00180         MAGENTA,
00181         CYAN,   
00182         WHITE   
00183 }
00184 _COLOR_ ;
00185 
00186 
00192 typedef enum { 
00193         FALSE, 
00194         TRUE  
00195 } 
00196 BOOLEAN;
00197 
00198 
00199 static BOOLEAN _DYNAMIC_MENU = FALSE; 
00200 static int _WINDOW_LARGE = 0; 
00202 static int _MENU_PADDING = 0; 
00204 static BOOLEAN _SHOW_BOLD_TEXT =FALSE;
00205 
00206 static int FGCOLOR, 
00207         BGCOLOR; 
00210 static BOOLEAN _CHANGE_FGCOLOR=FALSE, 
00211                 _CHANGE_BGCOLOR=FALSE; 
00222 void BG_COLOR_ON(_COLOR_ COLOR);
00223 
00232 void FG_COLOR_ON(_COLOR_ COLOR);
00233 
00239 void BG_COLOR_OFF();
00240 
00246 void FG_COLOR_OFF();
00247 
00253 void BOLD_TEXT_ON();
00254 
00260 void BOLD_TEXT_OFF();
00261 
00262 
00263 /***********************************************/
00264 /*               OTHER PREFERENCES             */
00265 /***********************************************/
00266 
00267 /* 
00268  * make the menu dynamic
00269 
00270  */
00271 
00278 void dynamic_menu_ON();
00279 
00285 void dynamic_menu_OFF();
00286 
00287 
00294 void menu_in_middle_ON();
00295 
00300 void menu_in_middle_OFF();
00301 
00309 void set_menu_padding(int padding);
00310 
00311 /*
00312  * The borders;
00313  */
00314 
00315 static BOOLEAN _MENU_BORDER = FALSE, 
00318                 _ITEM_BORDER = FALSE; 
00327 void menu_border_ON() { _MENU_BORDER = TRUE; _ITEM_BORDER = FALSE; }
00328 
00333 void menu_border_OFF() { _MENU_BORDER = FALSE; }
00334 
00340 void item_border_ON() { _ITEM_BORDER = TRUE; _MENU_BORDER = FALSE; }
00341 
00346 void item_border_OFF() { _ITEM_BORDER = FALSE; }
00347 
00348 
00349 
00350 
00351 /***********************************************/
00352 /*                  FUNCTIONS                  */
00353 /***********************************************/
00354 
00355 void init_new_menu (custom_Menu** mymenu) {
00356         *mymenu = malloc (sizeof(*mymenu));
00357 }
00358 
00359 int getch(void) {
00360         
00361         struct termios to, t;
00362         
00363     tcgetattr (1, &t);
00364     to = t;
00365     t.c_lflag &= ~(ICANON | ECHO);
00366     tcsetattr (1, 0, &t);
00367     char c;
00368     c=getchar () ;
00369     tcsetattr (1, 0, &to);
00370         
00371         return c;
00372 }
00373 
00374 int getTouch (void) {
00375         int keyUp = 300;
00376         int keyDown = 301;
00377         int keyRight = 302;
00378         int keyLeft = 303;
00379         int retVal;
00380         int code1,code2,code3;
00381         
00382         code1 = getch(); if (code1!=27) return code1; // si la touche differente de les 4 touches de direction
00383         code2 = getch(); if (code2!=91) return code2;
00384         code3 = getch(); 
00385         switch (code3) {
00386                 case 65: {
00387                         retVal = keyUp;
00388                         break;
00389                 }
00390                 case 66: {
00391                         retVal = keyDown;
00392                         break;
00393                 }
00394                 case 67: {
00395                         retVal = keyRight;
00396                         break;
00397                 }
00398                 case 68: {
00399                         retVal = keyLeft;
00400                         break;
00401                 }
00402                 default: {
00403                         retVal = code3;
00404                         break;
00405                 }       
00406         }
00407         
00408         return retVal;
00409 }
00410 
00411 
00412 void addNewItem (custom_Menu ** mymenu, char newItem[]) {
00413         
00414         custom_Menu *newItemTmp = malloc(sizeof *newItemTmp);
00415         if (newItemTmp != NULL)
00416         {
00417                 strcpy (newItemTmp->item , newItem);
00418                 newItemTmp->index = (*mymenu)->index+1;
00419                 newItemTmp->last = *mymenu;
00420                 *mymenu = newItemTmp;
00421         }
00422 }
00423 
00424 
00425 int put_menu (custom_Menu * mymenu, void (*before)(void), void (*after)(void)) {
00426         /* The longest string (item) */
00427         int THE_LONGEST_ITEM = 0;
00428         
00429         int listeSize = mymenu->index;
00430         //printf("%d\n",listeSize);
00431         char *liste[listeSize];
00432         int i,j; 
00433         for (i=0;i<listeSize;i++) {
00434                 liste[i]= malloc(sizeof(mymenu->item));
00435         }
00436         
00437         custom_Menu * menuTmp = malloc(sizeof(*menuTmp));
00438         
00439         *menuTmp = *mymenu;
00440         
00441         while (menuTmp->last!=NULL) {
00442                 //printf("[%d] %s\n",menuTmp->index, menuTmp->item);
00443                 strcpy (liste[menuTmp->index-1], menuTmp->item);
00444                 if(strlen(liste[menuTmp->index-1]) >THE_LONGEST_ITEM)
00445                         THE_LONGEST_ITEM = strlen(liste[menuTmp->index-1]);
00446                 menuTmp = menuTmp->last;
00447         }
00448         int retVal;
00449         BOOLEAN outOf = FALSE;
00450         int currentItem=1;
00451         int userChoice;
00452         do {
00453                 toPosition();
00454                 before();
00455                 if (_MENU_BORDER==TRUE || _ITEM_BORDER==TRUE) {
00456                         for (j=0; j<_MENU_PADDING; j++ )
00457                                 printf(" ");
00458                         printf("+");
00459                         for(j=_MENU_PADDING; j<_MENU_PADDING+THE_LONGEST_ITEM+6; j++)
00460                                 printf("-");
00461                         printf("+\n");
00462                 }
00463                 for (i=0; i<listeSize; i++) {
00464                         if (_WINDOW_LARGE != 0) {
00465                                 int row;
00466                                 for (row = 0 ; row < _WINDOW_LARGE-(strlen(liste[i]))/2 ; row++)
00467                                         printf(" ");
00468                         }
00469                         else if (_MENU_PADDING !=0) {
00470                                 int row;
00471                                 for (row = 0 ; row < _MENU_PADDING ; row++)
00472                                         printf(" ");
00473                         }
00474                         if (currentItem==i+1)
00475                         {
00476                                 if (_MENU_BORDER || _ITEM_BORDER) printf("| ");
00477                                 if (_CHANGE_BGCOLOR) printf("\033[%dm",BGCOLOR);
00478                                 if (_CHANGE_FGCOLOR) printf("\033[%dm",FGCOLOR);
00479                                 if (_SHOW_BOLD_TEXT) printf("\033[1m");
00480                                 printf("[*] %s",liste[i]);
00481                                 if (_SHOW_BOLD_TEXT) printf("\033[0m");
00482                                 if (_CHANGE_FGCOLOR) printf("\033[0m");
00483                                 if (_CHANGE_BGCOLOR) printf("\033[0m");
00484                                 
00485                                 if (_MENU_BORDER || _ITEM_BORDER) {
00486                                         for(j=_MENU_PADDING+strlen(liste[i])+4; j<_MENU_PADDING+THE_LONGEST_ITEM+4;j++ )
00487                                                 printf(" ");
00488                                         printf(" |\n");
00489                                 }
00490                                 else printf("\n");
00491                         }
00492                         else
00493                         {       
00494                                 if (_MENU_BORDER || _ITEM_BORDER) {
00495                                         printf("| [ ] %s",liste[i]);
00496                                         for(j=_MENU_PADDING+strlen(liste[i])+4; j<_MENU_PADDING+THE_LONGEST_ITEM+4;j++ )
00497                                                 printf(" ");
00498                                         printf(" |\n");
00499                                 }
00500                                 else 
00501                                         printf("[ ] %s\n",liste[i]);
00502                         }
00503                         if (_ITEM_BORDER) {
00504                                 for (j=0; j<_MENU_PADDING; j++ )
00505                                         printf(" ");
00506                                 printf("+");
00507                                 for(j=_MENU_PADDING; j<_MENU_PADDING+THE_LONGEST_ITEM+6; j++)
00508                                         printf("-");
00509                                 printf("+\n");
00510                         }
00511                 } // end of for
00512                 if (_MENU_BORDER) {
00513                         for (j=0; j<_MENU_PADDING; j++ )
00514                                 printf(" ");
00515                         printf("+");
00516                         for(j=_MENU_PADDING; j<_MENU_PADDING+THE_LONGEST_ITEM+6; j++)
00517                                 printf("-");
00518                         printf("+\n");
00519                 }
00520                 
00521                 
00522                 after();
00523                 userChoice = getTouch();
00524                 switch(userChoice) {
00525                         case 300: {
00526                                 if (currentItem>1)
00527                                         currentItem--;
00528                                 else {
00529                                         if (_DYNAMIC_MENU == TRUE) 
00530                                                 currentItem= listeSize;
00531                                 }
00532                                 break;
00533                         }
00534                         case 301: {
00535                                 if (currentItem<listeSize) 
00536                                         currentItem++;
00537                                 else {
00538                                         if (_DYNAMIC_MENU==TRUE)
00539                                                 currentItem=1;
00540                                 }
00541                                 break;
00542                         }
00543                         default : {
00544                                 if (userChoice == '\n' || userChoice=='\r') {
00545                                         retVal = currentItem;
00546                                         outOf = TRUE;
00547                                 }
00548                                 break;
00549                         }
00550                 }
00551         }while (!outOf);
00552         
00553         return(retVal);
00554 }
00555 
00556 
00557 int put_menu_with (custom_Menu * mymenu /* , int a, char b, int liste[]... */ ) {
00558         /* The longest string (item) */
00559         int THE_LONGEST_ITEM = 0;
00560         
00561         int listeSize = mymenu->index;
00562         //printf("%d\n",listeSize);
00563         char *liste[listeSize];
00564         int i,j; 
00565         for (i=0;i<listeSize;i++) {
00566                 liste[i]= malloc(sizeof(mymenu->item));
00567         }
00568         
00569         custom_Menu * menuTmp = malloc(sizeof(*menuTmp));
00570         
00571         *menuTmp = *mymenu;
00572         
00573         while (menuTmp->last!=NULL) {
00574                 //printf("[%d] %s\n",menuTmp->index, menuTmp->item);
00575                 strcpy (liste[menuTmp->index-1], menuTmp->item);
00576                 if(strlen(liste[menuTmp->index-1]) >THE_LONGEST_ITEM)
00577                         THE_LONGEST_ITEM = strlen(liste[menuTmp->index-1]);
00578                 menuTmp = menuTmp->last;
00579         }
00580         int retVal;
00581         BOOLEAN outOf = FALSE;
00582         int currentItem=1;
00583         int userChoice;
00584         do {
00585                 toPosition();
00586                 /**************************************/
00587                         // put your code here to display
00588                         // any thing before the menu
00589                 /**************************************/
00590                 
00591                 if (_MENU_BORDER==TRUE || _ITEM_BORDER==TRUE) {
00592                         for (j=0; j<_MENU_PADDING; j++ )
00593                                 printf(" ");
00594                         printf("+");
00595                         for(j=_MENU_PADDING; j<_MENU_PADDING+THE_LONGEST_ITEM+6; j++)
00596                                 printf("-");
00597                         printf("+\n");
00598                 }
00599                 for (i=0; i<listeSize; i++) {
00600                         if (_WINDOW_LARGE != 0) {
00601                                 int row;
00602                                 for (row = 0 ; row < _WINDOW_LARGE-(strlen(liste[i]))/2 ; row++)
00603                                         printf(" ");
00604                         }
00605                         else if (_MENU_PADDING !=0) {
00606                                 int row;
00607                                 for (row = 0 ; row < _MENU_PADDING ; row++)
00608                                         printf(" ");
00609                         }
00610                         if (currentItem==i+1)
00611                         {
00612                                 if (_MENU_BORDER || _ITEM_BORDER) printf("| ");
00613                                 if (_CHANGE_BGCOLOR) printf("\033[%dm",BGCOLOR);
00614                                 if (_CHANGE_FGCOLOR) printf("\033[%dm",FGCOLOR);
00615                                 if (_SHOW_BOLD_TEXT) printf("\033[1m");
00616                                 printf("[*] %s",liste[i]);
00617                                 if (_SHOW_BOLD_TEXT) printf("\033[0m");
00618                                 if (_CHANGE_FGCOLOR) printf("\033[0m");
00619                                 if (_CHANGE_BGCOLOR) printf("\033[0m");
00620                                 if (_MENU_BORDER || _ITEM_BORDER) {
00621                                         for(j=_MENU_PADDING+strlen(liste[i])+4; j<_MENU_PADDING+THE_LONGEST_ITEM+4;j++ )
00622                                                 printf(" ");
00623                                         printf(" |\n");
00624                                 }
00625                                 else printf("\n");
00626                         }
00627                         else
00628                         {       
00629                                 if (_MENU_BORDER || _ITEM_BORDER) {
00630                                         printf("| [ ] %s",liste[i]);
00631                                         for(j=_MENU_PADDING+strlen(liste[i])+4; j<_MENU_PADDING+THE_LONGEST_ITEM+4;j++ )
00632                                                 printf(" ");
00633                                         printf(" |\n");
00634                                 }
00635                                 else 
00636                                         printf("[ ] %s\n",liste[i]);
00637                         }
00638                         if (_ITEM_BORDER) {
00639                                 for (j=0; j<_MENU_PADDING; j++ )
00640                                         printf(" ");
00641                                 printf("+");
00642                                 for(j=_MENU_PADDING; j<_MENU_PADDING+THE_LONGEST_ITEM+6; j++)
00643                                         printf("-");
00644                                 printf("+\n");
00645                         }
00646                 } // end of for
00647                 if (_MENU_BORDER) {
00648                         for (j=0; j<_MENU_PADDING; j++ )
00649                                 printf(" ");
00650                         printf("+");
00651                         for(j=_MENU_PADDING; j<_MENU_PADDING+THE_LONGEST_ITEM+6; j++)
00652                                 printf("-");
00653                         printf("+\n");
00654                 }
00655                 
00656                 
00657                 /**************************************/
00658                 // put your code here to display
00659                 // any thing after the menu
00660                 /**************************************/
00661                 
00662                 
00663                 userChoice = getTouch();
00664                 switch(userChoice) {
00665                         case 300: {
00666                                 if (currentItem>1)
00667                                         currentItem--;
00668                                 else {
00669                                         if (_DYNAMIC_MENU == TRUE) 
00670                                                 currentItem= listeSize;
00671                                 }
00672                                 break;
00673                         }
00674                         case 301: {
00675                                 if (currentItem<listeSize) 
00676                                         currentItem++;
00677                                 else {
00678                                         if (_DYNAMIC_MENU==TRUE)
00679                                                 currentItem=1;
00680                                 }
00681                                 break;
00682                         }
00683                         default : {
00684                                 if (userChoice == '\n' || userChoice=='\r') {
00685                                         retVal = currentItem;
00686                                         outOf = TRUE;
00687                                 }
00688                                 break;
00689                         }
00690                 }
00691         }while (!outOf);
00692         
00693         return(retVal);
00694 }
00695 
00696 
00697 
00698 void startBasicMenu(void) {
00699         system("clear");
00700         printf("\033[s");
00701 }
00702 
00703 void toPosition() {
00704         struct winsize w;
00705         printf("\033[u");
00706         ioctl(0, TIOCGWINSZ, &w);
00707         int line, column;
00708         for (line=0;line<w.ws_row;line++) {
00709                 for (column=0;column<w.ws_col;column++) {
00710                         printf(" ");
00711                 }
00712         }
00713         printf("\033[u");
00714 }
00715 
00716 void BG_COLOR_ON(_COLOR_ COLOR) {
00717         
00718         switch (COLOR) {
00719                 case (BLACK):
00720                 {
00721                         BGCOLOR = 40;
00722                         _CHANGE_BGCOLOR = 1;
00723                         break;
00724                 }
00725                 case RED:
00726                 {
00727                         BGCOLOR = 41;
00728                         _CHANGE_BGCOLOR = 1;
00729                         break;
00730                 }
00731                 case GREEN:
00732                 {
00733                         BGCOLOR = 42;
00734                         _CHANGE_BGCOLOR = 1;
00735                         break;
00736                 }
00737                 case YELLOW:
00738                 {
00739                         BGCOLOR = 43;
00740                         _CHANGE_BGCOLOR = 1;
00741                         break;
00742                 }
00743                 case BLUE:
00744                 {
00745                         BGCOLOR = 44;
00746                         _CHANGE_BGCOLOR = 1;
00747                         break;
00748                 }
00749                 case MAGENTA:
00750                 {
00751                         BGCOLOR = 45;
00752                         _CHANGE_BGCOLOR = 1;
00753                         break;
00754                 }
00755                 case CYAN:
00756                 {
00757                         BGCOLOR = 46;
00758                         _CHANGE_BGCOLOR = 1;
00759                         break;
00760                 }
00761                 case WHITE:
00762                 {
00763                         BGCOLOR = 47;
00764                         _CHANGE_BGCOLOR = 1;
00765                         break;
00766                 }
00767                 default: 
00768                 {
00769                         break;
00770                 }
00771         }
00772 }
00773 
00774 void FG_COLOR_ON(_COLOR_ COLOR) {
00775         
00776         switch (COLOR) {
00777                 case BLACK:
00778                 {
00779                         FGCOLOR = 30;
00780                         _CHANGE_FGCOLOR = 1;
00781                         break;
00782                 }
00783                 case RED:
00784                 {
00785                         FGCOLOR = 31;
00786                         _CHANGE_FGCOLOR = 1;
00787                         break;
00788                 }
00789                 case GREEN:
00790                 {
00791                         FGCOLOR = 32;
00792                         _CHANGE_FGCOLOR = 1;
00793                         break;
00794                 }
00795                 case YELLOW:
00796                 {
00797                         FGCOLOR =33;
00798                         _CHANGE_FGCOLOR = 1;
00799                         break;
00800                 }
00801                 case BLUE:
00802                 {
00803                         FGCOLOR = 34;
00804                         _CHANGE_FGCOLOR = 1;
00805                         break;
00806                 }
00807                 case MAGENTA:
00808                 {
00809                         FGCOLOR = 35;
00810                         _CHANGE_FGCOLOR = 1;
00811                         break;
00812                 }
00813                 case CYAN:
00814                 {
00815                         FGCOLOR = 36;
00816                         _CHANGE_FGCOLOR = 1;
00817                         break;
00818                 }
00819                 case WHITE:
00820                 {
00821                         FGCOLOR = 37;
00822                         _CHANGE_FGCOLOR = 1;
00823                         break;
00824                 }
00825                 default: 
00826                 {
00827                         break;
00828                 }
00829         }
00830 }
00831 
00832 void FG_COLOR_OFF() { _CHANGE_FGCOLOR = 0; }
00833 void BG_COLOR_OFF() { _CHANGE_BGCOLOR = 0; }
00834 
00835 void dynamic_menu_ON() { _DYNAMIC_MENU = TRUE; }
00836 void dynamic_menu_OFF() { _DYNAMIC_MENU = FALSE; }
00837 
00838 void menu_in_middle_ON() {
00839         struct winsize w;
00840         ioctl(0, TIOCGWINSZ, &w); 
00841         _WINDOW_LARGE = w.ws_col/2 ;
00842 }
00843 void menu_in_middle_OFF() { _WINDOW_LARGE = 0; }
00844 
00845 void set_menu_padding(int padding) { _MENU_PADDING = padding; }
00846 
00847 void BOLD_TEXT_ON() {
00848         _SHOW_BOLD_TEXT = TRUE;
00849 }
00850 
00851 void BOLD_TEXT_OFF() {
00852         _SHOW_BOLD_TEXT = FALSE;
00853 }
00854 
00855 /*************************************/
00856 /*          How to                   */
00857 /*************************************/
00858 
00859 
00860 
00882 #endif