home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Graphics / graphics-16000.iso / msdos / animutil / fastgfx / fgdemo / menu.c < prev    next >
Text File  |  1991-10-02  |  15KB  |  545 lines

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