Skip to content

Integration into Other Modules

shbatm edited this page Jan 3, 2019 · 15 revisions

The MMM-KeyBindings Module must be integrated into other modules in order for it to be useful. See information below on how to receive key press events in your module.

Examples

See MMM-Carousel w/ Navigation and MMM-OnScreenMenu for example implementations.

Setup in Your Module

In order for Key Bindings to work with your module, you must have the following:

  1. A key map in your modules' definition, and config/defaults.

  2. A function in your module code to do something on a valid key press.

  3. Declarations in your notificationReceived function.

  4. Typical Key Map in your modules definition & config/defaults

// Inside Defaults:
defaults: {
    keyBindings: {
        enabled: true
    }
},
// Right below Defaults:
// These are kept separate and combined later to keep the config section clean.
// The user can overwrite just the parts they want without copying the whole thing
// Same principle as CONFIG and DEFAULTS for a module.
keyBindings: {
    // If you want a certain key to give your module "focus" set it here:
    takeFocus: { keyName: "Menu", keyState: "KEY_LONGPRESSED" },
    mode: "MYMODE", // The mode, once you have focus, or "DEFAULT" to respond to all keys
    multiInstance: true,
    map: { NextSlide: "ArrowRight", PrevSlide: "ArrowLeft" }
}
  1. Functions to handle a valid key press, taking and losing focus:
validKeyPress: function(kp) {
    if (kp.keyName === this.keyHandler.map.NextSlide) {
        this.nextSlide();
    } else if (kp.keyName === this.keyHandler.map.PrevSlide) {
        this.previousSlide();
    } 
    // You can also use this.keyHandler.reverseMap[kp.KeyName] to get the action
},
hasFocus: function() {
    // Optional: Do something now that you have focus.
},
lostFocus: function() {
    // Optional: Do something now that you lost focus.
}
  1. Declarations in your notificationReceived function:
if (notification === 'MODULE_DOM_CREATED') {
    // Register Key Handler
    if (this.config.keyBindings.enabled && MM.getModules().filter(kb => kb.name === "MMM-KeyBindings").length > 0) {
        // First combine our configs,
        this.keyBindings = Object.assign({}, this.keyBindings, this.config.keyBindings)
        // Then, register the handler definition,
        KeyHandler.register(this.name, {
            sendNotification: (n, p) => { this.sendNotification(n,p); }, // Reference to send notifications
            validKeyPress: (kp) => { this.validKeyPress(kp); }, // Your Key Press Function
            onFocus: () => { this.hasFocus(); }, // Do something when you get focus
            onFocusReleased: () => { this.lostFocus(); } // Do something when focus is lost
        });
        // Finally, create the handler.
        this.keyHandler = KeyHandler.create(this.name, this.keyBindings);
    }
}
// For all future notifications, check if it is a key press and if we should worry about it.
if (this.keyHandler && this.keyHandler.validate(notification, payload)) { return; }

Receiving Key Presses

When a key is pressed, this module will send a module notification on with the following properties (if the key is not a special key, handled by this module):

notification: "KEYPRESS"
payload: {  currentMode: "DEFAULT",  // "Mode" or "Focus" to respond to
            keyName: "Enter",        // The plain text key name pressed
            keyState: "KEY_PRESSED", // What happened
            sender: "SERVER"         // Source of the input.
            instance: "SERVER"       // Your current instance (Server or Local)
}
Parameter Description
CurrentMode The current "Mode" or "Focus". "DEFAULT" is the default mode. Your module should check the mode and respond appropriately. See Changing Modes below.
keyName The plain text name of the key that was pressed. Remote control keys are normalized to the Standard Keyboard Enumeration where possible.
keyState The type of key press. Options are:
KEY_PRESSED - a normal key press.
KEY_LONGPRESSED - a long key press.
KEY_UP or keyup - key released*
KEY_DOWN or keydown - key pressed* down
KEY_HOLD - a key being held*
* Raw Mode Only
sender The sender either "SERVER" if sent by evdev or a keyboard connected to the server running the mirror; otherwise "LOCAL".
instance The current instance, are you connected to the Mirror directly (SERVER) or are you on a remote web browser (LOCAL)

Changing Focus

A module can request focus or a "Mode" change by sending a notification to request it:

this.keyHandler.focusReceived();

All subsequent key presses will be sent with the new mode. Make sure to release the focus when done by sending a mode change of "DEFAULT" back:

this.keyHandler.releaseFocus();
Clone this wiki locally