Wheel UI
Jester Wheel consists of a web-based frontend and offers an API exposed to Lua for modifying its content and reacting to actions.
Frontend
The frontend is a Pixi JS based website defined in
f-4e\ModFolders\Mods\aircraft\F-4E\UI\JesterWheel
Opening index.html in a browser shows the wheel filled with the base content.
The website can be edited freely, changes are visible after reloading DCS (SHIFT+R).
The UI logic, such as animations are defined in renderer.js, while the
interactions are handled in main.js.
interface.js declares the base content of the wheel, as well as all methods
relevant for the C++ to JS communication.
The method hb_send_proxy is used to send commands to C++, such as notifying it
that an action has been clicked.
Lua
The wheel is essentially a menu-tree. Each menu consists of up to 8 items. An item might be final or contain another sub-menu. Additionally, a sub-menu can also be spawned as outer-menu, which increases its item slots to 18.
Each item can be associated with an action, a string that is tied to the Event
System and can hence be reacted to if invoked.
To interact with the menu, several methods are defined and exported to Lua:
Wheel.ReplaceMainMenu(main_menu)
Wheel.ReplaceSubMenu(sub_menu, menu_location)
Wheel.AddItem(item, menu_location)
Wheel.RemoveItem(item_name, menu_location)
Wheel.ReplaceItem(item, item_name, menu_location)
Wheel.RenameItem(new_item_name, current_item_name, menu_location)
Wheel.SetMenuInfo(info_text, menu_location)
Wheel.NavigateTo(menu_location)
The following shows a simple example to add a new sub-menu to the Navigation
menu:
local waypoint_menu = Wheel.Item:new({
  name = "Select Waypoint",
  menu = Wheel.Menu:new({
    name = "Select Waypoint",
    items = {
      Wheel.Item:new({ name = "TGT 1", action = "select_tgt_1" }),
      Wheel.Item:new({ name = "TGT 2", action = "select_tgt_2" }),
      Wheel.Item:new({ name = "Advanced", outer_menu = Wheel.Menu:new({
        name = "More Waypoints",
        items = {
          Wheel.Item:new({ name = "RTB", action = "select_rtb" }),
          Wheel.Item:new({ name = "Nearest Target", action = "select_tgt" }),
        },
      })}),
    }
  }),
})
Wheel.AddItem(waypoint_menu, {"Navigation"})
The info text of the menu can then be updated using
local current_waypoint = "WP 2"
Wheel.SetMenuInfo(current_waypoint, {"Navigation", "Select Waypoint"})
To react to a selected action, listen to the corresponding event:
ListenTo("select_tgt_1", "Navigation", function(task)
  -- Component interface
  task:Click("Nav Panel Function", "TARGET_1")
  -- or Raw interface
  task:Then(function()
    ClickRaw(
      devices.NavigationComputer_AN_ASN_46A,
      device_commands.RIO_NAV_COMP_FUNCTION_SELECTOR_KNOB,
      3,
      5
    ) -- Target 1
  end)
end)