Skip to content

Keybinding

commy2 edited this page May 27, 2020 · 9 revisions

Keybinding System

About

CBA Keybinding allows users to change the keybindings for custom addons and missions from a unified location. It also allows modders to easily include GUI-based configurable keybindings in their addons or missions without developing their own user interface and key handling routines. CBA Keybinding uses CBA's highly reliable internal key-handling routines to ensure that these keybinds persist across mission reloads, editor sessions, and other actions which can cause custom keybinds to disappear.

Keybiding GUI

For Users

CBA Keybinding is easy to use. First, load Arma 3 with CBA and the mods you intend to use.

Then, to access the configuration page for CBA-defined mod keybindings:

  1. Select Configure -> Controls from the Main Menu.
  2. Click the Configure Addons button in the lower right of the dialog.
  3. Select the name of the addon you'd like to configure from the drop-down menu.
  4. Double click any action to change the key assigned to it.

For Addon and Mission Makers

CBA Keybinding is easy to use for addon and mission makers, too. Simply create a function that performs some action on a keypress, and then associate that function name with a keybinding by calling CBA_fnc_addKeybind (usually in your init.sqf or XEH_clientInit.sqf). There is no need to remove your keybinding; it will not appear when your mod or mission is unloaded, and keybinds which are not defined in future versions of your mod or mission will also disappear.

Function Spec

Function: CBA_fnc_addKeybind

Description:
 Adds or updates the keybind handler for a specified mod action, and associates
 a function with that keybind being pressed.

Parameters:
 _modName           Name of the registering mod [String]
 _actionId  	    Id of the key action. [String]
 _displayName       Pretty name, or an array of strings for the pretty name and a tool tip [String]
 _downCode          Code for down event, empty string for no code. [Code]
 _upCode            Code for up event, empty string for no code. [Code]

 Optional:
 _defaultKeybind    The keybinding data in the format [DIK, [shift, ctrl, alt]] [Array]
 _holdKey           Will the key fire every frame while down [Bool]
 _holdDelay         How long after keydown will the key event fire, in seconds. [Float]
 _overwrite         Overwrite any previously stored default keybind [Bool]

Returns:
 Returns the current keybind for the action [Array]

If _downCode returns true, block all further actions bound to this key, including base game actions.

Example

Suppose that you want show your user a hint message every time a key is pressed. First, write the function that will show your hint.

mymod_fnc_showGameHint = {
    hint format ["You can breathe air right now: %1", isAbleToBreathe player];
};

Now you need associate the function name with a keybind. The keybind you specify here will be the default, and calling this function later will not overwrite user changes. A keybind is an array in the format: [DIK code, [Shift?, Ctrl?, Alt?]] where DIK code is a number representing the key.

If you add the line

#include "\a3\editor_f\Data\Scripts\dikCodes.h"

to your script, you can use names for the keys rather than numbers.

Example: Shift-M would be [DIK_M, [true, false, false]]

Finally, to bind your function to a key, call CBA_fnc_addKeybind:

["My Awesome Mod","show_breathing_key", "Show Breathing", {_this call mymod_fnc_showGameHint}, "", [DIK_B, [true, true, false]]] call CBA_fnc_addKeybind;

Do this in your init.sqf or XEH client-only event handler to ensure that it is registered when your mission/mod is initialized.

Advanced Usage

Fleximenu Integration

You might want to open a CBA FlexiMenu using a configurable keybind.

First, create the parameter array you would normally pass to CBA_ui_fnc_fleximenu_add, but leave the keycode array empty:

["player", [], -100, "_this call my_fleximenu"];

Finally, add your keybinding using the function CBA_fnc_addKeybindToFleximenu:

Function: CBA_fnc_addKeybindToFleximenu

Description:
 Adds or updates the keybind handler for a defined Fleximenu and creates that Fleximenu.

Parameters:
 _modName	    Name of the registering mod [String]
 _actionName	    Name of the action to register [String]
 _displayName	    Pretty name, or an array of strings for the pretty name and a tool tip [String]
 _fleximenuDef	    Parameter array for CBA_fnc_flexiMenu_Add, but with the keybind set to [] [Array]

