It/VGUI: Making GameUI Panels

==Resource\UI\TestPanel.res==
Questo è l’esempio di un pannello che verrà visualizzato quando un verrà effettuato un determinato comando in un determinato periodo: 
 "Resource/UI/TestPanel.res"
 {
 	"testpanel"
 	{
 		"ControlName"	"CTestPanel"
 		"fieldName"	"testpanel"
 		"title"		"Test Panel"
 		"xpos"		"0"
 		"ypos"		"0"
 		"wide"		"200"
 		"tall"		"200"
 		"autoResize"	"0"
 		"pinCorner"	"0"
 		"visible"	"1"
 		"enabled"	"1"
 		"tabPosition"	"0"
 	}
 	"Label1"
 	{
 		"ControlName"	"Label"
 		"fieldName"	"Label1"
 		"xpos"		"8"
 		"ypos"		"32"
 		"wide"		"200"
 		"tall"		"175"
 		"wrap"		"1"
 		"autoResize"	"0"
 		"pinCorner"	"0"
 		"visible"	"1"
 		"enabled"	"1"
 		"tabPosition"	"0"
 		"labelText"	"An example label inside of an example frame"
 		"textAlignment"	"north"
 		"dulltext"	"0"
 		"brighttext"	"0"
 	}
 	"close"
 	{
 		"ControlName"	"Button"
 		"fieldName"	"close"
 		"xpos"		"68"
 		"ypos"		"168"
 		"wide"		"64"
 		"tall"		"24"
 		"labelText"	"#GameUI_Close"
 		"Command"	"Close"
 		"autoResize"	"0"
 		"pinCorner"	"0"
 		"visible"	"1"
 		"enabled"	"1"
 		"tabPosition"	"0"
 	}
 }
==cl_dll\vgui_helpers.h==
Aggiungi i seguenti dopo i precedenti: 
 class IGameUI
 {
 public:
 	virtual void Create( vgui::VPANEL parent ) = 0;
 	virtual void Destroy( void ) = 0;
 	virtual vgui::Panel *GetPanel(void) = 0;
 };
 #define DeclarePanel(className,panelClassName,globalPanel)\
 	class className : public IGameUI\
 	{\
 	private:\
 		panelClassName *myPanel;\
 	public:\
 		className(void)\
 		{\
 			myPanel = NULL;\
 		}\
 		void Create( vgui::VPANEL parent )\
 		{\
 			myPanel = new panelClassName( parent );\
 		}\
 		void Destroy( void )\
 		{\
 			if(myPanel)\
 			{\
 				myPanel->SetParent( (vgui::Panel *)NULL );\
 				delete myPanel;\
 			}\
 		}\
 		vgui::Panel *GetPanel(void)\
 		{\
 			return myPanel;\
 		}\
 	};\
 	extern IGameUI *globalPanel
 //Doesn't use panelClassName but has it to base code on copy and paste work 
 #define PanelGlobals(className,panelClassName,globalPanel)\
 	static className g_##className##Panel;\
 	IGameUI *globalPanel = (IGameUI *)&g_##className##Panel
 
 #define ToggleVisibility(panel)\
 	panel->SetVisible(!panel->IsVisible())
 
 //only the prototype for AlignPanel exists 
 #define CenterThisPanelOnScreen()\
 	int x,w,h;\
 	GetBounds(x,x,w,h);\
 	SetPos((ScreenWidth()-w)/2,(ScreenHeight()-h)/2)
 #define CenterPanelOnScreen(panel)\
 	int x,w,h;\
 	panel->GetBounds(x,x,w,h);\
 	panel->SetPos((panel->ScreenWidth()-w)/2,(panel->ScreenHeight()-h)/2)
==cl_dll\testpanel.h==
 #ifndef TESTPANEL_H
 #define TESTPANEL_H
 #ifdef _WIN32
 #pragma once
 #endif
 #include "vgui_helpers.h"
 #include <vgui_controls/Frame.h>
 using namespace vgui;
 class CTestPanel : public Frame
 {
 	DECLARE_CLASS_SIMPLE(CTestPanel,Frame);
 public:
 	CTestPanel( vgui::VPANEL parent );
 };
 DeclarePanel(CTest,CTestPanel,test);
 #endif // TESTPANEL_H 
==cl_dll\testpanel.cpp==
 #include "cbase.h"
 #include "testpanel.h"
 // memdbgon must be the last include file in a .cpp file!!! 
 #include "tier0/memdbgon.h"
 PanelGlobals(CTest,CTestPanel,test);
 CON_COMMAND(ToggleTestPanel,NULL)
 {
 	ToggleVisibility(test->GetPanel());
 }
 CTestPanel::CTestPanel( vgui::VPANEL parent ) : BaseClass( NULL, "testpanel" )
 {
 	SetParent(parent);
 	vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFile("resource/SourceScheme.res", "SourceScheme");
 	SetScheme( scheme );
 	LoadControlSettings("Resource/UI/TestPanel.res");
 	CenterThisPanelOnScreen();//keep in mind, hl2 supports widescreen 
 	SetVisible(false);//made visible on command later 
 
 	//Other useful options
 	//SetSizeable(false);
 	//SetMoveable(false);
 } 
Hai visto quanto la ridefinizione ha ridotto la codificazione per il testpanel.cpp e per il testpanel.h?
==cl_dll\vgui_int.cpp==
Ora abbiamo la struttura del pannello... 
Per prima cosa andiamo all’intestazione inclusa e aggiungi il testpanel.h alla lista degli inclusi in modo da accedere al tuo nuovo pannello creato. 
Scorri giù fino al VGui_CreateGlobalPanels e aggiungi questa stringa dopo la seconda linea: 
 	VPANEL uiParent = enginevgui->GetPanel( PANEL_GAMEUIDLL ); 
Il pannello GameUI è quello che genererà i nostri pannelli, aggiungi questo alla lista “Creates”: 
 	test->Create( uiParent ); 
Scorri giù poco sotto VGui_Shutdown and e aggiungi questa stringa alla lista “Destroys”: 
 	test->Destroy();
==Conclusioni==
Ora noi abbiamo un pannello che sarà generato durante lo startup, distrutto una volta chiuso, e accessibile tramite un comando. Però, mantieni queste regole in mente: 
* Non devi usare una struttura per il pannello 
* Puoi fare in modo che un comando lo mostri, e anche che non lo richiuda
* Potete creare il pannello creato da un comando effettuato, e distrutto una volta chiuso, in modo da non occupare memoria
Questo è un’esempio di cosa si può creare con questo codice:
M