Understanding VGUI2 Resource Files: Difference between revisions
Beerdude26 (talk | contribs) (Created Page.) |
Beerdude26 (talk | contribs) m (* Split up the design part) |
||
Line 10: | Line 10: | ||
Resource files are simple [[KeyValues]] that are parsed from top to bottom: each control that is specified in the file is created with a control factory and has its settings applied in a hierarchical manner. | Resource files are simple [[KeyValues]] that are parsed from top to bottom: each control that is specified in the file is created with a control factory and has its settings applied in a hierarchical manner. | ||
== | == When creating a new in-game panel == | ||
=== Loading a resource file === | |||
To load a resource file for a panel, simply add the following in your constructor: | |||
<source lang="cpp"> | |||
LoadControlSettings( "Path/To/Resource/File.res" ); | |||
</source> | |||
=== Modifying resource file-generated controls in code === | |||
Let's say you've made your own panel and put some ImagePanels in the resource file. If you wish to modify an automatically generated control, you only need to do a few things: | |||
* Create a pointer for the control in your header file: | |||
<source lang="cpp"> | |||
vgui::ImagePanel* m_pTestImage; | |||
</source> | |||
* Populate the control in your constructor: | |||
<source lang="cpp"> | |||
m_pTestImage = dynamic_cast<ImagePanel*>( FindChildByName( "NameOfPanelInResourceFile", true ) ); | |||
</source> | |||
* Done! You can now access the ImagePanel (don't forget to check for null pointers!) | |||
Don't worry about having to clean up the auto-generated panels; they do that themselves. | |||
== When creating a new type of control == | |||
=== Factory === | |||
The system needs to know which controls can be built using a factory method. This is necessary to automatically create controls when reading a resource file. It uses the following macro for this: | |||
<source lang="cpp"> | <source lang="cpp"> | ||
DECLARE_BUILD_FACTORY( Label ); | DECLARE_BUILD_FACTORY( Label ); | ||
Line 26: | Line 48: | ||
</source> | </source> | ||
== Applying Settings == | === Applying Settings === | ||
The method '''ApplySettings( KeyValues* inResourceData )''' is what does the heavy lifting when laying out your control. Because of the hierarchical structure of the controls (A inherits from B, B inherits from C, etc), it is very easy to create a new control whose particular settings can be data-driven (that is, initialized from the resource file). Here is an example: | The method '''ApplySettings( KeyValues* inResourceData )''' is what does the heavy lifting when laying out your control. Because of the hierarchical structure of the controls (A inherits from B, B inherits from C, etc), it is very easy to create a new control whose particular settings can be data-driven (that is, initialized from the resource file). Here is an example: | ||
Line 71: | Line 93: | ||
</source> | </source> | ||
= Hierarchical overview of keys in resource files = | = Hierarchical overview of keys in resource files = | ||
This is an overview of which keys are defined where in code and what their function is. | This is an overview of which keys are defined where in code and what their function is. | ||
== Panel == | == Panel == | ||
'''Inherits from:''' ''None'' | '''Inherits from:''' ''None'' |
Revision as of 19:55, 24 March 2011
Introduction
I've witnessed a lot of confusion when I asked other coders how the VGUI2 system interacts with Resource Files, and I have not found any complete reference for using them, so here goes.
What they do
Resource files are used to automatically generate controls (=panels) that can be put in a parent control. This way, panel layout is far easier to do. Hence, resource files are very handy when you're creating your own in-game panel and want the heavy layout-lifting done automatically.

The design
Resource files are simple KeyValues that are parsed from top to bottom: each control that is specified in the file is created with a control factory and has its settings applied in a hierarchical manner.
When creating a new in-game panel
Loading a resource file
To load a resource file for a panel, simply add the following in your constructor:
LoadControlSettings( "Path/To/Resource/File.res" );
Modifying resource file-generated controls in code
Let's say you've made your own panel and put some ImagePanels in the resource file. If you wish to modify an automatically generated control, you only need to do a few things:
- Create a pointer for the control in your header file:
vgui::ImagePanel* m_pTestImage;
- Populate the control in your constructor:
m_pTestImage = dynamic_cast<ImagePanel*>( FindChildByName( "NameOfPanelInResourceFile", true ) );
- Done! You can now access the ImagePanel (don't forget to check for null pointers!)
Don't worry about having to clean up the auto-generated panels; they do that themselves.
When creating a new type of control
Factory
The system needs to know which controls can be built using a factory method. This is necessary to automatically create controls when reading a resource file. It uses the following macro for this:
DECLARE_BUILD_FACTORY( Label );
This method will attempt to create an instance of the control with a constructor with two parameters, which are both NULL:
#define DECLARE_BUILD_FACTORY( className ) \
static vgui::Panel *Create_##className##( void ) \
{ \
return new className( NULL, NULL ); \
}; \
static vgui::CBuildFactoryHelper g_##className##_Helper( #className, Create_##className## );\
className *g_##className##LinkerHack = NULL;
Applying Settings
The method ApplySettings( KeyValues* inResourceData ) is what does the heavy lifting when laying out your control. Because of the hierarchical structure of the controls (A inherits from B, B inherits from C, etc), it is very easy to create a new control whose particular settings can be data-driven (that is, initialized from the resource file). Here is an example:
Say your control, ImagePanelBetter, inherits from ImagePanel. You would then override the virtual ApplySettings() function and read things for your control:
void ImagePanelBetter::ApplySettings(KeyValues *inResourceData)
{
// VERY IMPORTANT: ALWAYS CALL THE BASE CLASS!
BaseClass::ApplySettings( inResourceData );
const char *value = NULL;
value = inResourceData->GetString("normalImage", "");
if (*value)
UpdateNormalImage( value );
value = inResourceData->GetString("mouseoverImage", "");
if (*value)
UpdateMouseOverImage( value );
value = inResourceData->GetString("mouseclickImage", "");
if (*value)
UpdateMouseClickImage( value );
value = inResourceData->GetString("command", "");
if (*value)
UpdateCommand( value );
}
Pretty simple, no?
Because resource files are simply KeyValues, you can also nest items:
void ImagePanelBetter::ApplySettings(KeyValues *inResourceData)
{
// VERY IMPORTANT: ALWAYS CALL THE BASE CLASS!
BaseClass::ApplySettings( inResourceData );
KeyValues* nestedItem;
nestedItem = inResourceData->FindKey( "NameOfNestedItemInResourceFile" );
if (nestedItem )
DoStuff( nestedItem );
}
Hierarchical overview of keys in resource files
This is an overview of which keys are defined where in code and what their function is.
Panel
Inherits from: None
- fieldName: Determines the name of the control.
- xpos: Determines the horizontal offset from the top left (by default) of the parent panel.
- ypos; Determines the vertical offset from the top left (by default) of the parent panel.

- zpos: Determines the depth of the panel. Deeper panels are drawn first. Lower numbers = deeper.
- wide: Determines the width of the control.

- tall: Determines the height of the control.
- visible: Determines if the control will be drawn.

- enabled: Determines if the control is enabled. Used by controls higher up the chain (like Buttons).
- tabPosition: Determines the tab order of the control.
- tooltiptext: Determines the tooltip text to show when you hover over this control.
- paintbackground: Paint the background color of this control?
- paintborder: Paint the border of this control?
There are also a number of overridable colors defined in several controls. Panel checks the ones of itself and its children and has the following defined:
- fgcolor_override: Overrides the color of the foreground (for Labels, this is the text color).
- bgcolor_override: Overrides the color of the background.
