home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of A1200
/
World_Of_A1200.iso
/
programs
/
text
/
jed
/
src
/
jed.lha
/
menus.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-05
|
7KB
|
354 lines
/*
* MENUS.C
* (c) 1992-3 J.Harper
*/
#include "jed.h"
#include "jed_protos.h"
#define MAX_MENUS 300
#define NMSIZE (MAX_MENUS * sizeof(struct NewMenu))
Prototype VALUE * cmd_menu (LONG, VALUE *);
Prototype VALUE * cmd_setmenu (LONG, VALUE *);
Local BOOL makemenu (STRPTR);
Prototype VOID killmenu (VOID);
Prototype VOID clearmenu (struct Window *);
Local VOID clearallmenus (VOID);
Prototype VOID setmenu (struct Window *);
Local VOID setallmenus (VOID);
Prototype VOID evalmenu (WORD, WORD);
Local struct MenuItem * findcommmenu (UBYTE);
Local STRPTR getstring (STRPTR *);
Local struct Menu *Menu;
Local STRPTR MenuDef;
Local APTR VisInfo;
/*
* (menu 1)
* (menu 0)
*/
VALUE *
cmd_menu(LONG argc, VALUE *argv)
{
if(TPLATE1(VTF_NUMBER))
{
BOOL rc = FALSE;
if(ARG1.val_Value.Number)
{
setmenu(CurrVW->vw_Window);
rc = TRUE;
}
else
{
clearmenu(CurrVW->vw_Window);
rc = TRUE;
}
setnumres(rc);
}
return(&RES);
}
/*
* (setmenu `fileName')
*/
VALUE *
cmd_setmenu(LONG argc, VALUE *argv)
{
if(TPLATE1(VTF_STRING))
{
setnumres(makemenu(ARG1.val_Value.String));
}
return(&RES);
}
Local BOOL
makemenu(STRPTR file)
{
killmenu();
if(MenuDef = squirrelfile(file))
{
STRPTR def = MenuDef;
struct NewMenu *nm;
if(!(nm = (struct NewMenu *)AllocMem(NMSIZE, MEMF_CLEAR)))
{
settitle(NoMemMsg);
freestring(MenuDef);
MenuDef = NULL;
return(FALSE);
}
else
{
struct NewMenu *cnm = nm;
UBYTE keyword[20];
BOOL exitflag = FALSE;
def = stpblk(def);
while((!exitflag) && (*def))
{
cpyalnum(keyword, def);
def = stpblk(stpalnum(def));
if(!(stricmp(keyword, "MENU")))
{
cnm->nm_Type = NM_TITLE;
cnm->nm_Label = getstring(&def);
cnm++;
}
else if(!(stricmp(keyword, "ITEM")))
{
STRPTR temp;
cnm->nm_Type = NM_ITEM;
cnm->nm_Label = getstring(&def);
temp = getstring(&def);
if(*temp == NULL)
cnm->nm_CommKey = NULL;
else
cnm->nm_CommKey = temp;
cnm->nm_UserData = getstring(&def);
cnm++;
}
else if(!(stricmp(keyword, "SUB")))
{
STRPTR temp;
cnm->nm_Type = NM_SUB;
cnm->nm_Label = getstring(&def);
temp = getstring(&def);
if(*temp == NULL)
cnm->nm_CommKey = NULL;
else
cnm->nm_CommKey = temp;
cnm->nm_UserData = getstring(&def);
cnm++;
}
else if(!(stricmp(keyword, "BAR")))
{
cnm->nm_Type = NM_ITEM;
cnm->nm_Label = NM_BARLABEL;
cnm++;
}
else if(!(stricmp(keyword, "SBAR")))
{
cnm->nm_Type = NM_SUB;
cnm->nm_Label = NM_BARLABEL;
cnm++;
}
else if(!(stricmp(keyword, "END")))
{
cnm->nm_Type = NM_END;
exitflag = TRUE;
}
else
{
settitlefmt("error: unknown menu type %s", (LONG)keyword);
FreeMem(nm, NMSIZE);
freestring(MenuDef);
MenuDef = NULL;
return(FALSE);
}
def = stpblk(def);
}
}
if(!(Menu = CreateMenus(nm, TAG_END)))
settitle("createmenus error: either out of mem or an illegal menu");
else
{
if(VisInfo = GetVisualInfo(CurrVW->vw_Window->WScreen, TAG_END))
{
if(LayoutMenus(Menu, VisInfo, TAG_END))
setallmenus();
else
{
FreeVisualInfo(VisInfo);
VisInfo = NULL;
FreeMenus(Menu);
Menu = NULL;
freestring(MenuDef);
MenuDef = NULL;
}
}
else
{
FreeMenus(Menu);
Menu = NULL;
freestring(MenuDef);
MenuDef = NULL;
}
}
FreeMem(nm, NMSIZE);
}
else
settitle("error: can't open menu definition file");
return((BOOL)Menu);
}
VOID
killmenu(VOID)
{
if(Menu)
{
clearallmenus();
FreeMenus(Menu);
Menu = NULL;
}
if(MenuDef)
{
freestring(MenuDef);
MenuDef = NULL;
}
if(VisInfo)
{
FreeVisualInfo(VisInfo);
VisInfo = NULL;
}
}
VOID
clearmenu(struct Window *wd)
{
ClearMenuStrip(wd);
}
Local VOID
clearallmenus(VOID)
{
TX *thistx = (TX *)TXList.mlh_Head;
VW *thisvw;
for(thistx = (TX *)TXList.mlh_Head; thistx->tx_Node.mln_Succ; thistx = (TX *)thistx->tx_Node.mln_Succ)
{
for(thisvw = (VW *)thistx->tx_Views; thisvw->vw_Node.mln_Succ; thisvw = (VW *)thisvw->vw_Node.mln_Succ)
{
ClearMenuStrip(thisvw->vw_Window);
}
}
}
VOID
setmenu(struct Window *wd)
{
if(Menu)
SetMenuStrip(wd, Menu);
}
Local VOID
setallmenus(VOID)
{
TX *thistx = (TX *)TXList.mlh_Head;
VW *thisvw;
for(thistx = (TX *)TXList.mlh_Head; thistx->tx_Node.mln_Succ; thistx = (TX *)thistx->tx_Node.mln_Succ)
{
for(thisvw = (VW *)thistx->tx_Views; thisvw->vw_Node.mln_Succ; thisvw = (VW *)thisvw->vw_Node.mln_Succ)
{
SetMenuStrip(thisvw->vw_Window, Menu);
}
}
}
/*
* called from IDCMP event loop
*/
VOID
evalmenu(WORD code, WORD qual)
{
if(Menu)
{
struct MenuItem *mi;
while(mi = ItemAddress(Menu, code))
{
VALUE result;
if(mi->Command && (qual & IEQUALIFIER_RCOMMAND))
{
struct MenuItem *actual;
if(qual & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
{
if(actual = findcommmenu(toupper(mi->Command)))
mi = actual;
}
else
{
if(actual = findcommmenu(tolower(mi->Command)))
mi = actual;
}
code = MENUNULL;
}
else
code = mi->NextSelect;
cursor(OFF);
execstr(GTMENUITEM_USERDATA(mi), &result, FALSE, 0, NULL);
cursor(ON);
releasevalue(&result);
}
}
}
/*
* This routine is used so we can make command key shortcuts case
* sensitive - is there an easier way than this???
*/
Local struct MenuItem *
findcommmenu(UBYTE commKey)
{
struct Menu *menu;
for(menu = Menu; menu; menu = menu->NextMenu)
{
struct MenuItem *mi;
for(mi = menu->FirstItem; mi; mi = mi->NextItem)
{
struct MenuItem *si;
for(si = mi->SubItem; si; si = si->NextItem)
{
if(si->Command == commKey)
return(si);
}
if(mi->Command == commKey)
return(mi);
}
}
return(FALSE);
}
/*
* Get a string enclosed in "...", zero terminate it and return it.
* string is not copied, input is advanced past the zero.
*/
STRPTR
getstring(STRPTR *text_pt)
{
STRPTR text;
STRPTR rtn;
UBYTE c;
text = *text_pt;
while((c = *text++) != '\"')
{
if(!c)
{
*text_pt = text-1;
settitle("premature EOF: quoted string expected");
return(FALSE);
}
}
rtn = text;
while((c = *text++) != '\"')
{
if(!c)
{
*text_pt = text-1;
settitle("premature EOF: no string termination quote");
return(FALSE);
}
}
*(text-1) = '\0';
*text_pt = text;
return(rtn);
}