# Custom Button Command

PinballY's user interface is designed to be fully operable with just the basic set of four buttons that are pretty much mandatory for any pin cab just to play simulated pinball games: the flipper buttons, the Start button, and an Exit button. That minimalism in the UI design ensures that all functions are accessible even on virtually any cab, even with the bare minimum of buttons.

But if you're not so minimalist, and your cab has a bunch of extra buttons beyond the core four, you probably want to put them to some use. PinballY lets you map a number of commands beyond the minimal set through the Button Options page in the settings, but that dialog doesn't include every possible command in the program. Fortunately, there is a way to go beyond the fixed set of commands available in the settings dialog and map almost any button to almost any command. I'm sure you already guessed what it is: Javascript.

Mapping a button to a command through Javascript is a simple matter of combining two Javascript capabilities:

- Keyboard events and Joystick button events, which let you intercept button presses and program custom actions in response
- Commands, which let you execute program commands from scripting code

## Keyboard key handlers

The basic code template for mapping a keyboard key to a custom command looks like this:

mainWindow.on("keydown", ev => { if (ev.code == "F7") { mainWindow.doCommand(command.Flyer); ev.preventDefault(); } });

This creates an event listener for the keydown event, which fires each time a key is pressed. The listener checks which key was actually pressed by looking at the code property in the event descriptor object (the variable ev) that PinballY passes to the event handler when firing the event. The code value is a string that identifies which key was pressed, using a standard set of key names that most Internet browsers use in their Javascript event system. For this example, we used the function key F7. You can find out more about the available keys and their code strings in the KeyEvent section.

If the key matches the one we're looking for, the event handler calls mainWindow.doCommand() to carry out the command. For this example, we're executing the "Flyer" command, which shows the current game's flyer. See the Commands section for a full list of the available command codes.

The final step in the event handler calls preventDefault() on the event descriptor object, which cancels any built-in handling the system would have applied to the key event after the Javascript handler returns. This isn't really necessary for keys that aren't mapped to other functions already, since PinballY's built-in handling for unmapped keys is simply to ignore them, but I still think it's a good idea because it prevents any surprises should the key take on a default meaning in some future PinballY version.

## Joystick button presses

The template for a joystick button handler is almost exactly the same as for keyboard keys. We just listen for the joystickbuttondown event instead of the keydown event.

mainWindow.on("joystickbuttondown", ev => { if (ev.button == 7) { mainWindow.doCommand(command.Flyer); ev.preventDefault(); } });

Joystick buttons are identified by their button number, so here we're looking for joystick button #7. That will match button #7 on any joystick device. If you have more than one joystick device in your system, you might want to also test for the "unit" number to distinguish your different devices. See JoystickButtonEvent for more details.

## Customizing the examples

To adapt this example to any other keyboard key, simply pick out which key you want to map, and replace the "F7" key code in the example with the key code for the key you want to map. See the KeyEvent section for details on how to identify the different keyboard keys.

To adapt it to other joystick buttons, pick out the joystick button you want to use and change the button test to match. See the JoystickEvent section for details on how to identify the joystick buttons.

To fire a different command, change the command ID used in the call to mainWindow.doCommand() to the one you want to execute instead. See Commands for the full list of available command codes.

## Multiple key command handlers

You can set up as many custom keyboard key and joystick button handlers along these lines as you like. There are two ways to handle multiple button customizations:

- You can create a separate handler for each button, following the same templates shown above. This is the best way if you want to keep the customizations separate, since each handler stands on its own.
- You can add else if tests within the templates above to test for different keys/buttons. That's a little more efficient than using a separate handler per button, because it doesn't require the overhead of a separate function call for each button. It has the downside of tangling up the code for the different buttons, though.