home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / FGDEMO40.ZIP / SOURCE.COM / MENU.C < prev    next >
Text File  |  1995-02-12  |  15KB  |  533 lines

  1. /**********************************************************************\
  2. *                                                                      *
  3. *  menu.c -- menu management functions                                 *
  4. *                                                                      *
  5. \**********************************************************************/
  6.  
  7. #include "defs.h"
  8.  
  9. MENU main_menu[] =
  10. {
  11.    { submenu1, "File",             6,  91, 1, 4},
  12.    { submenu2, "Video",           92, 190, 2, 0},
  13.    { submenu3, "Fundamentals",   191, 345, 3, 1},
  14.    { submenu4, "Display",        346, 457, 4, 2},
  15.    { submenu5, "Miscellaneous",  458, 633, 0, 3}
  16. };
  17.  
  18. MENU menu1[] =
  19. {
  20.    {     about_fg, "About Fastgraph   ", 7, 174, 1,10},
  21.    {   about_demo, "About This Demo   ", 7, 174, 2, 0},
  22.    {   about_tech, "Technical Support ", 7, 174, 3, 1},
  23.    {   about_docs, "Documentation     ", 7, 174, 4, 2},
  24.    {   about_site, "Site Licenses     ", 7, 174, 5, 3},
  25.    { about_source, "Source Code       ", 7, 174, 6, 4},
  26.    {    about_fgl, "Fastgraph/Light   ", 7, 174, 7, 5},
  27.    {  about_order, "Order by Phone/FAX", 7, 174, 8, 6},
  28.    {   print_form, "Print Order Form  ", 7, 174, 9, 7},
  29.    {        shell, "Shell to DOS      ", 7, 174,10, 8},
  30.    { exit_program, "Exit              ", 7, 174, 0, 9}
  31. };
  32.  
  33. MENU menu2[] =
  34. {
  35.    {    about_modes, "Video Modes    ", 93, 230, 1, 6},
  36.    {    auto_detect, "Autodetect     ", 93, 230, 2, 0},
  37.    { physical_pages, "Physical Pages ", 93, 230, 3, 1},
  38.    {  virtual_pages, "Virtual Pages  ", 93, 230, 4, 2},
  39.    {  logical_pages, "Logical Pages  ", 93, 230, 5, 3},
  40.    {virtual_buffers, "Virtual Buffers", 93, 230, 6, 4},
  41.    {    coordinates, "Coordinates    ", 93, 230, 0, 5}
  42. };
  43.  
  44. MENU menu3[] =
  45. {
  46.    {  do_points, "Points     ", 192, 324, 1, 8},
  47.    {   do_lines, "Lines      ", 192, 324, 2, 0},
  48.    {   do_rects, "Rectangles ", 192, 324, 3, 1},
  49.    {   do_boxes, "Boxes      ", 192, 324, 4, 2},
  50.    { do_circles, "Circles    ", 192, 324, 5, 3},
  51.    {do_ellipses, "Ellipses   ", 192, 324, 6, 4},
  52.    {do_polygons, "Polygons   ", 192, 324, 7, 5},
  53.    {    do_text, "Text       ", 192, 324, 8, 6},
  54.    {   do_paint, "Region Fill", 192, 324, 0, 7}
  55. };
  56.  
  57. MENU menu4[] =
  58. {
  59.    {   do_bitmaps, "Bitmaps     ", 347, 464, 1, 4},
  60.    {   do_scaling, "Scaling     ", 347, 464, 2, 0},
  61.    {  do_transfer, "Transfer    ", 347, 464, 3, 1},
  62.    {    do_scroll, "Scroll      ", 347, 464, 4, 2},
  63.    {     do_split, "Split Screen", 347, 464, 0, 3}
  64. };
  65.  
  66. MENU menu5[] =
  67. {
  68.    { do_keyboard, "Keyboard ", 459, 588, 1, 6},
  69.    { do_joystick, "Joystick ", 459, 588, 2, 0},
  70.    {    do_mouse, "Mouse    ", 459, 588, 3, 1},
  71.    {     do_bird, "Bird     ", 459, 588, 4, 2},
  72.    {  do_borland, "Borland  ", 459, 588, 5, 3},
  73.    {      do_dub, "Dub Media", 459, 588, 6, 4},
  74.    {do_histogram, "Histogram", 459, 588, 0, 5}
  75. };
  76.  
  77. /**********************************************************************\
  78. *                                                                      *
  79. *  highlight option -- highlight an option on the main menu            *
  80. *                                                                      *
  81. \**********************************************************************/
  82.  
  83. void highlight_option(int n)
  84. {
  85.    int y;
  86.  
  87.    y = menu_top + PTSIZE + 1;
  88.  
  89.    /* set the color to black, draw a rectangle */
  90.  
  91.    fg_setcolor(0);
  92.    fg_rect(main_menu[n].x1,main_menu[n].x2,menu_top,menu_bottom-1);
  93.  
  94.    /* set the color to white, write the text */
  95.  
  96.    fg_setcolor(15);
  97.    center_pstring(main_menu[n].menu_item,main_menu[n].x1,main_menu[n].x2,y);
  98. }
  99.  
  100. /**********************************************************************\
  101. *                                                                      *
  102. *  horizontal_menu -- main menu function. All the vertical submenu     *
  103. *  functions are called from this function, and this function contains *
  104. *  the main program loop. Parameters are passed to horizontal menu     *
  105. *  as follows:                                                         *
  106. *                                                                      *
  107. *  MENU menutab[] -- this is the command table, an array of structures *
  108. *                    defining the menu commands, the location and the  *
  109. *                    function to be called when this item is selected. *
  110. *                                                                      *
  111. *  int n -- number of items on the horizontal menu                     *
  112. *                                                                      *
  113. *  int current -- the current highlighted option                       *
  114. *                                                                      *
  115. \**********************************************************************/
  116.  
  117. horizontal_menu(struct menu *menutab,int n,int current)
  118. {
  119.    register int i, k;
  120.    int c;
  121.    int found, choice;
  122.    int ymin, ymax;
  123.    char l;
  124.    int foregrnd, backgrnd;
  125.    int hilite_fgnd, hilite_bkgnd;
  126.  
  127.    /* colors for highlighted and unhighted text and background */
  128.  
  129.    foregrnd = 0; backgrnd = 15; hilite_fgnd = 15; hilite_bkgnd = 0;
  130.  
  131.    /* check if current item is out of range */
  132.  
  133.    if (current >= abs(n))
  134.       return(ERR);
  135.  
  136.    ymin = menu_top;
  137.    ymax = ymin + PTSIZE + 1;
  138.  
  139.    fg_mousevis(OFF);
  140.  
  141.    /* set up the list of options -- display the menu on the screen */
  142.    if (n < 0)
  143.    {
  144.       for (i = 0; i < abs(n); i++)
  145.       {
  146.          fg_setcolor(backgrnd);
  147.          fg_rect(menutab[i].x1,menutab[i].x2,ymin,ymax);
  148.          fg_setcolor(foregrnd);
  149.          center_pstring(menutab[i].menu_item,menutab[i].x1,menutab[i].x2,ymax);
  150.       }
  151.    }
  152.  
  153.    /* if we're just displaying the menu options, return */
  154.  
  155.    if (current < 0) return (OK);
  156.  
  157.    /* highlight current option */
  158.  
  159.    i = (current);
  160.  
  161.    fg_setcolor(hilite_bkgnd);
  162.    fg_rect(menutab[i].x1,menutab[i].x2,ymin,ymax);
  163.    fg_setcolor(hilite_fgnd);
  164.    center_pstring(menutab[i].menu_item,menutab[i].x1,menutab[i].x2,ymax);
  165.    fg_mousevis(ON);
  166.  
  167.    /* A negative number is a flag to display the options and return
  168.       without taking any action. */
  169.  
  170.    if (n < 0)  return(OK);
  171.  
  172.    /* choose an option */
  173.  
  174.    choice = current;
  175.    fg_setnum(OFF);
  176.    flushkey();
  177.  
  178.    for(;;)
  179.    {
  180.       /* activate the corresponding vertical menu */
  181.  
  182.       c = (*menutab[i].menu_func)();
  183.  
  184.       /* cycle through choices */
  185.  
  186.       if (c == LEFT_ARROW || c == BS)
  187.          choice = menutab[i].prev;
  188.  
  189.       else if (c == RIGHT_ARROW || c == SPACEBAR)
  190.          choice = menutab[i].next;
  191.  
  192.       else if (c >= 0 && c <= n)
  193.          choice = c;
  194.  
  195.       else if (c == ESC)
  196.       {
  197.          exit_program();
  198.       }
  199.  
  200.       else if (isalpha(c))
  201.       {
  202.           c = tolower(c);
  203.           found = FALSE;
  204.           for (k = i+1; k < n; k++)
  205.           {
  206.              l = first_nonblank(menutab[k].menu_item);
  207.              if (c == tolower((int)l))
  208.              {
  209.                 found = TRUE;
  210.                 break;
  211.              }
  212.           }
  213.           if (!found)
  214.           {
  215.              for (k = 0; k <= i; k++)
  216.              {
  217.                 l = first_nonblank(menutab[k].menu_item);
  218.                 if (c == (char)tolower((int)l))
  219.                 {
  220.                    found = TRUE;
  221.                    break;
  222.                 }
  223.              }
  224.          }
  225.          if (found)
  226.             choice = k;
  227.       }
  228.  
  229.       if (i != choice)
  230.       {
  231.  
  232.          /* unmark previous option */
  233.  
  234.          fg_mousevis(OFF);
  235.          fg_setcolor(backgrnd);
  236.          fg_rect(menutab[i].x1,menutab[i].x2,ymin,ymax);
  237.          fg_setcolor(foregrnd);
  238.          center_pstring(menutab[i].menu_item,menutab[i].x1,menutab[i].x2,ymax);
  239.  
  240.          /* mark new option */
  241.  
  242.          i = choice;
  243.          fg_setcolor(hilite_bkgnd);
  244.          fg_rect(menutab[i].x1,menutab[i].x2,ymin,ymax);
  245.          fg_setcolor(hilite_fgnd);
  246.          center_pstring(menutab[i].menu_item,menutab[i].x1,menutab[i].x2,ymax);
  247.          fg_mousevis(ON);
  248.       }
  249.    }
  250. }
  251.  
  252. /**********************************************************************\
  253. *                                                                      *
  254. *  submenus -- functions called from the horizontal menu               *
  255. *                                                                      *
  256. \**********************************************************************/
  257.  
  258. int submenu1()
  259. {
  260.    return(vertical_menu(menu1,0,11));
  261. }
  262. int submenu2()
  263. {
  264.    return(vertical_menu(menu2,1,7));
  265. }
  266. int submenu3()
  267. {
  268.    return(vertical_menu(menu3,2,9));
  269. }
  270. int submenu4()
  271. {
  272.    return(vertical_menu(menu4,3,5));
  273. }
  274. int submenu5()
  275. {
  276.    return(vertical_menu(menu5,4,7));
  277. }
  278.  
  279. /**********************************************************************\
  280. *                                                                      *
  281. *  vertical_menu -- submenu from horizontal menu. This function        *
  282. *  works almost the same as the horizontal menu function.              *
  283. *                                                                      *
  284. \**********************************************************************/
  285.  
  286. vertical_menu(struct menu *menutab,int index,int n)
  287. {
  288.     register int i, j, k;
  289.     int found, choice;
  290.     int height;
  291.     int left, right;
  292.     int string_x;
  293.     int x1, x2, y1, y2;
  294.     int ymin, ymax;
  295.     int count;
  296.     char c, l;
  297.     unsigned char key, aux;
  298.     int foregrnd, backgrnd;
  299.     int hilite_fgnd, hilite_bkgnd;
  300.  
  301.     foregrnd = 0; backgrnd = 15; hilite_fgnd = 15; hilite_bkgnd = 0;
  302.  
  303.     /* height in pixels of an individual menu item */
  304.  
  305.     height = PTSIZE + 2;
  306.  
  307.    /* the first menu item determines the x coordinate for the other items */
  308.  
  309.    string_x = get_center(menutab[0].menu_item,menutab[0].x1,menutab[0].x2);
  310.  
  311.    /* define the menu extremes */
  312.  
  313.    x1 = menutab[0].x1 - 1;
  314.    x2 = menutab[0].x2 + 3;
  315.    y1 = menu_bottom;
  316.    y2 = menu_bottom + n*height + 1;
  317.  
  318.    /* define the associated horizontal mouse limits */
  319.  
  320.     if (mouse)
  321.    {
  322.       left  = mouse_limits[index];
  323.       right = mouse_limits[index+1] - 2;
  324.    }
  325.  
  326.    /* display the vertical menu if necessary */
  327.  
  328.    if (redraw)
  329.    {
  330.       /* do this stuff on the hidden page to make it look faster */
  331.  
  332.       fg_setpage(hidden);
  333.  
  334.       /* draw the menu outline and the shadow around it */
  335.  
  336.       fg_mousevis(OFF);
  337.       fg_setcolor(backgrnd);
  338.       fg_box(x1,x2-2,y1,y2-1);
  339.       fg_setcolor(8);
  340.       fg_rect(x1+2,x2,y2,y2);
  341.       fg_rect(x2-1,x2,y1+2,y2);
  342.       fg_setcolor(foregrnd);
  343.       fg_box(x1,x2-2,y1,y2-1);
  344.  
  345.       /* set up list of options */
  346.  
  347.       ymax = menu_bottom - 1;
  348.       for (i = 0; i < n; i++)
  349.       {
  350.          ymin = ymax + 1;
  351.          ymax = ymin + height - 1;
  352.          fg_setcolor(backgrnd);
  353.          fg_rect(menutab[i].x1,menutab[i].x2,ymin,ymax);
  354.             fg_setcolor(foregrnd);
  355.             put_pstring(menutab[i].menu_item,string_x,ymax);
  356.         }
  357.  
  358.         /* highlight first or previously selected option */
  359.  
  360.         i = selection;
  361.         ymin = menu_bottom + i*height;
  362.         ymax = ymin + height - 1;
  363.         fg_setcolor(hilite_bkgnd);
  364.         fg_rect(menutab[i].x1,menutab[i].x2,ymin,ymax);
  365.         fg_setcolor(hilite_fgnd);
  366.         put_pstring(menutab[i].menu_item,string_x,ymax);
  367.  
  368.         /* restore the menu to the visual page */
  369.  
  370.         fg_setpage(visual);
  371.         fg_restore(x1,x2,y1,y2);
  372.         redraw = FALSE;
  373.         fg_setpage(hidden);
  374.  
  375.         /* clear the hidden page under the menu */
  376.  
  377.         fg_setcolor(15);
  378.         fg_rect(x1,x2,y1,y2);
  379.         fg_setcolor(11);
  380.         fg_drect(x1,x2,y1,y2,matrix2);
  381.  
  382.         fg_setpage(visual);
  383.         fg_mousevis(ON);
  384.     }
  385.  
  386.     /* choose an option */
  387.  
  388.     i = selection;
  389.     choice = i;
  390.     fg_setnum(OFF);
  391.     flushkey();
  392.  
  393.     for(;;)
  394.     {
  395.         /* read a keystroke */
  396.  
  397.         fg_mousevis(ON);
  398.         fg_waitfor(1);
  399.         fg_intkey(&key,&aux);
  400.  
  401.       /* if using a mouse, check its position */
  402.  
  403.       if (mouse && key+aux == 0)
  404.       {
  405.          fg_mousebut(1,&count,&xmouse,&ymouse);
  406.  
  407.          if (count > 0)
  408.          {
  409.             if (BETWEEN(xmouse,x1,x2) && BETWEEN(ymouse,y1,y2-2))
  410.             {
  411.                choice = (ymouse - y1) / height;
  412.  
  413.                /* check if this is the second click of a double click */
  414.  
  415.                if (i == choice)
  416.                   key = CR;
  417.             }
  418.             else if (!BETWEEN(xmouse,left,right) && BETWEEN(ymouse,menu_top,y1-1))
  419.             {
  420.                fg_mousevis(OFF);
  421.                fg_restore(0,xlimit,menu_bottom,ylimit);
  422.                redraw = TRUE;
  423.                selection = 0;
  424.                for (j = 0; j <= ITEMS; j++)
  425.                {
  426.                  if (BETWEEN(xmouse,mouse_limits[j],mouse_limits[j+1]))
  427.                     return(j);
  428.                }
  429.             }
  430.          }
  431.       }
  432.  
  433.       /* cycle through choices */
  434.  
  435.       if (aux == UP_ARROW || key == BS)
  436.          choice = menutab[i].prev;
  437.       else if (aux == DOWN_ARROW || key == SPACEBAR)
  438.          choice = menutab[i].next;
  439.  
  440.       else if (aux == HOME || aux == PAGE_UP)
  441.          choice = 0;
  442.  
  443.       else if (aux == END || aux == PAGE_DOWN)
  444.          choice = n - 1;
  445.  
  446.       else if (aux == LEFT_ARROW || aux == RIGHT_ARROW)
  447.       {
  448.          fg_mousevis(OFF);
  449.          fg_restore(0,xlimit,menu_bottom,ylimit);
  450.          redraw = TRUE;
  451.          selection = 0;
  452.          return((int)aux);
  453.       }
  454.  
  455.       /* pick one choice */
  456.  
  457.       else if (key == CR)
  458.       {
  459.          (*menutab[i].menu_func)();
  460.          wait_for_mouse_buttons();
  461.          selection = i;
  462.          return(index);
  463.       }
  464.  
  465.       else if (key == ESC)
  466.       {
  467.          selection = 0;
  468.          return(ESC);
  469.       }
  470.       else if (isalpha((int)key))
  471.       {
  472.           c = (char)tolower((int)key);
  473.           found = FALSE;
  474.           for (k = i+1; k < n; k++)
  475.           {
  476.              l = first_nonblank(menutab[k].menu_item);
  477.              if (c == (char)tolower((int)l))
  478.              {
  479.                 found = TRUE;
  480.                 break;
  481.              }
  482.           }
  483.           if (!found)
  484.           {
  485.              for (k = 0; k <= i; k++)
  486.              {
  487.                 l = first_nonblank(menutab[k].menu_item);
  488.                 if (c == (char)tolower((int)l))
  489.                 {
  490.                    found = TRUE;
  491.                    break;
  492.                 }
  493.              }
  494.          }
  495.          if (found)
  496.             choice = k;
  497.          else
  498.          {
  499.             redraw = TRUE;
  500.             return(-1);
  501.          }
  502.       }
  503.       else if (key+aux > 0) /* any other key */
  504.       {
  505.          redraw = TRUE;
  506.          return(-1);
  507.       }
  508.  
  509.       if (i != choice)
  510.       {
  511.          /* unmark previous option */
  512.  
  513.          ymin = menu_bottom + i*height;
  514.          ymax = ymin + height - 1;
  515.          fg_mousevis(OFF);
  516.          fg_setcolor(backgrnd);
  517.          fg_rect(menutab[i].x1,menutab[i].x2,ymin,ymax);
  518.          fg_setcolor(foregrnd);
  519.          put_pstring(menutab[i].menu_item,string_x,ymax);
  520.  
  521.          /* mark option */
  522.  
  523.          i = choice;
  524.          ymin = menu_bottom + i*height;
  525.          ymax = ymin + height - 1;
  526.          fg_setcolor(hilite_bkgnd);
  527.          fg_rect(menutab[i].x1,menutab[i].x2,ymin,ymax);
  528.          fg_setcolor(hilite_fgnd);
  529.          put_pstring(menutab[i].menu_item,string_x,ymax);
  530.       }
  531.    }
  532. }
  533.