Ru/Understanding VGUI2 Resource Files
Введение
Я стал свидетелем большого замешательства, когда спросил других программистов, как система VGUI2 взаимодействует с файлами ресурсов, и я не нашел полной справки по их использованию, так что вот.
Что они делают
Файлы ресурсов используются для автоматического создания элементов управления (= панелей), которые можно поместить в родительский элемент управления. Таким образом, сделать макет панели намного проще. Следовательно, файлы ресурсов очень удобны, когда вы создаете собственную внутриигровую панель и хотите, чтобы тяжелый подъем макета выполнялся автоматически.

Дизайн
Файлы ресурсов представляют собой простые KeyValues, которые анализируются сверху вниз: каждый элемент управления, указанный в файле, создается с помощью фабрики элементов управления, и его настройки применяются в иерархическом порядке..
При создании новой внутриигровой панели
Загрузка .res файла
Чтобы загрузить файл ресурсов для панели, просто добавьте в конструктор следующее:
LoadControlSettings( "Path/To/Resource/File.res" );
Настройка управления в игре
Смотрите The VGUI Build Mode чтобы получить больше информации.
Изменение элементов управления, сгенерированных файлом ресурсов, в коде
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 ) );
If you're using Source SDK 2013, you can use the shorter template method instead:
m_pTestImage = FindControl<ImagePanel>( "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;
If you want to pass other parameters, or you have non-nullable parameters that require a default value, you can use DECLARE_BUILD_FACTORY_CUSTOM:
// Example: ComboBoxNew inherits from ComboBox
// Custom ComboBoxNew method
vgui::Panel *ComboBoxNew_Factory()
{
return new ComboBoxNew( NULL, NULL, 5, true );
}
// Takes the class name and the method name. Ensure that the method is defined before this line!
DECLARE_BUILD_FACTORY_CUSTOM( ComboBoxNew, ComboBoxNew_Factory );
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
Description: A simple control that is the basis for all other VGUI controls. Contains many overrideable functions.
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.
- wide: Determines the width of the control.
- tall: Determines the height of the control.

- zpos: Determines the depth of the panel. Deeper panels are drawn first. Lower numbers = deeper.
- 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.

Label
Description: A control that can display (wrapped) text.
Inherits from: Panel
- labelText: Determines the text that the label will display.


- textAlignment: Determines the alignment of the label.

- associate: Allows the label to be associated with another control. Нужно сделать: See what uses this has.
- dulltext: A boolean that determines if text should be displayed in a dull manner.
- brighttext: A boolean that determines if text should be displayed in a bright manner.

- font: Determines the font used by the label. Use the font name as defined in the SourceScheme.res file.
- wrap: Determines if your label wraps around the available space.
- centerwrap: Same as above, except it also works for centered text.
- textinsetx: Additional horizontal offset space from whichever side it is aligned.
- textinsety: Additional vertical offset space from whichever side it is aligned.
Button
Description: A control that can display (wrapped) text and act as a button.
Inherits from: Label
- command: Determines which command to fire to the OnCommand handler when pressed.
- default: A boolean that determines if this button is to be activated when the user presses the enter or space bar keys. Only one such button can exist.
- selected: A boolean that determines if this button appears to have been selected.
- sound_armed: Determines what sound the button makes when hovered over.
- sound_depressed: Determines what sound the button makes when pressed upon.
- sound_released: Determines what sound the button makes when released.
ImagePanel
Description: Essentially an image.
Inherits from: Panel
- scaleImage: A boolean that determines whether to scale the image to its specified width and height.
- scaleAmount: A float that determines how much the image should scale.
- tileImage: A boolean that determines whether to tile the image.
- tileHorizontally: A boolean that determines whether to tile the image horizontally.
- tileVertically: A boolean that determines whether to tile the image vertically.
- image: The actual image. Expects a path to a .VMT file in the /materials/vgui folder.


- fillcolor: Determines the background color behind the image. Only painted if the alpha is higher than 0 (duh)

- border: Determines the border around the image. You can only refer to colors defined in the scheme files here using the names of the colors!
EditablePanel
Description: A window-like control that can house other controls, which can be edited using the VGUI Build Mode.
Inherits from: Panel
Frame
Description: A dynamically resizeable control that can be dragged around. Has a title bar, close and minimization buttons, etc.
Inherits from: EditablePanel

- title: Determines the title of the frame.
- title_font: Determines what font the title of the frame will use.
- clientinsetx_override: Overrides the default horizontal offset from the left side of the panel.
Color overrides:
- infocus_bgcolor_override: Override for the background color of the panel when it is in focus.
- outoffocus_bgcolor_override: Override for the background color of the panel when it is out of focus.
- titlebarbgcolor_override: Override for the background color of the title bar when it is in focus.
- titlebardisabledbgcolor_override: Override for the background color of the title bar when it is out of focus.
- titlebarfgcolor_override: Override for the foreground color of the title bar when it is in focus.
- titlebardisabledfgcolor_override: Override for the foreground color of the title bar when it is out of focus.