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