Dialog Control

From Bohemia Interactive Community
Revision as of 20:01, 27 December 2019 by Fini Lannister (talk | contribs) (Updated warning about syntactic errors in description.ext)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search


Dialogs are one way to provide custom graphical user interface in your missions and allow interaction with the player aswell as they are able to run code. They are defined as classes in the description.ext, campaignConfigFile or configFile.

Notice: If you change your description.ext file while the mission is still open in the editor, you will have to reload or resave the mission before the changes will take effect. This behaviour is due to the fact the mission editor only reads the description.ext file during save/load. Eden editor will automatically update the description.ext on mission preview.

Warning: Prior to Arma 3 syntactic errors in your description.ext file (e.g. incorrect spelling of keywords) will crash the game while processing the file, stating the nature and location of the error that caused it.

Arma 3 logo black.png
Only missing #include statements will cause a crash in Arma 3, other syntactic errors will simply display an error message.

Most of these definitions work with numeric constants, which are presented in the following section. For readability purposes you should consider favoring them instead of the actual integers.

  • Positions and dimensions (x, y, w, h) aswell as font sizes are relative to the viewport (not pixel values). Vieweport is a 4:3 area which covers the whole screen with Very Large interface size, but gets smaller with small interface sizes (and user interface gets smaller as well). See GUI Coordinates for more information
  • Colors are usually defined in the following convention: { Red, Green, Blue, Alpha }, each ranging from 0.0 to 1.0 as well. To easily convert from the more standard 0-255 range, simply divide the 255 based number by 255.
  • Sounds are usually defined in the following convention: { "file.ogg", volume, pitch }, Volume ranges from 0.0 to 1.0. Pitch is a floating point number ranging from 0.0 to 4.0. 2.0 doubles the pitch (makes it higher), 0.5 halfs the pitch (makes it deeper) and 1.0 is normal.

You can find a complete list of scripting related GUI functions in Category:Command Group: GUI Control.

Difference between dialogs and HUDs

There is two kind of displays :

  • Dialogs: Displays that interact with the player through controls. While dialogs are opened player can not move.
  • HUDs: Displays that print information about the game (amount of ammo, stance,...). HUDs do not interfere with the player's movement.

Global considerations

This document attempts to cover the genre of controls (idc's), display (idd's). It attempts to apply the same consistency as one (currently) finds in mission description.ext's, as well as configs. Specifically, config.cpp's relating to the so-called 'user ui'.

This document must be inaccurate because *everything* config-dialogs/displays/controls is at the whim of engine revisions and which flavor pizza was eaten on Friday night.

The token names used for color (purely as an example) are currently not only inconsistent across controls, they are subject to whim. Any addition to the engine's capabilities (with new control types) will (if history is the judge) produce new token names, that do exactly same as different names in other controls. color[]=, colorText[]= ActiveColor[]=ShadowColo[]= (an engine typo) =ColorActive[]=FrenchFries[]=….. all meaning the same thing (and NOT meaning the same thing, depending on the control's type)

Unfortunately, the current state of play with Arrowhead engine (and all engines prior) is that the entire caboodle is arbitrary. In terms of ui.config.cpp, most controls and most displays are hard-wired to the engine.

For config.cpp's, one of the hardest animals to deal with is the fixed-in-concrete classname definitions, aligned with matching fixed-in-concrete idd's.

Purely as an example

RscDisplaySelectIsland uses an idd of 51. Both are currently nuclear fallout shelters (hardened concrete). you can't change the name, you can't change the idd.

The engine is hard wired (with the equivalent of) createDisplay "RscDisplaySelectIsland" via various fixed-in-conrete idc's of other displays. There is no action, no eventhandler, no over-ride, which you can apply to this 'behavior'. Similarly, the engine reacts to that displays controls with hard-wired _display ctrlParent 'control' expecting the _display idd to be 51 to proceed any further. (in this case, open the editor and show the selected island's map)