Optional:
 _defaultKeybind    Default keybind [DIK code, [shift?, ctrl?, alt?]] [Array]
 _holdKey           Will the key fire every frame while down [Bool] (Default: true)
 _holdDelay         How long after keydown will the key event fire, in seconds. [Float] (Default: 0)
 _overwrite	    Overwrite existing keybind data? [Bool] (Default: False)


Returns:
 Returns the current keybind for the Fleximenu [Array]

Example:

["My Awesome Mod", "open_menu_key", "Open Menu", ["player", [], -100, "_this call my_fleximenu"], [DIK_P,[true,true,true]]] call CBA_fnc_addKeybindToFleximenu;

Calling this will create and register the Fleximenu, so you do not need to separately call CBA_ui_fnc_fleximenu_add.

Other Functions

Function: CBA_fnc_getKeybind

Description:
 Checks if a particular mod has already registered a keybind handler for the
 specified action.

Parameters:
 _modName               Name of the registering mod [String]
 _actionName            Name of the action to get [String]

Returns:
 Keyboard entry.

Examples:
 _index = ["your_mod", "openMenu"] call cba_fnc_getKeybind;

 if (_index >= 0) then {
	_handler = cba_keybind_handlers select _index;
 };

Same Action, Different Functions on KeyDown/KeyUp

For certain actions, you might want to execute a function on both keydown and keyup events. (For example, lasing a target.)

// Register different events for both keydown and keyup of the same action
["Your Mod", "your_mod__double_action_key", "Your Double Action", {_this call your_mod_fnc_keyDown}, {_this call your_mod_fnc_keyUp}, [DIK_P, [false, false, false]]] call cba_fnc_addKeybind;

Additional DIK codes

Undocumented DIK codes for supported controllers.

#define DIK_XBOX_A 327680
#define DIK_XBOX_B 327681
#define DIK_XBOX_X 327682
#define DIK_XBOX_Y 327683
#define DIK_XBOX_UP 327684
#define DIK_XBOX_DOWN 327685
#define DIK_XBOX_LEFT 327686
#define DIK_XBOX_RIGHT 327687
#define DIK_XBOX_START 327688
#define DIK_XBOX_BACK 327689
#define DIK_XBOX_BLACK 327690
#define DIK_XBOX_WHITE 327691
#define DIK_XBOX_LEFT_TRIGGER 327692
#define DIK_XBOX_RIGHT_TRIGGER 327693
#define DIK_XBOX_LEFT_THUMB 327694
#define DIK_XBOX_RIGHT_THUMB 327695
#define DIK_XBOX_LEFT_THUMB_X_RIGHT 327696
#define DIK_XBOX_LEFT_THUMB_Y_UP 327697
#define DIK_XBOX_RIGHT_THUMB_X_RIGHT 327698
#define DIK_XBOX_RIGHT_THUMB_Y_UP 327699
#define DIK_XBOX_LEFT_THUMB_X_LEFT 327700
#define DIK_XBOX_LEFT_THUMB_Y_DOWN 327701
#define DIK_XBOX_RIGHT_THUMB_X_LEFT 327702
#define DIK_XBOX_RIGHT_THUMB_Y_DOWN 327703

These are made up DIK codes for CBA keybinding to bind CBA key actions to the base game user action keys.

#define USER_1 0xFA
#define USER_2 0xFB
#define USER_3 0xFC
#define USER_4 0xFD
#define USER_5 0xFE
#define USER_6 0xFF
#define USER_7 0x100
#define USER_8 0x101
#define USER_9 0x102
#define USER_10 0x103
#define USER_11 0x104
#define USER_12 0x105
#define USER_13 0x106
#define USER_14 0x107
#define USER_15 0x108
#define USER_16 0x109
#define USER_17 0x10A
#define USER_18 0x10B
#define USER_19 0x10C
#define USER_20 0x10D

Corrupt Keybinding Registry?

If you make an incorrectly formatted call while testing, you could corrupt the keybinding registry (although many checks are in place to prevent this). If that happens, run

profileNamespace setVariable ["cba_keybinding_registrynew", nil]; saveProfileNamespace;

in your debug console.

Final Notes

Please submit any bugs to the CBA bug tracker.

Clone this wiki locally