Skip to content

Custom Action

Material Foundry edited this page Oct 18, 2023 · 1 revision

The Custom Action allows you to fully configure the behavior of a button, either through a macro or from another module.

To use this action, you create a new 'Custom' action and fill in the 'Button Identifier', which can be any value. You then have to register the button.

Button Registration

Hooks.call('MaterialDeck', {
  action: 'custom',
  buttonId: 'your button id',  //Button Id
  text: 'Initial text',        //(Optional) Text to display immediately after registering
  icon: 'initialImage.png',    //(Optional) Icon to display immediately after registering
  options,                     //(Optional) Icon options, see below
  keyUp: keyUpCallback,        //(Optional) Function to call on a key up event
  keyDown: keyDownCallback,    //(Optional) Function to call on a key down event
  appear: appearCallback,      //(Optional) Function to call when the button appears
  disappear: disappearCallback //(Optional) Function to call when the button disappears
});

Icon Options

You have the following options to configure the button icon, all of them are optional:

const options = {
  background: '#FF0000', //Background color
  ring: 0,               //Ring display mode, see below
  ringColor: '#00FF00',  //Ring color
  overlay: false,        //Overlay enabled, see below
  uses: {
    available: 2,        //Available uses, see below
    maximum: 4           //Maximum uses, see below
  }
}

Ring

'Ring' is a colored band around the icon which can be used to, for example, indicate if something is on or off.
Whenever the ring is enabled, the displayed icon is made slightly smaller to fit within the ring.
There are 3 modes:

  1. No ring displayed, icon fills the button
  2. No ring displayed, but icon is shrunk to make space for the ring
  3. Ring displayed, icon is shrunk and 'ringColor' sets the color of the ring

Overlay

Enabling 'overlay' adds a gray overlay over the icon, which can be helpful to make text visible over bright icons.

Uses

The uses option adds a box to the bottom of the button that can be used to display any numerical value.
If a maximum is defined, the available uses will be displayed as a fraction of that maximum, for example: 4/10.

Callback Functions

Callback functions are functions that are called whenever the specified event occurs.
There are 4 events for which you can register a callback function, all of them are optional:

  • keyDown: Called when a button is pressed down
  • keyUp: Called when a button is released
  • appear: Called when a button appears (for example if a folder or profile is changed)
  • disappear: Called when a button disappears (for example if a folder or profile is changed)

All functions for all buttons share the same scope which can be accessed as a function parameter.
This scope can be used to define variables:

const keyDownCallback = function(scope) {
  scope.myVariable = 10;
}

You can use these variables within the same or different callback functions:

const keyUpCallback = function(scope) {
  console.log('myVariable', scope.myVariable);
}

Within the callback functions you can set the button icon or text:

scope.setText('Key Up');
scope.setIcon('pathToIcon.png', options);

Example

The example below demonstrates a wide range of things you can do with the custom action.
A different icon and text will be displayed when the icon is registered, appears, is pressed down or is released.
Additionally, it demonstrates registering a variable and counting this value up with every button press and displaying it in the 'uses' box.

This example can be ran as a 'script macro' and requires the buttonId to be set to 'example'.

const keyUpCallback = function(scope) {
  if (!scope.counter) scope.counter = 0;
  scope.counter++;
  if (scope.counter > 10) scope.counter = 1;

  const options = {
    background: '#228822',
    ringColor: '#00FF00',
    uses: {
      available: scope.counter,
      maximum: 10
    }
  };
  scope.setText('Key Up');
  scope.setIcon('modules/MaterialDeck/img/move/up.png', options);
}

const keyDownCallback = function(scope) {
  const options = {
    background: '#22FF22',
    ringColor: '#FF0000'
  }
  scope.setText('Key Down');
  scope.setIcon('modules/MaterialDeck/img/move/down.png', options);
}

const appearCallback = function(scope) {
  const options = {
    background: '#0000FF'
  }
  scope.counter = 0;
  scope.setText('Appear');
  scope.setIcon('modules/MaterialDeck/img/move/center.png', options);
}

const disappearCallback = function(scope) {
  console.log('Disappear');
}

Hooks.call('MaterialDeck', {
  action: 'custom',
  buttonId: 'example',
  text: 'Register',
  icon: 'modules/MaterialDeck/img/other/cogs.png',
  options: {
    background: '#666666',
    ring: 2,
    ringColor: '#FF0000',
    uses: {
      available: 0,
      maximum: 10
    }
  },
  keyUp: keyUpCallback,
  keyDown: keyDownCallback,
  appear: appearCallback,
  disappear: disappearCallback
});
Clone this wiki locally