|
|
//========= 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: $
//=============================================================================//
#if !defined( PANELMETACLASSMGR_H )
#define PANELMETACLASSMGR_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/dbg.h"
#include "basetypes.h"
#include <vgui/VGUI.h>
//-----------------------------------------------------------------------------
// forward declarations
//-----------------------------------------------------------------------------
class KeyValues; class Color;
namespace vgui { class Panel; }
//-----------------------------------------------------------------------------
// Class factory interface for metaclasses
//-----------------------------------------------------------------------------
abstract_class IPanelFactory { public: // Creation, destruction methods
virtual vgui::Panel *Create( const char *pMetaClassName, KeyValues* pKeyValues, void *pInitData, vgui::Panel *pParent ) = 0; };
//-----------------------------------------------------------------------------
// Purpose: Singleton class responsible for managing vgui panel metaclasses
// A metaclass is simply an association of panel implementation class with
// various initialization data
//-----------------------------------------------------------------------------
abstract_class IPanelMetaClassMgr { public: // Call this to load up a file containing metaclass definitions
virtual void LoadMetaClassDefinitionFile( const char *pFileName ) = 0;
// Call this to install a new panel type
// MetaClasses will refer to the panel type to create along with
// various initialization data
virtual void InstallPanelType( const char *pPanelName, IPanelFactory *pFactory ) = 0;
// Creates a metaclass panel with the specified parent panel.
// Chain name is used as a filter of the metaclass data; if specified,
// it recursively iterates through the keyvalue sections and calls
// chainKeyValue on sections whose name matches the chain name
virtual vgui::Panel *CreatePanelMetaClass( const char *pMetaClassType, int sortorder, void *pInitData, vgui::Panel *pParent, const char *pChainName = NULL ) = 0;
// removes a particular panel meta class
virtual void DestroyPanelMetaClass( vgui::Panel *pPanel ) = 0;
protected: // Don't delete me!
virtual ~IPanelMetaClassMgr() {} };
//-----------------------------------------------------------------------------
// Returns the panel meta class manager
//-----------------------------------------------------------------------------
IPanelMetaClassMgr *PanelMetaClassMgr();
//-----------------------------------------------------------------------------
// Helper class for simple construction of planel class factories
// This class is expected to be a singleton
// Note the panel must have a constructor of the following form:
// CPanel( vgui::Panel* );
// and it must have the following member function:
// bool CPanel::Init( KeyValues* pInitData )
// which returns true if the panel initialized successfully
//-----------------------------------------------------------------------------
#include "tier0/memdbgon.h"
template< class CPanel, class CInitData > class CPanelFactory : public IPanelFactory { public: CPanelFactory( const char *pTypeName ) { // Hook us up baby
Assert( pTypeName ); PanelMetaClassMgr()->InstallPanelType( pTypeName, this ); }
// Creation, destruction methods
virtual vgui::Panel *Create( const char *pMetaClassName, KeyValues* pKeyValues, void *pVoidInitData, vgui::Panel *pParent ) { // NOTE: make sure this matches the panel allocation pattern;
// it will break if panels are deleted differently
CPanel* pPanel = new CPanel( pParent, pMetaClassName ); if (pPanel) { // Set parent before Init; it may be needed there...
CInitData* pInitData = (CInitData*)(pVoidInitData); if (!pPanel->Init( pKeyValues, pInitData )) { delete pPanel; pPanel = NULL; } } return pPanel; } };
#include "tier0/memdbgoff.h"
//-----------------------------------------------------------------------------
// Helper macro to make panel factories one line of code. Use like this:
// DECLARE_PANEL_FACTORY( CEntityImagePanel, CInitData, "image" );
// The type string is used in a panel script file to specify the type.
// CInitData is the type of the data to pass to the init function
//-----------------------------------------------------------------------------
#define DECLARE_PANEL_FACTORY( _PanelClass, _InitData, _nameString ) \
CPanelFactory< _PanelClass, _InitData > g_ ## _PanelClass ## Factory( _nameString )
//-----------------------------------------------------------------------------
// Helper class to make meta class panels
//-----------------------------------------------------------------------------
class CPanelWrapper { public: CPanelWrapper(); ~CPanelWrapper(); void Activate( char const* pMetaClassName, vgui::Panel *pParent, int sortorder, void *pVoidInitData ); void Deactivate( void ); vgui::Panel *GetPanel( );
private: vgui::Panel *m_pPanel; };
//-----------------------------------------------------------------------------
// Macros for help with simple registration of panel metaclass
// Put DECLARE_METACLASS_PANEL() in your class definition
// and CONSTRUCT_METACLASS_PANEL() in your class constructor
//-----------------------------------------------------------------------------
#define DECLARE_METACLASS_PANEL( _memberName ) CPanelWrapper _memberName
#define CONSTRUCT_METACLASS_PANEL( _memberName, _metaClassName, _parentPanel, _sortorder, _initData ) \
_memberName.Activate( _metaClassName, _parentPanel, _sortorder, _initData ) #define DESTRUCT_METACLASS_PANEL( _memberName ) \
_memberName.Deactivate()
//-----------------------------------------------------------------------------
// Helper KeyValues parsing methods
//-----------------------------------------------------------------------------
bool ParseRGBA( KeyValues* pValues, const char* pFieldName, int& r, int& g, int& b, int& a ); bool ParseRGBA( KeyValues* pValues, const char* pFieldName, Color& c ); bool ParseCoord( KeyValues* pValues, const char* pFieldName, int& x, int& y ); bool ParseRect( KeyValues* pValues, const char* pFieldName, int& x, int& y, int& w, int& h );
/* FIXME: Why do we have KeyValues too!?!??! Bleah
bool ParseRGBA( KeyValues *pValues, const char* pFieldName, int& r, int& g, int& b, int& a ); bool ParseRGBA( KeyValues* pValues, const char* pFieldName, vgui::Color& c ); */
#endif // PANELMETACLASSMGR_H
|