home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / vos2-121.zip / v / srcos2 / vmenu.cpp < prev    next >
C/C++ Source or Header  |  1999-02-11  |  11KB  |  318 lines

  1. //===============================================================
  2. // vMenu.cxx - vMenuPane class functions - X11R5
  3. //
  4. // Copyright (C) 1995,1996,1997,1998  Bruce E. Wampler
  5. //
  6. // This file is part of the V C++ GUI Framework, and is covered
  7. // under the terms of the GNU Library General Public License,
  8. // Version 2. This library has NO WARRANTY. See the source file
  9. // vapp.cxx for more complete information about license terms.
  10. //===============================================================
  11. #include <v/vos2.h>        // for OS/2 stuff
  12. #include <v/vmenu.h>        // our header
  13. #include <v/vcmdwin.h>        // we need access to vcmdwin
  14. #include <stdlib.h>
  15.  
  16. // Define static data of the class
  17.   static char curLbl[100];    // for fixed labels
  18.  
  19. //==================>>> vMenuPane::vMenuPane <<<===========================
  20.   vMenuPane::vMenuPane(VCONST vMenu* menu) : vPane(P_Menu)
  21.   {
  22.     int i;
  23.     char *ch;
  24.     // set up menus -----------------------------------------------
  25.     SysDebug(Constructor,"vMenuPane::vMenuPane() constructor\n")
  26.     _nextMenuButton = 0;    // no menus defined so far
  27.     for (i = 0 ; i < MAX_MENU_BUTTONS ; ++i)
  28.     {
  29.       _mb[i].label[0] = 0; // null out menu button array
  30.       _mb[i].menuId = 0;
  31.       _mb[i].SubMenu = 0;
  32.       _mb[i].hPullDown = 0;
  33.     }
  34.     // copy the menus as defined to our array
  35.     for (i = 0 ; i < MAX_MENU_BUTTONS && &menu[i] != 0 && menu[i].label; ++i)
  36.     {
  37. //      _mb[i].label = menu[i].label;
  38.       strcpy(_mb[i].label, menu[i].label);
  39.       _mb[i].menuId = menu[i].menuId;
  40.       _mb[i].SubMenu = menu[i].SubMenu;
  41.  
  42.       // translate V '&' for OS/2 '~' in labels for menu accelerators
  43.       for (ch  = _mb[i].label; *ch != 0; ch++)
  44.       {
  45.         if (*ch == '&')
  46.         *ch = '~';
  47.       }
  48.     }
  49.     _nextSubMenu = i;        // we will start submenus here
  50.     _nextMenuButton = i;    // this many menus defined
  51.     _topLevelMenu = 0;
  52.   }
  53. //==================>>> vMenuPane::vMenuPane <<<===========================
  54.   vMenuPane::vMenuPane(const vMenuPane& m) : vPane(m)
  55.   {
  56.     vSysError("V Semantics do not allow copy constructors.");
  57.   }
  58. //====================>>> vMenuPane::~vMenuPane <<<=======================
  59.   vMenuPane::~vMenuPane()            // destructor
  60.   {
  61.     SysDebug(Destructor,"vMenuPane::~vMenuPane() destructor\n")
  62.     WinDestroyWindow(_topLevelMenu);    // Start with the top
  63.     for (int i = _nextSubMenu - 1 ; i >= 0 ; --i)    // all menus
  64.     {
  65.       WinDestroyWindow(_mb[i].hPullDown);
  66.       delete _mb[i].mInfo;        // free the space
  67.     }
  68.   }
  69. //======================>>> vMenuPane::initialize <<<=======================
  70.   void vMenuPane::initialize(vWindow* pWin, HWND hMenu)
  71.   {
  72.     vPane::initialize(pWin, hMenu);        // initialize these
  73.     _topLevelMenu = (HWND)hMenu;        // handle to menu bar
  74.     // Now we have to add our menus
  75.     for (int i = 0 ; i < _nextMenuButton ; ++i)
  76.     {
  77.       doAddMenu(i, _topLevelMenu);
  78.     }
  79. //    pWin->_WindowMenuIndex = _nextMenuButton - 1; // Window menu for MDI
  80.   }
  81. //======================>>> vMenuPane::fixLabel <<<========================
  82.   void vMenuPane::fixLabel(VCONST char* lbl, VCONST char* key)
  83.   {
  84.     // copy label to global curLbl
  85.     VCONST char* cp;
  86.     int ix = 0;
  87.     for (cp = lbl ; *cp && ix < 99 ; ++cp)     // Scan label
  88.     {
  89.       curLbl[ix++] = *cp;
  90.     }
  91.     if (key && *key)
  92.     {
  93.       curLbl[ix++] = ' '; curLbl[ix++] = ' '; curLbl[ix++] = '\t';
  94.       for (cp = key ; *cp && ix < 99 ; ++cp)
  95.       {
  96.         curLbl[ix++] = *cp;
  97.       }
  98.     }
  99.     curLbl[ix] = 0;      // finish off
  100.  
  101.     // translate V '&' for OS/2 '~' in labels for menu accelerators
  102.     char *ch;
  103.     for (ch  = curLbl; *ch != 0; ch++)
  104.     {
  105.       if (*ch == '&')
  106.       *ch = '~';
  107.     }
  108.   }
  109.  
  110. //======================>>> vMenuPane::doAddMenu <<<========================
  111.   void vMenuPane::doAddMenu(int id, HWND parent)
  112.   {
  113.     MENUITEM mi;
  114.  
  115.     // create a drop down window on the menu bar
  116.     _mb[id].hPullDown = WinCreateWindow (HWND_OBJECT, WC_MENU, NULL,
  117.                              WS_CLIPSIBLINGS, 0, 0, 0, 0, HWND_OBJECT,
  118.                              HWND_BOTTOM, _mb[id].menuId, NULL, NULL);
  119.  
  120.     // loop through the list
  121.     _mb[id].mInfo = 0;              // empty list so far
  122.     vMenu* item = _mb[id].SubMenu;  // The first item in list
  123.     MenuInfo* info;                 // for current info
  124.     for (int ix = 0 ; item[ix].label != 0 ; ++ix)
  125.     {
  126.       info = new MenuInfo;            //  new space for current item
  127.       info->NxtInfo = _mb[id].mInfo;  // add to front of list
  128.       _mb[id].mInfo = info;           // fix front pointer
  129.       info->ItemIndex = ix;                // index to item list
  130.       info->SubMenuIndex = 0;              // no submenu normally
  131.       if (item[ix].menuId == M_Line)
  132.       {
  133.         mi.iPosition = MIT_END;
  134.         mi.afStyle = MIS_SEPARATOR;
  135.         mi.afAttribute = 0;
  136.         mi.id = 0;
  137.         mi.hwndSubMenu = NULLHANDLE;
  138.         mi.hItem = 0;
  139.         WinSendMsg (_mb[id].hPullDown, MM_INSERTITEM, (MPARAM) &mi, NULL);
  140.       }
  141.       else if (item[ix].SubMenu != 0)     // a submenu
  142.       {
  143.         if(_nextSubMenu >= MAX_MENU_BUTTONS)
  144.         {
  145.           SysDebug(BadVals,"Too many submenus!\n");
  146.           continue;
  147.         }
  148.         // we will create a submenu
  149.         // copy the definitions, track the new index
  150.         int sub = _nextSubMenu++;        // get our index, bump for next time
  151.  
  152. //      _mb[sub].label = item[ix].label;
  153.         strcpy(_mb[sub].label,  item[ix].label);
  154.  
  155.         // translate V '&' for OS/2 '~' in labels for menu accelerators
  156.         char *ch;
  157.         for (ch  = _mb[sub].label; *ch != 0; ch++)
  158.         {
  159.           if (*ch == '&')
  160.             *ch = '~';
  161.         }
  162.         _mb[sub].menuId = item[ix].menuId;
  163.         _mb[sub].SubMenu = item[ix].SubMenu;
  164.         info->SubMenuIndex = sub;
  165.  
  166.         // Now, recursively call doAddMenu with the submenu
  167.         doAddMenu(sub, _mb[id].hPullDown);
  168.       }
  169.       else
  170.       {
  171.         // create the item
  172.         fixLabel(item[ix].label,item[ix].keyLabel);
  173.         mi.iPosition = MIT_END;
  174.         mi.afStyle = MIS_TEXT;
  175.         mi.afAttribute = 0;
  176.         mi.id = item[ix].menuId;
  177.         mi.hwndSubMenu = NULLHANDLE;
  178.         mi.hItem = 0;
  179.         WinSendMsg(_mb[id].hPullDown, MM_INSERTITEM,
  180.                   (MPARAM) &mi, (MPARAM) curLbl);
  181.  
  182.         WinCheckMenuItem(_mb[id].hPullDown,
  183.           item[ix].menuId,
  184.           (item[ix].checked ? TRUE : FALSE));
  185.  
  186.         WinEnableMenuItem (_mb[id].hPullDown, item[ix].menuId,
  187.           item[ix].sensitive ? TRUE : FALSE);
  188.       }
  189.     }
  190.     mi.iPosition = MIT_END;
  191.     mi.afStyle = MIS_SUBMENU;
  192.     mi.afAttribute = 0;
  193.     mi.id = _mb[id].menuId;
  194.     mi.hwndSubMenu = _mb[id].hPullDown;
  195.     mi.hItem = 0;
  196.     WinSendMsg(parent, MM_INSERTITEM, (MPARAM) &mi, (MPARAM) _mb[id].label);
  197.   }
  198.  
  199. //====================>>> vMenuPane::CheckAccel <<<======================
  200.   int vMenuPane::CheckAccel(vKey vkey, unsigned int shift, ItemVal& id) VCONST
  201.   {
  202.     // scan all menus in this window to see if this keystroke
  203.     // matches an accelerator key
  204.     vMenu* item;
  205.     // Search all menus in this list
  206.     for (int ix = 0 ; ix < _nextSubMenu ; ++ix)
  207.       {
  208.     MenuInfo* info;            // for current info
  209.     // scan the list of info for each menu entry
  210.     for (info = _mb[ix].mInfo ; info != 0 ; info = info->NxtInfo)
  211.       {
  212.         item = _mb[ix].SubMenu;    // The current item in list
  213.         // see if its menuId is the same as the one we are setting
  214.         if (item[info->ItemIndex].accel == vkey
  215.          && item[info->ItemIndex].kShift == shift)
  216.           {
  217.         id = item[info->ItemIndex].menuId;
  218.         return 1;
  219.           }
  220.       }
  221.       }
  222.     id = 0;
  223.     return 0;        // assume 0 if not found
  224.   }
  225. //====================>>> vMenuPane::GetPaneValue <<<======================
  226.   int vMenuPane::GetPaneValue(ItemVal id, int& val) VCONST
  227.   {
  228.     // scan all menus in this window to retrieve the what value
  229.     // then scan button bar if not found
  230.     vMenu* item;
  231.     // Search all menus in this list
  232.     for (int ix = 0 ; ix < _nextSubMenu ; ++ix)
  233.       {
  234.     MenuInfo* info;            // for current info
  235.     // scan the list of info for each menu entry
  236.     for (info = _mb[ix].mInfo ; info != 0 ; info = info->NxtInfo)
  237.       {
  238.         item = _mb[ix].SubMenu;    // The current item in list
  239.         // see if its menuId is the same as the one we are setting
  240.         if (item[info->ItemIndex].menuId == id)
  241.           {
  242.         // Ah Ha! We found the value we want
  243.         val = item[info->ItemIndex].checked;
  244.         return 1;
  245.           }
  246.       }
  247.       }
  248.     val = 0;
  249.     return 0;        // assume 0 if not found
  250.   }
  251. //==================>>> vMenuPane::SetPaneValue <<<========================
  252.   void vMenuPane::SetPaneValue(ItemVal id, int val, ItemSetType setType)
  253.   {
  254.     // Set the given item on or off
  255.     vMenu* item;
  256.     // Search all menus in this list
  257.     for (int ix = 0 ; ix < _nextSubMenu ; ++ix)
  258.       {
  259.     MenuInfo* info;            // for current info
  260.     // scan the list of info for each menu entry
  261.     for (info = _mb[ix].mInfo ; info != 0 ; info = info->NxtInfo)
  262.       {
  263.         item = _mb[ix].SubMenu;    // The current item in list
  264.         // see if its menuId is the same as the one we are setting
  265.         if (item[info->ItemIndex].menuId == id)
  266.           {
  267.         // Ah Ha! We found the value we want
  268.         switch (setType)
  269.           {
  270.             case Value:            // check box
  271.             case Checked:        // check box
  272.               {
  273.             item[info->ItemIndex].checked = val;
  274.             WinCheckMenuItem (_mb[ix].hPullDown,
  275.                 item[info->ItemIndex].menuId,
  276.                 val ? TRUE : FALSE);
  277.             break;
  278.               }
  279.             case Sensitive:            // sensitive
  280.               {
  281.             item[info->ItemIndex].sensitive = val;
  282.             WinEnableMenuItem (_mb[ix].hPullDown,
  283.                 item[info->ItemIndex].menuId,
  284.                 val ? TRUE : FALSE);
  285.             break;
  286.               }
  287.           }    // end switch
  288.           }
  289.       }
  290.       }
  291.   }
  292. //================>>> vMenuPane::SetPaneString <<<========================
  293.   void vMenuPane::SetPaneString(ItemVal id, VCONST char* str)
  294.   {
  295.     // Set the given item on or off
  296.     vMenu* item;
  297.     // Search all menus in this window
  298.     for (int ix = 0 ; ix < _nextSubMenu ; ++ix)
  299.     {
  300.       MenuInfo* info;            // for current info
  301.       // scan the list of info for each menu entry
  302.       for (info = _mb[ix].mInfo ; info != 0 ; info = info->NxtInfo)
  303.       {
  304.         item = _mb[ix].SubMenu;    // The current item in list
  305.     if (item[info->ItemIndex].menuId == id)
  306.     {
  307.       // Ah Ha! We found the value we want
  308.       item[info->ItemIndex].label = str;
  309.       WinSetMenuItemText (_mb[ix].hPullDown,         // the menu
  310.                     item[info->ItemIndex].menuId,  // same id
  311.                     item[info->ItemIndex].label);  // new label
  312.  
  313.       WinSendMsg (theApp->_Frame, WM_UPDATEFRAME, MPFROMLONG(FCF_MENU), MPVOID);
  314.     }
  315.       }
  316.     }
  317.   }
  318.