home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / DSIIC2.ZIP / PD.C < prev    next >
C/C++ Source or Header  |  1991-07-15  |  9KB  |  273 lines

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