GUI Scripting: GUI:: Parameters

From The DarkMod Wiki
Revision as of 16:03, 13 November 2023 by Geep (talk | contribs) (→‎Bound In a Property List: fix & expand gui::BriefingVideoMaterial info)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

This page is part of a series. See GUI Scripting Language for overview.

What and Why of GUI:: Parameters

"GUI:: Parameters" are different from standard GUI properties and GUI user variables. But just like user variables, you invent their names. They can easily take on float values (including representing boolean and integer values) or string values. Vector values such as color can handled not as a whole, but by passing any given component as a float.

If you have an entity with both a .gui and .script, a GUI:: Parameter provides a channel to pass a value in either direction. This will be potentially "instantaneous", in that values could be re-evaluated on every frame. In the GUI file, the GUI:: Parameter is always prefixed with "gui::". That prefix is NOT used in the .script file.

Besides these custom GUI:: Parameters, there are also predefined ones associated with certain system CVars. These are global, in the sense that they can be accessed in your .gui without mention in your .script. They are not covered here; see GUI Scripting: Getting System CVars.

The Magic Prefix "Gui_Parm"

If you have an entity with:

  • a "gui" spawnarg of valid value, and
  • one or more spawnargs with name prefix "gui_parm".

then when the entity and its GUI are spawned, gui:: parameters with the gui_parm names will be created and initialized from the spawnargs values, and can be used immediately in the GUI. The usual naming convention is "gui_parm" alone or followed by a digit, but any suffix string will do.

