User:Psycommando/VGUI OverrideTest
Author's note :
This page is a logbook for an experiment on VGUI. I put it here, so anybody can learn from my mistakes, or something. Its also a neat way to start messing around with vgui.
The Test
Valve hasn't given us access to the dll handling the main menu, loading screens, and console. But, those panels are still accessible and modifiable at runtime. Here is how it can be done (HL2 single player OrangeBox mod):
Add the following in your ..\src\game\client\vgui_int.cpp file. This is a simple console command to print out a list of childrens and basic infos. This can also be done with the vgui_drawtree 1 console command.
Add to end of file : ..\src\game\client\vgui_int.cpp
CON_COMMAND(
test_listinfoforpanel, //The actual console command that we'll type in the console
"Show infos for panel, including childrens listing, and HPanel#. If no params specified, displays info about root panel. : <HPanel#>"
)
{
VPANEL panel;
if ( args.ArgC() == 2 )
{
//parse the HPanel #
panel = vgui::ivgui()->HandleToPanel( Q_atoi( args.ArgV()[1] ) );
}
else
{
//Panel 1 is always the static panel (parent of gameuidll) at least it seams to be...
panel = vgui::ivgui()->HandleToPanel( 1 );
}
GetInfoAboutPanel( panel );
}
void GetInfoAboutPanel( VPANEL panel )
{
if( panel != 0 )
{
int NbChilds = vgui::ipanel()->GetChildCount(panel); //Get our ammount of children VPANELs
DevMsg( "PanelName: %s, Class: %s, HPanel# : %d, NbChildrens: %d, IsVisible: %d\n",
vgui::ipanel()->GetName( panel),
vgui::ipanel()->GetClassName(panel),
vgui::ivgui()->PanelToHandle( panel ),
NbChilds,
vgui::ipanel()->IsVisible(panel)
);
ListChilds(NbChilds,panel);
}
}
void ListChilds( int nbchilds, VPANEL panel )
{
for( int i = 0; i < nbchilds; ++i )
{
VPANEL tmppanel = vgui::ipanel()->GetChild( panel, i ); //Get the child of panel, at index i
DevMsg( "- %d : ", i );
int NbChilds = vgui::ipanel()->GetChildCount(tmppanel); //Get the ammount of child from panel's child VPANEL
DevMsg( "PanelName: %s, Class: %s, HPanel# : %d, NbChildrens: %d, IsVisible: %d\n",
vgui::ipanel()->GetName( tmppanel),
vgui::ipanel()->GetClassName(tmppanel),
vgui::ivgui()->PanelToHandle( tmppanel ),
NbChilds,
vgui::ipanel()->IsVisible(tmppanel)
);
}
}
So, it's nice to print all this stuff on the console but why not use the info for something ? Let's make a console command to hide/show VPANEL based on their HPanel number.
Add to end of file : ..\src\game\client\vgui_int.cpp
CON_COMMAND( test_setvisible, "Show or hide the panel : <HPanel#> <1/0>." )
{
if ( args.ArgC() == 3 )
{
//This convert the HPanel value into an actual VPANEL
VPANEL panel = vgui::ivgui()->HandleToPanel( Q_atoi( args.ArgV()[1] ) );
vgui::ipanel()->SetVisible( panel, (bool)Q_atoi( args.ArgV()[2] ) ); //Set our panel's visibility state
}
else
{
//Wrong number of params print the help message!
engine->ClientCmd_Unrestricted( "help test_setvisible" );
}
}
Have fun hiding panels, you can also try changing other params than visibility, just don't start deleting panels arbitrarily, or the game might crash when it tries to access those now deleted panels.
Oh, and don't assume that HPanel numbers( Panel Handle ) are always the same value, they may change at runtime or at the next launch.