There is nothing wrong with this approach. It has been the same since CWC. But, with the increasing abundance of official bis sqf scripts which specifically deal with and react to ui controls and displays (see \ca\ui\scripts). The burden of the engine dealing with this is becoming anachronistic and contrary to the flexibility that those scripts provide.

In short:

  • The token names described here as general, have to be taken in context to the control/display they are used in. There can be no guarantee that they are the same for all controls, and no guarantee that they wont change. the bin\config.bin of the engine, is the ultimate umpire. It declares what this engine, expects.
  • Any reference to eventHandlers and 'actions' are subject to the whim of the engine. It may, or may not, force-over-ride any action depending on display(idd) and it's control (idc)
  • Any class definition may or may not be fixed in concrete. Some classnames are, some classnames are not. Which ones, depend on whether it's Monday afternoon.


Dialogs are parent containers for the actual controls it contains. Their definition contains several properties on the controls it contains, how the dialog can be addressed, and whether or not the player is able to continue regular movement while the dialog is shown.

They can be defined in the description.ext file or externalized to separate hpp-files, which are included in the description.ext file using the #include preprocessor directive. The latter method is generally a good idea to split a large description.ext file into several small chunks in order to keep track of what's where.

Most often, controls of a dialog are defined within the definition of the dialog itself, though it's a good practice to generalize common controls in a base definition in the global scope. See best practice for details. For simplicity we won't apply this practice in the following code examples.

Name Type Remark
idd integer The unique ID number of this dialog. can be -1 if you don't require access to the dialog itself from within a script.
movingEnable boolean Specifies whether the dialog can be moved or not (if enabled one of the dialogs controls should have the moving property set to 1 so it becomes the "handle" the dialog can be moved with). Doesn't seem to matter in Arma 3
enableSimulation boolean Specifies whether the game continues while the dialog is shown or not.
controlsBackground array or class (see the note at the bottom of this section) Contains class names of all background controls associated to this dialog.

The sequence in which the controls are listed will decide their z-index (i.e. the last ones will on top of the first ones).

controls array or class (see the note at the bottom of this section) Contains class names of all foreground controls associated to this dialog.
objects array or class (see the note at the bottom of this section)

Setting the idd property to a non-negative (i.e. "useful") number is only required if you want to access the dialog itself via the findDisplay function. Accessing the dialog itself via the idd property though does not mean that you can implicitly access the controls within the dialog. For that you will have to rely on the control's idc properties. Hence, in most basic cases you won't need it and -1 should be sufficient.

It's also noteworthy for more advanced developers that there is a numeric property named access with the following possible values (and their named constants):

  • 0 - ReadAndWrite - this is the default case where properties can still be added or overridden.
  • 1 - ReadAndCreate - this only allows creating new properties.
  • 2 - ReadOnly - this does not allow to do anything in deriving classes.
  • 3 - ReadOnlyVerified - this does not allow to do anything either in deriving classes, and a CRC check will be performed.

This does not have any impact other than limiting what deriving classes are allowed to (re-)specify. Generally this is not required for dialogs or dialog controls and can be safely ignored.

Here's an example of a dialog that will only display Hello world in the top right corner of the screen. If you get confused by the MyHelloText class, just ignore it for the moment until you have read details on the definition of controls in the following chapter, Controls.

  • Example 1:
class MyHelloWorldDialog {
	idd = -1;						// set to -1, because we don't require a unique ID
	movingEnable = 1;			// the dialog can be moved with the mouse (see "moving" below)
	enableSimulation = 0;		// freeze the game
	controlsBackground[] = { };		// no background controls needed
	objects[] = { };				// no objects needed
	controls[] = { "MyHelloText" }; 	// our "Hello world" text as seen below:

	class MyHelloText {
		idc = -1;					// set to -1, unneeded
		moving = 1;					// left click (and hold) this control to move the dialog
									// (requires "movingEnabled" to be 1, see above)
		type = CT_STATIC;			// constant
		style = ST_LEFT;			// constant
		text = "Hello world";
		font = FontM;
		sizeEx = 0.023;

		colorBackground[] = { 1, 1, 1, 0.3 };
		colorText[] = { 0, 0, 0, 1 };

