/* * MenuAlloc.c - Copyright © 1990 by S.R. & P.C. * * Created: 16 Jun 1990 * Modified: 05 Jul 1990 * * Make>> make */ /* #define DO_ARP_COPIES #include #include #include */ #include "ParM.h" #define STEP 10 /***** global functions *****/ char *copystr(char *); void AddMenu(char *); void AddSubMenu(char *); void AddEntry(char *, char *, char*, char*, char, char, long, short); void EndSubMenu(void); void CleanUp(void); void FreeMenus(void); /***** global variables *****/ extern struct Menu Menu1; extern UBYTE menu_pen; extern struct TextAttr TOPAZ80; /***** local variables *****/ static struct Menu *CurrentMenu = &Menu1; static struct MenuItem *CurrentSubMenu, **CurrentItem; /* clean up widths and other info now that menu is all built */ void CleanUp(void) { UWORD maxw, smaxw, txtw, top, stop, left; struct Menu *mptr; struct MenuItem *iptr, *sptr; left = Menu1.Width + STEP; for( mptr = Menu1.NextMenu ; mptr ; mptr=mptr->NextMenu ) { mptr->LeftEdge = left; maxw = mptr->Width = (strlen(mptr->MenuName)+2) * 8; left += maxw + STEP; top = 0; /* determine max width */ for( iptr = mptr->FirstItem ; iptr ; iptr=iptr->NextItem ) { iptr->TopEdge = top; top += iptr->Height; txtw = IntuiTextLength((struct IntuiText *)iptr->ItemFill)+2; if( iptr->Flags & COMMSEQ ) txtw += 48; if( txtw > maxw ) maxw = txtw; } for( iptr = mptr->FirstItem ; iptr ; iptr=iptr->NextItem ) { iptr->Width = maxw; stop = smaxw = 0; for( sptr=iptr->SubItem ; sptr ; sptr=sptr->NextItem ) { sptr->LeftEdge = maxw; sptr->TopEdge = stop; stop += sptr->Height; txtw = IntuiTextLength((struct IntuiText *)sptr->ItemFill)+2; if( sptr->Flags & COMMSEQ ) txtw += 48; if( txtw > smaxw ) smaxw = txtw; } for( sptr=iptr->SubItem ; sptr ; sptr=sptr->NextItem ) sptr->Width = smaxw; } } } /***** make (and allocate) a copy of the passed string *****/ char *copystr( char *str ) { char *newstr; newstr = AllocMem(strlen(str)+1, MEMF_PUBLIC); strcpy(newstr, str); return newstr; } /* allocate and initialize a new MenuItem */ struct Extended_MenuItem *AllocItem(char *itemstr) { struct IntuiText *IT; struct Extended_MenuItem *emi; emi = (struct Extended_MenuItem *) AllocMem(sizeof(struct Extended_MenuItem), MEMF_PUBLIC|MEMF_CLEAR); IT = (struct IntuiText *)AllocMem(sizeof(struct IntuiText), MEMF_PUBLIC|MEMF_CLEAR); emi->emi_MenuItem.Height = 10; emi->emi_MenuItem.Flags = ITEMTEXT+HIGHCOMP+ITEMENABLED; IT->FrontPen = menu_pen; IT->LeftEdge = IT->TopEdge = 1; IT->ITextFont = &TOPAZ80; IT->DrawMode = JAM1; IT->IText = (UBYTE*)copystr(itemstr); emi->emi_MenuItem.ItemFill = (APTR)IT; return emi; } /* allocate and initialize a new Menu */ void AddMenu(char *str) { struct Menu *Menu; Menu = (struct Menu *)AllocMem(sizeof(struct Menu), MEMF_PUBLIC|MEMF_CLEAR); Menu->MenuName = copystr(str); Menu->Flags = MENUENABLED; CurrentMenu->NextMenu = Menu; CurrentMenu = Menu; CurrentItem = &Menu->FirstItem; } void AddSubMenu(char *substr) { *CurrentItem = (struct MenuItem *)AllocItem(substr); CurrentSubMenu = *CurrentItem; CurrentItem = &CurrentSubMenu->SubItem; } void EndSubMenu(void) { CurrentItem = &CurrentSubMenu->NextItem; } void AddEntry( char *item, char *cmd, char *args, char *win, char shortcut, char mode, long stk, short pri ) { struct Extended_MenuItem *emi; emi = AllocItem(item); emi->emi_Mode = mode; emi->emi_Cmd = copystr(cmd); if (args) emi->emi_Args = copystr(args); if (shortcut) { emi->emi_MenuItem.Flags |= COMMSEQ; emi->emi_MenuItem.Command = shortcut; } if (mode=='c') { emi->emi_Window = copystr(win); emi->emi_Pri = pri; if (stk < DEFAULT_STACK) stk = DEFAULT_STACK; emi->emi_Stack = stk; } *CurrentItem = (struct MenuItem *)emi; CurrentItem = &emi->emi_MenuItem.NextItem; } /* free up memory used by a menu item */ static void FreeItem( struct Extended_MenuItem *Item ) { struct IntuiText *IT; IT = (struct IntuiText *)Item->emi_MenuItem.ItemFill; if (IT->IText) FreeMem(IT->IText, strlen((char *)IT->IText)+1); if (IT) FreeMem(IT, sizeof(struct IntuiText)); if (Item->emi_Cmd) FreeMem(Item->emi_Cmd, strlen(Item->emi_Cmd)+1); if (Item->emi_Args) FreeMem(Item->emi_Args, strlen(Item->emi_Args)+1); if (Item->emi_Window) FreeMem(Item->emi_Window, strlen(Item->emi_Window)+1); FreeMem(Item, sizeof(struct Extended_MenuItem)); } /* free up all space taken up by our menus */ void FreeMenus( void ) { struct Menu *mptr, *mtmp; struct MenuItem *iptr, *sptr, *itmp; mptr = Menu1.NextMenu; while( mptr ) { iptr = mptr->FirstItem; while( iptr ) { sptr = iptr->SubItem; while( sptr ) { itmp = sptr; sptr = sptr->NextItem; FreeItem( (struct Extended_MenuItem *)itmp ); } itmp = iptr; iptr = iptr->NextItem; FreeItem( (struct Extended_MenuItem *)itmp ); } mtmp = mptr; mptr = mptr->NextMenu; if (mtmp->MenuName) FreeMem(mtmp->MenuName, strlen(mtmp->MenuName)+1); FreeMem( mtmp , sizeof(struct Menu) ); } Menu1.NextMenu = NULL; CurrentMenu = &Menu1; }