Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

195 lines
5.8 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: The menu manager
  4. //
  5. // $Revision: $
  6. // $NoKeywords: $
  7. //===========================================================================//
  8. #include "menumanager.h"
  9. #include "vgui_controls/panel.h"
  10. #include "vgui_controls/frame.h"
  11. #include "uimanager.h"
  12. //-----------------------------------------------------------------------------
  13. // Singleton
  14. //-----------------------------------------------------------------------------
  15. static CMenuManager s_MenuManager;
  16. extern CMenuManager *g_pMenuManager = &s_MenuManager;
  17. //-----------------------------------------------------------------------------
  18. // Static members.
  19. // NOTE: Do *not* set this to 0; it could cause us to lose some registered
  20. // menus since that list is set up during construction
  21. //-----------------------------------------------------------------------------
  22. IMenuFactory *CMenuManager::m_pFirstFactory;
  23. //-----------------------------------------------------------------------------
  24. // Call to register methods which can construct menus w/ particular names
  25. //-----------------------------------------------------------------------------
  26. IMenuFactory *CMenuManager::RegisterMenu( IMenuFactory *pMenuFactory )
  27. {
  28. // NOTE: This method is expected to be called during global constructor
  29. // time, so it must not require any global constructors to be called to work
  30. IMenuFactory *pPrevFactory = m_pFirstFactory;
  31. m_pFirstFactory = pMenuFactory;
  32. return pPrevFactory;
  33. }
  34. //-----------------------------------------------------------------------------
  35. // Init, shutdown
  36. //-----------------------------------------------------------------------------
  37. bool CMenuManager::Init()
  38. {
  39. // Build a dictionary of all registered menus
  40. IMenuFactory *pFactory;
  41. for ( pFactory = m_pFirstFactory; pFactory; pFactory = pFactory->GetNextFactory() )
  42. {
  43. m_MenuFactories.Insert( pFactory->GetMenuName(), pFactory );
  44. }
  45. m_bPopRequested = false;
  46. m_bPopAllRequested = false;
  47. m_pPushRequested = NULL;
  48. return true;
  49. }
  50. void CMenuManager::Shutdown()
  51. {
  52. CleanUpAllMenus();
  53. }
  54. //-----------------------------------------------------------------------------
  55. // Push, pop menus
  56. //-----------------------------------------------------------------------------
  57. void CMenuManager::PushMenu( const char *pMenuName )
  58. {
  59. AssertMsg( !m_pPushRequested, "Can't request to push two menus in a single frame!" );
  60. MenuFactoryIndex_t i = m_MenuFactories.Find( pMenuName );
  61. if ( i == m_MenuFactories.InvalidIndex() )
  62. {
  63. Warning( "Tried to push unknown menu %s\n", pMenuName );
  64. return;
  65. }
  66. m_pPushRequested = m_MenuFactories[i];
  67. }
  68. void CMenuManager::PopMenu( )
  69. {
  70. AssertMsg( !m_bPopRequested, "Can't request to pop two menus in a single frame!" );
  71. AssertMsg( !m_pPushRequested, "Can't request to pop after requesting to push a menu in a single frame!" );
  72. m_bPopRequested = true;
  73. }
  74. void CMenuManager::PopAllMenus( )
  75. {
  76. AssertMsg( !m_pPushRequested, "Can't request to pop after requesting to push a menu in a single frame!" );
  77. m_bPopAllRequested = true;
  78. }
  79. //-----------------------------------------------------------------------------
  80. // Request a menu to switch to
  81. //-----------------------------------------------------------------------------
  82. void CMenuManager::SwitchToMenu( const char *pMenuName )
  83. {
  84. AssertMsg( !m_bPopRequested, "Can't request to pop two menus in a single frame!" );
  85. AssertMsg( !m_pPushRequested, "Can't request to push two menus in a single frame!" );
  86. MenuFactoryIndex_t i = m_MenuFactories.Find( pMenuName );
  87. if ( i == m_MenuFactories.InvalidIndex() )
  88. {
  89. Warning( "Tried to switch to unknown menu %s\n", pMenuName );
  90. return;
  91. }
  92. m_bPopRequested = true;
  93. m_pPushRequested = m_MenuFactories[i];
  94. }
  95. //-----------------------------------------------------------------------------
  96. // Returns the name of the topmost panel
  97. //-----------------------------------------------------------------------------
  98. const char *CMenuManager::GetTopmostPanelName()
  99. {
  100. if ( !m_nActiveMenu.Count() )
  101. return NULL;
  102. return m_nActiveMenu.Top()->GetName();
  103. }
  104. //-----------------------------------------------------------------------------
  105. // Request a menu to switch to
  106. //-----------------------------------------------------------------------------
  107. void CMenuManager::Update( )
  108. {
  109. if ( m_bPopAllRequested )
  110. {
  111. CleanUpAllMenus();
  112. m_bPopAllRequested = false;
  113. return;
  114. }
  115. if ( m_bPopRequested )
  116. {
  117. AssertMsg( m_nActiveMenu.Count(), "Tried to pop a menu when no menus are active" );
  118. vgui::Panel *pTop = m_nActiveMenu.Top();
  119. pTop->MarkForDeletion();
  120. m_nActiveMenu.Pop();
  121. // Mark the new active menu as visible, attach it to hierarchy.
  122. if ( m_nActiveMenu.Count() > 0 )
  123. {
  124. vgui::Panel *pTop = m_nActiveMenu.Top();
  125. pTop->SetVisible( true );
  126. pTop->SetParent( g_pUIManager->GetRootPanel( UI_ROOT_MENU ) );
  127. }
  128. else
  129. {
  130. g_pUIManager->EnablePanel( UI_ROOT_MENU, false );
  131. }
  132. m_bPopRequested = false;
  133. }
  134. if ( m_pPushRequested )
  135. {
  136. // Mark the previous menu as not visible, detach it from hierarchy.
  137. if ( m_nActiveMenu.Count() > 0 )
  138. {
  139. vgui::Panel *pTop = m_nActiveMenu.Top();
  140. pTop->SetVisible( false );
  141. pTop->SetParent( (vgui::Panel*)NULL );
  142. }
  143. else
  144. {
  145. g_pUIManager->EnablePanel( UI_ROOT_MENU, true );
  146. }
  147. vgui::Panel *pMenu = m_pPushRequested->CreateMenu( g_pUIManager->GetRootPanel( UI_ROOT_MENU ) );
  148. m_nActiveMenu.Push( pMenu );
  149. static_cast<vgui::Frame*>( pMenu )->Activate();
  150. m_pPushRequested = NULL;
  151. }
  152. }
  153. //-----------------------------------------------------------------------------
  154. // Cleans up all menus
  155. //-----------------------------------------------------------------------------
  156. void CMenuManager::CleanUpAllMenus()
  157. {
  158. while ( m_nActiveMenu.Count() )
  159. {
  160. vgui::Panel *pTop = m_nActiveMenu.Top();
  161. pTop->MarkForDeletion();
  162. m_nActiveMenu.Pop();
  163. }
  164. g_pUIManager->EnablePanel( UI_ROOT_MENU, false );
  165. }