		x = 0.8;
		y = 0.1;
		w = 0.2;
		h = 0.05;
  • Example 2:

The benefit of the following syntax is that you do not need to double list all of the control class names.

class RscText; // assume external declaration

class MyHelloWorldDialog {
	idd = -1;
	movingEnable = 0;
	class ControlsBackground {
		// define controls here
	class Objects {
		// define controls here
	class Controls {
		// define controls here

		class MyHelloText: RscText {
			idc = -1;
			text = "Hello world";
			x = 0.80;
			y = 0.10;
			w = 0.20;
			h = 0.05;

Once you have defined (or prototyped) dialogs you want to use, be sure to reload the mission in the editor if it is already running. In the Eden editor it's enough to save the mission via CTRL + S (Default). This will precompile the description.ext.

controls[] only matters if there is no class Controls, then the order of controls is taken from this array, if there is class Controls then controls[] is ignored and the order is the same as the order in which controls appear inside class Controls. The same is true for objects[] vs. class Objects and controlsBackground[] vs. class ControlsBackground

Creating dialogs

Dialogs can then be created and shown using the createDialog function. If you do so by script and await a responsive action from the user, you might also want to wait until the user has closed the dialog by using a wait statement (e.g. waitUntil) in conjunction with the dialog function, if you intend to handle the dialog result within the same script.

  • Example:

_ok = createDialog "MyHelloWorldDialog"; waitUntil { !dialog }; // hit ESC to close it hint "Dialog closed.";

Closing dialogs

In most use cases a dialog "closes itself", ie. by invoking the closeDialog function in an action field. However dialogs don't necessarily have to close themselves, but can also be closed from the "outside" (ie. by scripts or triggers). Once closed, the dialog function returns false and wait statements with a !dialog condition will end.

