Menus¶
Architecture¶


Usage¶
Create a menu¶
There are several ways to create a menu :
Create a menu by registering it
Create an extended version of an already existing menu
Create a SubMenu to an existing menu
Note
Creating an extended version of a menu, does not mean the original menu will be changed. It only means the created menu will be based on the original menu and inherit its sections and entries.
Create a registered menu
UToolMenu* menu = UToolMenus::Get()->RegisterMenu("newMenuID");
Create an extended version of a menu
UToolMenu* menu = UToolMenus::Get()->RegisterMenu("newMenuID", "menuToExtendID");
Create a SubMenu
// Add a "My Menu" sub menu in parentMenu
UToolMenu* menu = parentMenu->AddSubMenu(
iOwner, //The Owner
NAME_None, //The name of the section to create in the submenu, usually none, as section are created explicitly later
myMenuID, //The ID of the menu
LOCTEXT("MyMenu", "My Menu"), //The name to display for this menu
LOCTEXT("MyMenu_ToolTip", "Open my menu") //The Tooltip to display for this menu
);
Retrieve a Menu¶
Retrieve a menu
//Retrieve the menu
UToolMenu* menu = UToolMenus::Get()->FindMenu(menuID);
Add a Section¶
Retrieve a menu
// Add a "My Section" section to menu
FToolMenuSection& section = menu->AddSection("MySection", LOCTEXT("MySection", "My Section"));
Retrieve a Section¶
Retrieve a menu
// Find a section with the ID "MySection" in menu
FToolMenuSection* section = menu->FindSection("MySection");
Add an Entry¶
There are several ways to add an entry depending on what you need :
Add a FUICommand entry to a menu
// Add an entry relying on the "MyCommand" command from "FMyCommands"
// The entry will use the name, tooltip, icon, etc... of the command
section->AddMenuEntry(FMyCommands::Get().MyCommand);
//Alternatively, you can also override the name, tooltip and icon of the command for this entry
section->AddMenuEntry(
FMyCommands::Get().MyCommand
, LOCTEXT("MyCustomCommand", "My Custom Command")
, LOCTEXT("MyCustomCommand_Tooltip", "My Custom Command Tooltip")
, FSlateIcon("MyStyle", "MyIcon")
, NAME_None
);
Add a function entry to a menu
// Add a "My Entry" entry relying on a function
section->AddMenuEntry(
"MyEntry", //An ID for the entry
LOCTEXT("MyEntry", "My Entry"), //A Label to display
LOCTEXT("MyEntry_Tooltip", "My Entry Tooltip"), //A Tooltip to display
FSlateIcon("MyStyle", "MyIcon"), //An Icon to Display
FExecuteAction::CreateLambda([]()
{
//The action to execute
}
),
EUserInterfaceActionType::Button, //The Action Type of the entry (usually Button, but there is athoer usefull action types)
NAME_None //An ID for a tutorial to rely on (usually not needed)
);
// Alternatively, you can define even more options for the action, like when it should be executable, when its checkbox should be checked, is it visible, etc....
section->AddMenuEntry(
"MyEntry", //An ID for the entry
LOCTEXT("MyEntry", "My Entry"), //A Label to display
LOCTEXT("MyEntry_Tooltip", "My Entry Tooltip"), //A Tooltip to display
FSlateIcon("MyStyle", "MyIcon"), //An Icon to Display
FUIAction(
FExecuteAction::CreateLambda([]()
{
//The action to execute
}
),
FCanExecuteAction::CreateLambda([]()
{
return false; //action is greyed out
}
),
FIsActionChecked::CreateLambda([]()
{
return true; //entry is checked
}
),
FIsActionButtonVisible::CreateLambda([]()
{
return true; //entry is visible
}
)
),
EUserInterfaceActionType::Button, //The Action Type of the entry (usually Button, but there is athoer usefull action types)
NAME_None //An ID for a tutorial to rely on (usually not needed)
);
Add entries dynamically under some conditions
// Add a "My Entry" entry, only if the given condition is true
section->AddDynamicEntry("MyDynamicEntry", FNewToolMenuSectionDelegate::CreateLambda([](FToolMenuSection& iSection)
{
if (condition)
{
iSection.AddMenuEntry(FMyCommands::Get().MyCommand);
}
}));
Advanced¶
Owner¶
Owner
.Owner
of a menu is not the parent menu, it is another concept.Owner
parameter of a menu.Owner
can be provided to several menus.Owner
of a menu, it allows you to identify menus you want to be able to unregister later using a single call to UToolMenus::UnregisterOwner(Owner)
.Owner
does not change the behaviour of a Menu.Owner
parameter can take several forms :a String
a Number
a Pointer (the pointer can point to anything, it is the value of the pointer which is important, not what it is pointing)
Here is a simple example of how to use it:
Owner usage on a SubMenu
//somewhere in your code, create a submenu with an owner
{
// ...
mainMenu->AddSubMenu(
"MyOwner", //The Owner
NAME_None,
id,
LOCTEXT("MyMenu", "My Menu"),
LOCTEXT("MyMenu_ToolTip", "Open my menu")
);
//...
}
//somewhere else in your code, unregister the menus
{
// ...
UToolMenus::UnregisterOwner("MyOwner");
//...
}
Unreal Engine also provides an scoped way to provide an owner when registering menus. This should certainly be the main way to set the Owner property.
Scoped Owner usage
//somewhere in your code, create a submenu with an owner
void
function1()
{
//Every menu in this scope will use this owner
FToolMenuOwnerScoped scopedOwner("MyOwner1");
//Create a menu which will automatically have the MyOwner1 owner
UToolMenu* menu1 = UToolMenus::Get()->RegisterMenu("MyMenu1");
//Add a SubMenu using the scopedOwner
menu1->AddSubMenu(
scopedOwner.GetOwner(), //use the scoped Owner
NAME_None,
"MyMenu2",
LOCTEXT("MyMenu2", "My Menu 2"),
LOCTEXT("MyMenu2_ToolTip", "Open my menu 2")
);
//Call function2, which will also add some menus and submenus
function2();
//menu7 will still have the MyOwner1 as its owner, even if function2 creates a scoped owner
//because menu7 is outside of function2 scope.
UToolMenu* menu7 = UToolMenus::Get()->RegisterMenu("MyMenu7");
}
void
function2()
{
//Create a menu which will automatically have the MyOwner1 owner
UToolMenu* menu3 = UToolMenus::Get()->RegisterMenu("MyMenu3");
//Add a SubMenu using the scopedOwner
menu3->AddSubMenu(
UToolMenus::Get()->CurrentOwner(), //Current Owner will be MyOwner1
NAME_None,
"MyMenu4",
LOCTEXT("MyMenu4", "My Menu 4"),
LOCTEXT("MyMenu4_ToolTip", "Open my menu 4")
);
//Every menu in this scope will use this owner
FToolMenuOwnerScoped scopedOwner("MyOwner2");
//Create a menu which will automatically have the MyOwner2 owner
UToolMenu* menu3 = UToolMenus::Get()->RegisterMenu("MyMenu5");
//Add a SubMenu using the scopedOwner
menu3->AddSubMenu(
UToolMenus::Get()->CurrentOwner(), //Current Owner will be MyOwner2
NAME_None,
"MyMenu6",
LOCTEXT("MyMenu6", "My Menu 6"),
LOCTEXT("MyMenu6_ToolTip", "Open my menu 6")
);
}
Customized Menu¶
Unreal Engine also includes a system to add custommized menus, which are menus, sections and entries you can fully control, from their behaviour to their aspect.
Todo
This section needs more informations. Right now it is here to let you know it exists, but no one had to dive into this, so there is no informations about it.