GUI Scripting: BindDef

From The DarkMod Wiki
Jump to navigationJump to search

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

Introduction

A bindDef is a menu component that allows the user to easily bind a particular key or mouse button to a particular engine function. It also displays what key(s) if any are so bound. The binding is done when the game is not running; a bound key is used when the game is running to evoke the desired behavior.

In TDM, bindDefs are used only (but extensively) in the Settings/Controls portion of the main menu system. Please review Bindings and User Settings, which, from the user’s perspective, covers:

  • how these controls are operated
  • what functions they are bound to in the 6 submenus of Settings/Controls
  • how key binding works in general, in conjunction with the DarkmodKeybinds.cfg file
  • available keys and functions.

Features Shared with All GuiDef Types

The example below shows how bindDef works with certain Properties in common to all guiDefs. A bindDef’s overall functionality derives from C++ code and has little need for User Variables or Event Handlers.

BindDef's Unique Property: "Bind"

® = A property known as a "register", that can be altered at runtime by binding it to a GUI:: parameter, or in a "set" or "transition" script command. Other properties cannot be so altered. NOTE: TDM core never alters "bind" in this way.

bind "function" ®

Specifies the function to which key(s) may be bound by the user. Note that (unlike the "bind" command used in the console or appearing in the .cfg file), there is no mention of the key(s) here. Instead, the C++ code has an internal structure to maintain the keys and their association with the stated function, and persist this with the .cfg file. Syntax examples:

bind "_impulse10"
bind "inventory_hotkey '#str_02397'" // "Compass"

TDM’s Use of BindDef – A Representative Example

Settings/Controls/Movement

The English-language version is portrayed here, but menus are rendered in other TDM-supported languages.

The figure shows a representative page (Movement) from TDM’s Settings/Controls main menu. On the right-hand side, a column of bindDefs (here individually annotated with a red border) is paired with a left-hand column of corresponding informative function titles in windowDefs.

Settings controls movement red cropped.png

To add a binding, the user hits LMB on a right-hand cell, which then reads "Press any key...". Hitting a key (or mouse button) adds that key to the list of those for that function. In the process, keyscan-code mapping is applied that takes into account the country-specific keyboard and the OS in use. The rectangle of the bindDef subsequently shows the logical (and language-specific) key names with " or " between them. Except pressing the Escape key will remove the bindings, showing "<empty>". Also, any older key binding elsewhere in the menu system that conflicts with a new one is automatically unbound.

The GUI Code: Main Menu #Defines

The Settings/Controls pages rely on these #defines from tdm_gui01.pk4\guis\mainmenu_defs.gui:

#define SETTINGS_FONT	        'fonts/carleton'
#define BINDINGS_FONT	        'fonts/carleton'
#define SETTINGS_FONT_SCALE 0.24
#define SETTINGS_FONT_COLOUR 0, 0, 0, .85
// The text on the left side in the settings menu
#define SETTINGS_TEXT   font SETTINGS_FONT  textscale SETTINGS_FONT_SCALE  forecolor  SETTINGS_FONT_COLOUR  visible 1
// for keybindings
#define BINDINGS_TEXT   font BINDINGS_FONT  textscale SETTINGS_FONT_SCALE  forecolor  SETTINGS_FONT_COLOUR  visible 1  textalign 2  textalignx  -3

Note that no background is specified in either SETTINGS_TEXT or BINDINGS_TEXT. The backgrounds are left transparent, relying on the lined-parchment background seen throughout Settings/Controls menus. Observe that the key name is right justified, as specified by "textalign 2" in BINDINGS_TEXT. The default value of hoverColor (opaque white: 1 1 1 1) is used, as initialized in Window.cpp. The bind code handles painting the normal or hover-color text

Finally, to prepare the figure, the red borders were created by temporarily appending this to #define SETTINGS_TEXT:

... bordercolor  1,0,0,1  bordersize 1

The GUI Code: Movement Page BindDefs

All the Settings/Control pages are implemented with a single GUI file, mainmenu_settings_controls.gui. The GUI and engine code conspire to make only a single page visible at a time. For our Movement example, here are code snippets for the cursor’d row of the above figure:

... Not shown: Enclosing desktop windowDef that provides the lined-parchment background.
windowDef SCMovementParent
{
   rect    45,185,320,640
   visible 0
   ...
   windowDef SCMovementText8
   {
      rect   TEXT_X_OFFSET, 119, 230, MM_LINE_H
      text   "#str_02421" // Turn Right
      SETTINGS_TEXT
    }
    ...
    bindDef TurnRight
    {
       rect   SETTINGS_X_OFFSET_CONTROLS, 119, 110, MM_LINE_H
       bind   "_right"
       BINDINGS_TEXT
     }
    ...
 }
...

To sum up, the underlying C++ code takes care of keystroke/mouse-button reception, mapping to a function and display of key names in a human-friendly, language-specific way.

For More