VGUI Position and Size Flags

From Valve Developer Community
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
Dead End - Icon.png
This article has no Wikipedia icon links to other VDC articles. Please help improve this article by adding links Wikipedia icon that are relevant to the context within the existing text.
January 2024

The .res files used in VGUI Controls have four key position and size tokens that can allow the user to define custom sizes without having to hardcode the values. Further, programmers can use flags to help align or size their controls without needing to in-code. This article is about those flags.

The following information can be found from Panel.cpp, under the ComputePos() and ComputeWide() and ComputeTall() methods.

Size ("wide" and "tall")

Size is listed first since it is calculated before Position, as some Position flags require size to be calculated.

Fill

F

The flag "f" or "F" means that the size value shall fill up to the parent's corresponding size variable, subtracting the given offset.

Warning.pngWarning:By default, any control's "parent" is considered the screen, so it will fill to the screen size, regardless of if its parent takes up the full screen! Use
"proportionalToParent" "1"
in the control's .res file to have this flag fill to its immediate parent size (instead of the screen). This is recommended for components inside of modals (or similar)!

Examples:

"wide" "f100"

This makes the control have a width of (Parent Width - 100 pixels). If the parent width is 300 pixels, this control would have a width of 200 pixels.

"tall" "f100"

This makes the control have a height of (Parent Tall - 100 pixels). If the parent's height is 300 pixels, this control would have a height of 200 pixels.

Note.pngNote:A negative value for the F flag is very rarely needed. ComputeWide() automatically subtracts the value!



Proportional

O

The flag "o" or "O" means the control's size variable is proportional to the other correlating size variable, with a given float scale.

Examples:

"wide" "o1.0"
"tall" "100"

This sets the control's width to be 1.0x (equal to) the control's height. In this case, it would be 100 pixels wide.

"tall" "o2.0"
"wide" "100"

This sets the control's height to be 2.0x the control's width. In this case, it would be 200 pixels tall.

Warning.pngWarning:It is not possible for both wide and tall to have the "O" flag!



P

Todo: Determine what this actually does. There may be a bug/typo in Valve's code.

This reads the value after the "p" flag, getting the proportional value of it, subtracts it from the parent's corresponding size variable, but then multiplies it by the original value. The scale is the difference between the parent's size variable and this control's proportionally scaled size variable. This just makes the size variable a wildly large number.

For example, using the code from Panel.cpp, with "wide" "p100"' in the res file, and a parent wide of 1600 pixels:

        else if ( _buildModeFlags & BUILDMODE_SAVE_WIDE_PROPORTIONAL )
	{
		// scale the height up to our screen co-ords
                //wide is 100 here
		wide = scheme()->GetProportionalScaledValueEx(GetScheme(), wide);
                //wide = 187 here
		wide = nParentWide - wide;
                //wide = 1413 here...
		wide *= flWide; // flWide is 100.0000... here
                //wide is now 141300 !!!???
	}

Why does this have both GetProportionalScaledValueEx and wide *= flWide ?? Makes no sense...


Combinations

It is not possible to combine any of the flags for Size in any way.

Position ("xpos" and "ypos")

Position gets calculated after Size, and has some flags to help explain why.

Alignment

R

The flag "r" or "R" means that the control shall be aligned to the fullest extent of the respective value, subtracting a provided offset.

Examples:

"xpos" "r30" // can also be "r+30"

This sets the control's X position to be right-aligned, with an offset of 30 pixels from the right edge of the screen.

"ypos" "r30" // can also be "r+30"

This sets the control's Y position to be bottom-aligned, with an offset of 30 pixels from the bottom edge of the screen.

Note.pngNote:NOTE: A negative value is very rarely needed when using R. The ComputePos() method subtracts the value automatically!



C

The flag "c" or "C" means that the value shall be centered for its respective value, with a provided offset.

Examples:

"xpos" "c-50"

This sets the control's X position to be center-aligned to the parent control's width, and shifted 50 pixels left.

"ypos" "c50" // can also be "c+50"

This sets the control's Y position to be center-aligned to the parent control's height, and shifted 50 pixels down.


Scale

S

The flag "s" or "S" means that the control shall be offset by a given float scale with regards to the control's correlating size variable.

Examples:

"xpos" "s1.5"
"wide" "200"

This sets the X position to be 1.5x the control's width, or in this instance, at 300 pixels.

"ypos" "s0.5"
"tall" "200"

This sets the Y position to be 0.5x the control's height, or in this instance, at 100 pixels.


P

The flag "p" or "P" means that the control shall be offset by a given float scale with regards to the control's parent's correlating size variable.

Examples:

"xpos" "p0.5"
"wide" "100" //doesn't matter

This sets the X position to be at 0.5x the control's parent's width. If the parent is 400 pixels wide, this would have an X position of 200 pixels.

"ypos" "p0.5"
"tall" "200" //doesn't matter

This sets the Y position to be at 0.5x the control's parent's height. If the parent is 400 pixels tall, this would have a Y position of 200 pixels.

Combinations

It is possible to combine only one Alignment flag with only one Scale flag. Potential examples of this can be found in the next section.

Warning.pngWarning:The Alignment flag must come first, otherwise it causes undefined behavior!

Helpful Examples

Center a control with regards to its size

"xpos" "cs-0.5"
"ypos" "cs-0.5"
"wide" "200" // This makes the "xpos" similar to "c-100", yet this solution does not require the modification of the "xpos" for centering
"tall" "400" // Similarly, this makes the "ypos" similar to "c-200"

Align a control to the bottom right corner

"xpos" "rs1.0"
"ypos" "rs1.0"
"wide" "200" // This makes the "xpos" similar to "r200", yet this solution does not require the modification of the "xpos" for alignment
"tall" "400" // Similarly, this makes the "ypos" similar to "r400"

Make a control take up as much space as its parent

"xpos" "0"
"ypos" "0"
"wide" "f0"
"tall" "f0"

Note on Proportionality

If a control is created under a parent that is declared proportional, or if the panel/control itself is declared proportional (in code), all values (except float scales) used with these flags, upon reading, will be proportional!
For example, if an EditablePanel has the following in its constructor:

SetProportional(true);
LoadControlSettings("resource/ui/MyPanel.res");

The child controls created in MyPanel.res will have the values be read and set as proportional values. So the values used in this article may not be correct (larger/smaller) depending on if the control/parent is proportional, and what size the game is running at!