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

  1. /* Copyright (c) James L. Pinson 1990,1991  */
  2.  
  3. /**********************   L_LIST.C   ***************************/
  4.  
  5. #include "mydef.h"   /* always include this */
  6. #include <stddef.h>  /* we need the definition of NULL from here */
  7. #include <dos.h>     /* directory related header files */
  8.  
  9. #include <ctype.h>
  10. #include <stdio.h>
  11. #include <string.h>
  12.  
  13. /* load memory allocation header files for specific compiler */
  14.  
  15. #if defined QUICKC
  16.  
  17. #include "malloc.h"
  18. #include "memory.h"
  19.  
  20. #endif
  21.  
  22. #if defined TURBOC
  23.  
  24. #include <alloc.h>
  25. #include <mem.h>
  26. #include <stdlib.h>
  27. #include <dir.h>
  28.  
  29. #endif
  30.  
  31.  
  32. /*****************************************************************
  33.  
  34.  Usage: int list_select (char *ptr[]);
  35.  
  36.  
  37.         char *ptr[]= Array of pointers, each of which points to
  38.                      to a option. The pointer following the last
  39.                      option must be NULL.
  40.  
  41.  This function allows selection from a list of options.  The user
  42.  may point to the option using the Up/Down cursor keys, and select
  43.  by pressing Enter.   Pressing Escape exits without making a
  44.  selection.
  45.  
  46.  The user may also Speed Search by typing in the option. As the
  47.  user types in the text, the option most closely matching the typed
  48.  text is highlighted.  Actual selection must still be made by
  49.  pressing Enter.
  50.  
  51.  The number corresponding to the selection is returned.  A -1
  52.  indicates the user pressed Escape without making a selection.
  53.  
  54. *****************************************************************/
  55.  
  56. int list_select (char *ptr[])
  57. {
  58. extern struct  screen_structure scr;
  59. extern struct window_structure w[];
  60.  
  61. int current_opt=0;    /* highlighted current option */
  62. int top_opt=0;        /* first option in window */
  63. int offset=0;         /* distance between top_opt and current_opt */
  64. int last_opt;         /* the last option which was highlighted */
  65. int height;           /* height of the window */
  66. int last=0;           /* last element in pointer array */
  67. int i=0,y,j=0;        /* general purpose */
  68. char ch,ext;          /* character and extension*/
  69. int sub_search=0;     /* index for location within search string */
  70. int sub_option=0 ;    /* index for location within list options */
  71. char search[MAX_STRING];  /* holds the speedsearch characters */
  72. int redraw=TRUE;          /* flag which forces a redraw of selection
  73.                              window */
  74. int start,end;            /* pre-existing start end scan lines */
  75. height = scr.bottom-scr.top +1;   /* height of selection window */
  76.  
  77. /* find out how many options are in the NULL terminated
  78.    array of pointers */
  79.  
  80. for(last=0;ptr[last++]!=NULL;);
  81. last-=2;     /* decrease by one so "last"
  82.                 now indicates the last option */
  83.  
  84. scr.current=scr.normal;
  85. what_cursor(&start,&end);
  86.  
  87. /* draw initial window */
  88.  
  89. cursor(NO_CURSOR); /* turn off cursor */
  90. y=1;
  91.  
  92. /* begin loop to process use selection */
  93.  
  94.  for(;;){
  95.  
  96.   if(redraw){     /* redraw the window contents */
  97.    alt_screen(ON); /* turn on alternate screen so that
  98.                       redraw appears to be instantaneous */
  99.    cls();
  100.    y=1;    /* y location (row) to print option */
  101.    scr.current=scr.normal;      /* start with normal attribute */
  102.  
  103.     for(i=top_opt;i<top_opt+height;i++){
  104.     if (ptr[i]==NULL) break;     /* stop if we go too far */
  105.      if (i==current_opt)scr.current=scr.inverse;
  106.  
  107.       /* highlight current option */
  108.       print (1,y++,ptr[i]);
  109.       scr.current=scr.normal;   /* reset to normal */
  110.     }
  111.    alt_screen(OFF);
  112.    redraw=FALSE;
  113.   } /* end if (redraw) */
  114.  
  115.   ch='\0';ext='\0';       /* reset character and extension */
  116.   get_key( &ch, &ext);    /* get character and extension */
  117.  
  118.   /* scan list of options match search key */
  119.  
  120.   /* make sure we have a valid letter, number or punctuation */
  121.   if (ch>=32 && ch <=126 ) {
  122.  
  123.    /* here we search to find match for speed search letters */
  124.    last_opt=current_opt;     /* save the highlight position */
  125.  
  126.    if(sub_search==0){     /* are we looking for the first letter
  127.                              of the word? */
  128.      for(i=0;i<=last;i++){  /* scan each list option */
  129.        sub_option=0;    /* look for the first letter within option */
  130.        while(ptr[i][sub_option]==' ') sub_option++; /* skip spaces */
  131.  
  132.        if(toupper(ptr[i][sub_option])==toupper(ch)){ /* match*/
  133.             search[sub_search]=ch;  /* add it to the speed search
  134.                                        string */
  135.             offset=current_opt-top_opt;  /* difference between window
  136.                                             top and highlighter */
  137.             current_opt=i;      /* set current_opt to option found */
  138.             sub_search++;       /* reposition indexes within search */
  139.             sub_option++;       /* string and option */
  140.  
  141.             break;
  142.        }
  143.      }  /* end scan each list option */
  144.    } /* end first letter */
  145.    else{    /* No longer the first letter.
  146.                The next loop examines further letters within the
  147.                current highlighted option to see if they still
  148.                match ch.*/
  149.  
  150.    if(toupper(ptr[current_opt][sub_option]) != toupper(ch)){
  151.       /* Match with current highlighted option fails.
  152.          Scan list to see if we can match string elsewhere. */
  153.  
  154.      search[sub_search]=ch;  /* finish building string */
  155.      search[sub_search+1]='\0';
  156.      sub_search=0;    /* reset to begin search at first letter */
  157.  
  158.       /* see if a match exists anywhere else */
  159.  
  160.       for(i=0;i<=last;i++){   /* examine each option */
  161.        sub_option=0;          /* start at beginning of
  162.                                  each option */
  163.        while(ptr[i][sub_option]==' ') /* skip space */
  164.            sub_option++;
  165.  
  166.            j=pos(&ptr[i][sub_option],search); /* is search string
  167.                                                  in option? */
  168.            if (j==0){                     /* search string found */
  169.             offset=current_opt-top_opt;  /* calculate distance
  170.                                             (top to current)*/
  171.             current_opt=i;
  172.             sub_search=strlen(search);
  173.             sub_option=j+strlen(search);
  174.             break;
  175.            }
  176.       } /* end (examine each option) */
  177.  
  178.    } /* end failed to match within current option */
  179.      else
  180.       {   /* current option still matches search key */
  181.        search[sub_search]=ch;
  182.        sub_search++;
  183.       }
  184.    } /* end of (not first letter) */
  185.  
  186. /* the following code moves the highlighter or
  187.    requests a redraw as needed */
  188.  
  189.  
  190.   /* is new selection beyond window?  */
  191.  
  192.   if(current_opt >top_opt+ height-1 || current_opt < top_opt){
  193.     top_opt=current_opt-offset;   /* keep the offset the same */
  194.     if (top_opt <0) top_opt=0;    /* correct if off top of window */
  195.     redraw=TRUE;                  /* redraw window */
  196.   } else{
  197.                /* new option is within displayed page */
  198.                /* un-highlight old position and redraw highlight */
  199.      scr.current=scr.normal;  /* over-write highlighter with
  200.                                  normal attribute */
  201.      print(1,last_opt-top_opt+1,ptr[last_opt]);
  202.  
  203.      scr.current=scr.inverse;  /* print new highlighter */
  204.      print(1,current_opt-top_opt+1,ptr[current_opt]);
  205.     }
  206.  
  207.   } /* end valid letter */
  208.  
  209.   else /* not valid letter */
  210.   {
  211.    sub_search=0;  /* reset sub_search to look for first letter */
  212.  
  213.     if(ch==RETURN || ch==ESCAPE){ /* selection made or Escape key */
  214.       scr.current= scr.normal;
  215.       set_cursor(start,end);
  216.      if (ch==RETURN) return(current_opt); /* item selected */
  217.       else
  218.        return(-1);         /* no selection */
  219.     }
  220.      y=current_opt-top_opt+1;   /* y = distance from top of window
  221.                                    to highlighter */
  222.  
  223.    /* down arrow and not at bottom of window */
  224.    if (ext==DOWN && y<height && current_opt<last ){
  225.      /* overwrite highlighter with normal attribute */
  226.      scr.current=scr.normal;
  227.      print(1,y,ptr[current_opt]);
  228.  
  229.      scr.current=scr.inverse;
  230.      current_opt++;                  /* increment list pointer */
  231.      print(1,y+1,ptr[current_opt]);  /* print new highlighter */
  232.    }
  233.     else  /* down arrow and bottom of window */
  234.  
  235.    if (ext==DOWN && y==height && current_opt<last){
  236.  
  237.     /* rewrite current line with normal attribute */
  238.     scr.current=scr.normal;
  239.     print(1,y,ptr[current_opt]);
  240.     scroll_up (1);                    /* scroll window up */
  241.     current_opt++;                    /* increment positions */
  242.     top_opt++;
  243.     scr.current=scr.inverse;       /* print a new highlighter */
  244.     print(1,y,ptr[current_opt]);
  245.    }
  246.    if (ext==UP && y>1){   /* up arrow and not at top of window */
  247.      /* rewrite current line with normal attribute */
  248.      scr.current=scr.normal;
  249.      print(1,y,ptr[current_opt]);
  250.  
  251.      scr.current=scr.inverse;
  252.      current_opt--;               /* increment list pointer */
  253.      print(1,y-1,ptr[current_opt]); /* print new highlighter */
  254.    } else
  255.    if (ext==UP && y==1 && current_opt>0){  /* up arrow and top
  256.                                               of window */
  257.    /* rewrite current line with normal attribute */
  258.     scr.current=scr.normal;
  259.     print(1,y,ptr[current_opt]);
  260.     scroll_down (1);                 /* scroll window down */
  261.     current_opt--;                   /* move current_opt back */
  262.     top_opt--;
  263.  
  264.       scr.current=scr.inverse;       /* print new highlighter */
  265.      print(1,y-1,ptr[current_opt]);
  266.    }
  267.  
  268.   /* page down and not at end of selection list */
  269.   if(ext==PGDN && top_opt!= last) {
  270.     offset=current_opt-top_opt; /* how far is the highlighter
  271.                                    from the top of window? */
  272.     top_opt+=height;            /* increase top_opt by the height
  273.                                    of screen */
  274.     current_opt=top_opt+offset; /* increase current_opt for
  275.                                    new location */
  276.      /* check for boundary errors */
  277.     if(top_opt>last) top_opt=last;
  278.     if(current_opt>last) current_opt=last;
  279.  
  280.     redraw=TRUE;  /* force a redraw of list options */
  281.  
  282.   }
  283.   if(ext==PGUP && top_opt !=0){  /* PgUp pressed and not at top
  284.                                     of window */
  285.     offset=current_opt-top_opt;  /* move all positions up */
  286.     top_opt-=height;
  287.     current_opt=top_opt+offset;
  288.  
  289.     if(top_opt<0){     /* out of bounds ?*/
  290.      top_opt=0;        /* reset */
  291.      current_opt=offset;
  292.     }
  293.     redraw=TRUE;
  294.  
  295.   } /* end ext==PGUP */
  296.   } /* end of not valid letter */
  297.  
  298.  } /* end of for(;;) loop which reads user selection*/
  299. }
  300.