// Copyright Epic Games, Inc. All Rights Reserved. #include "EditorUtilityWidgetBlueprint.h" #include "WidgetBlueprint.h" #include "Editor.h" #include "EditorUtilityWidget.h" #include "IBlutilityModule.h" #include "Modules/ModuleManager.h" #include "LevelEditor.h" ///////////////////////////////////////////////////// // UEditorUtilityWidgetBlueprint UEditorUtilityWidgetBlueprint::UEditorUtilityWidgetBlueprint(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { } void UEditorUtilityWidgetBlueprint::BeginDestroy() { // Only cleanup script if it has been registered and we're not shutdowning editor if (!IsEngineExitRequested() && RegistrationName != NAME_None) { IBlutilityModule* BlutilityModule = FModuleManager::GetModulePtr("Blutility"); if (BlutilityModule) { BlutilityModule->RemoveLoadedScriptUI(this); } FLevelEditorModule* LevelEditorModule = FModuleManager::GetModulePtr(TEXT("LevelEditor")); if (LevelEditorModule) { TSharedPtr LevelEditorTabManager = LevelEditorModule->GetLevelEditorTabManager(); if (LevelEditorTabManager.IsValid()) { LevelEditorTabManager->UnregisterTabSpawner(RegistrationName); } } } Super::BeginDestroy(); } TSharedRef UEditorUtilityWidgetBlueprint::SpawnEditorUITab(const FSpawnTabArgs& SpawnTabArgs) { TSharedRef SpawnedTab = SNew(SDockTab); TSharedRef TabWidget = CreateUtilityWidget(); SpawnedTab->SetContent(TabWidget); SpawnedTab->SetOnTabClosed(SDockTab::FOnTabClosedCallback::CreateUObject(this, &UEditorUtilityWidgetBlueprint::UpdateRespawnListIfNeeded)); CreatedTab = SpawnedTab; OnCompiled().AddUObject(this, &UEditorUtilityWidgetBlueprint::RegenerateCreatedTab); FLevelEditorModule& LevelEditor = FModuleManager::LoadModuleChecked("LevelEditor"); LevelEditor.OnMapChanged().AddUObject(this, &UEditorUtilityWidgetBlueprint::ChangeTabWorld); return SpawnedTab; } TSharedRef UEditorUtilityWidgetBlueprint::CreateUtilityWidget() { TSharedRef TabWidget = SNullWidget::NullWidget; UClass* BlueprintClass = GeneratedClass; TSubclassOf WidgetClass = BlueprintClass; UWorld* World = GEditor->GetEditorWorldContext().World(); if (World) { if (CreatedUMGWidget) { CreatedUMGWidget->Rename(nullptr, GetTransientPackage(), REN_DoNotDirty); } CreatedUMGWidget = CreateWidget(World, WidgetClass); if (CreatedUMGWidget) { // Editor Utility is flagged as transient to prevent from dirty the World it's created in when a property added to the Utility Widget is changed CreatedUMGWidget->SetFlags(RF_Transient); } } if (CreatedUMGWidget) { TabWidget = SNew(SVerticalBox) + SVerticalBox::Slot() .HAlign(HAlign_Fill) [ CreatedUMGWidget->TakeWidget() ]; } return TabWidget; } void UEditorUtilityWidgetBlueprint::RegenerateCreatedTab(UBlueprint* RecompiledBlueprint) { if (CreatedTab.IsValid()) { TSharedRef TabWidget = CreateUtilityWidget(); CreatedTab.Pin()->SetContent(TabWidget); } } void UEditorUtilityWidgetBlueprint::ChangeTabWorld(UWorld* World, EMapChangeType MapChangeType) { if (MapChangeType == EMapChangeType::TearDownWorld) { // We need to Delete the UMG widget if we are tearing down the World it was built with. if (CreatedUMGWidget && World == CreatedUMGWidget->GetWorld()) { if (CreatedTab.IsValid()) { CreatedTab.Pin()->SetContent(SNullWidget::NullWidget); } CreatedUMGWidget->Rename(nullptr, GetTransientPackage()); CreatedUMGWidget = nullptr; } } else if (MapChangeType != EMapChangeType::SaveMap) { // Recreate the widget if we are loading a map or opening a new map RegenerateCreatedTab(nullptr); } } void UEditorUtilityWidgetBlueprint::UpdateRespawnListIfNeeded(TSharedRef TabBeingClosed) { if (GeneratedClass) { const UEditorUtilityWidget* EditorUtilityWidget = GeneratedClass->GetDefaultObject(); if (EditorUtilityWidget && EditorUtilityWidget->ShouldAlwaysReregisterWithWindowsMenu() == false) { IBlutilityModule* BlutilityModule = FModuleManager::GetModulePtr("Blutility"); BlutilityModule->RemoveLoadedScriptUI(this); } } CreatedUMGWidget = nullptr; } void UEditorUtilityWidgetBlueprint::GetReparentingRules(TSet< const UClass* >& AllowedChildrenOfClasses, TSet< const UClass* >& DisallowedChildrenOfClasses) const { AllowedChildrenOfClasses.Empty(); AllowedChildrenOfClasses.Add(UEditorUtilityWidget::StaticClass()); }