home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 206.lha / C-Functions / MakeMenu.c < prev    next >
C/C++ Source or Header  |  1996-02-14  |  8KB  |  257 lines

  1.  
  2. /* Program for generating menues dynamicaly */
  3. /* (C)Copyright 1988 by Lars Thuring */
  4.  
  5. /* May be freely distributed and used for any purpose as long as
  6.    the Copyright notice is left unchanged. */
  7.  
  8. /* 24 oct 1987 V1.0 */
  9. /* 24 nov 1987 V1.1 Library version */
  10. /* 18 jan 1988 V1.2 Adjusted to K&R return values */
  11. /* 19 jan 1988 V1.3 Select box of menu increased
  12.                     NULL terminated text pointer list */
  13. /* 28 apr 1988 V1.4 Bug; ItemExcl must be long value */
  14.  
  15.  
  16. #include <exec/types.h>
  17. #include <intuition/intuition.h>
  18.  
  19. #define DOMENU 1
  20. #define DOITEM 2
  21. #define DOSUB  3
  22. #define DOALT  4
  23.  
  24. USHORT IntuiTextLength();        /* Return length of txt in pixels */
  25.  
  26. VOID MakeMenu( Data, M, I, Txt)
  27. UBYTE *Data[];          /* Pointers to the texts and options to use */
  28. struct Menu M[];        /* The Menu structs */
  29. struct MenuItem I[];    /* and the MenuItem structs */
  30. struct IntuiText Txt[]; /* The IntuiText structs */
  31.    {
  32. USHORT ix=0;                     /* Index to current Data[] */
  33. USHORT strings=0;                /* Number of Data[] to process */
  34. USHORT Mix=0,Iix=0,Tix=0;        /* Currently working with ... */
  35. USHORT PreviousItem;             /* Last item generated in current menu */
  36. USHORT NotFirstItem;             /* Set when true */
  37. USHORT NotFirstSubItem;          /* Set when true */
  38. USHORT OptStart,OptEnd;          /* Position of [ and ] in Data[ix] */
  39.  
  40. USHORT ItemLow=0;        /* First Item for current Menu */
  41. USHORT SubLow=0;         /* First SubItem for current Item */
  42.  
  43. USHORT MenuX,ItemX=0,ItemY,SubX,SubY;   /* Values ... */
  44. USHORT MenuW,ItemW=0,SubW;              /* Current min widths */
  45.  
  46. USHORT Op;               /* What current string is about anyway  */
  47. UBYTE *p,*p2;            /* Pointer to Data[ix] and start of text */
  48. USHORT trash,i=0;
  49.  
  50. USHORT menuspace = 14;   /* Inter menutext space */
  51. USHORT itemspace =  7;   /* Item ditto */
  52. USHORT chrwidth  =  7;   /* default characterwidth */
  53. USHORT chrheight = 10;   /* default characterheight */
  54.  
  55. UBYTE *ExclString = "abcdefghijklmnopqrstuvwxyz01234";   /* For xor */
  56. ULONG  ItemExcl;
  57.  
  58. USHORT MenuFlag,ItemFlag;           /* Set to defaults and changed if */
  59. APTR   ThisItem,OtherItem;          /* options selected indicate so.  */
  60. USHORT Style;                       /* How to write texts */
  61. UBYTE  ItemChr=' ';                 /* right-AMIGA key command */
  62.  
  63.    /* Function: count strings, set values and write them into structs */
  64.  
  65.    MenuX=1;
  66.  
  67.    FOREVER                                /* Count strings passed */
  68.       if (NOT Data[strings++]) break;
  69.  
  70.    while (--strings)
  71.       {
  72.       p=p2=Data[ix];                      /* Pointers to the text data */
  73.       OptStart=strinstr( p, '[' )-1;      /* Start of options...       */
  74.       OptEnd=strinstr( p, ']' )-1;        /*               ...and end  */
  75.       p[OptEnd]='\0';                     /* Split string into 2 strings */
  76.  
  77.       while (*p2++);                      /* Point at text to be shown */
  78.       p[OptEnd]=']';                      /* Restore source string */
  79.  
  80.    /* Set the defaults */
  81.  
  82.       MenuFlag = MENUENABLED;
  83.       ItemFlag = ITEMTEXT | ITEMENABLED | HIGHCOMP;
  84.       ItemExcl = 0;
  85.       ThisItem = (APTR) &Txt[Tix];
  86.       OtherItem = ThisItem;
  87.       Style = JAM1;
  88.  
  89.    /* Now determine parameters and fill in current structs */
  90.  
  91.       for (i=OptStart; i<OptEnd; i++)     /* Find user needs */
  92.          {
  93.          switch ( p[i] )
  94.             {
  95.          case '_':                  /* Right amiga-key select */
  96.             ItemFlag |= COMMSEQ;
  97.             ItemChr = p[++i];
  98.             break;
  99.          case 'A':            /* Alternate text for previous item */
  100.             Op=DOALT;
  101.             break;
  102.          case 'B':                  /* Show select by drawing box */
  103.             ItemFlag &= ~(HIGHCOMP | HIGHIMAGE | HIGHNONE);
  104.             ItemFlag |= HIGHBOX;
  105.             break;
  106.          case 'C':
  107.             ItemFlag |= CHECKIT;
  108.             break;
  109.          case 'D':                  /* Menu/Item is disabled at first */
  110.             MenuFlag &= ~MENUENABLED;
  111.             ItemFlag &= ~ITEMENABLED;
  112.             break;
  113.          case 'H':                  /* Begin on next column */
  114.             ItemLow = Iix;
  115.             ItemX += ItemW + itemspace;
  116.             ItemY = ItemW = 0;
  117.             break;
  118.          case 'I':                  /* This is a MenuItem */
  119.             Op=DOITEM;
  120.             SubW = SubY = SubX = NotFirstSubItem = 0;
  121.             break;
  122.          case 'J':                  /* Use FrontPen and BackPen */
  123.             Style = JAM2;
  124.             break;
  125.          case 'M':                  /* This is a menuheader */
  126.             Op=DOMENU;
  127.             ItemW = ItemY = ItemX = PreviousItem = 0;
  128.             NotFirstItem = 0;
  129.             if (Iix) Mix++;         /* Will err if no items for menu 0 */
  130.             break;
  131.          case 'N':                  /* No indication when selected */
  132.             ItemFlag &= ~(HIGHCOMP | HIGHBOX | HIGHIMAGE);
  133.             ItemFlag |= HIGHNONE;
  134.             break;
  135.          case 'S':                  /* This is subitem */
  136.             Op=DOSUB;
  137.             break;
  138.          case 'V':                  /* Item is marked from start */
  139.             ItemFlag |= CHECKIT|CHECKED;
  140.             break;
  141.          default:
  142.             if (trash = strinstr(ExclString, p[i]))   /* MutualExclude ? */
  143.                ItemExcl |= 1 << (trash-1);            /* Position is >=1 */
  144.             break;
  145.             }
  146.          }
  147.  
  148.  
  149.       if ( Op == DOMENU )
  150.          {
  151.          if (Mix) M[Mix-1].NextMenu = &M[Mix];
  152.             else M[Mix].NextMenu = NULL;
  153.          M[Mix].LeftEdge = MenuX;
  154.          MenuW = (strlen(p2)+1) * chrwidth+6;
  155.          MenuX += MenuW + menuspace;
  156.          M[Mix].Width = MenuW;
  157.          M[Mix].Flags = MenuFlag;
  158.          M[Mix].MenuName = p2;
  159.          }
  160.  
  161.       if ( Op == DOITEM || Op == DOSUB || Op == DOALT )
  162.          {
  163.          Txt[Tix].FrontPen  = 3;
  164.          Txt[Tix].BackPen   = 2;
  165.          Txt[Tix].DrawMode  = Style;
  166.          Txt[Tix].LeftEdge  = 2;
  167.          Txt[Tix].TopEdge   = 1;
  168.          Txt[Tix].ITextFont = NULL;
  169.          Txt[Tix].IText     = p2;
  170.          Txt[Tix].NextText  = NULL;
  171.          }
  172.  
  173.       if (Op==DOITEM)
  174.          {
  175.          if (NOT PreviousItem) ItemLow = Iix;
  176.          trash = IntuiTextLength( &Txt[Tix] )+4;
  177.          if (trash>ItemW)
  178.             {
  179.             ItemW = trash;
  180.             for (i=ItemLow; i<Iix; i++)
  181.                I[i].Width = ItemW;
  182.             }
  183.  
  184.          if (NotFirstItem) I[PreviousItem].NextItem = &I[Iix];
  185.             else M[Mix].FirstItem = &I[Iix];
  186.  
  187.          I[Iix].NextItem      = NULL;
  188.          I[Iix].LeftEdge      = ItemX;
  189.          I[Iix].TopEdge       = ItemY;
  190.          I[Iix].Width         = ItemW;
  191.          I[Iix].Height        = chrheight;
  192.          I[Iix].Flags         = ItemFlag;
  193.          I[Iix].MutualExclude = ItemExcl;
  194.          I[Iix].ItemFill      = ThisItem;
  195.          I[Iix].SelectFill    = NULL;
  196.          I[Iix].Command       = ItemChr;
  197.          I[Iix].SubItem       = NULL;
  198.  
  199.          ItemY += chrheight;
  200.          PreviousItem = Iix;
  201.          NotFirstItem = TRUE;
  202.          Iix++;
  203.          Tix++;
  204.          }
  205.        
  206.       if (Op==DOSUB)
  207.          {
  208.          if (NOT NotFirstSubItem) SubLow = Iix;
  209.          SubX = ItemX + ItemW - 5;
  210.          trash = IntuiTextLength( &Txt[Tix] )+4;
  211.          if (trash>SubW)
  212.             {
  213.             SubW=trash;
  214.             for (i=SubLow; i<Iix; i++)
  215.                I[i].Width = SubW;
  216.             }
  217.  
  218.          if (NotFirstSubItem) I[Iix-1].NextItem = &I[Iix];
  219.          else
  220.             {
  221.             I[PreviousItem].SubItem = &I[Iix];
  222.             SubLow = Iix;
  223.             }
  224.  
  225.          I[Iix].NextItem      = NULL;
  226.          I[Iix].LeftEdge      = SubX;
  227.          I[Iix].TopEdge       = SubY;
  228.          I[Iix].Width         = SubW;
  229.          I[Iix].Height        = chrheight;
  230.          I[Iix].Flags         = ItemFlag;
  231.          I[Iix].MutualExclude = ItemExcl;
  232.          I[Iix].ItemFill      = ThisItem;
  233.          I[Iix].SelectFill    = NULL;
  234.          I[Iix].Command       = ItemChr;
  235.          I[Iix].SubItem       = NULL;
  236.  
  237.          SubY += chrheight;
  238.          NotFirstSubItem = TRUE;
  239.          Tix++;
  240.          Iix++;
  241.          }
  242.  
  243.       if (Op == DOALT)
  244.          {
  245.          I[Iix-1].Flags       &= ~(HIGHCOMP | HIGHBOX | HIGHNONE);
  246.          I[Iix-1].Flags       |= HIGHIMAGE;
  247.          I[Iix-1].SelectFill   = OtherItem;
  248.          Tix++;
  249.          }
  250.  
  251.       ix++;       /* Process next string */
  252.       }
  253.  
  254.    }  /* End of MakeMenu() */
  255.  
  256.  
  257.