  • Example - close by action
class CloseButton : RscButton {
	/* … */
	type = CT_BUTTON;
	text = "Close";
	action = "closeDialog 0";
  • Example - close by external request

closeDialog 0;


Controls are the actual content of dialogs and can be anything, ranging from simple solid rectangles to a complex 3d object within a dialog. Like dialogs, controls can have a unique ID saved in the idc property to access them from within scripts using GUI functions.

The type of the control is usually set in the type property. Different types allow or require a different set of properties. However most controls share a set of properties in addition to the properties described in the following sections:

Common properties
Name Type Remark
idc integer the unique ID number of this control. can be -1 if you don't require access to the control itself from within a script
moving boolean whether the dialog will be moved if this control is dragged (may require "movingEnable" to be 1 in the dialog. In Arma 3 works regardless). Another way of allowing moving of the dialog is to have control of type CT_STATIC and style ST_TITLE_BAR. If moving is defined, it takes priority over style.
type integer CT_TYPES
style integer CT_STYLES can be combinatorial: style = "0x400+0x02+0x10";
x/y/w/h float the position and size of the control in fractions of screen size.
sizeEx float the font size of text (0..1)
font string the font to use. See the list of available fonts for possible values
colorText color array text color
colorBackground color array background color
text string or texture the text or picture to display
shadow 0,1 or 2 can be applied to most controls (0 = no shadow, 1 = drop shadow with soft edges, 2 = stroke). Additional params for shadow: shadowPictureLeft, shadowPictureRight, shadowTextLeft, shadowTextRight
show boolean Initial visibility of the control
tooltip string Text to display in a tooltip when control is moused over. A tooltip can be added to any control type except CT_STATIC and CT_STRUCTURED_TEXT. Note: As of Arma 3 v1.48 (approx), most controls now support tooltips.
tooltipColorShade color array Tooltip background color
tooltipColorText color array Tooltip text color
tooltipColorBox color array Tooltip border color
autocomplete string Option for entry fields (e.g. RscEdit) to activate autocompletion. For known script commands and functions use autocomplete = "scripting".
deletable boolean Whether or not control can be deleted by scripts with ctrlDelete command
fade float Initial fade of the control
url string URL which will be opened when clicking on the control. Used on e.g. a button control. Does not utilize the Steam Overlay browser if enabled, opens the link in the default browser set by the OS.

Attributes class

Name Type Remark
font string
color HTML color
align string center, left, etc
shadow integer not image class

AttributesImage class

Name Type Remark
font string optional
color HTML color
align string center, left, etc optional

To save space and effort, it is generally a good idea to make use of class polymorphism, i.e. deriving from very basic classes that already have some specific properties set. See the Best practice for details.


There is an ingame dialog with examples of how the control types look and act like: createDialog "RscTestControlTypes";

Define Decimal Hexadecimal Remark
CT_STATIC 0 0x00
CT_BUTTON 1 0x01
CT_EDIT 2 0x02
CT_SLIDER 3 0x03
CT_COMBO 4 0x04
CT_HTML 9 0x09
CT_TREE 12 0x0C
CT_XBUTTON 41 0x29
CT_MENU 46 0x2E Arma 3 (EDEN)
CT_MENU_STRIP 47 0x2F Arma 3 (EDEN)
CT_CHECKBOX 77 0x4D Arma 3
CT_OBJECT 80 0x50
CT_USER 99 0x63
CT_MAP 100 0x64
CT_MAP_MAIN 101 0x65
CT_LISTNBOX 102 0x66
CT_ITEMSLOT 103 0x67

Control Types Defines

Show text


Common Controls Styles

Note that drawing of vertical text is not supported and any attempt to use ST_UP, ST_DOWN, ST_VCENTER is likely to result in the following .rpt spam:
Obsolete, sizeH and sizeW calculation missing
In addition, ST_UP, ST_DOWN, ST_VCENTER are stand alone styles and should not be mixed with any other styles

To get an idea of how the styles look like you can create the following dialog: createDialog "RscTestControlStyles";

Define Decimal Hexadecimal Remark
ST_LEFT 0 0x00 Default, text left aligned
ST_RIGHT 1 0x01 Modifier, adding this to another style will force text to be aligned to the right
ST_CENTER 2 0x02 Modifier, adding this to another style will force text to be centered
ST_DOWN 4 0x04 Vertical text alignment (See the note above)
ST_UP 8 0x08 Vertical text alignment (See the note above)
ST_VCENTER 12 0x0C Vertical text alignment, same as ST_DOWN + ST_UP (See the note above)
ST_SINGLE 0 0x00 Plain single line box without a border
ST_MULTI 16 0x10 Plain multiple line box with a slight border. To remove border add 512 (+ ST_NO_RECT) to the style (style 528, 529 and 530 are therefore border-less). Additional parameter lineSpacing is required for this style. lineSpacing = 1; is normal line spacing. Any \n character in the text string will be interpreted as new line.
ST_TITLE_BAR 32 0x20 Plain single line box with semi-transparent background and somewhat embossed border. When this style is used, the dialog containing control becomes draggable by this control
ST_PICTURE 48 0x30 Border-less picture box. Text string is treated as a path to a texture. Alignment has no effect. The texture is stretched to fit the box by default. To force original aspect ratio add 2048 (+ ST_KEEP_ASPECT_RATIO) to the style. Background is ignored, colorText controls texture colour and opacity
ST_FRAME 64 0x40 Legend like frame without background with text showing over the frame edge. Alignment has no effect. colorText defines both text and frame colour
ST_BACKGROUND 80 0x50 Single line box with always black opaque background and thick raised beveled border
ST_GROUP_BOX 96 0x60 Single line box with delicate semi-transparent background and slight border. Only text colour can be controlled
ST_GROUP_BOX2 112 0x70 Plain single line box, same as ST_SINGLE, only with a slight border similar to ST_MULTI box border
ST_HUD_BACKGROUND 128 0x80 Sets special texture for corners. It was used for rounded corners in OFP, Arma and Arma 2. In Arma 3, square corners are used everywhere, so the texture is adapted to the unified style, but the technology is not removed. In Arma 3 it looks the same as normal ST_SINGLE. Corner textures are defined in configFile >> "CfgInGameUI" >> "imageCornerElement" (can be set only globally for the whole game, not per control)”
ST_TILE_PICTURE 144 0x90 The picture is tiled according to tileH and tileW values. To force tiled picture to keep aspect ratio of original image, add 2048 (+ ST_KEEP_ASPECT_RATIO) to the style.
ST_WITH_RECT 160 0xA0 Single line box frame, similar to ST_FRAME box. The text however is displayed inside the frame. Frame and text colour are set with colorText
ST_LINE 176 0xB0 Diagonal line going from left top corner to bottom right corner. To control line direction, width w and height h parameters of the box could be negative. Line and text colour are set with colorText
ST_UPPERCASE 192 0xC0 Forces control text to upper case
ST_LOWERCASE 208 0xD0 Forces control text to lower case
ST_SHADOW 256 0x0100
ST_NO_RECT 512 0x0200 This style works for CT_STATIC in conjunction with ST_MULTI
ST_KEEP_ASPECT_RATIO 2048 0x0800 When used with image or texture, stops it from stretching to fit the control

CT_SLIDER Specific Styles

Define Decimal Hexadecimal Remark
SL_VERT 0 0x00
SL_HORZ 1024 0x0400

CT_PROGRESS Specific Styles

Define Decimal Hexadecimal Remark

CT_LISTBOX Specific Styles

Define Decimal Hexadecimal Remark
LB_MULTI 32 0x20 Makes CT_LISTBOX multi-selectable (see also lbSetCurSel, lbCurSel, lbSetSelected, lbSelection)

CT_TREE Specific Styles

Define Decimal Hexadecimal Remark

Control Styles Defines

Show text

UI Eventhandlers

A reference list of User Interface Event Handlers.

Best practice


Using inheritance can reduce your dialog class definitions significantly by standardising common attributes in base classes and just changing unique attributes in derived classes. There is no need to redeclare all attributes for each class definition.

