aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/client/panelmetaclassmgr.cpp
diff options
context:
space:
mode:
authorJørgen P. Tjernø <[email protected]>2013-12-02 19:31:46 -0800
committerJørgen P. Tjernø <[email protected]>2013-12-02 19:46:31 -0800
commitf56bb35301836e56582a575a75864392a0177875 (patch)
treede61ddd39de3e7df52759711950b4c288592f0dc /mp/src/game/client/panelmetaclassmgr.cpp
parentMark some more files as text. (diff)
downloadsource-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz
source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/game/client/panelmetaclassmgr.cpp')
-rw-r--r--mp/src/game/client/panelmetaclassmgr.cpp874
1 files changed, 437 insertions, 437 deletions
diff --git a/mp/src/game/client/panelmetaclassmgr.cpp b/mp/src/game/client/panelmetaclassmgr.cpp
index 1b2064cb..6f0b50d0 100644
--- a/mp/src/game/client/panelmetaclassmgr.cpp
+++ b/mp/src/game/client/panelmetaclassmgr.cpp
@@ -1,437 +1,437 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: A panel "metaclass" is a name given to a particular type of
-// panel with particular instance data. Such panels tend to be dynamically
-// added and removed from their parent panels.
-//
-// $Workfile: $
-// $NoKeywords: $
-//=============================================================================//
-#include "cbase.h"
-#include "panelmetaclassmgr.h"
-#include <KeyValues.h>
-#include <vgui_controls/Panel.h>
-#include "utldict.h"
-#include "filesystem.h"
-#include <KeyValues.h>
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-//-----------------------------------------------------------------------------
-// Helper KeyValue parsing methods
-//-----------------------------------------------------------------------------
-bool ParseRGBA( KeyValues *pValues, const char* pFieldName, int& r, int& g, int& b, int& a )
-{
- r = g = b = a = 255;
- const char *pColorString = pValues->GetString( pFieldName, "255 255 255 255" );
- if ( !pColorString || !pColorString[ 0 ] )
- return false;
-
- // Try and scan them in
- int scanned;
- scanned = sscanf( pColorString, "%i %i %i %i", &r, &g, &b, &a );
- if ( scanned != 4 )
- {
- Warning( "Couldn't scan four color values from %s\n", pColorString );
- return false;
- }
-
- return true;
-}
-
-bool ParseRGBA( KeyValues* pValues, const char* pFieldName, Color& c )
-{
- int r, g, b, a;
- if (!ParseRGBA( pValues, pFieldName, r, g, b, a ))
- return false;
-
- c.SetColor( r, g, b, a );
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// FIXME: Why do we have vgui::KeyValues too!?!??! Bleah
-/*-----------------------------------------------------------------------------
-bool ParseRGBA( KeyValues *pValues, const char* pFieldName, int& r, int& g, int& b, int& a )
-{
- r = g = b = a = 255;
- const char *pColorString = pValues->GetString( pFieldName, "255 255 255 255" );
- if ( !pColorString || !pColorString[ 0 ] )
- return false;
-
- // Try and scan them in
- int scanned;
- scanned = sscanf( pColorString, "%i %i %i %i", &r, &g, &b, &a );
- if ( scanned != 4 )
- {
- Warning( "Couldn't scan four color values from %s\n", pColorString );
- return false;
- }
-
- return true;
-}
-
-bool ParseRGBA( KeyValues* pValues, const char* pFieldName, Color& c )
-{
- int r, g, b, a;
- if (!ParseRGBA( pValues, pFieldName, r, g, b, a ))
- return false;
-
- c.SetColor( r, g, b, a );
- return true;
-} */
-
-
-bool ParseCoord( KeyValues *pValues, const char* pFieldName, int& x, int& y )
-{
- x = y = 0;
- const char *pCoordString = pValues->GetString( pFieldName, "0 0" );
- if ( !pCoordString || !pCoordString[ 0 ] )
- return false;
-
- // Try and scan them in
- int scanned;
- scanned = sscanf( pCoordString, "%i %i", &x, &y );
- if ( scanned != 2 )
- {
- Warning( "Couldn't scan 2d coordinate values from %s\n", pCoordString );
- return false;
- }
-
- // coords are within 640x480 screen space
- x = ( x * ( ( float )ScreenWidth() / 640.0 ) );
- y = ( y * ( ( float )ScreenHeight() / 480.0 ) );
-
- return true;
-}
-
-bool ParseRect( KeyValues *pValues, const char* pFieldName, int& x, int& y, int& w, int& h )
-{
- x = y = w = h = 0;
- const char *pRectString = pValues->GetString( pFieldName, "0 0 0 0" );
- if ( !pRectString || !pRectString[ 0 ] )
- return false;
-
- // Try and scan them in
- int scanned;
- scanned = sscanf( pRectString, "%i %i %i %i", &x, &y, &w, &h );
- if ( scanned != 4 )
- {
- Warning( "Couldn't scan rectangle values from %s\n", pRectString );
- return false;
- }
-
- // coords are within 640x480 screen space
- x = ( x * ( ( float )ScreenWidth() / 640.0 ) );
- y = ( y * ( ( float )ScreenHeight() / 480.0 ) );
- w = ( w * ( ( float )ScreenWidth() / 640.0 ) );
- h = ( h * ( ( float )ScreenHeight() / 480.0 ) );
-
- return true;
-}
-
-
-//-----------------------------------------------------------------------------
-// Helper class to make meta class panels (for use in entities, so they autocleanup)
-//-----------------------------------------------------------------------------
-CPanelWrapper::CPanelWrapper() : m_pPanel(NULL)
-{
-}
-
-CPanelWrapper::~CPanelWrapper()
-{
- Deactivate();
-}
-
-void CPanelWrapper::Activate( char const* pMetaClassName, vgui::Panel *pParent, int sortorder, void *pVoidInitData )
-{
- if ( m_pPanel )
- {
- Deactivate();
- }
-
- m_pPanel = PanelMetaClassMgr()->CreatePanelMetaClass( pMetaClassName, sortorder, pVoidInitData, pParent );
-}
-
-void CPanelWrapper::Deactivate( void )
-{
- if ( m_pPanel )
- {
- PanelMetaClassMgr()->DestroyPanelMetaClass( m_pPanel );
- m_pPanel = NULL;
- }
-}
-
-vgui::Panel *CPanelWrapper::GetPanel( )
-{
- return m_pPanel;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Singleton class responsible for managing metaclass panels
-//-----------------------------------------------------------------------------
-class CPanelMetaClassMgrImp : public IPanelMetaClassMgr
-{
-public:
- // constructor, destructor
- CPanelMetaClassMgrImp();
- virtual ~CPanelMetaClassMgrImp();
-
- // Members of IPanelMetaClassMgr
- virtual void LoadMetaClassDefinitionFile( const char* pLevelName );
- virtual void InstallPanelType( const char* pPanelName, IPanelFactory* pFactory );
- virtual vgui::Panel *CreatePanelMetaClass( const char* pMetaClassName,
- int sortorder, void *pInitData, vgui::Panel *pParent, const char *pChainName );
- virtual void DestroyPanelMetaClass( vgui::Panel *pPanel );
-
-private:
- struct MetaClassDict_t
- {
- unsigned short m_KeyValueIndex;
- unsigned short m_TypeIndex;
- KeyValues* m_pKeyValues;
- };
-
- // various parsing helper methods
- bool ParseSingleMetaClass( const char* pFileName, const char* pInstanceName,
- KeyValues* pMetaClass, int keyValueIndex );
- bool ParseMetaClassList( const char* pFileName, KeyValues* pKeyValues, int keyValueIndex );
-
- // No copy constructor
- CPanelMetaClassMgrImp( const CPanelMetaClassMgrImp & );
-
- // List of panel types...
- CUtlDict< IPanelFactory*, unsigned short > m_PanelTypeDict;
-
- // List of metaclass types
- CUtlDict< MetaClassDict_t, unsigned short > m_MetaClassDict;
-
- // Create key value accesor
- CUtlDict< KeyValues*, unsigned short > m_MetaClassKeyValues;
-};
-
-
-//-----------------------------------------------------------------------------
-// Returns the singleton panel metaclass mgr interface
-//-----------------------------------------------------------------------------
-IPanelMetaClassMgr* PanelMetaClassMgr()
-{
- // NOTE: the CPanelFactory implementation requires the local static here
- // even though it means an extra check every time PanelMetaClassMgr is accessed
- static CPanelMetaClassMgrImp s_MetaClassMgrImp;
- return &s_MetaClassMgrImp;
-}
-
-
-//-----------------------------------------------------------------------------
-// constructor, destructor
-//-----------------------------------------------------------------------------
-CPanelMetaClassMgrImp::CPanelMetaClassMgrImp() : m_PanelTypeDict( true, 0, 32 )
-{
-}
-
-CPanelMetaClassMgrImp::~CPanelMetaClassMgrImp()
-{
-}
-
-
-//-----------------------------------------------------------------------------
-// Call this to install a new panel type
-//-----------------------------------------------------------------------------
-void CPanelMetaClassMgrImp::InstallPanelType( const char* pPanelName, IPanelFactory* pFactory )
-{
- Assert( pPanelName && pFactory );
-
- // convert to lowercase
- int len = Q_strlen(pPanelName) + 1;
- char* pTemp = (char*)stackalloc( len );
- Q_strncpy( pTemp, pPanelName, len );
- Q_strnlwr( pTemp, len );
-
- m_PanelTypeDict.Insert( pTemp, pFactory );
-
- stackfree( pTemp );
-}
-
-
-//-----------------------------------------------------------------------------
-// Parse a single metaclass
-//-----------------------------------------------------------------------------
-bool CPanelMetaClassMgrImp::ParseSingleMetaClass( const char* pFileName,
- const char* pMetaClassName, KeyValues* pMetaClassValues, int keyValueIndex )
-{
- // Complain about duplicately defined metaclass names...
- if ( m_MetaClassDict.Find( pMetaClassName ) != m_MetaClassDict.InvalidIndex() )
- {
- Warning( "Meta class %s duplicately defined (file %s)\n", pMetaClassName, pFileName );
- return false;
- }
-
- // find the type...
- const char* pPanelType = pMetaClassValues->GetString( "type" );
- if (!pPanelType || !pPanelType[0])
- {
- Warning( "Unable to find type of meta class %s in file %s\n", pMetaClassName, pFileName );
- return false;
- }
-
- unsigned short i = m_PanelTypeDict.Find( pPanelType );
- if (i == m_PanelTypeDict.InvalidIndex())
- {
- Warning( "Type %s of meta class %s undefined!\n", pPanelType, pMetaClassName );
- stackfree(pLwrMetaClass);
- return false;
- }
-
- // Add it to the metaclass dictionary
- MetaClassDict_t element;
- element.m_TypeIndex = i;
- element.m_KeyValueIndex = keyValueIndex;
- element.m_pKeyValues = pMetaClassValues;
- m_MetaClassDict.Insert( pMetaClassName, element );
-
- return true;
-}
-
-
-//-----------------------------------------------------------------------------
-// Parse the metaclass list
-//-----------------------------------------------------------------------------
-bool CPanelMetaClassMgrImp::ParseMetaClassList( const char* pFileName,
- KeyValues* pKeyValues, int keyValueIdx )
-{
- // Iterate over all metaclasses...
- KeyValues* pIter = pKeyValues->GetFirstSubKey();
- while( pIter )
- {
- if (!ParseSingleMetaClass( pFileName, pIter->GetName(), pIter, keyValueIdx ))
- {
- // return false;
- Warning( "MetaClass missing for %s\n", pIter->GetName() );
- }
- pIter = pIter->GetNextKey();
- }
-
- return true;
-}
-
-
-//-----------------------------------------------------------------------------
-// Loads up a file containing metaclass definitions
-//-----------------------------------------------------------------------------
-void CPanelMetaClassMgrImp::LoadMetaClassDefinitionFile( const char *pFileName )
-{
- MEM_ALLOC_CREDIT();
-
- // Blat out previous metaclass definitions read in from this file...
- int i = m_MetaClassKeyValues.Find( pFileName );
- if (i != m_MetaClassKeyValues.InvalidIndex() )
- {
- // Blow away the previous keyvalues from that file
- unsigned short j = m_MetaClassDict.First();
- while ( j != m_MetaClassDict.InvalidIndex() )
- {
- unsigned short next = m_MetaClassDict.Next(j);
- if ( m_MetaClassDict[j].m_KeyValueIndex == i)
- {
- m_MetaClassDict.RemoveAt(j);
- }
-
- j = next;
- }
-
- m_MetaClassKeyValues[i]->deleteThis();
- m_MetaClassKeyValues.RemoveAt(i);
- }
-
- // Create a new keyvalues entry
- KeyValues* pKeyValues = new KeyValues(pFileName);
- int idx = m_MetaClassKeyValues.Insert( pFileName, pKeyValues );
-
- // Read in all metaclass definitions...
-
- // Load the file
- if ( !pKeyValues->LoadFromFile( filesystem, pFileName ) )
- {
- Warning( "Couldn't find metaclass definition file %s\n", pFileName );
- pKeyValues->deleteThis();
- m_MetaClassKeyValues.RemoveAt(idx);
- return;
- }
- else
- {
- // Go ahead and parse the data now
- if ( !ParseMetaClassList( pFileName, pKeyValues, idx ) )
- {
- Warning( "Detected one or more errors parsing %s\n", pFileName );
- }
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Performs key value chaining
-//-----------------------------------------------------------------------------
-static void KeyValueChainRecursive( KeyValues* pKeyValues, const char *pSectionName )
-{
- KeyValues* pSection = pKeyValues->FindKey( pSectionName );
-
- if (pSection)
- {
- pKeyValues->ChainKeyValue( pSection );
- }
-
- KeyValues* pIter = pKeyValues->GetFirstSubKey();
- while (pIter)
- {
- // Don't both setting up links on a keyvalue that has no children
- if (pIter->GetFirstSubKey())
- KeyValueChainRecursive( pIter, pSectionName );
-
- pIter = pIter->GetNextKey();
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Create, destroy panel...
-//-----------------------------------------------------------------------------
-vgui::Panel *CPanelMetaClassMgrImp::CreatePanelMetaClass( const char* pMetaClassName,
- int sortorder, void *pInitData, vgui::Panel *pParent, const char *pChainName )
-{
- // Search for the metaclass name
- int i = m_MetaClassDict.Find( pMetaClassName );
- if (i == m_MetaClassDict.InvalidIndex())
- return NULL;
-
- // Now that we've got the metaclass, we can figure out what kind of
- // panel to instantiate...
- MetaClassDict_t &metaClass = m_MetaClassDict[i];
- IPanelFactory* pFactory = m_PanelTypeDict[metaClass.m_TypeIndex];
-
- // Set up the key values for use in initialization
- if (pChainName)
- {
- KeyValueChainRecursive( metaClass.m_pKeyValues, pChainName );
- }
-
- // Create and initialize the panel
- vgui::Panel *pPanel = pFactory->Create( pMetaClassName, metaClass.m_pKeyValues, pInitData, pParent );
- if ( pPanel )
- {
- pPanel->SetZPos( sortorder );
- }
-
- return pPanel;
-}
-
-void CPanelMetaClassMgrImp::DestroyPanelMetaClass( vgui::Panel *pPanel )
-{
-// if ( pPanel )
-// pPanel->MarkForDeletion();
- delete pPanel;
-}
-
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: A panel "metaclass" is a name given to a particular type of
+// panel with particular instance data. Such panels tend to be dynamically
+// added and removed from their parent panels.
+//
+// $Workfile: $
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "panelmetaclassmgr.h"
+#include <KeyValues.h>
+#include <vgui_controls/Panel.h>
+#include "utldict.h"
+#include "filesystem.h"
+#include <KeyValues.h>
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+//-----------------------------------------------------------------------------
+// Helper KeyValue parsing methods
+//-----------------------------------------------------------------------------
+bool ParseRGBA( KeyValues *pValues, const char* pFieldName, int& r, int& g, int& b, int& a )
+{
+ r = g = b = a = 255;
+ const char *pColorString = pValues->GetString( pFieldName, "255 255 255 255" );
+ if ( !pColorString || !pColorString[ 0 ] )
+ return false;
+
+ // Try and scan them in
+ int scanned;
+ scanned = sscanf( pColorString, "%i %i %i %i", &r, &g, &b, &a );
+ if ( scanned != 4 )
+ {
+ Warning( "Couldn't scan four color values from %s\n", pColorString );
+ return false;
+ }
+
+ return true;
+}
+
+bool ParseRGBA( KeyValues* pValues, const char* pFieldName, Color& c )
+{
+ int r, g, b, a;
+ if (!ParseRGBA( pValues, pFieldName, r, g, b, a ))
+ return false;
+
+ c.SetColor( r, g, b, a );
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// FIXME: Why do we have vgui::KeyValues too!?!??! Bleah
+/*-----------------------------------------------------------------------------
+bool ParseRGBA( KeyValues *pValues, const char* pFieldName, int& r, int& g, int& b, int& a )
+{
+ r = g = b = a = 255;
+ const char *pColorString = pValues->GetString( pFieldName, "255 255 255 255" );
+ if ( !pColorString || !pColorString[ 0 ] )
+ return false;
+
+ // Try and scan them in
+ int scanned;
+ scanned = sscanf( pColorString, "%i %i %i %i", &r, &g, &b, &a );
+ if ( scanned != 4 )
+ {
+ Warning( "Couldn't scan four color values from %s\n", pColorString );
+ return false;
+ }
+
+ return true;
+}
+
+bool ParseRGBA( KeyValues* pValues, const char* pFieldName, Color& c )
+{
+ int r, g, b, a;
+ if (!ParseRGBA( pValues, pFieldName, r, g, b, a ))
+ return false;
+
+ c.SetColor( r, g, b, a );
+ return true;
+} */
+
+
+bool ParseCoord( KeyValues *pValues, const char* pFieldName, int& x, int& y )
+{
+ x = y = 0;
+ const char *pCoordString = pValues->GetString( pFieldName, "0 0" );
+ if ( !pCoordString || !pCoordString[ 0 ] )
+ return false;
+
+ // Try and scan them in
+ int scanned;
+ scanned = sscanf( pCoordString, "%i %i", &x, &y );
+ if ( scanned != 2 )
+ {
+ Warning( "Couldn't scan 2d coordinate values from %s\n", pCoordString );
+ return false;
+ }
+
+ // coords are within 640x480 screen space
+ x = ( x * ( ( float )ScreenWidth() / 640.0 ) );
+ y = ( y * ( ( float )ScreenHeight() / 480.0 ) );
+
+ return true;
+}
+
+bool ParseRect( KeyValues *pValues, const char* pFieldName, int& x, int& y, int& w, int& h )
+{
+ x = y = w = h = 0;
+ const char *pRectString = pValues->GetString( pFieldName, "0 0 0 0" );
+ if ( !pRectString || !pRectString[ 0 ] )
+ return false;
+
+ // Try and scan them in
+ int scanned;
+ scanned = sscanf( pRectString, "%i %i %i %i", &x, &y, &w, &h );
+ if ( scanned != 4 )
+ {
+ Warning( "Couldn't scan rectangle values from %s\n", pRectString );
+ return false;
+ }
+
+ // coords are within 640x480 screen space
+ x = ( x * ( ( float )ScreenWidth() / 640.0 ) );
+ y = ( y * ( ( float )ScreenHeight() / 480.0 ) );
+ w = ( w * ( ( float )ScreenWidth() / 640.0 ) );
+ h = ( h * ( ( float )ScreenHeight() / 480.0 ) );
+
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Helper class to make meta class panels (for use in entities, so they autocleanup)
+//-----------------------------------------------------------------------------
+CPanelWrapper::CPanelWrapper() : m_pPanel(NULL)
+{
+}
+
+CPanelWrapper::~CPanelWrapper()
+{
+ Deactivate();
+}
+
+void CPanelWrapper::Activate( char const* pMetaClassName, vgui::Panel *pParent, int sortorder, void *pVoidInitData )
+{
+ if ( m_pPanel )
+ {
+ Deactivate();
+ }
+
+ m_pPanel = PanelMetaClassMgr()->CreatePanelMetaClass( pMetaClassName, sortorder, pVoidInitData, pParent );
+}
+
+void CPanelWrapper::Deactivate( void )
+{
+ if ( m_pPanel )
+ {
+ PanelMetaClassMgr()->DestroyPanelMetaClass( m_pPanel );
+ m_pPanel = NULL;
+ }
+}
+
+vgui::Panel *CPanelWrapper::GetPanel( )
+{
+ return m_pPanel;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Singleton class responsible for managing metaclass panels
+//-----------------------------------------------------------------------------
+class CPanelMetaClassMgrImp : public IPanelMetaClassMgr
+{
+public:
+ // constructor, destructor
+ CPanelMetaClassMgrImp();
+ virtual ~CPanelMetaClassMgrImp();
+
+ // Members of IPanelMetaClassMgr
+ virtual void LoadMetaClassDefinitionFile( const char* pLevelName );
+ virtual void InstallPanelType( const char* pPanelName, IPanelFactory* pFactory );
+ virtual vgui::Panel *CreatePanelMetaClass( const char* pMetaClassName,
+ int sortorder, void *pInitData, vgui::Panel *pParent, const char *pChainName );
+ virtual void DestroyPanelMetaClass( vgui::Panel *pPanel );
+
+private:
+ struct MetaClassDict_t
+ {
+ unsigned short m_KeyValueIndex;
+ unsigned short m_TypeIndex;
+ KeyValues* m_pKeyValues;
+ };
+
+ // various parsing helper methods
+ bool ParseSingleMetaClass( const char* pFileName, const char* pInstanceName,
+ KeyValues* pMetaClass, int keyValueIndex );
+ bool ParseMetaClassList( const char* pFileName, KeyValues* pKeyValues, int keyValueIndex );
+
+ // No copy constructor
+ CPanelMetaClassMgrImp( const CPanelMetaClassMgrImp & );
+
+ // List of panel types...
+ CUtlDict< IPanelFactory*, unsigned short > m_PanelTypeDict;
+
+ // List of metaclass types
+ CUtlDict< MetaClassDict_t, unsigned short > m_MetaClassDict;
+
+ // Create key value accesor
+ CUtlDict< KeyValues*, unsigned short > m_MetaClassKeyValues;
+};
+
+
+//-----------------------------------------------------------------------------
+// Returns the singleton panel metaclass mgr interface
+//-----------------------------------------------------------------------------
+IPanelMetaClassMgr* PanelMetaClassMgr()
+{
+ // NOTE: the CPanelFactory implementation requires the local static here
+ // even though it means an extra check every time PanelMetaClassMgr is accessed
+ static CPanelMetaClassMgrImp s_MetaClassMgrImp;
+ return &s_MetaClassMgrImp;
+}
+
+
+//-----------------------------------------------------------------------------
+// constructor, destructor
+//-----------------------------------------------------------------------------
+CPanelMetaClassMgrImp::CPanelMetaClassMgrImp() : m_PanelTypeDict( true, 0, 32 )
+{
+}
+
+CPanelMetaClassMgrImp::~CPanelMetaClassMgrImp()
+{
+}
+
+
+//-----------------------------------------------------------------------------
+// Call this to install a new panel type
+//-----------------------------------------------------------------------------
+void CPanelMetaClassMgrImp::InstallPanelType( const char* pPanelName, IPanelFactory* pFactory )
+{
+ Assert( pPanelName && pFactory );
+
+ // convert to lowercase
+ int len = Q_strlen(pPanelName) + 1;
+ char* pTemp = (char*)stackalloc( len );
+ Q_strncpy( pTemp, pPanelName, len );
+ Q_strnlwr( pTemp, len );
+
+ m_PanelTypeDict.Insert( pTemp, pFactory );
+
+ stackfree( pTemp );
+}
+
+
+//-----------------------------------------------------------------------------
+// Parse a single metaclass
+//-----------------------------------------------------------------------------
+bool CPanelMetaClassMgrImp::ParseSingleMetaClass( const char* pFileName,
+ const char* pMetaClassName, KeyValues* pMetaClassValues, int keyValueIndex )
+{
+ // Complain about duplicately defined metaclass names...
+ if ( m_MetaClassDict.Find( pMetaClassName ) != m_MetaClassDict.InvalidIndex() )
+ {
+ Warning( "Meta class %s duplicately defined (file %s)\n", pMetaClassName, pFileName );
+ return false;
+ }
+
+ // find the type...
+ const char* pPanelType = pMetaClassValues->GetString( "type" );
+ if (!pPanelType || !pPanelType[0])
+ {
+ Warning( "Unable to find type of meta class %s in file %s\n", pMetaClassName, pFileName );
+ return false;
+ }
+
+ unsigned short i = m_PanelTypeDict.Find( pPanelType );
+ if (i == m_PanelTypeDict.InvalidIndex())
+ {
+ Warning( "Type %s of meta class %s undefined!\n", pPanelType, pMetaClassName );
+ stackfree(pLwrMetaClass);
+ return false;
+ }
+
+ // Add it to the metaclass dictionary
+ MetaClassDict_t element;
+ element.m_TypeIndex = i;
+ element.m_KeyValueIndex = keyValueIndex;
+ element.m_pKeyValues = pMetaClassValues;
+ m_MetaClassDict.Insert( pMetaClassName, element );
+
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Parse the metaclass list
+//-----------------------------------------------------------------------------
+bool CPanelMetaClassMgrImp::ParseMetaClassList( const char* pFileName,
+ KeyValues* pKeyValues, int keyValueIdx )
+{
+ // Iterate over all metaclasses...
+ KeyValues* pIter = pKeyValues->GetFirstSubKey();
+ while( pIter )
+ {
+ if (!ParseSingleMetaClass( pFileName, pIter->GetName(), pIter, keyValueIdx ))
+ {
+ // return false;
+ Warning( "MetaClass missing for %s\n", pIter->GetName() );
+ }
+ pIter = pIter->GetNextKey();
+ }
+
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Loads up a file containing metaclass definitions
+//-----------------------------------------------------------------------------
+void CPanelMetaClassMgrImp::LoadMetaClassDefinitionFile( const char *pFileName )
+{
+ MEM_ALLOC_CREDIT();
+
+ // Blat out previous metaclass definitions read in from this file...
+ int i = m_MetaClassKeyValues.Find( pFileName );
+ if (i != m_MetaClassKeyValues.InvalidIndex() )
+ {
+ // Blow away the previous keyvalues from that file
+ unsigned short j = m_MetaClassDict.First();
+ while ( j != m_MetaClassDict.InvalidIndex() )
+ {
+ unsigned short next = m_MetaClassDict.Next(j);
+ if ( m_MetaClassDict[j].m_KeyValueIndex == i)
+ {
+ m_MetaClassDict.RemoveAt(j);
+ }
+
+ j = next;
+ }
+
+ m_MetaClassKeyValues[i]->deleteThis();
+ m_MetaClassKeyValues.RemoveAt(i);
+ }
+
+ // Create a new keyvalues entry
+ KeyValues* pKeyValues = new KeyValues(pFileName);
+ int idx = m_MetaClassKeyValues.Insert( pFileName, pKeyValues );
+
+ // Read in all metaclass definitions...
+
+ // Load the file
+ if ( !pKeyValues->LoadFromFile( filesystem, pFileName ) )
+ {
+ Warning( "Couldn't find metaclass definition file %s\n", pFileName );
+ pKeyValues->deleteThis();
+ m_MetaClassKeyValues.RemoveAt(idx);
+ return;
+ }
+ else
+ {
+ // Go ahead and parse the data now
+ if ( !ParseMetaClassList( pFileName, pKeyValues, idx ) )
+ {
+ Warning( "Detected one or more errors parsing %s\n", pFileName );
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Performs key value chaining
+//-----------------------------------------------------------------------------
+static void KeyValueChainRecursive( KeyValues* pKeyValues, const char *pSectionName )
+{
+ KeyValues* pSection = pKeyValues->FindKey( pSectionName );
+
+ if (pSection)
+ {
+ pKeyValues->ChainKeyValue( pSection );
+ }
+
+ KeyValues* pIter = pKeyValues->GetFirstSubKey();
+ while (pIter)
+ {
+ // Don't both setting up links on a keyvalue that has no children
+ if (pIter->GetFirstSubKey())
+ KeyValueChainRecursive( pIter, pSectionName );
+
+ pIter = pIter->GetNextKey();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Create, destroy panel...
+//-----------------------------------------------------------------------------
+vgui::Panel *CPanelMetaClassMgrImp::CreatePanelMetaClass( const char* pMetaClassName,
+ int sortorder, void *pInitData, vgui::Panel *pParent, const char *pChainName )
+{
+ // Search for the metaclass name
+ int i = m_MetaClassDict.Find( pMetaClassName );
+ if (i == m_MetaClassDict.InvalidIndex())
+ return NULL;
+
+ // Now that we've got the metaclass, we can figure out what kind of
+ // panel to instantiate...
+ MetaClassDict_t &metaClass = m_MetaClassDict[i];
+ IPanelFactory* pFactory = m_PanelTypeDict[metaClass.m_TypeIndex];
+
+ // Set up the key values for use in initialization
+ if (pChainName)
+ {
+ KeyValueChainRecursive( metaClass.m_pKeyValues, pChainName );
+ }
+
+ // Create and initialize the panel
+ vgui::Panel *pPanel = pFactory->Create( pMetaClassName, metaClass.m_pKeyValues, pInitData, pParent );
+ if ( pPanel )
+ {
+ pPanel->SetZPos( sortorder );
+ }
+
+ return pPanel;
+}
+
+void CPanelMetaClassMgrImp::DestroyPanelMetaClass( vgui::Panel *pPanel )
+{
+// if ( pPanel )
+// pPanel->MarkForDeletion();
+ delete pPanel;
+}
+
+