home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 337_01 / pd.c < prev    next >
C/C++ Source or Header  |  1991-01-14  |  9KB  |  269 lines

  1. /* Copyright (c) James L. Pinson 1990,1991  */
  2.  
  3. /**********************   PD.C   ***************************/
  4.  
  5. #include "mydef.h"
  6. #include <stdio.h>
  7.  
  8.  
  9. int pull_down (struct pd_str m_menu[], struct window_colors color)
  10. {
  11. extern struct screen_structure scr;
  12. extern struct window_structure w[];
  13.  
  14. int i,j;              /* general index variables */
  15. int cur_x,cur_y;      /* screen coordinates */
  16. int cur_opt=0;        /* the current option (highlighted) */
  17. int found=FALSE;      /* flag to indicate if option found */
  18. int expert=TRUE;      /* flag to indicate expert/novice mode */
  19. char ch=' ', ext=' '; /* character and extension from keyboard */
  20. int return_code;      /* return code */
  21. int main_win;         /* integer handle for main options window */
  22.  
  23. /* find out if a frame is requested and make window */
  24.  
  25. if (PD_MAIN_FRAME[0]=='\0')  /* no frame requested */
  26.     main_win=win_make(1,1,scr.columns,1,PD_MAIN_FRAME,""\
  27.       ,color.main_frame,color.main_interior);
  28.    else       /* frame requested */
  29.      main_win=win_make(2,2,scr.columns-2,1,PD_MAIN_FRAME,"",\
  30.       color.main_frame,color.main_interior);
  31.  
  32.   cursor(NO_CURSOR);   /* turn off cursor */
  33.  
  34.   for(;;){
  35.        /* if a true letter is pressed */
  36.        if(ch!= ' '&& ch!=RETURN){  
  37.         for(i=0;i<MAIN_OPT;i++){   /* for each main option */
  38.           j=0;
  39.           while(m_menu[i].main[j]!= '\0'){   /* scan each letter */
  40.             /* if quick key found */
  41.             if (m_menu[i].main[j++] ==ch && ch != ' '){  
  42.              found= TRUE;        /* mark found true */
  43.              cur_opt = i;        /* mark it as current option */
  44.              break;
  45.             }
  46.           }
  47.         }
  48.        }
  49.           if (ch==RETURN){     /* if Enter (return) is pressed */
  50.            found = TRUE;       /* accecpt current option */
  51.            expert = FALSE;     /* action indicates non-expert */
  52.           }
  53.  
  54.          /* reset variables */
  55.          ch=' ';
  56.          cur_x=1;cur_y=1;
  57.  
  58.        /* turn on bold caps if necessary */
  59.            if (found || !expert )scr.bold_caps=FALSE;
  60.              else scr.bold_caps=TRUE;
  61.  
  62.            for(i=0;i< MAIN_OPT;i++){  /* print options */
  63.                if(i == cur_opt) scr.current= color.main_inverse;
  64.                 else scr.current= color.main_interior;
  65.                  print(cur_x,cur_y,m_menu[i].main);
  66.              /* move to next screen location*/
  67.              cur_x= cur_x+strlen(m_menu[i].main)+3;  
  68.            }
  69.  
  70.            if (!expert) found = TRUE; /* if not expert then     */
  71.                                       /* force found=TRUE so    */
  72.                                       /* sub-menu always called */
  73.  
  74.            if (found){                /* enter here if found==TRUE */
  75.  
  76.              /* redraw  main menu with bold_caps  off */
  77.              scr.bold_caps=FALSE;
  78.  
  79.              /* call function to create pull-down */
  80.              return_code =(pull_down_sub(m_menu,color,cur_opt,
  81.                            &ext, &expert));
  82.              win_pop_top(main_win);
  83.              if(return_code!=0) break;
  84.  
  85.              /* reactivate expert mode */
  86.              if (ext == ESCAPE) expert = TRUE; 
  87.  
  88.              /* if cursor keys used then not expert */
  89.              if (ext == RIGHT || ext == LEFT) expert = FALSE;
  90.  
  91.              /* if cursor keys then adjust counter */
  92.              if (ext==RIGHT) cur_opt++;
  93.              if (ext ==LEFT) cur_opt--;
  94.              ch= ' ';
  95.              ext= ' ';
  96.  
  97.            } /* end if found */
  98.             else
  99.            {    /* if selection not made then get key */
  100.             ch=' ';
  101.             get_key(&ch,&ext);
  102.             ch=toupper(ch);
  103.            } /* end not found */
  104.  
  105.            if (ch==ESCAPE) break;   /* exit if "Escape" pressed */
  106.  
  107.  
  108.            /* if cursor keys then not expert */
  109.            if (ext ==RIGHT || ext == LEFT) expert = FALSE;
  110.            /* adjust counter if cursor key used */
  111.            if (ext == RIGHT)  cur_opt++;
  112.            if (ext == LEFT)  cur_opt--;
  113.            if (cur_opt >= MAIN_OPT) cur_opt =0;
  114.            if (cur_opt < 0) cur_opt = MAIN_OPT-1;
  115.            ext=' ';
  116.            found=0;
  117.  
  118.   } /* end for(;;) */
  119.   /* close window and return return-code */
  120.   win_delete(main_win);
  121.   return(return_code);
  122. }
  123.  
  124.  
  125. static int pull_down_sub(struct pd_str m_menu[],
  126.                          struct window_colors color,int option,
  127.                          char *ext, int *expert)
  128. {
  129.  
  130. char ch=' ';
  131.  
  132. int i,j;              /* general index variables */
  133. int y;                /* y screen coordinate (row) */
  134. int start,width;      /* info for pull-down window */
  135. int nu_opt;           /* the number of options in pull-down */
  136. int cur_opt=0;        /* the current (highlighted) option */
  137. int found= FALSE;     /* flag to indicate selection made (found)*/
  138. int pd_win;           /* handle of pull-down window */
  139. int return_code=0;    /* return code */
  140.  
  141. nu_opt=PD_SUB;   /* set nu_opt to maximum value */
  142.  
  143. scr.bold_caps=TRUE;   /* turn on bold_caps */
  144.  
  145. /* find out how many options are in pull-down menu */
  146.  
  147. for(i=0;i<nu_opt;i++){
  148.   /* scan until empty string found */
  149.   if (m_menu[option].sub[i][0] == '\0'){  
  150.    nu_opt = i;
  151.    break;
  152.   }
  153. }
  154.  
  155. start=3;  /* Figure where to draw pull-down box.
  156.              The column must begin at least on the 3rd column.
  157.              We can calculate the column at which to place
  158.              the pull-down window by adding up the lengths
  159.              of the main menu options appearing before
  160.              the current option. */
  161.  
  162.   for(i=0; i< option; i++)  start= start+strlen(m_menu[i].main)+3;
  163.  
  164.   width=0;      /* figure max length of window, assume 0 to start */
  165.   for (i=0;i< nu_opt;i++){
  166.    if (strlen(m_menu[option].sub[i]) > width){
  167.     /* set width to largest strlen */
  168.     width= strlen(m_menu[option].sub[i]);    
  169.    }
  170.   }
  171.  
  172.  /* move box to left if it will spill off right side */
  173.  if(start+width+1>scr.columns) start = scr.columns-width-2;
  174.  
  175.  /* create pull-down window based on calculated values */
  176.  pd_win= win_make(start++,PD_SUB_ROW,width,nu_opt,PD_SUB_FRAME,"",\
  177.           color.pd_frame,color.pd_interior); /*make a window */
  178.  cursor(NO_CURSOR); /* turn off cursor for this window */
  179.  
  180.  y=1;  /* reposition in pull-down window for writing */
  181.  
  182.   for(;;){     /* begin endless loop while we process input */
  183.          y=1;
  184.         /* if a selection is made, turn off bold_caps */
  185.         if (found )scr.bold_caps=FALSE;
  186.          else scr.bold_caps=TRUE;
  187.  
  188.    /* print options in pull-down menu highlighing current option */
  189.          for(i=0;i< nu_opt;i++){
  190.            if(i == cur_opt) scr.current= color.pd_inverse;
  191.             else scr.current= color.pd_interior;
  192.             print(1,y++,m_menu[option].sub[i]);
  193.          };
  194.  
  195.           if(found ) {  /* an option is selected */
  196.  
  197.             scr.bold_caps=FALSE;  /* turn off bold caps */
  198.              /* if function pointer =NULL return specified code */
  199.              /* else call function */
  200.              if (m_menu[option].fun[cur_opt]==NULL)
  201.               return_code=m_menu[option].select_id[cur_opt];
  202.               else
  203.               return_code=(*m_menu[option].fun[cur_opt])() ;
  204.                win_pop_top(pd_win);
  205.  
  206.             /* exit pull-down if expert and return_code >0 */
  207.             if(*expert==TRUE && return_code >=0)break;
  208.  
  209.             if(return_code>0) break;
  210.             /* reset for next pass */
  211.             if(return_code <0) return_code=0;
  212.             found = FALSE;
  213.             scr.bold_caps=TRUE;
  214.             /* make sure keyboard buffer is clear */
  215.             if (kbhit()) getch();  
  216.           } /* end found */
  217.           else {         /* begin not found */
  218.  
  219.             /* get a character */
  220.             get_key(&ch,ext); ch=toupper(ch);  
  221.  
  222.             /* adjust cur_opt if up or down cursor key pressed */
  223.             if (*ext == DOWN )  cur_opt = cur_opt +1;
  224.             if (*ext == UP)  cur_opt = cur_opt -1;
  225.  
  226.             /* test for boundary and wrap if necessary */
  227.             if (cur_opt >= nu_opt) cur_opt =0;
  228.             if (cur_opt < 0) cur_opt = nu_opt-1;
  229.  
  230.            /* has a regular letter key been pressed? */
  231.            if(ch=='\0') *expert=FALSE; 
  232.  
  233.            if (ch== RETURN){  /* user pressed "Enter" */
  234.              found = TRUE;
  235.              *expert=FALSE;
  236.            }
  237.  
  238.            if(ch!='\0'){    /* check for quick keys */
  239.             for(i=0;i<nu_opt;i++){   /* do for each option */
  240.              j=0;
  241.  
  242.             /* check each letter in option to
  243.                see if it matches character */
  244.  
  245.               while( m_menu[option].sub[i][j]!='\0'){
  246.                if ( m_menu[option].sub[i][j++]==ch && ch != ' '){
  247.                 cur_opt = i;
  248.                 found = TRUE;
  249.                 break;
  250.                }
  251.               }
  252.              } /* end for(); */
  253.            }   /* end if(ch) */
  254.           }    /* end else */
  255.  
  256.            /* check for options which would exit pull-down */
  257.            if (*ext==LEFT || *ext==RIGHT) break;
  258.            if (ch==ESCAPE){          /* EXIT IF ESCAPE KEY */
  259.             *ext = ch;
  260.             break;
  261.            }
  262.            *ext=' ';ch=' ';
  263.   } /* end for(;;)*/
  264.  
  265.   /* exit pull-down */
  266.   win_delete(pd_win);
  267.   return (return_code);
  268. }
  269.