The are few parameters I haven’t touched in previous part, so here it is. colorText and colorBackground are pretty standard r,g,b,a colours. I have made HEX 2 ArmA GUI Colour Converter tool which might also help explain better how it all works. As for the font, I used “EtelkaNarrowMediumPro” because this font looks almost generic and is present in both ArmA 2 and ArmA 3, so it suits my tutorial. sizeEx is used to define font overall size and relative to the anchor blue box, which I’ve explained earlier.

Now that we passed some basics I’d like to look at some more advanced stuff like dynamic class loading. The video above demonstrates how Rsc can be loaded with a bunch of random parameters on each draw. In some cases this method can reduce amount of scripting required in some cases you can alter parameters which do not even have a scripting command associated with.

For example to alter the size and position of your Rsc you need to first load it with cutRsc, then use onLoad UI handler to get the display instance of this Rsc (which will be passed inside _this variable) so that you can use displayCtrl to get control instance so that then you can use ctrlSetPosition. And even after all that you still have to call ctrlCommit to complete the action. This is how it would look with our generic example:

//description.ext class RscTitles { class ExampleTitle { idd = -1; duration = 60; //1 min onLoad = "_this call onRscLoad"; //UI event handler class controls { class ExampleControl { idc = -1; //control reference type = 0; style = 0; x = 0; y = 0; w = 1; h = 1; font = "EtelkaNarrowMediumPro"; sizeEx = 0.1; colorBackground[] = {0,0,0,1}; colorText[] = {1,1,1,1}; text = "Example Text"; }; }; }; };
//init.sqf onRscLoad = { private ["_display","_idc","_ctrl"]; _display = _this select 0; _idc = -1; _ctrl = _display displayCtrl _idc; _ctrl ctrlSetPosition newPosition; _ctrl ctrlCommit 10; }; newPosition = [0.5,0.5,0.5,0.5]; cutRsc ["ExampleTitle","PLAIN"];

Once the “ExampleTitle” Rsc is loaded it will call onRscLoad function from its onLoad UI handler, which will change position and size of the control. onLoad is called after the class has been initialised and works with both cutRsc and createDialog. There is also onUnload even handler, which works only with createDialog. I also made the transition to last 10 seconds (ctrlCommit 10) so that you can observe the process. For instant effect it should be set to 0. Also in order to reference control we need to indicate its idc (in our case -1). There could be more controls than one under the same display so idc will have to be different for each one.

onLoad is executed in missionNamespace, therefore any variable found inside onLoad statement will be treated as missionNamespace variable unless you specify different namespace. The interesting thing is that during class loading, other class parameters are getting some sort of call compile done to them and you can also use variables there or even script commands. The difference is that in order to pass a variable to class parameter you must specify namespace you want to use. So to dynamically load parameters of the Rsc class upon loading we can do this:

//description.ext class RscTitles { class ExampleTitle { idd = -1; duration = 60; //1 min class controls { class ExampleControl { idc = -1; type = 0; style = 0; x = "missionNamespace getVariable 'newPosition' select 0"; y = "missionNamespace getVariable 'newPosition' select 1"; w = "missionNamespace getVariable 'newPosition' select 2"; h = "missionNamespace getVariable 'newPosition' select 3"; font = "EtelkaNarrowMediumPro"; sizeEx = 0.1; colorBackground[] = {0,0,0,1}; colorText[] = {1,1,1,1}; text = "Example Text"; }; }; }; };
//init.sqf newPosition = [0.5,0.5,0.5,0.5]; cutRsc ["ExampleTitle","PLAIN"];

In the above example Rsc transformation will be instant as it will already load with specified parameters. Notice how I included script statements in quotes. Sometimes you can get away without quotes but to be on a safe side it is better to use them. Also text is a special parameter it will not get compiled. It will recognise localisation variables preceded with $ but if you want dynamic text changing you will have to do it with onLoad and ctrlSetText combination.

Another peculiar thing about using scripts inside class parameters, only the first statement gets compiled and executed. If you have more than one statement, anything after the ; will get ignored. As a workaround you can call a function instead, which will have multiple statements. In this case nothing will be passed to your function by default unlike when you use onLoad handler. Now going back to where I started this part, the code for the video example is this:

//description.ext class RscTitles { class ExampleTitle { idd = -1; duration = 0.1; fadein = 0; fadeout = 0.1; onLoad = "(\ (_this select 0) displayCtrl -1) ctrlSetText ([\ 'DISCO',\ 'BALL',\ 'SUBLIMINAL',\ 'VERSES'\ ] select (floor (random 4)));\ "; class controls { class ExampleControl { idc = -1; type = 0; style = 2; x = "random 1 min 0.5"; y = "random 1 min 0.5"; h = "random 1 min 0.5"; w = "random 1 min 0.5"; font = "EtelkaNarrowMediumPro"; sizeEx = "random 0.2 min 0.08"; colorBackground[] = {"random 1","random 1","random 1",1}; colorText[] = {"random 1","random 1","random 1",1}; text = ""; }; }; }; };
//init.sqf mytime = diag_tickTime + 10; onEachFrame { if (mytime < diag_tickTime) then [ {random 100}, {100} ] cutRsc ["exampleTitle", "Plain"]; };

To explain what is happening here. Our Rsc is called every frame and it gets written on the same layer (100) for 10 seconds. Rsc is loaded with a bunch of random parameters for colour, background colour, size and position as well as random text. Because it goes to the same layer the next call erases previous one. After 10 seconds the Rsc is called on random layer on which it stays for 0.1 seconds before fading away. This is why you see it appearing in more than one place.

One more note on using UI handlers. This is the best way of handling UI. You do not need to use disableSerialization in any of the functions that are called from UI event handler. It is only if you are planning on storing UI variables and then reusing them later you might get complains from the engine and consider using disableSerialization. Even storing your UI variables in uiNamespace might not be enough in this case.

Enjoy,
KK