home *** CD-ROM | disk | FTP | other *** search
/ World of A1200 / World_Of_A1200.iso / programs / text / jed / src / jed.lha / menus.c < prev    next >
C/C++ Source or Header  |  1993-01-05  |  7KB  |  354 lines

  1.  
  2. /*
  3.  * MENUS.C
  4.  * (c) 1992-3 J.Harper
  5.  */
  6.  
  7. #include "jed.h"
  8. #include "jed_protos.h"
  9.  
  10. #define MAX_MENUS 300
  11. #define NMSIZE (MAX_MENUS * sizeof(struct NewMenu))
  12.  
  13. Prototype   VALUE *        cmd_menu    (LONG, VALUE *);
  14. Prototype   VALUE *        cmd_setmenu    (LONG, VALUE *);
  15. Local        BOOL        makemenu    (STRPTR);
  16. Prototype   VOID        killmenu    (VOID);
  17. Prototype   VOID        clearmenu    (struct Window *);
  18. Local        VOID        clearallmenus    (VOID);
  19. Prototype   VOID        setmenu        (struct Window *);
  20. Local        VOID        setallmenus    (VOID);
  21. Prototype   VOID        evalmenu    (WORD, WORD);
  22. Local        struct MenuItem *    findcommmenu    (UBYTE);
  23. Local        STRPTR        getstring    (STRPTR *);
  24.  
  25. Local struct Menu *Menu;
  26. Local STRPTR MenuDef;
  27. Local APTR VisInfo;
  28.  
  29. /*
  30.  * (menu 1)
  31.  * (menu 0)
  32.  */
  33. VALUE *
  34. cmd_menu(LONG argc, VALUE *argv)
  35. {
  36.     if(TPLATE1(VTF_NUMBER))
  37.     {
  38.     BOOL rc = FALSE;
  39.     if(ARG1.val_Value.Number)
  40.     {
  41.         setmenu(CurrVW->vw_Window);
  42.         rc = TRUE;
  43.     }
  44.     else
  45.     {
  46.         clearmenu(CurrVW->vw_Window);
  47.         rc = TRUE;
  48.     }
  49.     setnumres(rc);
  50.     }
  51.     return(&RES);
  52. }
  53.  
  54. /*
  55.  * (setmenu `fileName')
  56.  */
  57. VALUE *
  58. cmd_setmenu(LONG argc, VALUE *argv)
  59. {
  60.     if(TPLATE1(VTF_STRING))
  61.     {
  62.     setnumres(makemenu(ARG1.val_Value.String));
  63.     }
  64.     return(&RES);
  65. }
  66.  
  67. Local BOOL
  68. makemenu(STRPTR file)
  69. {
  70.     killmenu();
  71.     if(MenuDef = squirrelfile(file))
  72.     {
  73.     STRPTR def = MenuDef;
  74.     struct NewMenu *nm;
  75.  
  76.     if(!(nm = (struct NewMenu *)AllocMem(NMSIZE, MEMF_CLEAR)))
  77.     {
  78.         settitle(NoMemMsg);
  79.         freestring(MenuDef);
  80.         MenuDef = NULL;
  81.         return(FALSE);
  82.     }
  83.     else
  84.     {
  85.         struct NewMenu *cnm = nm;
  86.         UBYTE keyword[20];
  87.         BOOL exitflag = FALSE;
  88.  
  89.         def = stpblk(def);
  90.         while((!exitflag) && (*def))
  91.         {
  92.         cpyalnum(keyword, def);
  93.         def = stpblk(stpalnum(def));
  94.  
  95.         if(!(stricmp(keyword, "MENU")))
  96.         {
  97.             cnm->nm_Type = NM_TITLE;
  98.             cnm->nm_Label = getstring(&def);
  99.             cnm++;
  100.         }
  101.         else if(!(stricmp(keyword, "ITEM")))
  102.         {
  103.             STRPTR temp;
  104.  
  105.             cnm->nm_Type = NM_ITEM;
  106.             cnm->nm_Label = getstring(&def);
  107.             temp = getstring(&def);
  108.             if(*temp == NULL)
  109.             cnm->nm_CommKey = NULL;
  110.             else
  111.             cnm->nm_CommKey = temp;
  112.             cnm->nm_UserData = getstring(&def);
  113.             cnm++;
  114.         }
  115.         else if(!(stricmp(keyword, "SUB")))
  116.         {
  117.             STRPTR temp;
  118.  
  119.             cnm->nm_Type = NM_SUB;
  120.             cnm->nm_Label = getstring(&def);
  121.             temp = getstring(&def);
  122.             if(*temp == NULL)
  123.             cnm->nm_CommKey = NULL;
  124.             else
  125.             cnm->nm_CommKey = temp;
  126.             cnm->nm_UserData = getstring(&def);
  127.             cnm++;
  128.         }
  129.         else if(!(stricmp(keyword, "BAR")))
  130.         {
  131.             cnm->nm_Type = NM_ITEM;
  132.             cnm->nm_Label = NM_BARLABEL;
  133.             cnm++;
  134.         }
  135.         else if(!(stricmp(keyword, "SBAR")))
  136.         {
  137.             cnm->nm_Type = NM_SUB;
  138.             cnm->nm_Label = NM_BARLABEL;
  139.             cnm++;
  140.         }
  141.         else if(!(stricmp(keyword, "END")))
  142.         {
  143.             cnm->nm_Type = NM_END;
  144.             exitflag = TRUE;
  145.         }
  146.         else
  147.         {
  148.             settitlefmt("error: unknown menu type %s", (LONG)keyword);
  149.             FreeMem(nm, NMSIZE);
  150.             freestring(MenuDef);
  151.             MenuDef = NULL;
  152.             return(FALSE);
  153.         }
  154.         def = stpblk(def);
  155.         }
  156.     }
  157.     if(!(Menu = CreateMenus(nm, TAG_END)))
  158.         settitle("createmenus error: either out of mem or an illegal menu");
  159.     else
  160.     {
  161.         if(VisInfo = GetVisualInfo(CurrVW->vw_Window->WScreen, TAG_END))
  162.         {
  163.         if(LayoutMenus(Menu, VisInfo, TAG_END))
  164.             setallmenus();
  165.         else
  166.         {
  167.             FreeVisualInfo(VisInfo);
  168.             VisInfo = NULL;
  169.             FreeMenus(Menu);
  170.             Menu = NULL;
  171.             freestring(MenuDef);
  172.             MenuDef = NULL;
  173.         }
  174.         }
  175.         else
  176.         {
  177.         FreeMenus(Menu);
  178.         Menu = NULL;
  179.         freestring(MenuDef);
  180.         MenuDef = NULL;
  181.         }
  182.     }
  183.     FreeMem(nm, NMSIZE);
  184.     }
  185.     else
  186.     settitle("error: can't open menu definition file");
  187.     return((BOOL)Menu);
  188. }
  189.  
  190. VOID
  191. killmenu(VOID)
  192. {
  193.     if(Menu)
  194.     {
  195.     clearallmenus();
  196.     FreeMenus(Menu);
  197.     Menu = NULL;
  198.     }
  199.     if(MenuDef)
  200.     {
  201.     freestring(MenuDef);
  202.     MenuDef = NULL;
  203.     }
  204.     if(VisInfo)
  205.     {
  206.     FreeVisualInfo(VisInfo);
  207.     VisInfo = NULL;
  208.     }
  209. }
  210.  
  211. VOID
  212. clearmenu(struct Window *wd)
  213. {
  214.     ClearMenuStrip(wd);
  215. }
  216.  
  217. Local VOID
  218. clearallmenus(VOID)
  219. {
  220.     TX *thistx = (TX *)TXList.mlh_Head;
  221.     VW *thisvw;
  222.  
  223.     for(thistx = (TX *)TXList.mlh_Head; thistx->tx_Node.mln_Succ; thistx = (TX *)thistx->tx_Node.mln_Succ)
  224.     {
  225.     for(thisvw = (VW *)thistx->tx_Views; thisvw->vw_Node.mln_Succ; thisvw = (VW *)thisvw->vw_Node.mln_Succ)
  226.     {
  227.         ClearMenuStrip(thisvw->vw_Window);
  228.     }
  229.     }
  230. }
  231.  
  232. VOID
  233. setmenu(struct Window *wd)
  234. {
  235.     if(Menu)
  236.     SetMenuStrip(wd, Menu);
  237. }
  238.  
  239. Local VOID
  240. setallmenus(VOID)
  241. {
  242.     TX *thistx = (TX *)TXList.mlh_Head;
  243.     VW *thisvw;
  244.  
  245.     for(thistx = (TX *)TXList.mlh_Head; thistx->tx_Node.mln_Succ; thistx = (TX *)thistx->tx_Node.mln_Succ)
  246.     {
  247.     for(thisvw = (VW *)thistx->tx_Views; thisvw->vw_Node.mln_Succ; thisvw = (VW *)thisvw->vw_Node.mln_Succ)
  248.     {
  249.         SetMenuStrip(thisvw->vw_Window, Menu);
  250.     }
  251.     }
  252. }
  253.  
  254. /*
  255.  * called from IDCMP event loop
  256.  */
  257. VOID
  258. evalmenu(WORD code, WORD qual)
  259. {
  260.     if(Menu)
  261.     {
  262.     struct MenuItem *mi;
  263.     while(mi = ItemAddress(Menu, code))
  264.     {
  265.         VALUE result;
  266.         if(mi->Command && (qual & IEQUALIFIER_RCOMMAND))
  267.         {
  268.         struct MenuItem *actual;
  269.         if(qual & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  270.         {
  271.             if(actual = findcommmenu(toupper(mi->Command)))
  272.             mi = actual;
  273.         }
  274.         else
  275.         {
  276.             if(actual = findcommmenu(tolower(mi->Command)))
  277.             mi = actual;
  278.         }
  279.         code = MENUNULL;
  280.         }
  281.         else
  282.         code = mi->NextSelect;
  283.         cursor(OFF);
  284.         execstr(GTMENUITEM_USERDATA(mi), &result, FALSE, 0, NULL);
  285.         cursor(ON);
  286.         releasevalue(&result);
  287.     }
  288.     }
  289. }
  290.  
  291. /*
  292.  * This routine is used so we can make command key shortcuts case
  293.  * sensitive - is there an easier way than this???
  294.  */
  295. Local struct MenuItem *
  296. findcommmenu(UBYTE commKey)
  297. {
  298.     struct Menu *menu;
  299.     for(menu = Menu; menu; menu = menu->NextMenu)
  300.     {
  301.     struct MenuItem *mi;
  302.     for(mi = menu->FirstItem; mi; mi = mi->NextItem)
  303.     {
  304.         struct MenuItem *si;
  305.         for(si = mi->SubItem; si; si = si->NextItem)
  306.         {
  307.         if(si->Command == commKey)
  308.             return(si);
  309.         }
  310.         if(mi->Command == commKey)
  311.         return(mi);
  312.     }
  313.     }
  314.     return(FALSE);
  315. }
  316.  
  317. /*
  318.  * Get a string enclosed in "...", zero terminate it and return it.
  319.  * string is not copied, input is advanced past the zero.
  320.  */
  321. STRPTR
  322. getstring(STRPTR *text_pt)
  323. {
  324.     STRPTR text;
  325.     STRPTR rtn;
  326.     UBYTE c;
  327.  
  328.     text = *text_pt;
  329.  
  330.     while((c = *text++) != '\"')
  331.     {
  332.     if(!c)
  333.     {
  334.         *text_pt = text-1;
  335.         settitle("premature EOF: quoted string expected");
  336.         return(FALSE);
  337.     }
  338.     }
  339.     rtn = text;
  340.     while((c = *text++) != '\"')
  341.     {
  342.     if(!c)
  343.     {
  344.         *text_pt = text-1;
  345.         settitle("premature EOF: no string termination quote");
  346.         return(FALSE);
  347.     }
  348.     }
  349.     *(text-1) = '\0';
  350.     *text_pt = text;
  351.     return(rtn);
  352. }
  353.  
  354.