source-engine/game/client/panelmetaclassmgr.h

180 lines
6.6 KiB
C
Raw Normal View History

2020-04-22 16:56:21 +00:00
//========= 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