Files
enigma-bbs/docs/_docs/modding/menu-modules.md
2022-08-08 22:19:20 -06:00

128 lines
3.8 KiB
Markdown

---
layout: page
title: Menu Modules
---
## Menu Modules
From initial connection to the screens and mods your users interact with, the entire experience is made up of menu entries — And all menu entries found within `menu.hjson` are backed by *Menu Modules*. For basic menus, a standard handler is implemented requiring no code. However, if you would like to create a menu that has custom handling, you will very likely be inheriting from from `MenuModule`. More on this below.
> :information_source: Remember that ENiGMA does not impose any stucture to your system! The "flow" of all `menu.hjson` entries is up to you!
> :bulb: If the `module` entry is not present in a `menu.hjson` entry, the system automatically uses [standard_menu.js](/core/standard_menu.js).
## Creating a New Module
At the highest level, to create a new custom menu or mod, inherit from `MenuModule` and expose it via the `getModule` exported method:
```javascript
// my_fancy_module.js
exports.getModule = class MyFancyModule extends MenuModule {
constructor(options) {
super(options);
}
};
```
Next, override the appropriate methods to add some functionality! Below is an example fragment overriding just `initSequence()`:
```javascript
initSequence() {
async.series(
[
callback => {
// call base method
return this.beforeArt(callback);
},
callback => {
// a private method to display a main "page"
return this._displayMainPage(false, callback);
},
],
() => {
this.finishedLoading();
}
);
}
```
## ModuleInfo
To register your module with the system, include a `ModuleInfo` declaration in your exports:
```javascript
exports.ModuleInfo = {
name: 'Super Dope Mod',
desc: '...a super dope mod, duh.',
author: 'You!',
};
```
## Lifecycle
Below is a very high level diagram showing the basic lifecycle of a menu.
![Basic Menu Lifecycle](../../assets/images/basic_menu_lifecycle.png)
Methods indicated above with `()` in their name such as `enter()` are overridable when inheriting form `MenuModule`.
## MenuModule Helper Methods
Many helper methods exist and are available to code inheriting from `MenuModule`. Below are some examples. Poke around at [menu_module.js](../../../core/menu_module.js) to discover more!
### Views & View Controller
* `displayAsset()`
* `prepViewController()`
* `prepViewControllerWithArt()`
* `displayArtAndPrepViewController()`
* `setViewText()`
* `getView()`
* `updateCustomViewTextsWithFilter()`
* `refreshPredefinedMciViewsByCode()`
### Validation
* `validateMCIByViewIds()`
* `validateConfigFields()`
### Date/Time Helpers
The following methods take a single input to specify style, defaulting to `short`:
* `getDateFormat()`
* `getTimeFormat()`
* `getDateTimeFormat()`
### Misc
* `promptForInput()`
`standardMCIReadyHandler()`: This is a standard and commonly used `mciReady()` implemenation:
```javascript
mciReady(mciData, cb) {
return this.standardMCIReadyHandler(mciData, cb);
}
```
> :information_source: Search the code for the above methods to see how they are used in the base system!
## Menu Methods
Form handler methods specified by `@method:someName` in your `menu.hjson` entries map to those found in your module's `menuMethods` object. That is, `this.menuMethods` and have the following signature `(formData, extraArgs, cb)`. For example, consider the following `menu.hjson` fragment:
```hjson
actionKeys: [
{
keys: [ "a", "shift + a" ]
action: @method:toggleAvailable
}
]
```
We can handle this in our module as such:
```javascript
exports.getModule = class MyFancyModule extends MenuModule {
constructor(options) {
super(options);
this.menuMethods = {
toggleAvailable: (formData, extraArgs, cb) => {
// ...do something fancy...
return cb(null);
}
};
}
}
```