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 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::ExtendMenu()
{
	MenuExtender = MakeShareable(new FExtender);

	struct Local
	{
		static void ExtendMenu(FMenuBuilder& MenuBuilder)
		{
			// View
			MenuBuilder.BeginSection("SkeletonEditor", LOCTEXT("SkeletonEditorAssetMenu_Skeleton", "Skeleton"));
			{
				MenuBuilder.AddMenuEntry(FSkeletonEditorCommands::Get().RemoveUnusedBones);
				MenuBuilder.AddMenuEntry(FSkeletonEditorCommands::Get().UpdateSkeletonRefPose);
				MenuBuilder.AddMenuEntry(FSkeletonEditorCommands::Get().TestSkeletonCurveNamesForUse);
			}
			MenuBuilder.EndSection();
		}
	};

	MenuExtender->AddMenuExtension(
		"AssetEditorActions",
		EExtensionHook::After,
		GetToolkitCommands(),
		FMenuExtensionDelegate::CreateStatic(&Local::ExtendMenu)
		);

	AddMenuExtender(MenuExtender);

	ISkeletonEditorModule& SkeletonEditorModule = FModuleManager::GetModuleChecked<ISkeletonEditorModule>("SkeletonEditor");
	AddMenuExtender(SkeletonEditorModule.GetToolBarExtensibilityManager()->GetAllExtenders(GetToolkitCommands(), GetEditingObjects()));
}
void FNiagaraEditor::InitNiagaraEditor( const EToolkitMode::Type Mode, const TSharedPtr< class IToolkitHost >& InitToolkitHost, UNiagaraScript* InScript )
{	
	Script = InScript;
	check(Script != NULL);
	Source = CastChecked<UNiagaraScriptSource>(Script->Source);
	check(Source->NodeGraph != NULL);

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

	FPropertyEditorModule& PropertyEditorModule = FModuleManager::GetModuleChecked<FPropertyEditorModule>("PropertyEditor");
	const FDetailsViewArgs DetailsViewArgs(false, false, true, FDetailsViewArgs::HideNameArea, true, this);
	NiagaraDetailsView = PropertyEditorModule.CreateDetailView(DetailsViewArgs);

	const bool bCreateDefaultStandaloneMenu = true;
	const bool bCreateDefaultToolbar = true;
	FAssetEditorToolkit::InitAssetEditor( Mode, InitToolkitHost, FNiagaraEditorModule::NiagaraEditorAppIdentifier, StandaloneDefaultLayout, bCreateDefaultStandaloneMenu, bCreateDefaultToolbar, Script );

	FNiagaraEditorModule& NiagaraEditorModule = FModuleManager::LoadModuleChecked<FNiagaraEditorModule>( "NiagaraEditor" );
	AddMenuExtender(NiagaraEditorModule.GetMenuExtensibilityManager()->GetAllExtenders(GetToolkitCommands(), GetEditingObjects()));

	ExtendToolbar();
	RegenerateMenusAndToolbars();

	// @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( NodeGraphTabId, TabInitializationPayload, EToolkitTabSpot::Details );
	}*/
}
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 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();
	}
