void FSoundCueEditor::ExtendToolbar()
{
	struct Local
{
		static void FillToolbar(FToolBarBuilder& ToolbarBuilder)
		{
			ToolbarBuilder.BeginSection("Toolbar");
			{
				ToolbarBuilder.AddToolBarButton(FSoundCueGraphEditorCommands::Get().PlayCue);

				ToolbarBuilder.AddToolBarButton(FSoundCueGraphEditorCommands::Get().PlayNode);

				ToolbarBuilder.AddToolBarButton(FSoundCueGraphEditorCommands::Get().StopCueNode);
			}
			ToolbarBuilder.EndSection();
		}
	};

	TSharedPtr<FExtender> ToolbarExtender = MakeShareable(new FExtender);

	ToolbarExtender->AddToolBarExtension(
		"Asset",
		EExtensionHook::After,
		GetToolkitCommands(),
		FToolBarExtensionDelegate::CreateStatic( &Local::FillToolbar )
		);

	AddToolbarExtender(ToolbarExtender);

	ISoundCueEditorModule* SoundCueEditorModule = &FModuleManager::LoadModuleChecked<ISoundCueEditorModule>( "SoundCueEditor" );
	AddToolbarExtender(SoundCueEditorModule->GetToolBarExtensibilityManager()->GetAllExtenders(GetToolkitCommands(), GetEditingObjects()));
}
void FSubstanceEditor::ExtendToolbar()
{
	struct Local
	{
		static void FillToolbar(FToolBarBuilder& ToolbarBuilder)
		{
			ToolbarBuilder.BeginSection("Reset to default values.");
			{
				ToolbarBuilder.AddToolBarButton(FSubstanceEditorCommands::Get().ResetDefaultValues);
			}
			ToolbarBuilder.EndSection();

			ToolbarBuilder.BeginSection("Presets");
			{
				ToolbarBuilder.AddToolBarButton(FSubstanceEditorCommands::Get().ExportPreset);
				ToolbarBuilder.AddToolBarButton(FSubstanceEditorCommands::Get().ImportPreset);
			}
			ToolbarBuilder.EndSection();
		}
	};

	TSharedPtr<FExtender> ToolbarExtender = MakeShareable(new FExtender);
	ToolbarExtender->AddToolBarExtension(
		"Asset",
		EExtensionHook::After,
		GetToolkitCommands(),
		FToolBarExtensionDelegate::CreateStatic(&Local::FillToolbar)
		);

	AddToolbarExtender(ToolbarExtender);

	ISubstanceEditorModule* SubstanceEditorModule = &FModuleManager::LoadModuleChecked<ISubstanceEditorModule>("SubstanceEditor");
	AddToolbarExtender(SubstanceEditorModule->GetToolBarExtensibilityManager()->GetAllExtenders());
}
void FSkeletonEditor::ExtendToolbar()
{
	// If the ToolbarExtender is valid, remove it before rebuilding it
	if (ToolbarExtender.IsValid())
	{
		RemoveToolbarExtender(ToolbarExtender);
		ToolbarExtender.Reset();
	}

	ToolbarExtender = MakeShareable(new FExtender);

	AddToolbarExtender(ToolbarExtender);

	ISkeletonEditorModule& SkeletonEditorModule = FModuleManager::GetModuleChecked<ISkeletonEditorModule>("SkeletonEditor");
	AddToolbarExtender(SkeletonEditorModule.GetToolBarExtensibilityManager()->GetAllExtenders(GetToolkitCommands(), GetEditingObjects()));

	TArray<ISkeletonEditorModule::FSkeletonEditorToolbarExtender> ToolbarExtenderDelegates = SkeletonEditorModule.GetAllSkeletonEditorToolbarExtenders();

	for (auto& ToolbarExtenderDelegate : ToolbarExtenderDelegates)
	{
		if (ToolbarExtenderDelegate.IsBound())
		{
			AddToolbarExtender(ToolbarExtenderDelegate.Execute(GetToolkitCommands(), SharedThis(this)));
		}
	}

	// extend extra menu/toolbars
	struct Local
	{
		static void ExtendToolbar(FToolBarBuilder& ToolbarBuilder)
		{
			ToolbarBuilder.BeginSection("Skeleton");
			{
				ToolbarBuilder.AddToolBarButton(FSkeletonEditorCommands::Get().AnimNotifyWindow);
				ToolbarBuilder.AddToolBarButton(FSkeletonEditorCommands::Get().RetargetManager, NAME_None, LOCTEXT("Toolbar_RetargetManager", "Retarget Manager"));
				ToolbarBuilder.AddToolBarButton(FSkeletonEditorCommands::Get().ImportMesh);
			}
			ToolbarBuilder.EndSection();
		}
	};

	ToolbarExtender->AddToolBarExtension(
		"Asset",
		EExtensionHook::After,
		GetToolkitCommands(),
		FToolBarExtensionDelegate::CreateStatic(&Local::ExtendToolbar)
		);

	ToolbarExtender->AddToolBarExtension(
		"Asset",
		EExtensionHook::After,
		GetToolkitCommands(),
		FToolBarExtensionDelegate::CreateLambda([this](FToolBarBuilder& ParentToolbarBuilder)
		{
			FPersonaModule& PersonaModule = FModuleManager::LoadModuleChecked<FPersonaModule>("Persona");
			TSharedRef<class IAssetFamily> AssetFamily = PersonaModule.CreatePersonaAssetFamily(Skeleton);
			AddToolbarWidget(PersonaModule.CreateAssetFamilyShortcutWidget(SharedThis(this), AssetFamily));
		}	
	));
}
void FNiagaraEditor::ExtendToolbar()
{
	struct Local
	{
		static void FillToolbar(FToolBarBuilder& ToolbarBuilder, TSharedRef<SWidget> CompileBox)
		{
			ToolbarBuilder.BeginSection("Compile");
			{
				ToolbarBuilder.AddWidget(CompileBox);
			}
			ToolbarBuilder.EndSection();
		}
	};

	TSharedPtr<FExtender> ToolbarExtender = MakeShareable(new FExtender);

	TSharedRef<SWidget> Compilebox = SNew(SHorizontalBox)
		+SHorizontalBox::Slot()
		.AutoWidth()
		.Padding(4)
		[
			SNew(SButton)
			.OnClicked(this, &FNiagaraEditor::OnCompileClicked)
			.Content()
			[
				SNew(SVerticalBox)
				+SVerticalBox::Slot()
				.AutoHeight()
				[
					SNew(SImage)
					.Image(FEditorStyle::GetBrush("LevelEditor.Recompile"))
				]
				+SVerticalBox::Slot()
				.AutoHeight()
				[
					SNew(STextBlock)
					.Text(LOCTEXT("NiagaraToolbar_Compile", "Compile"))
				]
			]
		];

	ToolbarExtender->AddToolBarExtension(
		"Asset",
		EExtensionHook::After,
		GetToolkitCommands(),
		FToolBarExtensionDelegate::CreateStatic( &Local::FillToolbar, Compilebox )
		);

	AddToolbarExtender(ToolbarExtender);

	FNiagaraEditorModule& NiagaraEditorModule = FModuleManager::LoadModuleChecked<FNiagaraEditorModule>( "NiagaraEditor" );
	AddToolbarExtender(NiagaraEditorModule.GetToolBarExtensibilityManager()->GetAllExtenders(GetToolkitCommands(), GetEditingObjects()));
}
void FCurveAssetEditor::InitCurveAssetEditor( const EToolkitMode::Type Mode, const TSharedPtr< class IToolkitHost >& InitToolkitHost, UCurveBase* CurveToEdit )
{	
	TSharedRef<FTabManager::FLayout> StandaloneDefaultLayout = FTabManager::NewLayout( "Standalone_CurveAssetEditor_Layout" )
	->AddArea
	(
		FTabManager::NewPrimaryArea()
		->SetOrientation(Orient_Vertical)
		->Split
		(
			FTabManager::NewStack()
			->SetSizeCoefficient(0.1f)
			->SetHideTabWell( true )
			->AddTab(GetToolbarTabId(), ETabState::OpenedTab)
		) 
		->Split
		(
			FTabManager::NewStack()
			->SetHideTabWell( true )
			->AddTab( CurveTabId, ETabState::OpenedTab )
		)
	);

	const bool bCreateDefaultStandaloneMenu = true;
	const bool bCreateDefaultToolbar = true;
	FAssetEditorToolkit::InitAssetEditor( Mode, InitToolkitHost, FCurveAssetEditorModule::CurveAssetEditorAppIdentifier, StandaloneDefaultLayout, bCreateDefaultStandaloneMenu, bCreateDefaultToolbar, CurveToEdit );
	
	FCurveAssetEditorModule& CurveAssetEditorModule = FModuleManager::LoadModuleChecked<FCurveAssetEditorModule>( "CurveAssetEditor" );
	AddMenuExtender(CurveAssetEditorModule.GetMenuExtensibilityManager()->GetAllExtenders(GetToolkitCommands(), GetEditingObjects()));
	AddToolbarExtender(GetToolbarExtender());

	// @todo toolkit world centric editing
	/*// Setup our tool's layout
	if( IsWorldCentricAssetEditor() )
	{
		const FString TabInitializationPayload(TEXT(""));		// NOTE: Payload not currently used for table properties
		SpawnToolkitTab( CurveTabId, TabInitializationPayload, EToolkitTabSpot::Details );
	}*/

	if (TrackWidget.IsValid())
	{
		RegenerateMenusAndToolbars();
	}
}
	void Open(const TArray<UObject*>& InObjects, TSharedPtr<IToolkitHost> EditWithinLevelEditor)
	{
		Context = InObjects[0];

		const EToolkitMode::Type Mode = EditWithinLevelEditor.IsValid() ? EToolkitMode::WorldCentric : EToolkitMode::Standalone;

		if (Outer->Commands)
		{
			Outer->Commands->Bind(&(GetToolkitCommands().Get()));
		}
				
		TSharedPtr<FTabManager::FLayout> StandaloneDefaultLayout = FTabManager::FLayout::NewFromString(Outer->Layout.Replace(TEXT("#toolbartab"), *(GetToolbarTabId().ToString())));

		// Initialize the asset editor and spawn nothing (dummy layout)
		InitAssetEditor(Mode, EditWithinLevelEditor, Outer->ToolkitFName, StandaloneDefaultLayout.ToSharedRef(), /*bCreateDefaultStandaloneMenu=*/ true, /*bCreateDefaultToolbar=*/ true, InObjects);

		if (Outer->MenuExtender)
		{
			auto Extender = Outer->MenuExtender->TakeMenuExtender(GetToolkitCommands());
			if (Extender.IsValid())
			{
				AddMenuExtender(Extender);
			}
		}

		if (Outer->ToolbarExtender)
		{
			auto Extender = Outer->ToolbarExtender->TakeToolbarExtender(GetToolkitCommands());
			if (Extender.IsValid())
			{
				AddToolbarExtender(Extender);
			}
		}

		RegenerateMenusAndToolbars();
	}
