home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR21 / DOUGM.ZIP / DM168SRC.ZIP / DOUGMENU.C next >
Text File  |  1992-08-17  |  10KB  |  345 lines

  1. /***************************************************************************/
  2. /*                Dougmenu for DOS  Aug 15, 1992                           */
  3. /*                                                                         */
  4. /*        This code can be compiled using Microsoft C 6.0a.                */
  5. /*                                                                         */
  6. /*        The compile can be buggy with the routines Break_Off             */
  7. /*        and Check_Disk_Space - Microsoft's problem, not mine.            */
  8. /*                                                                         */
  9. /*        A list of all the routines grouped by module can be found        */
  10. /*                         in dougmenu.h                                   */
  11. /***************************************************************************/
  12. #define VERSION_STRING   "DougMenu v1.68"
  13.  
  14.  
  15. #include <stdio.h>
  16. #include <conio.h>
  17. #include <string.h>
  18. #include <malloc.h>
  19.  
  20. #include "nwbindry.h" //  Replace "" with <> if you already
  21. #include "nwlocal.h"  //  have the Novell API
  22.  
  23. #include "dougmenu.h"
  24. #include "novell.c"
  25. #include "parse.c"
  26. #include "draw.c"
  27. #include "input.c"
  28. #include "execute.c"
  29. #include "misc.c"
  30.  
  31. /***************************************************************************/
  32. void Last_Window_Globals(void)
  33.  
  34. {
  35.     win_index--;
  36.  
  37.     current_menu = Win[win_index].menu;
  38.     current_item = Win[win_index].item;
  39.     top    = Win[win_index].top;
  40.     bottom = Win[win_index].bottom;
  41.     left   = Win[win_index].left;
  42.     right  = Win[win_index].right;
  43.     width  = Win[win_index].width;
  44.     height = Win[win_index].height;
  45. }
  46.  
  47. /***************************************************************************/
  48. boolean Windowfy_Menu(menu)
  49.  
  50. Menu *menu;
  51.  
  52. {
  53.     if (menu == NULL){
  54.         current_item = Win[win_index].item; 
  55.         return(NO);
  56.     }
  57.     if (win_index == MAX_RECURSION){
  58.         Error_Box("Only 10 windows can open at a time.","The next menu cannot be displayed.");
  59.         current_item = Win[win_index].item;
  60.         return(NO);
  61.     }
  62.  
  63.     win_index++;
  64.     current_menu = menu;
  65.  
  66.         /* determine hight and width */
  67.     height = current_menu->number_of_items+3;
  68.     width = current_menu->title_length+3;
  69.     current_item = current_menu->first_item;
  70.  
  71.     while (current_item != NULL){
  72.         if (quick_select && current_item->first_line != NULL){
  73.             if (width < current_item->title_length+6)
  74.                 width = current_item->title_length+6;
  75.         }
  76.         else{    
  77.             if (width < current_item->title_length+3)
  78.                 width = current_item->title_length+3;
  79.         }
  80.         current_item=current_item->next_item;
  81.     }
  82.  
  83.     if (height > (byte)(max_screen_y-4) || width >= max_screen_x){
  84.         Last_Window_Globals();
  85.         Error_Box("Unable to display menu.","The menu is too large.");
  86.         return(NO);
  87.     }
  88.  
  89.         /* determine left,right, top, and bottom */
  90.     left    = current_menu->offset_x;
  91.     top     = current_menu->offset_y;
  92.     if (left == CENTER)
  93.             left   = (byte)( (max_screen_x - width)/2 );
  94.     if (top == CENTER)
  95.             top    = (byte)( (max_screen_y - height)/2 );
  96.  
  97.     else if (cascade && current_menu->offset_x == Win[0].left &&
  98.              current_menu->offset_y == Win[0].top){
  99.         left   = (byte) ( Win[0].left + (win_index) * cascade_x );
  100.         top    = (byte) ( Win[0].top + (win_index) * cascade_y );
  101.     }    
  102.  
  103.     if (top <3)
  104.         top = 3;
  105.  
  106.     right = left + width;
  107.     if (right >= (byte)(max_screen_x-1) ){
  108.         right = (byte)(max_screen_x-2);
  109.         left = (byte)(right - width);
  110.     }
  111.  
  112.     bottom = top + height;
  113.     if (bottom > (byte)(max_screen_y-1) ){
  114.         bottom = (byte)(max_screen_y-1);
  115.         top = (byte)(bottom - height);
  116.     }
  117.  
  118.         /* determine if this is a valid menu to display */
  119.     current_item = Home_Item();
  120.     if (current_item == NULL){
  121.         Last_Window_Globals();
  122.         Error_Box("Unable to display menu.","The menu has no choosable options.");
  123.         return(NO);
  124.     }
  125.  
  126.     Win[win_index].menu    = current_menu;
  127.     Win[win_index].item    = current_item;
  128.     Win[win_index].top     = top;
  129.     Win[win_index].left    = left;
  130.     Win[win_index].right   = right;
  131.     Win[win_index].width   = width;
  132.     Win[win_index].bottom  = bottom;
  133.     Win[win_index].height  = height;
  134.     if (win_index) Win[win_index].storage = Store_Screen();
  135.  
  136.     return(YES);
  137. }
  138.  
  139. /***************************************************************************/
  140. Item *Number_To_Item(number)
  141.  
  142. byte number;
  143.  
  144. {
  145.     Item *item = current_item;
  146.  
  147.     if (number > current_menu->number_of_items)
  148.         return ( current_item );
  149.     
  150.     while (item->item_number < number)
  151.         item = item->next_item;
  152.     while (item->item_number > number) 
  153.         item = item->last_item;
  154.  
  155.     return(item);
  156. }
  157.  
  158. /***************************************************************************/
  159. Item *Home_Item()
  160.  
  161. {
  162.     Item *item = current_menu->first_item;
  163.     
  164.     while (item->first_line == NULL){
  165.         item = item->next_item;
  166.         if (item == NULL)     /* if no selectable items */
  167.             return(NULL);
  168.     }
  169.     return(item);
  170. }
  171.  
  172. /***************************************************************************/
  173. Item *End_Item()
  174.  
  175. {
  176.     Item *item = current_item;
  177.  
  178.     while (item->next_item != NULL)
  179.         item = item->next_item;
  180.  
  181.     while (item->first_line == NULL)
  182.         item = item->last_item;
  183.  
  184.     return(item);
  185. }
  186.  
  187. /***************************************************************************/
  188. Item *Previous_Item()
  189. {
  190.     Item *item = current_item->last_item;
  191.  
  192.     if (item == NULL)
  193.         return( End_Item() );
  194.     while (item->first_line == NULL){
  195.         if (item->last_item == NULL)
  196.             return( End_Item() );
  197.         item = item->last_item;        
  198.     }
  199.     return(item);
  200. }
  201.  
  202. /***************************************************************************/
  203. Item *Next_Item()
  204. {
  205.     Item *item = current_item->next_item;
  206.  
  207.     if (item == NULL)
  208.         return( Home_Item () );
  209.  
  210.     while (item->first_line == NULL){
  211.         if (item->next_item == NULL)
  212.             return( Home_Item () );
  213.         item = item->next_item;        
  214.     }
  215.     return(item);
  216. }
  217.  
  218. /***************************************************************************/
  219. void Remove_Window()
  220.  
  221. {
  222.     byte number_to_remove=1;
  223.     if (event.action == ESCAPE)
  224.         number_to_remove = event.data;
  225.     
  226.     if (shadow) Remove_Shadow();
  227.  
  228.     while ( number_to_remove-- > 0){
  229.         Restore_Screen(Win[win_index].storage);
  230.         Last_Window_Globals();    
  231.     }
  232. }
  233.  
  234. /***************************************************************************/
  235. Menu *Find_Menu(title_text)
  236.  
  237. Linked_Text *title_text;
  238.  
  239. {
  240.     char *menu_to_find;
  241.     Menu *menu_to_check = first_menu;
  242.  
  243.  
  244.     while ( title_text != NULL && *(title_text->text_line) != '%' ){
  245.         if( title_text->text_line[0]!='#' )
  246.             return(NULL);
  247.         if(Compare(title_text->text_line,"#if"))
  248.             return(NULL);
  249.         title_text = title_text->next_line;
  250.     }
  251.     if (title_text == NULL)
  252.         return(NULL);
  253.  
  254.     menu_to_find = title_text->text_line;
  255.     menu_to_find++;                              /* chop off '%' */
  256.   
  257.     while ( strcmpi(menu_to_find,menu_to_check->title) )
  258.         if ((menu_to_check = menu_to_check->next_menu) == NULL){
  259.             Error_Box("Unable to locate menu labeled:",menu_to_find);    
  260.             return(NULL);
  261.         }
  262.     return (menu_to_check);
  263. }
  264.  
  265. /***************************************************************************/
  266. void main( argc, argv )
  267.           
  268. int argc;
  269. char *argv[];
  270.  
  271. {
  272.     if ( argc < 2 ){
  273.         fputs("Dougmenu.exe should be called from inside DMENU.BAT\n",stderr);
  274.         exit(LEAVE_MENU);
  275.     }
  276.     Break_Off();
  277.         // Clear Keyboard Buffer 
  278.     while (kbhit())
  279.         getch();
  280.  
  281.     Get_Video_Info(argv[2]);
  282.     Fill_Screen(' ',7);
  283.     Set_Up_Enviroment();
  284.     Set_Up_Mouse();
  285.     Parse( argv[1] );
  286.     Set_Up_Screen();
  287.  
  288.  
  289.     for (;;){
  290.         Wait_For_Event();
  291.         if (event.action == KEY_PRESS)
  292.             Scan_For_Letter(event.data);            
  293.  
  294.         switch ( event.action ){
  295.             case MOVE_UP:
  296.                 Select(Previous_Item());
  297.                 break;
  298.             case MOVE_DOWN:
  299.                 Select(Next_Item());
  300.                 break;
  301.             case GOTO_BOTTOM:
  302.                 Select(End_Item());
  303.                 break;
  304.             case GOTO_TOP:
  305.                 Select(Home_Item());
  306.                 break;
  307.             case GOTO_ITEM:
  308.                 Select( Number_To_Item( event.data ) );
  309.                 break;
  310.             case ESCAPE:
  311.             case BACK_SPACE:
  312.                 if (win_index > 0){
  313.                     Remove_Window();
  314.                     Display_Menu(NULL);
  315.                     Select(current_item);
  316.                     break;
  317.                 }
  318.                 if (!exitable) 
  319.                     break;
  320.                 Display_Menu(current_item);
  321.                 Exit_Query();
  322.                 Display_Menu(NULL);
  323.                 Select(current_item);
  324.                 if (event.action != SPECIAL)
  325.                     break;
  326.  
  327.             case DO_ITEM: case SPECIAL:
  328.                 Win[win_index].item = current_item;
  329.                 Display_Menu( current_item );
  330.                 while ( event.action == DO_ITEM || event.action == SPECIAL){
  331.                     Win[win_index].event = DO_ITEM;
  332.                     if (event.action == SPECIAL){
  333.                         current_item = special_item[ event.data ];    
  334.                         Win[win_index].event = SPECIAL+event.data;
  335.                     }
  336.                     Execute_Item();
  337.                 }
  338.                 current_item = Win[win_index].item;
  339.                 Display_Menu( NULL );
  340.                 Select( current_item );
  341.                 break;
  342.         }
  343.     }
  344. }
  345.