Counter Strike : Global Offensive Source Code
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.

228 lines
5.9 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Helper for the CHudElement class to add themselves to the list of hud elements
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "vgui/IVGui.h"
  8. #include "vgui_controls/MessageMap.h"
  9. // memdbgon must be the last include file in a .cpp file!!!
  10. #include "tier0/memdbgon.h"
  11. #include "vgui_controls/Panel.h"
  12. using namespace vgui;
  13. // Start with empty list
  14. CBuildFactoryHelper *CBuildFactoryHelper::m_sHelpers = NULL;
  15. //-----------------------------------------------------------------------------
  16. // Purpose: Constructs a panel factory
  17. // Input : pfnCreate - fn Ptr to a function which generates a panel
  18. //-----------------------------------------------------------------------------
  19. CBuildFactoryHelper::CBuildFactoryHelper( char const *className, PANELCREATEFUNC func )
  20. {
  21. // Make this fatal
  22. if ( HasFactory( className ) )
  23. {
  24. Error( "CBuildFactoryHelper: Factory for '%s' already exists!!!!\n", className );
  25. }
  26. //List is empty, or element belongs at front, insert here
  27. m_pNext = m_sHelpers;
  28. m_sHelpers = this;
  29. Assert( func );
  30. m_CreateFunc = func;
  31. Assert( className );
  32. m_pClassName = className;
  33. }
  34. //-----------------------------------------------------------------------------
  35. // Purpose: Returns next object in list
  36. // Output : CBuildFactoryHelper
  37. //-----------------------------------------------------------------------------
  38. CBuildFactoryHelper *CBuildFactoryHelper::GetNext( void )
  39. {
  40. return m_pNext;
  41. }
  42. char const *CBuildFactoryHelper::GetClassName() const
  43. {
  44. return m_pClassName;
  45. }
  46. vgui::Panel *CBuildFactoryHelper::CreatePanel()
  47. {
  48. if ( !m_CreateFunc )
  49. return NULL;
  50. return ( *m_CreateFunc )();
  51. }
  52. // private static meethod
  53. bool CBuildFactoryHelper::HasFactory( char const *className )
  54. {
  55. CBuildFactoryHelper *p = m_sHelpers;
  56. while ( p )
  57. {
  58. if ( !Q_stricmp( className, p->GetClassName() ) )
  59. return true;
  60. p = p->GetNext();
  61. }
  62. return false;
  63. }
  64. // static method
  65. vgui::Panel *CBuildFactoryHelper::InstancePanel( char const *className )
  66. {
  67. CBuildFactoryHelper *p = m_sHelpers;
  68. while ( p )
  69. {
  70. if ( !Q_stricmp( className, p->GetClassName() ) )
  71. return p->CreatePanel();
  72. p = p->GetNext();
  73. }
  74. return NULL;
  75. }
  76. // static method
  77. void CBuildFactoryHelper::GetFactoryNames( CUtlVector< char const * >& list )
  78. {
  79. list.RemoveAll();
  80. CBuildFactoryHelper *p = m_sHelpers;
  81. while ( p )
  82. {
  83. list.AddToTail( p->GetClassName() );
  84. p = p->GetNext();
  85. }
  86. }
  87. CDmxElement *CBuildFactoryHelper::CreatePanelDmxElement( vgui::Panel *pPanel )
  88. {
  89. // Create DMX elements representing panels
  90. CDmxElement *pPanelElement = CreateDmxElement( "CDmePanelDefinition" );
  91. CDmxElementModifyScope modify( pPanelElement );
  92. CDmxAttribute *panelTypeAttr = pPanelElement->AddAttribute( "panelClassType" );
  93. panelTypeAttr->SetValue( pPanel->GetClassName() );
  94. const DmxElementUnpackStructure_t *pUnpack = pPanel->GetUnpackStructure();
  95. if ( pUnpack )
  96. {
  97. pPanelElement->AddAttributesFromStructure( pPanel, pUnpack );
  98. }
  99. // Hack to deal with IPanel ( pretty sure this works! )
  100. pUnpack = vgui::ipanel()->GetUnpackStructure( pPanel->GetVPanel() );
  101. if ( pUnpack )
  102. {
  103. pPanelElement->AddAttributesFromStructure( (void *)pPanel->GetVPanel(), pUnpack );
  104. }
  105. CDmxAttribute* pAttribute = pPanelElement->AddAttribute( "children" );
  106. CUtlVector< CDmxElement* >& children = pAttribute->GetArrayForEdit<CDmxElement*>();
  107. int nChildCount = pPanel->GetChildCount();
  108. for ( int i = 0; i < nChildCount; ++i )
  109. {
  110. CDmxElement *pChildElement = CreatePanelDmxElement( pPanel->GetChild(i) );
  111. children.AddToTail( pChildElement );
  112. }
  113. return pPanelElement;
  114. }
  115. bool CBuildFactoryHelper::Serialize( CUtlBuffer &buf, vgui::Panel *pPanel )
  116. {
  117. DECLARE_DMX_CONTEXT();
  118. CDmxElement *pRoot = CreatePanelDmxElement( pPanel );
  119. bool bOk = SerializeDMX( buf, pRoot );
  120. CleanupDMX( pRoot );
  121. return bOk;
  122. }
  123. Panel* CBuildFactoryHelper::UnserializeDmxElementPanel( CDmxElement *pElement )
  124. {
  125. // FIXME: This will change as the file format changes
  126. if ( Q_stricmp( pElement->GetTypeString(), "CDmePanelDefinition" ) )
  127. return NULL;
  128. Panel *pNewPanel = CBuildFactoryHelper::InstancePanel( pElement->GetValueString( "panelClassType" ) );
  129. if ( !pNewPanel )
  130. {
  131. return NULL;
  132. }
  133. const DmxElementUnpackStructure_t *pUnpack = pNewPanel->GetUnpackStructure();
  134. if ( pUnpack )
  135. {
  136. pElement->UnpackIntoStructure( pNewPanel, pUnpack );
  137. }
  138. // Hack to deal with IPanel ( pretty sure this works! )
  139. pUnpack = vgui::ipanel()->GetUnpackStructure( pNewPanel->GetVPanel() );
  140. if ( pUnpack )
  141. {
  142. pElement->UnpackIntoStructure( (void *)pNewPanel->GetVPanel(), pUnpack );
  143. }
  144. // Children are added manually, since the unpack framework doesn't
  145. // know how to create all the various panel types
  146. const CDmxAttribute* pAttribute = pElement->GetAttribute( "children" );
  147. if ( pAttribute && pAttribute->GetType() == AT_ELEMENT_ARRAY )
  148. {
  149. const CUtlVector< CDmxElement* >& children = pAttribute->GetArray<CDmxElement*>();
  150. for ( int i = 0; i < children.Count(); ++i )
  151. {
  152. Panel *pChildPanel = UnserializeDmxElementPanel( children[i] );
  153. if ( pChildPanel )
  154. {
  155. pChildPanel->SetParent( pNewPanel );
  156. }
  157. }
  158. }
  159. // This is a new virtual method in Panel which is called post-serialization
  160. pNewPanel->OnUnserialized( pElement );
  161. return pNewPanel;
  162. }
  163. bool CBuildFactoryHelper::Unserialize( Panel **ppPanel, CUtlBuffer &buf, const char *pFileName )
  164. {
  165. DECLARE_DMX_CONTEXT();
  166. *ppPanel = NULL;
  167. CDmxElement *pRootElement;
  168. if ( !UnserializeDMX( buf, &pRootElement, pFileName ) )
  169. {
  170. Warning( "Unable to read panel %s! UtlBuffer is the wrong type!\n", pFileName );
  171. CleanupDMX( pRootElement );
  172. return false;
  173. }
  174. *ppPanel = UnserializeDmxElementPanel( pRootElement );
  175. if ( !*ppPanel )
  176. {
  177. Warning( "Unable to create panel %s!\n", pFileName );
  178. CleanupDMX( pRootElement );
  179. return false;
  180. }
  181. CleanupDMX( pRootElement );
  182. return true;
  183. }