Skip to content

Keybinding

Killswitch edited this page Dec 1, 2015 · 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]

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](https://community.bistudio.com/wiki/DIK_KeyCodes), [Shift?, Ctrl?, Alt?]]

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;

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.