How to do it...

  1. Inside of the Chapter_10Editor folder, create a new header file, CookbookCommands.h, and insert the following class declaration:
#pragma once
#include "Commands.h"
#include "EditorStyleSet.h"


class FCookbookCommands : public TCommands<FCookbookCommands>
{
public:
FCookbookCommands()
: TCommands<FCookbookCommands>(
FName(TEXT("UE4_Cookbook")),
FText::FromString("Cookbook Commands"),
NAME_None,
FEditorStyle::GetStyleSetName())
{
};

virtual void RegisterCommands() override;

TSharedPtr<FUICommandInfo> MyButton;

TSharedPtr<FUICommandInfo> MyMenuButton;
};
  1. Implement the new class by placing the following in the .cpp file:
#include "CookbookCommands.h"
#include "Chapter_10Editor.h"
#include "Commands.h"


void FCookbookCommands::RegisterCommands()
{
#define LOCTEXT_NAMESPACE ""
UI_COMMAND(MyButton, "Cookbook", "Demo Cookbook Toolbar Command", EUserInterfaceActionType::Button, FInputGesture());
UI_COMMAND(MyMenuButton, "Cookbook", "Demo Cookbook Toolbar Command", EUserInterfaceActionType::Button, FInputGesture());
#undef LOCTEXT_NAMESPACE
}

  1. Next, we will need to update our module class (Chapter_10Editor.h) to the following:
#pragma once

#include "Engine.h"
#include "Modules/ModuleInterface.h"
#include "Modules/ModuleManager.h"
#include "UnrealEd.h"
#include "CookbookCommands.h"
#include "Editor/MainFrame/Public/Interfaces/IMainFrameModule.h"


class FChapter_10EditorModule: public IModuleInterface
{
virtual void StartupModule() override;
virtual void ShutdownModule() override;

TSharedPtr<FExtender> ToolbarExtender;
TSharedPtr<const FExtensionBase> Extension;

void MyButton_Clicked()
{

TSharedRef<SWindow> CookbookWindow = SNew(SWindow)
.Title(FText::FromString(TEXT("Cookbook Window")))
.ClientSize(FVector2D(800, 400))
.SupportsMaximize(false)
.SupportsMinimize(false);

IMainFrameModule& MainFrameModule =
FModuleManager::LoadModuleChecked<IMainFrameModule>
(TEXT("MainFrame"));

if (MainFrameModule.GetParentWindow().IsValid())
{
FSlateApplication::Get().AddWindowAsNativeChild
(CookbookWindow, MainFrameModule.GetParentWindow()
.ToSharedRef());
}
else
{
FSlateApplication::Get().AddWindow(CookbookWindow);
}

};

void AddToolbarExtension(FToolBarBuilder &builder)
{

FSlateIcon IconBrush =
FSlateIcon(FEditorStyle::GetStyleSetName(),
"LevelEditor.ViewOptions",
"LevelEditor.ViewOptions.Small"); builder.AddToolBarButton(FCookbookCommands::Get()
.MyButton, NAME_None, FText::FromString("My Button"),
FText::FromString("Click me to display a message"),
IconBrush, NAME_None);

};
};

Be sure to #include the header file for your command class as well.

  1. We now need to implement StartupModule and ShutdownModule:
#include "Chapter_10Editor.h" 
#include "Modules/ModuleManager.h"
#include "Modules/ModuleInterface.h"
#include "LevelEditor.h"
#include "SlateBasics.h"
#include "MultiBoxExtender.h"
#include "CookbookCommands.h"

IMPLEMENT_GAME_MODULE(FChapter_10EditorModule, Chapter_10Editor)

void FChapter_10EditorModule::StartupModule()
{

FCookbookCommands::Register();

TSharedPtr<FUICommandList> CommandList = MakeShareable(new FUICommandList());

CommandList->MapAction(FCookbookCommands::Get().MyButton, FExecuteAction::CreateRaw(this, &FChapter_10EditorModule::MyButton_Clicked), FCanExecuteAction());


ToolbarExtender = MakeShareable(new FExtender());

FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked<FLevelEditorModule>( "LevelEditor" );

Extension = ToolbarExtender->AddToolBarExtension("Compile", EExtensionHook::Before, CommandList, FToolBarExtensionDelegate::CreateRaw(this, &FChapter_10EditorModule::AddToolbarExtension));


LevelEditorModule.GetToolBarExtensibilityManager()->AddExtender(ToolbarExtender);


}

void FChapter_10EditorModule::ShutdownModule()
{

ToolbarExtender->RemoveExtension(Extension.ToSharedRef());

Extension.Reset();
ToolbarExtender.Reset();

}
  1. Regenerate your project piles if needed, compile your project from Visual Studio and start the editor.
  2. Verify that there's a new button on the toolbar in the main level editor, which can be clicked on to open a new window: