Skip to content

MenuBuilder

Sebastian Gabl edited this page Dec 10, 2020 · 16 revisions

The MenuBuilder automatically builds a mod options menu from a provided settings table and sets up all the needed menu elements and callback functions.
When creating the MenuBuilder, it looks for existing localization in the form of menu_ID_SETTING and menu_ID_SETTING_desc where ID is the id you specified when creating the MenuBuilder and SETTING is the name of the setting in the settings table. The main menu node is using menu_ID and menu_ID_desc. If these localization strings can't be found, the MenuBuilder automatically creates localization strings based on the settings names. Localization strings for menu items of multi-select elements always have to be created manually.

A minimal example usage of the MenuBuilder looks like this:

TestMod = {}
TestMod.settings = {
  toggle = true,
  value = 0
}

local builder = MenuBuilder:new("test_mod", TestMod.settings)
Hooks:Add("MenuManagerBuildCustomMenus", "MenuManagerBuildCustomMenusTestMod", function(menu_manager, nodes)
  builder:create_menu(nodes)
end)

In the above example a new menu will be created in the BLT Mod Options, the setting toggle will turn into a checkbox and the setting value will turn into a slider with a minimum value of 0 and a maximum value of 1. The checkbox will be the first element in the menu.

Customizing settings

You can provide additional settings for creating the menu elements via the optional values argument. This parameter should be a table with keys of same name as the keys in your main settings table and the values for them should be tables containing some information about that specific setting. For settings containing number values, if the table contains an items entry, this is used to make a multi-select menu element instead of the default slider.
You can specify min, max and step for a slider, which will control the minimum and maximum allowed values of that menu element, as well as the step size when the arrow keys are pressed on it. The defaults are min = 0, max = 1 and step = 0.1.
You can also specify the priority for the created menu element of a setting, which determines the sorting of elements. By default, menu elements will be sorted alphabetically by their settings name, you can overwrite that by specifying a priority value.
Lastly, you can add a callback function that is execute whenever that setting is changed by adding the callback key.

Changing the code from the first example:

TestMod = {}
TestMod.settings = {
  toggle = true,
  value = 0
}
TestMod.values ={
  value = {
    items = { "dialog_yes", "dialog_no },
    priority = 99,
    callback = function () log("menu item has been changed") end
  }
}

local builder = MenuBuilder:new("test_mod", TestMod.settings)
Hooks:Add("MenuManagerBuildCustomMenus", "MenuManagerBuildCustomMenusTestMod", function(menu_manager, nodes)
  builder:create_menu(nodes, TestMod.values)
end)

This would result in the value setting turning into a multi-select instead and being displayed as the first element of the menu. The callback function will be called everytime the selection of the multi-select changes.

Sub-Menus

You can create sub-menus by adding table values to your settings table, and specifying some details for the sub-menu via the optional values argument will pass down those values to any child elements in that table and be used as default for them if no other values are specified.

Simple example of a sub-menu with its children elements inheriting values from it:

TestMod.settings = {
  toggle = true,
  submenu = {
    value1 = 0,
    value2 = 0
  }
}
TestMod.values ={
  submenu = {
    items = { "dialog_yes", "dialog_no }
  }
}

local builder = MenuBuilder:new("test_mod", TestMod.settings)
Hooks:Add("MenuManagerBuildCustomMenus", "MenuManagerBuildCustomMenusTestMod", function(menu_manager, nodes)
  builder:create_menu(nodes, TestMod.values)
end)

This will result in a sub-menu with both the value1 and value2 setting turning into a multi-select element.

Saving and loading

Note that you don't have to call the save_settings or load_settings functions manually in most cases. Settings are loaded when the MenuBuilder is created and saved whenever you leave the mod options menu. The functions are there in case you need to save/load data manually for some special usecase.
You can also create the MenuBuilder earlier and store a reference in case you need it to load the settings before the MenuManagerBuildCustomMenus hook is called.

Clone this wiki locally