1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
//========= 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
|