If a gui_parm has an i18n string value (i.e., a #str value), the corresponding gui:: parameter is automatically initialized with the correct language string.

The magic prefix naming is particularly useful for entities that don't need a .script file, as shown next.

Usage with Standard Assets that Need No .Script File

Decals for sign text with various fonts are provided as prefabs (in \tdm_prefabs01.pk4\prefabs\readables\sign_text_decals\). They all use "gui_parm1" with default hint "put text here". For example, for the regular size of Andrew font, sign_text_andrew.pfb (reformatted slightly here) is simply:

Version 2
// entity 0
{
   "classname" "func_static"
   "name" "sign_text"
   "gui" "guis/readables/sign_text_decals/sign_text_andrew.gui"
   "gui_parm1" "put text here"
   "model" "sign_text"
   "origin" "0 0 -320"
   // primitive 0
   {
       patchDef3  {
           "textures/darkmod/decals/signs/decal_gui"
           ... // not shown: coordinates of patch
       }
   }
}

The referenced GUI, "sign_text_andrew.gui", is:

//Suitable for signposts, graffiti text, etc.
windowDef Desktop {
   rect 0, 0, 640, 480
   backcolor 0, 0, 0, 0

   windowDef SignText {
      rect 0, 0, 640,480
      backcolor 0, 0, 0, 0
      text "gui::gui_parm1"
      font "fonts/andrew_script"
      textscale 2.5
      forecolor 0, 0, 0, 0.66
      visible 1
   }
}

Cautions when a .Script File is Involved

Be aware: if a GUI is created (or replaced) in a script (which is the norm for overlays), then during that process NO spawnargs will be consulted for gui:: parameter creation and initialization. Also, if an "gui_parm..." spawnarg value is updated by a script, that change is not automatically propagated to the gui:: parameter. However, in both those cases, script code can be written as needed to get the spawnarg value and send it to the gui:: parameter, as indicated next.

Important Use: Any Spawnarg -> .Script -> .Gui

Except for the magic prefix initialization, a .gui attached to an entity cannot read or access the entity's spawnargs directly. Instead, a .script function acts as the intermediary. The usual dance is:

  • The mapper sets a key/value spawnarg on the entity (with key and default value often predefined in an entityDef).
  • An attached script (say, specified in a "scriptobject" spawnarg) fetches the spawnarg value, with:
    • GetKey(spawnarg_name); // gets value in string form
    • GetIntKey(spawnarg_name);
    • GetFloatKey(spawnarg_name);
  • The script can then pass that on the GUI in a desired form, as discussed next.

As mentioned above, gui:: parameters do not involve or affect entity spawnargs (other than magic prefix initialization). Internally, a GUI's gui:: parameters are stored in a separate "dictionary" data structure. You create gui:: parameters in the dictionary by referencing them in your .gui and .script. If a GUI can access multiple script functions (e.g., both a frob_action_script and script object functions) , then each function can potentially access the gui:: parameters. Just the correct handle number and use of the appropriate names/types is needed.

In a GUI File – Syntax and Use

In the GUI file, use a "gui::" prefix, followed by a name, all in double quotes. A gui:: parameter can appear multiple times within a file and at any level of "guiDef" nesting.

Bound In a Property List

A gui:: parameter can be "bound" to a standard float or string property (not a user variable or vector). For example, in the property list of a "windowDef SignText":

text	"gui::gui_parm1"

CAUTION: No example was found of a gui_parm or more broadly any gui:: parameter being bound to a non-register property... so possibly that's not legal. [Someone please test!]

Another string example, from the mainmenu_briefing_video.gui:

background	"gui::BriefingVideoMaterial"

The value here is a path to a custom video material shader. It is set at runtime by the engine, based on information the FM author provided in mainmenu_custom_defs.gui as, e.g.:

#define MM_BRIEFING_VIDEO_MATERIAL_1 "video/tdm_briefing_video"

(In older FMs, the video was chopped into parts, in which case the engine updates the value just-in-time. See comments in mainmenu_custom_defs.gui for details.)

For a more dynamic use, see GUI Scripting: On Entity's Surface, where it is important that the boolean value of the bound property...

visible "gui::is_visible"

... is automatically re-evaluated every frame. Similarly, one could have an expression with changing value:

 visible 1-"gui::is_visible"

But in any case, be aware that automatic re-evaluation of a particular property (like "visible" in these examples) can become deactivated/disabled...

  • prior to TDM 2.11, if you include ANY reference to that property in an event handler body. Deactivation happens at startup [or perhaps right after property's first initialization].
  • In TDM 2.11, if you manually assign to that property using the "set" command. [Probably doesn't apply to "transition"]. Deactivation happens when "set" is executed.

Careful programming can avoid unwanted deactivation.

In Event Block’s Set Command

Usages are either sources or sinks for "set" commands (involving strings or floats, not vectors).

Consider some scripting from readable entities. As source examples, in one of the onTime handlers, strings are copied from two gui:: parameters to the text property of the two other windowDefs named "title" and "body":

set "title::text" "$gui::title";
set "body::text" "$gui::body";

As usual with "set", a "$" on the source indicates that the value is to be copied, not a literal string such as "gui::title".

Here's a sink example, where information is being passed from the .gui to the .script file:

set "gui::InteractionState" "3";

See also the example at this article’s end for more.

In Event Block’s "If" Statement

A gui:: parameter can be tested in a "if" conditional clauses. For example, when a readable fades out its background, it uses an onTime event handler containing:

if ("gui::numPages" > 1) {
  transition "backgroundmulti::matcolor" "1 1 1 1" "1 1 1 0" READABLE_FADE_TIME;
}
if ("gui::numPages" == 1) {
  transition "backgroundsingle::matcolor" "1 1 1 1" "1 1 1 0" READABLE_FADE_TIME;
}

In a SCRIPT File – Syntax, and Available Functions for GUI:: Parameters

In the body of a SCRIPT function, use a double-quoted parameter name that matches that in the GUI file, but without the "gui::" prefix. Pass that name in a SetGui… or GetGui… function call whose type - float, int (also used for bool), or string - matches the usage in the GUI file. You must specify a handle with these functions, as discussed in GUI Scripting: Handles.

GetGui… Functions

Each of these functions returns the value of the GUI:: Parameter given by "key":

  • getGuiFloat(float handle, string key); // returns a float
  • getGuiInt(float handle, string key); // returns a float with int value
  • getGuiString(float handle, string key); // returns a string

Don’t confuse that last one with this function:

  • getGui(float handle); // returns a string with the file currently loaded by the GUI.

SetGui… Functions

Similarly:

  • setGuiFloat(float handle, string key, float val);
  • setGuiInt(float handle, string key, float val);
  • setGuiString(float handle, string key, string val);

There is a 127 character size limit on script strings that can impede that last function. An alternative function gets around that, by copying a string value directly from an entity spawnarg to a gui:: parameter:

  • setGuiStringFromKey(float handle, string key, entity src, string srcKey);

So, for example, in the body of a script object function, it would typically take the form:

$player1.setGuiStringFromKey(myhandle, "myGuiParamName", self, "mySpawnArgName");

For More

  • GUI Scripting: Number Wheel Example shows how a GUI can detect a user action, then originate a change to a gui:: parameter in order to pass it on to a script object for processing.
  • GUI Scripting: Flashbomb Example also is relevant. In particular, it shows how to use a gui:: parameter to control color transitions, even though the GUI language parser will not accept a gui:: parameter embedded into a color vector.