[Plugin] Extending Designer with new widgets

I would like to create a plugin that extends the available widgets in the Designer view, but I don’t know how to tell the engine about my widgets. I would like to add my own buttons, views, etc., as items that can be visually dropped in and moved, edited, etc.

I’ve read the docs on Slate and Plugins, and found a lot of sample code. I have a project that will register a toolbar button that I found and am using as a starting point, included below in case it is a good starting point.

GWCommands.h



#pragma once
#include "SlateBasics.h"
#include "EditorStyleSet.h"


class FGWCommands : public TCommands<FGWCommands>
{
public:

    FGWCommands()
        : TCommands<FGWCommands>
        (
            TEXT("GUIWidgets"),
            NSLOCTEXT("Contexts", "GWPlugin", "GWPlugin"),
            NAME_None,
            FEditorStyle::GetStyleSetName()
            ) {}

    virtual void RegisterCommands() override;

public:

    TSharedPtr<FUICommandInfo> TestCommand;
};


GWCommands.cpp



#include "GWCommands.h"
#include "GUIWidgets.h"

#define LOCTEXT_NAMESPACE "FGWCommands"

void FGWCommands::RegisterCommands()
{
    UI_COMMAND(TestCommand, "TestCommand", "This is test command", EUserInterfaceActionType::Button, FInputGesture());
}

#undef LOCTEXT_NAMESPACE


GUIWidgets.h



// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.

#pragma once
#include "Modules/ModuleManager.h"
#include "Slate/Public/Framework/Commands/UIAction.h"

class FToolBarBuilder;
class FMenuBuilder;
class FReply;
class SWidget;

class FGUIWidgetsModule : public IModuleInterface
{
public:

    /** IModuleInterface implementation */
    virtual void StartupModule() override;
    virtual void ShutdownModule() override;

private:

    TSharedPtr<class FUICommandList> PluginCommands;

    void AddToolbarButton(FToolBarBuilder& Builder);
    //void AddMenuEntry(FMenuBuilder& MenuBuilder);
    //void FillSubmenu(FMenuBuilder& MenuBuilder);

    //TSharedRef<SWidget> FillComboButton(TSharedPtr<class FUICommandList> Commands);

    void TestAction();

};


GUIWidgets.cpp



// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.

#include "GUIWidgets.h"
#include "GWCommands.h"
#include "LevelEditor.h"

#define LOCTEXT_NAMESPACE "FGUIWidgetsModule"

void FGUIWidgetsModule::StartupModule()
{
    FGWCommands::Register();

    PluginCommands = MakeShareable(new FUICommandList);
    PluginCommands->MapAction(
        FGWCommands::Get().TestCommand,
        FExecuteAction::CreateRaw(this, &FGUIWidgetsModule::TestAction)
    );

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

    {
        TSharedPtr<FExtender> NewToolbarExtender = MakeShareable(new FExtender);
        /**
         * Extends a tool bar at the specified extension point
         *
         * @param    ExtensionHook            Part of the menu to extend.  You can extend the same point multiple times, and extensions will be applied in the order they were registered.
         * @param    HookPosition            Where to apply hooks in relation to the extension hook
         * @param    CommandList                The UI command list responsible for handling actions for the toolbar items you'll be extending the menu with
         * @param    ToolbarExtensionDelegate    Called to populate the part of the toolbar you're extending
         *
         * @return    Pointer to the new extension object.  You can use this later to remove the extension.
         */
        NewToolbarExtender->AddToolBarExtension("Content",
            EExtensionHook::Before,
            PluginCommands,
            FToolBarExtensionDelegate::CreateRaw(this, &FGUIWidgetsModule::AddToolbarButton));
        LevelEditorModule.GetToolBarExtensibilityManager()->AddExtender(NewToolbarExtender);
    }
}

void FGUIWidgetsModule::ShutdownModule()
{
    FGWCommands::Unregister();
}

void FGUIWidgetsModule::AddToolbarButton(FToolBarBuilder& Builder)
{
    Builder.AddToolBarButton(FGWCommands::Get().TestCommand);
}

void FGUIWidgetsModule::TestAction()
{
    UE_LOG(LogTemp, Warning, TEXT("It Works!!!"));
}

#undef LOCTEXT_NAMESPACE

IMPLEMENT_MODULE(FGUIWidgetsModule, GUIWidgets)


I Figured it out. The following project files add a skeleton GWButton to the GUIWidgets category in the Designer Palette tab.

GWButton.h



// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Components/ContentWidget.h"
#include "GWButton.generated.h"

/**
 * The GWButton.
 *
 * * Single Child
 * * Clickable
 */
UCLASS()
class GUIWIDGETS_API UGWButton : public UContentWidget
{
    GENERATED_BODY()

public:

#if WITH_EDITOR
    virtual const FText GetPaletteCategory() override;
#endif

};


GWButton.cpp



#include "GWButton.h"

#if WITH_EDITOR
#undef LOCTEXT_NAMESPACE
#define LOCTEXT_NAMESPACE "FGUIWidgetsModule"

const FText UGWButton::GetPaletteCategory()
{
    return LOCTEXT("GUIWidgets", "GUIWidgets");
}
#endif