  • Example:
class RscText // Base definition used for inheritance
	type = CT_STATIC;
	idc = -1;
	style = ST_LEFT;
	colorBackground[] = {0, 0, 0, 1};
	colorText[] = {1, 1, 1, 1};
	font = FontM;
	sizeEx = 0.04;
	h = 0.04;
	text = "";

class My_BlueText : RscText // My_BlueText inherits all attributes from RscText defined above, thus only x,w & colorText need to be changed
	colorText[] = {0, 0, 1, 1};
	x = 0.1;
	w = 0.4;

class My_Dialog

	controls[] = {

	class My_Text_1 : My_BlueText // My_Text_1 inherits all attribute from My_BlueText, therefore only text & y attributes have to be changed
		text = "Line 1";
		y = 0.2;

	class My_Text_2 : My_BlueText
		text = "Line 2";
		y = 0.25;

Preprocessor instructions

Note that you can also add your own preprocessor instructions for commonly used data, eg. for colors, to save yourself the hassle of writing it in several different places and then adapt each of them if you want to change them afterwards (especially if class inheritance isn't applicable). Also it can make your code look more readable sometimes.

  • Example:
#define COLOR_LIGHTBROWN { 0.776, 0.749, 0.658, 1 }
#define COLOR_HALF_BLACK { 0, 0, 0, 0.5 }
#define COLOR_TRANSPARENT { 0, 0, 0, 0 }

// …

class MyDialog {
	idd = -1;
	movingEnable = 1;
	objects[] = {};
	controlsBackground[] = { MyDialogBackground };
	controls[] = { MyDialogText };

	class MyDialogBackground : RscText {
		colorBackground[] = COLOR_HALF_BLACK;
		x = 0.7;  y = 0.1;
		w = 0.25; h = 0.15;

	class MyDialogText : RscText {
		style = ST_MULTI;
		colorBackground[] = COLOR_TRANSPARENT;
		colorText[] = COLOR_LIGHTBROWN;
		text = "No power in the 'Verse can stop me.";
		lineSpacing = 1;
		x = 0.71; y = 0.11;
		w = 0.23; h = 0.13;