Humble Framework for SkyOS


Main Page | Modules | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

HMenu.h

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 **  $Header: /SkyOS.root/pig/Humble/HMenu.h 5     2/04/05 10:45a Neusel $
00004 **
00005 ****************************************************************************/
00011 #ifndef HMENU_H
00012 #   define  HMENU_H
00013 
00014 #ifndef HWIDGET_H
00015 #   include <HWidget.h>
00016 #endif
00017 /*  ----------------------------------------------------------------------
00018     HMenu class -- no implementation file
00019     ----------------------------------------------------------------------  */
00032 class HMenu :   public HWidget,
00033                 public HID
00034     {
00035     typedef HWidget     base_class;
00036     static StringPtr    ClassName(void) { return "HMenu"; }
00037 
00038 protected:
00039     friend class HMenuBar;
00040     typedef widget_menu_item *          MenuItemPtr;
00041     typedef HMap<int32, MenuItemPtr>    MenuItemMap;
00042 /*  ----------------------------------------------------------------------
00043     VARIABLES
00044     ----------------------------------------------------------------------  */
00045 protected:
00046     MenuItemMap         m_items;        
00047 /*  ----------------------------------------------------------------------
00048     CTOR/DTOR
00049     ----------------------------------------------------------------------  */
00050 public:
00051     HMenu(int32 id = 0) : HWidget(), HID(id)
00052         { /* EMPTY CTOR */ }
00053 
00054     virtual             
00055     ~HMenu(void)
00056         { Destroy(); }
00057 /*  ----------------------------------------------------------------------
00058     METHODS
00059     ----------------------------------------------------------------------  */
00060 public:
00072     ErrCode
00073     AddItem(int32 nCmd, StringPtr pstrLabel, uint32 uFlags = 0, bool bEnabled = true)
00074         {
00075         widget_menu_item    dummy;
00076         const uint32        kMaxItemLen = sizeof(dummy.text);
00077         
00078         ErrCode         ec = HError::NoError();
00079         MenuItemPtr     pItem = NULL;
00080         Text            szItem[kMaxItemLen+1];
00081         
00082         try
00083             {
00084             if (!IsValid())
00085                 HError::Throw(ERR_NOT_INITIALIZED, __FILE__, __LINE__);
00086         
00087             if (STR_EMPTY(pstrLabel))
00088                 HError::Throw(ERR_BAD_PARAMETER, __FILE__, __LINE__);
00089             
00090             if (nCmd && getMenuItem(nCmd) != NULL)
00091                 {
00092                 DEBUG_LOG("HMenu::AddItem() => item ID#%ld already in menu #%ld.\n", nCmd, m_id);
00093                 HError::Throw(ERR_DUPLICATE, __FILE__, __LINE__);
00094                 }
00095                 
00096             STR_NCPY(szItem, pstrLabel, kMaxItemLen);
00097             pItem = GI_create_menu_item(TEXT(szItem), nCmd, uFlags, bEnabled);
00098             if (NULL_PTR(pItem))
00099                 HError::Throw(ERR_API_ERROR, __FILE__, __LINE__);
00100             
00101             if (GI_add_menu_item(GetMenuPtr(), pItem) != S_OK)
00102                 HError::Throw(ERR_API_ERROR, __FILE__, __LINE__);
00103 
00104             m_items[nCmd] = pItem;
00105             }
00106         catch (const std::exception & e)
00107             {
00108             DEBUG_LOG("HMenu::AddItem() => caught %s\n", e.what());
00109 
00110             if ((ec = ErrCode( HError::GetLastError() )) == NO_ERROR)
00111                 ec = HError::Set(ERR_STL_EXCEPTION, __FILE__, __LINE__);
00112 
00113             if (GOOD_PTR(pItem))
00114                 (void) GI_destroy_window( reinterpret_cast<s_window *>(pItem) );
00115             }
00116             
00117         return ec;
00118         }
00124     ErrCode
00125     AddSeparator(void)
00126         { 
00127         ErrCode     ec = HError::NoError();
00128         MenuItemPtr pItem = NULL;
00129         
00130         try
00131             {
00132             if (!IsValid())
00133                 HError::Throw(ERR_NOT_INITIALIZED, __FILE__, __LINE__);
00134         
00135             pItem = GI_create_menu_item(TEXT(kStrEmpty), 0, MENU_SEPERATOR, false);
00136             if (NULL_PTR(pItem))
00137                 HError::Throw(ERR_API_ERROR, __FILE__, __LINE__);
00138             
00139             if (GI_add_menu_item(GetMenuPtr(), pItem) != S_OK)
00140                 HError::Throw(ERR_API_ERROR, __FILE__, __LINE__);
00141             }
00142         catch (const std::exception & e)
00143             {
00144             DEBUG_LOG("HMenu::AddSeparator() => caught %s\n", e.what());
00145 
00146             if ((ec = ErrCode( HError::GetLastError() )) == NO_ERROR)
00147                 ec = HError::Set(ERR_STL_EXCEPTION, __FILE__, __LINE__);
00148 
00149             if (GOOD_PTR(pItem))
00150                 (void) GI_destroy_window( reinterpret_cast<s_window *>(pItem) );
00151             }
00152             
00153         return ec;
00154         }
00164     ErrCode
00165     Create(int32 nID, HANDLE hWnd = NULL)
00166         {
00167         ErrCode     ec = HError::NoError();
00168         
00169         if (GOOD_HND(m_hMe))
00170             ec = HError::Set(ERR_DUPLICATE, __FILE__, __LINE__);
00171         else
00172             {
00173             m_hMe = reinterpret_cast<HANDLE>( GI_create_menu(hWnd) );
00174             if (NULL_HND(m_hMe))
00175                 ec = HError::Set(ERR_API_ERROR, __FILE__, __LINE__);
00176             else    // all is well
00177                 {
00178                 m_id = nID;
00179                 DEBUG_LOG(  "HMenu[%p]::Create() => 0x%08lX\n", 
00180                             this, int32(m_hMe));
00181                 }
00182             }
00183         
00184         return ec;
00185         }
00193     ErrCode
00194     EnableItem(int32 nCmd, bool bEnable = true)
00195         {
00196         ErrCode     ec = HError::NoError();
00197         MenuItemPtr pItem = getMenuItem(nCmd);
00198 
00199         if (GOOD_PTR(pItem))
00200             {
00201             //
00202             //  Check the internal menu structure to avoid redundant item changes
00203             //
00204             if ((!bEnable && pItem->enabled) || (bEnable && !(pItem->enabled)) &&
00205                 GI_widget_menu_item_enable(HANDLE(pItem), (bEnable ? 1 : 0)) != S_OK)
00206                 {
00207                 ec = HError::Set(ERR_API_ERROR, __FILE__, __LINE__);
00208                 }
00209             }
00210         else
00211             ec = HError::Set(ERR_NOT_FOUND, __FILE__, __LINE__);
00212         
00213         return ec;
00214         }
00215 /*  ----------------------------------------------------------------------
00216     GETTERS & SETTERS
00217     ----------------------------------------------------------------------  */
00218 public:
00221     widget_menu *       GetMenuPtr(void) const
00222                             { return reinterpret_cast<widget_menu *>( m_hMe ); }
00230     ErrCode             SetItemText(int32 nCmd, StringPtr pstrLabel)
00231                             {
00232                             ErrCode     ec = HError::NoError();
00233                             MenuItemPtr pItem = getMenuItem(nCmd);
00234 
00235                             if (GOOD_PTR(pItem))
00236                                 {
00237                                 if (STR_VALID(pstrLabel))
00238                                     STR_NCPY(TextPtr(pItem->text), pstrLabel, sizeof(pItem->text));
00239                                 else
00240                                     ec = HError::Set(ERR_BAD_PARAMETER, __FILE__, __LINE__);
00241                                 }
00242                             else
00243                                 ec = HError::Set(ERR_NOT_FOUND, __FILE__, __LINE__);
00244                             
00245                             return ec;
00246                             }
00247 protected:
00250     MenuItemPtr         getMenuItem(int32 nCmd)
00251                             {
00252                             MenuItemPtr     pItem = NULL;
00253                             
00254                             return (m_items.Get(nCmd, pItem) == NO_ERROR) ? pItem : NULL; 
00255                             }
00256     };
00257     
00258 typedef HMenu *     HMenuPtr;
00259 /*  ----------------------------------------------------------------------
00260     HMenuBar class -- no implementation file
00261     ----------------------------------------------------------------------  */
00271 class HMenuBar : public HMenu
00272     {
00273     typedef HMenu   base_class;
00274     static StringPtr    ClassName(void) { return "HMenuBar"; }
00275 
00276 protected:
00277     typedef std::map<int32, HMenuPtr> HMenuMap;
00278 /*  ----------------------------------------------------------------------
00279     VARIABLES
00280     ----------------------------------------------------------------------  */
00281 protected:
00282     HMenuMap        m_menus;            
00283 /*  ----------------------------------------------------------------------
00284     CTOR/DTOR
00285     ----------------------------------------------------------------------  */
00286 public:
00287     HMenuBar(void) : HMenu()
00288         { /* EMPTY CTOR */ }
00289 
00290     virtual             
00291     ~HMenuBar(void)
00292         { (void) Destroy(); }
00293 /*  ----------------------------------------------------------------------
00294     METHODS
00295     ----------------------------------------------------------------------  */
00296 public:
00309     ErrCode
00310     AddMenu(int32 nID, StringPtr pstrLabel, HMenuPtr & pMenu)
00311         {
00312         widget_menu_item    dummy;
00313         const uint32        kMaxItemLen = sizeof(dummy.text);
00314         
00315         ErrCode     ec = HError::NoError();
00316         MenuItemPtr pItem = NULL;
00317         Text        szLabel[kMaxItemLen+1];
00318         
00319         pMenu = NULL;
00320         
00321         try
00322             {
00323             if (nID == 0)
00324                 HError::Throw(ERR_BAD_PARAMETER, __FILE__, __LINE__);
00325             //
00326             //  See if the menu is already in the list
00327             //
00328             if (GetMenu(nID) != NULL)   // true if already in menu
00329                 {
00330                 DEBUG_LOG("HMenuBar::AddMenu() => menu #%ld already in menu bar\n", nID);
00331                 HError::Throw(ERR_DUPLICATE, __FILE__, __LINE__);
00332                 }
00333             //
00334             //  Now create the menu and add it to the menu bar...
00335             //
00336             pMenu = new HMenu;
00337             ASSERT_PTR(pMenu);
00338 
00339             if ((ec = pMenu->Create(nID)) != NO_ERROR)
00340                 throw HError::GetLastError();
00341         
00342             STR_NCPY(szLabel, pstrLabel, kMaxItemLen);
00343             pItem = GI_create_menu_item(TEXT(szLabel), nID, 0, true);
00344             if (NULL_PTR(pItem))
00345                 HError::Throw(ERR_API_ERROR, __FILE__, __LINE__);
00346                 
00347             if (GI_add_menu_sub(GetMenuPtr(), pItem, pMenu->GetMenuPtr()) != S_OK)
00348                 HError::Throw(ERR_API_ERROR, __FILE__, __LINE__);
00349                 
00350             m_menus[nID] = pMenu;   // add this menu to the map
00351             }
00352         catch (const std::exception & e)
00353             {
00354             DEBUG_LOG("HMenuBar::AddMenu() => caught %s\n", e.what());
00355 
00356             if ((ec = ErrCode( HError::GetLastError() )) == NO_ERROR)
00357                 ec = HError::Set(ERR_STL_EXCEPTION, __FILE__, __LINE__);
00358 
00359             pMenu->m_bAutoDestruct = false; // manually destroying the widget
00360             delete pMenu;
00361             pMenu = NULL;
00362             }
00363                 
00364         return ec;
00365         }
00373     ErrCode
00374     Destroy(void)
00375         {
00376         ErrCode     ec = HError::NoError();
00377         
00378         try
00379             {
00380             for (HMenuMap::iterator it = m_menus.begin(); it != m_menus.end(); ++it)
00381                 {
00382                 ASSERT(it != NULL);
00383                 delete it->second;  // this is the HMenu *
00384                 }
00385 
00386             m_menus.erase(m_menus.begin(), m_menus.end());
00387             ec = base_class::Destroy();
00388             }
00389         catch (const std::exception & e)
00390             {
00391             DEBUG_LOG("HMenuBar::Destroy() => caught %s\n", e.what());
00392             
00393             if ((ec = ErrCode( HError::GetLastError() )) == NO_ERROR)
00394                 ec = HError::Set(ERR_STL_EXCEPTION, __FILE__, __LINE__);
00395             }
00396                 
00397         return ec;
00398         }           
00408     ErrCode
00409     RemoveMenu(int32 nID)
00410         {
00411         ErrCode             ec = HError::NoError();
00412         HMenuMap::iterator  it;
00413         
00414         try
00415             {
00416             if ((it = m_menus.find(nID)) != m_menus.end())
00417                 {
00418                 ASSERT( it != NULL );
00419                 delete it->second;
00420                 m_menus.erase(it);
00421                 DEBUG_LOG("HMenuBar::RemoveMenu() => removed menu #%ld\n", nID);
00422                 }
00423             else
00424                 ec = HError::Set(ERR_NOT_FOUND, __FILE__, __LINE__);
00425             }
00426         catch (const std::exception & e)
00427             {
00428             DEBUG_LOG("HMenuBar::RemoveMenu() => caught %s\n", e.what());
00429             
00430             if ((ec = ErrCode( HError::GetLastError() )) == NO_ERROR)
00431                 ec = HError::Set(ERR_STL_EXCEPTION, __FILE__, __LINE__);
00432             }
00433             
00434         return ec;
00435         }
00436 /*  ----------------------------------------------------------------------
00437     GETTERS & SETTERS
00438     ----------------------------------------------------------------------  */
00439 public:
00450     HMenuPtr            GetMenu(int32 nID)
00451                             {
00452                             HMenuMap::iterator  it = m_menus.find(nID);
00453                             
00454                             if (it == m_menus.end())
00455                                 return NULL;    // didn't find it
00456 
00457                             ASSERT(it != NULL);
00458                             return it-> second;
00459                             }
00464     int32               GetMenuCount(void) const
00465                             { return m_menus.size(); }
00477     HMenuPtr            GetMenuByCommand(int32 nCmd)
00478                             {
00479                             for (HMenuMap::iterator it = m_menus.begin(); it != m_menus.end(); ++it)
00480                                 {
00481                                 HMenuPtr    pMenu = it->second;
00482 
00483                                 if (GOOD_PTR(pMenu) && 
00484                                     pMenu->getMenuItem(nCmd) != NULL)
00485                                     {
00486                                     return pMenu;   // found it!
00487                                     }
00488                                 }
00489 
00490                             return NULL;
00491                             }
00500     HMenuPtr            GetNthMenu(int32 index)
00501                             {
00502                             for (HMenuMap::iterator it = m_menus.begin(); it != m_menus.end(); ++it)
00503                                 if (index-- == 0)
00504                                     {
00505                                     ASSERT(it != NULL);
00506                                     return it->second;
00507                                     }
00508                             
00509                             return NULL;
00510                             }
00511     };
00512 #endif  // HMENU_H
00513 /****************************************************************************
00514 **
00515 **  $History: HMenu.h $
00516  * 
00517  * *****************  Version 5  *****************
00518  * User: Neusel       Date: 2/04/05    Time: 10:45a
00519  * Updated in $/SkyOS.root/pig/Humble
00520  * 
00521  * *****************  Version 4  *****************
00522  * User: Neusel       Date: 12/23/04   Time: 1:34p
00523  * Updated in $/SkyOS.root/pig/Humble
00524  * Posted as HFramework-debug 20041223
00525  * 
00526  * *****************  Version 3  *****************
00527  * User: Neusel       Date: 12/08/04   Time: 5:06p
00528  * Updated in $/SkyOS.root/pig/Humble
00529  * 20041208
00530  * 
00531  * *****************  Version 2  *****************
00532  * User: Neusel       Date: 11/30/04   Time: 1:01p
00533  * Updated in $/SkyOS.root/pig/Humble
00534  * Released as HUMBLE_VER 20041130.
00535  * 
00536  * *****************  Version 1  *****************
00537  * User: Neusel       Date: 11/23/04   Time: 8:24a
00538  * Created in $/SkyOS.root/pig/Humble
00539 **
00540 **  -------------------------------------------------------------------------
00541 **
00542 **  End of HMenu.h
00543 **
00544 ****************************************************************************/