/**
 * Builds the Matinee Tool Bar
 */
void FMatinee::ExtendToolbar()
{
    struct Local
    {
        static void FillToolbar(FToolBarBuilder& ToolbarBuilder, TSharedRef<SWidget> InterpolationBox, TSharedRef<SWidget> SpeedBox, TSharedRef<SWidget> SnapSettingBox)
        {
            ToolbarBuilder.BeginSection("CurveMode");
            {
                ToolbarBuilder.AddToolBarButton(FMatineeCommands::Get().AddKey);
            }
            ToolbarBuilder.EndSection();

            ToolbarBuilder.BeginSection("Interpolation");
            {
                ToolbarBuilder.AddWidget(InterpolationBox);
            }
            ToolbarBuilder.EndSection();

            ToolbarBuilder.BeginSection("Play");
            {
                ToolbarBuilder.AddToolBarButton(FMatineeCommands::Get().Play);
                ToolbarBuilder.AddToolBarButton(FMatineeCommands::Get().PlayLoop);
                ToolbarBuilder.AddToolBarButton(FMatineeCommands::Get().Stop);
                ToolbarBuilder.AddToolBarButton(FMatineeCommands::Get().PlayReverse);
            }
            ToolbarBuilder.EndSection();

            ToolbarBuilder.BeginSection("Camera");
            {
                ToolbarBuilder.AddToolBarButton(FMatineeCommands::Get().CreateCameraActor);
            }
            ToolbarBuilder.EndSection();

            ToolbarBuilder.BeginSection("Speed");
            {
                ToolbarBuilder.AddWidget(SpeedBox);
            }
            ToolbarBuilder.EndSection();

            //ToolbarBuilder.BeginSection("History");
            //{
            //	ToolbarBuilder.AddToolBarButton(FMatineeCommands::Get().Undo);
            //	ToolbarBuilder.AddToolBarButton(FMatineeCommands::Get().Redo);
            //}
            //ToolbarBuilder.EndSection();

            ToolbarBuilder.BeginSection("SnapSetting");
            {
                ToolbarBuilder.AddWidget(SnapSettingBox);
            }
            ToolbarBuilder.EndSection();

            ToolbarBuilder.BeginSection("Curve");
            {
                ToolbarBuilder.AddToolBarButton(FMatineeCommands::Get().ToggleCurveEditor);
            }
            ToolbarBuilder.EndSection();

            ToolbarBuilder.BeginSection("Snap");
            {
                ToolbarBuilder.AddToolBarButton(FMatineeCommands::Get().ToggleSnap);
                ToolbarBuilder.AddToolBarButton(FMatineeCommands::Get().ToggleSnapTimeToFrames);
                ToolbarBuilder.AddToolBarButton(FMatineeCommands::Get().FixedTimeStepPlayback);
            }
            ToolbarBuilder.EndSection();

            ToolbarBuilder.BeginSection("View");
            {
                ToolbarBuilder.AddToolBarButton(FMatineeCommands::Get().FitSequence);
                ToolbarBuilder.AddToolBarButton(FMatineeCommands::Get().FitViewToSelected);
                ToolbarBuilder.AddToolBarButton(FMatineeCommands::Get().FitLoop);
                ToolbarBuilder.AddToolBarButton(FMatineeCommands::Get().FitLoopSequence);
                ToolbarBuilder.AddToolBarButton(FMatineeCommands::Get().ViewEndofTrack);
            }
            ToolbarBuilder.EndSection();

            ToolbarBuilder.BeginSection("Record");
            {
                ToolbarBuilder.AddToolBarButton(FMatineeCommands::Get().LaunchRecordWindow);
                ToolbarBuilder.AddToolBarButton(FMatineeCommands::Get().CreateMovie);
            }
            ToolbarBuilder.EndSection();
        }
    };

    TSharedPtr<FExtender> ToolbarExtender = MakeShareable(new FExtender);

    InitialInterpModeStrings.Empty();
    InitialInterpModeStrings.Add( MakeShareable( new FString(NSLOCTEXT("Matinee", "Linear", "Linear").ToString()) ) );
    InitialInterpModeStrings.Add( MakeShareable( new FString(NSLOCTEXT("Matinee", "CurveAuto", "CurveAuto").ToString()) ) );
    InitialInterpModeStrings.Add( MakeShareable( new FString(NSLOCTEXT("Matinee", "Constant", "Constant").ToString()) ) );
    InitialInterpModeStrings.Add( MakeShareable( new FString(NSLOCTEXT("Matinee", "CurveUser", "CurveUser").ToString()) ) );
    InitialInterpModeStrings.Add( MakeShareable( new FString(NSLOCTEXT("Matinee", "CurveBreak", "CurveBreak").ToString()) ) );
    InitialInterpModeStrings.Add( MakeShareable( new FString(NSLOCTEXT("Matinee", "CurveAutoClamped", "CurveAutoClamped").ToString()) ) );

    InitialInterpModeComboBox =
        SNew( STextComboBox )
        .OptionsSource(&InitialInterpModeStrings)
        .InitiallySelectedItem(InitialInterpModeStrings[0])
        .OnSelectionChanged(this, &FMatinee::OnChangeInitialInterpMode)
        .ToolTipText(NSLOCTEXT("Matinee", "ToolTipInitialInterp", "Initial Interp Mode | Selects the curve interpolation mode for newly created keys"))
        ;

    TSharedRef<SWidget> InterpolationBox =
        SNew(SBox)
        .WidthOverride(150)
        [
            SNew(SVerticalBox)
            +SVerticalBox::Slot()
            .Padding(4)
            [
                SNew(STextBlock)
                .Text(NSLOCTEXT("Matinee.Toolbar", "InterpMode", "Interpolation:"))
                .Visibility( this, &FMatinee::GetLargeIconVisibility )
            ]
            +SVerticalBox::Slot()
            .AutoHeight()
            .Padding(4,0)
            [
                InitialInterpModeComboBox.ToSharedRef()
            ]
        ];

    SpeedSettingStrings.Empty();
    SpeedSettingStrings.Add( MakeShareable( new FString(NSLOCTEXT("UnrealEd", "FullSpeed", "100%").ToString()) ) );
    SpeedSettingStrings.Add( MakeShareable( new FString(NSLOCTEXT("UnrealEd", "50Speed", "50%").ToString()) ) );
    SpeedSettingStrings.Add( MakeShareable( new FString(NSLOCTEXT("UnrealEd", "25Speed", "25%").ToString()) ) );
    SpeedSettingStrings.Add( MakeShareable( new FString(NSLOCTEXT("UnrealEd", "10Speed", "10%").ToString()) ) );
    SpeedSettingStrings.Add( MakeShareable( new FString(NSLOCTEXT("UnrealEd", "1Speed", "1%").ToString()) ) );

    SpeedCombo =
        SNew(STextComboBox)
        .OptionsSource(&SpeedSettingStrings)
        .InitiallySelectedItem(SpeedSettingStrings[0])
        .OnSelectionChanged(this, &FMatinee::OnChangePlaySpeed)
        ;

    TSharedRef<SWidget> SpeedBox =
        SNew(SBox)
        .WidthOverride(103)
        [
            SNew(SVerticalBox)
            +SVerticalBox::Slot()
            .Padding(4)
            [
                SNew(STextBlock)
                .Text(NSLOCTEXT("Matinee.Toolbar", "PlaybackSpeed", "Playback Speed:"))
                .Visibility( this, &FMatinee::GetLargeIconVisibility )
            ]
            +SVerticalBox::Slot()
            .AutoHeight()
            .Padding(4,0)
            [
                SpeedCombo.ToSharedRef()
            ]
        ];

    // Append Second Snap Times
    SnapComboStrings.Empty();
    for(int32 i=0; i<ARRAY_COUNT(InterpEdSnapSizes); i++)
    {
        FString SnapCaption = FString::Printf( TEXT("%1.2f"), InterpEdSnapSizes[i] );
        SnapComboStrings.Add( MakeShareable( new FString(SnapCaption) ) );
    }
    // Append FPS Snap Times
    for(int32 i=0; i<ARRAY_COUNT(InterpEdFPSSnapSizes); i++)
    {
        FString SnapCaption = GetInterpEdFPSSnapSizeLocName( i );
        SnapComboStrings.Add( MakeShareable( new FString(SnapCaption) ) );
    }
    // Add option for snapping to other keys.
    SnapComboStrings.Add( MakeShareable( new FString(NSLOCTEXT("UnrealEd", "InterpEd_Snap_Keys", "Snap to Keys" ).ToString()) ) );

    SnapCombo =
        SNew(STextComboBox)
        .OptionsSource(&SnapComboStrings)
        .InitiallySelectedItem(SnapComboStrings[2])
        .OnSelectionChanged(this, &FMatinee::OnChangeSnapSize)
        .ToolTipText( NSLOCTEXT("Matinee", "SnapComboToolTip", "Snap Size | Selects the timeline granularity for snapping and visualization purposes") )
        ;

    TSharedRef<SWidget> SnapSettingBox =
        SNew(SBox)
        .WidthOverride(155)
        [
            SNew(SVerticalBox)
            +SVerticalBox::Slot()
            .Padding(4)
            [
                SNew(STextBlock)
                .Text(NSLOCTEXT("Matinee.Toolbar", "SnapSetting", "Snap Setting:"))
                .Visibility( this, &FMatinee::GetLargeIconVisibility )
            ]
            +SVerticalBox::Slot()
            .AutoHeight()
            .Padding(4,0)
            [
                SnapCombo.ToSharedRef()
            ]
        ];

    ToolbarExtender->AddToolBarExtension(
        "Asset",
        EExtensionHook::After,
        GetToolkitCommands(),
        FToolBarExtensionDelegate::CreateStatic( &Local::FillToolbar, InterpolationBox, SpeedBox, SnapSettingBox)
    );

    AddToolbarExtender(ToolbarExtender);

    IMatineeModule* MatineeModule = &FModuleManager::LoadModuleChecked<IMatineeModule>( "Matinee" );
    AddToolbarExtender(MatineeModule->GetToolBarExtensibilityManager()->GetAllExtenders(GetToolkitCommands(), GetEditingObjects()));
}
void FSoundClassEditor::InitSoundClassEditor( const EToolkitMode::Type Mode, const TSharedPtr< class IToolkitHost >& InitToolkitHost, UObject* ObjectToEdit )
{
	SoundClass = CastChecked<USoundClass>(ObjectToEdit);

	while (SoundClass->ParentClass)
	{
		SoundClass = SoundClass->ParentClass;
	}

	// Support undo/redo
	SoundClass->SetFlags(RF_Transactional);

	GEditor->RegisterForUndo(this);

	ToolkitCommands->MapAction(
		FGenericCommands::Get().Undo,
		FExecuteAction::CreateSP( this, &FSoundClassEditor::UndoGraphAction ));

	ToolkitCommands->MapAction(
		FGenericCommands::Get().Redo,
		FExecuteAction::CreateSP( this, &FSoundClassEditor::RedoGraphAction ));

	if( !SoundClass->SoundClassGraph )
	{
		SoundClass->SoundClassGraph = CastChecked<USoundClassGraph>(FBlueprintEditorUtils::CreateNewGraph(SoundClass, NAME_None, USoundClassGraph::StaticClass(), USoundClassGraphSchema::StaticClass()));
		SoundClass->SoundClassGraph->SetRootSoundClass(SoundClass);
	}

	SoundClass->SoundClassGraph->RebuildGraph();

	CreateInternalWidgets();

	TSharedRef<FTabManager::FLayout> StandaloneDefaultLayout = FTabManager::NewLayout( "Standalone_SoundClassEditor_Layout_v2" )
	->AddArea
	(
		FTabManager::NewPrimaryArea() ->SetOrientation(Orient_Vertical)
		->Split
		(
			FTabManager::NewStack()
			->SetSizeCoefficient(0.1f)
			->SetHideTabWell( true )
			->AddTab(GetToolbarTabId(), ETabState::OpenedTab)
		)
		->Split
		(
			FTabManager::NewSplitter()
			->Split
			(
				FTabManager::NewStack()
				->SetSizeCoefficient(0.2f)
				->AddTab(PropertiesTabId, ETabState::OpenedTab)
			)
			->Split
			(
				FTabManager::NewStack()
				->SetSizeCoefficient(0.8f)
				->AddTab(GraphCanvasTabId, ETabState::OpenedTab)
			)
		)
	);

	const bool bCreateDefaultStandaloneMenu = true;
	const bool bCreateDefaultToolbar = true;
	FAssetEditorToolkit::InitAssetEditor( Mode, InitToolkitHost, SoundClassEditorAppIdentifier, StandaloneDefaultLayout, bCreateDefaultStandaloneMenu, bCreateDefaultToolbar, ObjectToEdit );

	ISoundClassEditorModule* SoundClassEditorModule = &FModuleManager::LoadModuleChecked<ISoundClassEditorModule>( "SoundClassEditor" );
	AddMenuExtender(SoundClassEditorModule->GetMenuExtensibilityManager()->GetAllExtenders(GetToolkitCommands(), GetEditingObjects()));
	AddToolbarExtender(SoundClassEditorModule->GetToolBarExtensibilityManager()->GetAllExtenders(GetToolkitCommands(), GetEditingObjects()));

	GraphEditor->SelectAllNodes();
	for (UObject* SelectedNode : GraphEditor->GetSelectedNodes())
	{
		USoundClassGraphNode* GraphNode = CastChecked<USoundClassGraphNode>(SelectedNode);
		if (GraphNode->SoundClass == ObjectToEdit)
		{
			GraphEditor->ClearSelectionSet();
			GraphEditor->SetNodeSelection(GraphNode, true);
			DetailsView->SetObject(ObjectToEdit);
			break;
		}
	}
}