home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 300-399 / ff344.lzh / RKMCompanion / Disk1.lzh / libraries / intuition / menus / menus.c < prev    next >
C/C++ Source or Header  |  1990-04-12  |  12KB  |  388 lines

  1. /* Menus.c */
  2. /* Compiled with Lattice C v5.02                                     */
  3. /* Compiler invoked with: lc -b1 -cfist -L -v -ms                    */
  4.  
  5. /* Copyright (c) 1990 Commodore-Amiga, Inc.
  6.  *
  7.  * This example is provided in electronic form by Commodore-Amiga, Inc. for
  8.  * use with the 1.3 revisions of the Addison-Wesley Amiga reference manuals. 
  9.  * The 1.3 Addison-Wesley Amiga Reference Manual series contains additional
  10.  * information on the correct usage of the techniques and operating system
  11.  * functions presented in this example.  The source and executable code of
  12.  * this example may only be distributed in free electronic form, via bulletin
  13.  * board or as part of a fully non-commercial and freely redistributable
  14.  * diskette.  Both the source and executable code (including comments) must
  15.  * be included, without modification, in any copy.  This example may not be
  16.  * published in printed form or distributed with any commercial product.
  17.  * However, the programming techniques and support routines set forth in
  18.  * this example may be used in the development of original executable
  19.  * software products for Commodore Amiga computers.
  20.  * All other rights reserved.
  21.  * This example is provided "as-is" and is subject to change; no warranties
  22.  * are made.  All use is at your own risk.  No liability or responsibility
  23.  * is assumed.
  24.  */
  25.  
  26. #include <exec/types.h>
  27. #include <intuition/intuition.h>
  28. #include <intuition/intuitionbase.h>
  29. #include <libraries/dos.h>
  30. #include <stdlib.h>
  31. #include <stdio.h>
  32. #include <string.h>
  33. #ifdef LATTICE
  34. #include <proto/all.h>
  35. int CXBRK(void) {return(0);}
  36. #endif
  37.  
  38. #include "Menus.h"
  39.  
  40. /* Use lowest non-obsolete version that supplies the functions you need. */
  41. #define LIB_REV 33
  42.  
  43. /* prototypes */
  44. UBYTE    handleIDCMP(struct Window *);
  45. VOID     OpenAll(VOID);
  46. VOID     cleanExit(int);
  47.  
  48. /* prototypes for functions used to determine menu sizing */
  49. BOOL     AdjustMenus(struct Menu *, struct TextAttr *);
  50. VOID     AdjustItems(struct RastPort *, struct MenuItem *, struct TextAttr *,
  51.                      USHORT, USHORT, USHORT, USHORT);
  52. VOID     AdjustText(struct  IntuiText *text, struct  TextAttr *attr);
  53. USHORT   MaxLength(struct RastPort *, struct MenuItem *, USHORT);
  54.  
  55. /* Globals */
  56. struct   IntuitionBase *IntuitionBase = NULL;
  57. struct   GfxBase       *GfxBase = NULL; 
  58. struct   Window *window = NULL;
  59.  
  60. VOID     main(int argc, char *argv[])
  61. {
  62. /* Declare variables here */
  63. ULONG  signalmask, signals;
  64. UBYTE  done = 0;
  65.  
  66. OpenAll();
  67.  
  68. /* Set up the signals that you want to hear about ... */
  69. signalmask = 1L << window->UserPort->mp_SigBit;
  70.  
  71. /* And wait to hear from your signals */      
  72. while( !done )
  73.    {
  74.    signals = Wait(signalmask);    
  75.    if(signals & signalmask)
  76.       done = handleIDCMP(window);
  77.    };
  78.  
  79. /* Exit the program */
  80. cleanExit(RETURN_OK);
  81. }
  82.  
  83.  
  84. /* Handle the IDCMP messages */
  85. UBYTE handleIDCMP( struct Window *win )
  86. {
  87. UBYTE  flag = 0;
  88. USHORT code, selection, flags;
  89. struct IntuiMessage *message = NULL;
  90. ULONG  class, menuNum, itemNum, subNum;
  91.  
  92. /* Examine pending messages */
  93. while(message = (struct IntuiMessage *)GetMsg(win->UserPort))
  94.    {
  95.    class = message->Class;
  96.    code = message->Code;
  97.  
  98. /* When we're through with a message, reply */
  99.    ReplyMsg((struct Message *)message);
  100.  
  101. /* See what events occurred */
  102.    switch( class )
  103.       {
  104.       case CLOSEWINDOW:
  105.          flag = 1;
  106.          break;
  107.       case MENUPICK:
  108.          selection = code;
  109.          while(selection != MENUNULL)
  110.             {
  111.             menuNum = MENUNUM(selection);
  112.             itemNum = ITEMNUM(selection);
  113.             subNum  = SUBNUM(selection);
  114.             flags = ((struct MenuItem *)
  115.                     ItemAddress(FirstMenu,(LONG)selection))->Flags;
  116.             printf("Selected ");
  117.             if(flags&CHECKED)
  118.                 printf("(Checked) ");
  119.             switch( menuNum )
  120.                {
  121.                case 0:    /* Project Menu */
  122.                   switch(itemNum)
  123.                      {
  124.                      case 0:
  125.                         printf("New\n");
  126.                         break;
  127.                      case 1:
  128.                         printf("Open\n");
  129.                         break;
  130.                      case 2:
  131.                         printf("Save\n");
  132.                         break;
  133.                      case 3:
  134.                         printf("Save As\n");
  135.                         break;
  136.                      case 4:
  137.                         printf("Print ");
  138.                         switch(subNum)
  139.                            {
  140.                            case 0:
  141.                               printf("NLQ\n");
  142.                               break;
  143.                            case 1:
  144.                               printf("Draft\n");
  145.                               break;
  146.                            }
  147.                         break;
  148.                      case 5:
  149.                         printf("About\n");
  150.                         break;
  151.                      case 6:
  152.                         printf("Quit\n");
  153.                         flag = 1;
  154.                         break;
  155.                      default:
  156.                         break;
  157.                      } /* end switch */
  158.                   break;
  159.                case 1:    /* Edit Menu */
  160.                   switch(itemNum)
  161.                      {
  162.                      case 0:
  163.                         printf("Undo\n");
  164.                         break;
  165.                      case 1:
  166.                         printf("Cut\n");
  167.                         break;
  168.                      case 2:
  169.                         printf("Copy\n");
  170.                         break;
  171.                      case 3:
  172.                         printf("Paste\n");
  173.                         break;
  174.                      case 4:
  175.                         printf("Erase All\n");
  176.                         break;
  177.                      default:
  178.                         break;
  179.                      } /* end switch */
  180.                   break;
  181.                case 2:    /* Preferences Menu */
  182.                   switch(itemNum)
  183.                      {
  184.                      case 0:
  185.                         printf("Sound\n");
  186.                         break;
  187.                      case 1:
  188.                         printf("Auto Save\n");
  189.                         break;
  190.                      case 2:
  191.                         printf("Have Your Cake\n");
  192.                         break;
  193.                      case 3:
  194.                         printf("Eat It Too\n");
  195.                         break;
  196.                      default:
  197.                         break;
  198.                      }
  199.                   break;
  200.                default:
  201.                   break;
  202.                } /* end switch */
  203.             selection = ((struct MenuItem *)ItemAddress
  204.               (FirstMenu,(LONG)selection))->NextSelect;
  205.          } /* end while */
  206.          break; /* case of MENUPICK */
  207.       default:
  208.          break;
  209.       } /* end switch */
  210.    } /* end while */
  211. return(flag);
  212. }
  213.  
  214.  
  215. /* Open the needed libraries, windows, etc. */
  216. VOID     OpenAll(VOID)
  217. {
  218. /* Open the Intuition Library */
  219. IntuitionBase = (struct IntuitionBase *)
  220.     OpenLibrary( "intuition.library",LIB_REV);
  221. if(IntuitionBase == NULL)
  222.     cleanExit(RETURN_WARN);
  223.  
  224. /* Open the Graphics Library */
  225. GfxBase = (struct GfxBase *)
  226.     OpenLibrary("graphics.library", LIB_REV);
  227. if(GfxBase == NULL)
  228.     cleanExit(RETURN_WARN);
  229.  
  230. /* Open the window */
  231. window = OpenWindow(&NewWindow);
  232. if(window == NULL)
  233.     cleanExit(RETURN_WARN);
  234.  
  235. /* Give a brief explanation of the program */
  236. PrintIText(window->RPort,&WinText[1],0,0);
  237.  
  238. /* Adjust the menu to conform to the font (TextAttr) */
  239. AdjustMenus(FirstMenu, window->WScreen->Font);
  240.  
  241. /* attach the menu to the window */
  242. SetMenuStrip(window, FirstMenu);
  243. }
  244.  
  245. /* Free up all the resources that we where using */
  246. VOID     cleanExit(int returnValue)
  247. {
  248. if(window)
  249.    {
  250. /* If there is a menu strip, then remove it */
  251.    if(window->MenuStrip)
  252.       ClearMenuStrip(window);
  253.  
  254. /* Close the window */
  255.    CloseWindow(window);
  256.    }
  257.  
  258. /* Close the library, and then exit */
  259. if(GfxBase)
  260.    CloseLibrary((struct Library *)GfxBase);
  261.  
  262. if(IntuitionBase)
  263.    CloseLibrary((struct Library *)IntuitionBase);
  264. exit(returnValue);
  265. }
  266.  
  267. /* ----------------------------------------------------------------------
  268.  *  The following routines adjust an entire menu system to conform to
  269.  *  the specified fonts' width and height.  Allows for Proportional Fonts.
  270.  *  This is necessary for a clean look regardless of what the users
  271.  *  preference in Fonts may be.  Using these routines, you don't need to
  272.  *  specify TopEdge, LeftEdge, Width or Height in the MenuItem structures.
  273.  *
  274.  *  This set of routines does NOT check/correct if the menu runs off the
  275.  *  screen due to large fonts, too many items, lo-res screen.
  276.  */
  277.  
  278. BOOL     AdjustMenus(struct Menu *firstmenu, struct TextAttr *attr)
  279. {
  280. struct  RastPort  textrp = {0};              /* Temporary RastPort */
  281. struct  Menu      *menu;
  282. struct  TextFont  *font;                     /* Font to use */
  283. USHORT            start, width, height, space;
  284. BOOL              retval = FALSE;
  285.  
  286. /* open the font */
  287. if((font = OpenFont(attr)))
  288.     {
  289.     SetFont(&textrp, font);       /* Put font into temporary RastPort */
  290.  
  291.     width = font->tf_XSize;       /* Get the Width of the Font */
  292.  
  293.     /* To prevent crowding of the Amiga key when using COMMSEQ,
  294.      * don't allow the items to be less than 8 pixels high.
  295.      */
  296.     height = (font->tf_YSize < 8) ? 8 : font->tf_YSize;
  297.     height++;
  298.  
  299.     start = 2;                    /* Set Starting Pixel */
  300.  
  301.     /* Step thru the menu structure and adjust it */
  302.     menu = firstmenu;
  303.     while(menu)
  304.         {
  305.         menu->LeftEdge = start;
  306.         menu->Width = space =
  307.            TextLength(&textrp, menu->MenuName,
  308.                 (LONG)strlen(menu->MenuName)) + width;
  309.         AdjustItems(&textrp, menu->FirstItem, attr, width, height, 0, 0);
  310.         menu = menu->NextMenu;
  311.         start += (space + (width * 2));
  312.         }
  313.     CloseFont(font);              /* Close the Font */
  314.     retval = TRUE;
  315.     }
  316. return(retval);
  317. }
  318.  
  319. /* Adjust the MenuItems and SubItems */
  320. VOID
  321. AdjustItems(struct RastPort *txtrp, struct MenuItem *fi,
  322.             struct TextAttr *atr, USHORT wdth, USHORT hght,
  323.             USHORT lvl, USHORT edge)
  324. {
  325. struct   MenuItem *item = fi;
  326. register USHORT   num;
  327. USHORT   strip_width, sub_edge;
  328.  
  329. if(fi==NULL)    return;
  330. strip_width = MaxLength(txtrp, item, wdth);
  331. num = 0;
  332. while(item)
  333.     {
  334.     item->TopEdge = (num * hght) - lvl;
  335.     item->LeftEdge = edge;
  336.     item->Width = strip_width;
  337.     item->Height = hght;
  338.     sub_edge = strip_width - wdth;
  339.     AdjustText((struct IntuiText *)item->ItemFill, atr);
  340.     AdjustItems(txtrp, item->SubItem, atr, wdth, hght, 1, sub_edge);
  341.     item = item->NextItem;
  342.     num++;
  343.     }
  344. }
  345.  
  346.  
  347. /* Steps thru each item to determine the maximum width of the strip */
  348. USHORT   MaxLength(struct RastPort *txtrp, struct MenuItem *fi, USHORT width)
  349. {
  350. USHORT   maxval = 0, textlen;
  351. struct   MenuItem  *item = fi;
  352. struct   IntuiText *itext;
  353.  
  354. while(item)
  355.     {
  356.     if(item->Flags&COMMSEQ)
  357.         {
  358.         width += (width + COMMWIDTH);
  359.         break;
  360.         }
  361.     item = item->NextItem;
  362.     }
  363. item = fi;
  364. while(item)
  365.     {
  366.     itext = (struct IntuiText *)item->ItemFill;
  367.     textlen = itext->LeftEdge +
  368.               TextLength(txtrp, itext->IText,
  369.                           (LONG)strlen(itext->IText)) + width;
  370. /* returns the greater of the two */
  371.     maxval = (textlen<maxval)?maxval:textlen;
  372.     item = item->NextItem;
  373.     }
  374. return(maxval);
  375. }
  376.  
  377. /* Adjust the MenuItems font attribute */
  378. VOID     AdjustText(struct  IntuiText *text, struct  TextAttr *attr)
  379. {
  380. struct IntuiText *nt;
  381. nt = text;
  382. while(nt)
  383.     {
  384.     nt->ITextFont = attr;
  385.     nt = nt->NextText;
  386.     }
  387. }
  388.