void FSoundCueEditor::InitSoundCueEditor(const EToolkitMode::Type Mode, const TSharedPtr< class IToolkitHost >& InitToolkitHost, UObject* ObjectToEdit)
{
	SoundCue = CastChecked<USoundCue>(ObjectToEdit);

	// Support undo/redo
	SoundCue->SetFlags(RF_Transactional);
	
	GEditor->RegisterForUndo(this);

	FGraphEditorCommands::Register();
	FSoundCueGraphEditorCommands::Register();

	BindGraphCommands();

	CreateInternalWidgets();

	const TSharedRef<FTabManager::FLayout> StandaloneDefaultLayout = FTabManager::NewLayout("Standalone_SoundCueEditor_Layout_v3")
	->AddArea
	(
		FTabManager::NewPrimaryArea() ->SetOrientation(Orient_Vertical)
		->Split
		(
			FTabManager::NewStack()
			->SetSizeCoefficient(0.1f)
			->AddTab(GetToolbarTabId(), ETabState::OpenedTab) ->SetHideTabWell( true )
		)
		->Split
		(
			FTabManager::NewSplitter() ->SetOrientation(Orient_Horizontal) ->SetSizeCoefficient(0.9f)
			->Split
			(
				FTabManager::NewStack()
				->SetSizeCoefficient(0.225f)
				->AddTab(PropertiesTabId, ETabState::OpenedTab)
			)
			->Split
			(
				FTabManager::NewStack()
				->SetSizeCoefficient(0.65f)
				->AddTab(GraphCanvasTabId, ETabState::OpenedTab) ->SetHideTabWell( true )
			)
			->Split
			(
			FTabManager::NewStack()
			->SetSizeCoefficient(0.125f)
			->AddTab(PaletteTabId, ETabState::OpenedTab)
			)
		)
	);

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

	ISoundCueEditorModule* SoundCueEditorModule = &FModuleManager::LoadModuleChecked<ISoundCueEditorModule>( "SoundCueEditor" );
	AddMenuExtender(SoundCueEditorModule->GetMenuExtensibilityManager()->GetAllExtenders(GetToolkitCommands(), GetEditingObjects()));

	ExtendToolbar();
	RegenerateMenusAndToolbars();

	// @todo toolkit world centric editing
	/*if(IsWorldCentricAssetEditor())
	{
		SpawnToolkitTab(GetToolbarTabId(), FString(), EToolkitTabSpot::ToolBar);
		SpawnToolkitTab(GraphCanvasTabId, FString(), EToolkitTabSpot::Viewport);
		SpawnToolkitTab(PropertiesTabId, FString(), EToolkitTabSpot::Details);
	}*/
}
void FAssetEditorToolkit::GenerateToolbar()
{
	TSharedPtr<FExtender> Extender = FExtender::Combine(ToolbarExtenders);

	FToolBarBuilder ToolbarBuilder( GetToolkitCommands(), FMultiBoxCustomization::AllowCustomization( GetToolkitFName() ), Extender);
	ToolbarBuilder.SetIsFocusable(bIsToolbarFocusable);
	ToolbarBuilder.BeginSection("Asset");
	{
		if( IsActuallyAnAsset() )
		{
			ToolbarBuilder.AddToolBarButton(FAssetEditorCommonCommands::Get().SaveAsset);
			ToolbarBuilder.AddToolBarButton(FGlobalEditorCommonCommands::Get().FindInContentBrowser, NAME_None, LOCTEXT("FindInContentBrowserButton", "Find in CB"));
		}
	}
	ToolbarBuilder.EndSection();

	TSharedRef<SHorizontalBox> MiscWidgets = SNew(SHorizontalBox);

	for (int32 WidgetIdx = 0; WidgetIdx < ToolbarWidgets.Num(); ++WidgetIdx)
	{
		MiscWidgets->AddSlot()
		.AutoWidth()
		.VAlign(VAlign_Center)
		.Padding(0.0f, 2.0f, 0.0f, 2.0f)
		[
			ToolbarWidgets[WidgetIdx]
		];
	}
	
	Toolbar = 
		SNew(SHorizontalBox)
		+SHorizontalBox::Slot()
		.HAlign(HAlign_Left)
		.VAlign(VAlign_Center)
		[
			SNew(SVerticalBox)
			+SVerticalBox::Slot()
			.AutoHeight()
			.VAlign(VAlign_Bottom)
			[
				ToolbarBuilder.MakeWidget()
			]
		]
		+SHorizontalBox::Slot()
		.HAlign(HAlign_Right)
		.VAlign(VAlign_Center)
		.AutoWidth()
		[
			SNew(SVerticalBox)
			+SVerticalBox::Slot()
			.AutoHeight()
			.VAlign(VAlign_Bottom)
			[
				SNew(SBorder)
				.BorderImage(FEditorStyle::GetBrush(TEXT("Toolbar.Background")))
				.Visibility(ToolbarWidgets.Num() > 0 ? EVisibility::Visible : EVisibility::Collapsed)
				[
					MiscWidgets
				]
			]
		];

	if (ToolbarWidgetContent.IsValid())
	{
		ToolbarWidgetContent->SetContent(Toolbar.ToSharedRef());
	}
}
void FNiagaraEffectEditor::InitNiagaraEffectEditor(const EToolkitMode::Type Mode, const TSharedPtr< class IToolkitHost >& InitToolkitHost, UNiagaraEffect* InEffect)
{
	Effect = InEffect;
	check(Effect != NULL);
	EffectInstance = new FNiagaraEffectInstance(InEffect);

	const float InTime = -0.02f;
	const float OutTime = 3.2f;

	if (!Sequencer.IsValid())
	{
		MovieScene = NewObject<UMovieScene>(InEffect, FName("Niagara Effect MovieScene"), RF_RootSet);
		auto NewAnimation = NewObject<UNiagaraSequence>(MovieScene);
		MovieScene->StartTime = InTime;
		MovieScene->InTime = InTime;
		MovieScene->OutTime = OutTime;
		MovieScene->EndTime = OutTime;
		NewAnimation->MovieScene = MovieScene;

		FSequencerViewParams ViewParams(TEXT("NiagaraSequencerSettings"));
		{
			ViewParams.InitalViewRange = TRange<float>(InTime, OutTime);
			ViewParams.InitialScrubPosition = 0;
		}

		FSequencerInitParams SequencerInitParams;
		{
			SequencerInitParams.ViewParams = ViewParams;
			SequencerInitParams.RootSequence = NewAnimation;
			SequencerInitParams.bEditWithinLevelEditor = false;
			SequencerInitParams.ToolkitHost = nullptr;
		}

		ISequencerModule &SeqModule = FModuleManager::LoadModuleChecked< ISequencerModule >("Sequencer");
		FDelegateHandle CreateTrackEditorHandle = SeqModule.RegisterTrackEditor_Handle(FOnCreateTrackEditor::CreateStatic(&FNiagaraEffectEditor::CreateTrackEditor));
		Sequencer = SeqModule.CreateSequencer(SequencerInitParams);

		for (TSharedPtr<FNiagaraSimulation> Emitter : EffectInstance->GetEmitters())
		{
			UEmitterMovieSceneTrack *Track = Cast<UEmitterMovieSceneTrack> (MovieScene->AddMasterTrack(UEmitterMovieSceneTrack::StaticClass()) );
			 Track->SetEmitter(Emitter);
		}
	}




	TSharedRef<FTabManager::FLayout> StandaloneDefaultLayout = FTabManager::NewLayout("Standalone_Niagara_Effect_Layout_v7")
		->AddArea
		(
			FTabManager::NewPrimaryArea()->SetOrientation(Orient_Vertical)
			->Split
			(
				FTabManager::NewStack()
				->SetSizeCoefficient(0.1f)
				->AddTab(GetToolbarTabId(), ETabState::OpenedTab)
				->SetHideTabWell(true)
			)
			->Split
			(
				FTabManager::NewSplitter()->SetOrientation(Orient_Horizontal)
				->Split
				(
					FTabManager::NewStack()
					->SetSizeCoefficient(0.1f)
					->AddTab(ViewportTabID, ETabState::OpenedTab)
				)
				->Split
				(
					FTabManager::NewStack()
					->SetSizeCoefficient(0.3f)
					->AddTab(EmitterEditorTabID, ETabState::OpenedTab)
					->AddTab(DevEmitterEditorTabID, ETabState::OpenedTab)
				)
			)
			->Split
			(
			FTabManager::NewStack()
			->SetSizeCoefficient(0.3f)
			->AddTab(CurveEditorTabID, ETabState::OpenedTab)
			->AddTab(SequencerTabID, ETabState::OpenedTab)
			)
		);

	const bool bCreateDefaultStandaloneMenu = true;
	const bool bCreateDefaultToolbar = true;
	FAssetEditorToolkit::InitAssetEditor(Mode, InitToolkitHost, FNiagaraEditorModule::NiagaraEditorAppIdentifier, StandaloneDefaultLayout, bCreateDefaultStandaloneMenu, bCreateDefaultToolbar, Effect);
	
	FNiagaraEditorModule& NiagaraEditorModule = FModuleManager::LoadModuleChecked<FNiagaraEditorModule>("NiagaraEditor");
	AddMenuExtender(NiagaraEditorModule.GetMenuExtensibilityManager()->GetAllExtenders(GetToolkitCommands(), GetEditingObjects()));

	ExtendToolbar();
	RegenerateMenusAndToolbars();
}
void SStandaloneAssetEditorToolkitHost::SetupInitialContent( const TSharedRef<FTabManager::FLayout>& DefaultLayout, const TSharedPtr<SDockTab>& InHostTab, const bool bCreateDefaultStandaloneMenu )
{
	// @todo toolkit major: Expose common asset editing features here! (or require the asset editor's content to do this itself!)
	//		- Add a "toolkit menu"
	//				- Toolkits can access this and add menu items as needed
	//				- In world-centric, main frame menu becomes extendable
	//						- e.g., "Blueprint", "Debug" menus added
	//				- In standalone, toolkits get their own menu
	//						- Also, the core menu is just added as the first pull-down in the standalone menu
	//				- Multiple toolkits can be active and add their own menu items!
	//				- In world-centric, the core toolkit menu is available from the drop down
	//						- No longer need drop down next to toolkit display?  Not sure... Probably still want this
	//		- Add a "toolkit toolbar"
	//				- In world-centric, draws next to the level editor tool bar (or on top of)
	//						- Could either extend existing tool bar or add additional tool bars
	//						- May need to change arrangement to allow for wider tool bars (maybe displace grid settings too)
	//				- In standalone, just draws under the toolkit's menu

	
	if (bCreateDefaultStandaloneMenu)
	{
		struct Local
		{
			static void FillFileMenu( FMenuBuilder& MenuBuilder, TWeakPtr< FAssetEditorToolkit > AssetEditorToolkitWeak )
			{
				auto AssetEditorToolkit( AssetEditorToolkitWeak.Pin().ToSharedRef() );
				
				AssetEditorToolkit->FillDefaultFileMenuCommands( MenuBuilder );
			}

			static void AddAssetMenu( FMenuBarBuilder& MenuBarBuilder, TWeakPtr< FAssetEditorToolkit > AssetEditorToolkitWeak )
			{
				MenuBarBuilder.AddPullDownMenu( 
					LOCTEXT("AssetMenuLabel", "Asset"),		// @todo toolkit major: Either use "Asset", "File", or the asset type name e.g. "Blueprint" (Also update custom pull-down menus)
					LOCTEXT("AssetMenuLabel_ToolTip", "Opens a menu with commands for managing this asset"),
					FNewMenuDelegate::CreateStatic( &Local::FillAssetMenu, AssetEditorToolkitWeak ),
					"Asset");

				auto AssetEditorToolkit( AssetEditorToolkitWeak.Pin().ToSharedRef() );
			}

			static void FillAssetMenu( FMenuBuilder& MenuBuilder, TWeakPtr< FAssetEditorToolkit > AssetEditorToolkitWeak )
			{
				auto AssetEditorToolkit( AssetEditorToolkitWeak.Pin().ToSharedRef() );
				
				MenuBuilder.BeginSection("AssetEditorActions", LOCTEXT("ActionsHeading", "Actions") );
				{
					AssetEditorToolkit->FillDefaultAssetMenuCommands( MenuBuilder );
				}
				MenuBuilder.EndSection();
			}

			static void ExtendHelpMenu( FMenuBuilder& MenuBuilder, TWeakPtr< FAssetEditorToolkit > AssetEditorToolkitWeak )
			{
				auto AssetEditorToolkit( AssetEditorToolkitWeak.Pin().ToSharedRef() );

				MenuBuilder.BeginSection("HelpBrowse", NSLOCTEXT("MainHelpMenu", "Browse", "Browse"));
				{
					AssetEditorToolkit->FillDefaultHelpMenuCommands( MenuBuilder );
				}
				MenuBuilder.EndSection();
			}
		};

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

		auto AssetEditorToolkit = HostedAssetEditorToolkit.ToSharedRef();

		// Add asset-specific menu items to the top of the "File" menu
		MenuExtender->AddMenuExtension( "FileLoadAndSave", EExtensionHook::First, AssetEditorToolkit->GetToolkitCommands(), FMenuExtensionDelegate::CreateStatic( &Local::FillFileMenu, TWeakPtr< FAssetEditorToolkit >( AssetEditorToolkit ) ) );

		// Add the "Asset" menu, if we're editing an asset
		if (AssetEditorToolkit->IsActuallyAnAsset())
		{
			MenuExtender->AddMenuBarExtension( "Edit", EExtensionHook::After, AssetEditorToolkit->GetToolkitCommands(), FMenuBarExtensionDelegate::CreateStatic( &Local::AddAssetMenu, TWeakPtr< FAssetEditorToolkit >( AssetEditorToolkit ) ) );
		}

		MenuExtender->AddMenuExtension( "HelpOnline", EExtensionHook::Before, AssetEditorToolkit->GetToolkitCommands(), FMenuExtensionDelegate::CreateStatic( &Local::ExtendHelpMenu, TWeakPtr< FAssetEditorToolkit >( AssetEditorToolkit ) ) );

		MenuExtenders.Add(MenuExtender);
	}

	DefaultMenuWidget = SNullWidget::NullWidget;

	HostTabPtr = InHostTab;

	RestoreFromLayout(DefaultLayout);
	GenerateMenus(bCreateDefaultStandaloneMenu);
}
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();
	}
}
/**
 * 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;
		}
	}
}