Files
UnrealEngineUWP/Engine/Source/Editor/UnrealEd/Private/WorkflowCentricApplication.cpp
justin hare f2dc935bf9 Fixed issue where "unrecognized" tabs could start spawning in the Blueprint Editor after also using other asset editors.
The core issue was that the BP editor was performing deactivation/cleanup work whenever any system asked if it can be closed, whereas other editors were not and sometimes interrupting/canceling the closure process.  This led to situations where a BP editor tab deactivated itself before a different editor tab halted the window closing process, putting it in a dysfunctional state.

#jira UE-106350
#rb michael.noland matt.kuhlenschmidt

[CL 16391884 by justin hare in ue5-main branch]
2021-05-19 16:39:45 -04:00

160 lines
4.6 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "WorkflowOrientedApp/WorkflowCentricApplication.h"
#include "Framework/Application/SlateApplication.h"
#include "WorkflowOrientedApp/WorkflowTabFactory.h"
#include "WorkflowOrientedApp/WorkflowTabManager.h"
#include "WorkflowOrientedApp/ApplicationMode.h"
#include "ToolMenus.h"
#define LOCTEXT_NAMESPACE "WorkflowCentricApplication"
/////////////////////////////////////////////////////
// FWorkflowCentricApplication
TArray<FWorkflowApplicationModeExtender> FWorkflowCentricApplication::ModeExtenderList;
void FWorkflowCentricApplication::RegisterTabSpawners(const TSharedRef<class FTabManager>& InTabManager)
{
if (CurrentAppModePtr.IsValid())
{
CurrentAppModePtr->RegisterTabFactories(InTabManager);
}
}
void FWorkflowCentricApplication::UnregisterTabSpawners(const TSharedRef<class FTabManager>& InTabManager)
{
InTabManager->UnregisterAllTabSpawners();
}
FName FWorkflowCentricApplication::GetToolMenuToolbarName(FName& OutParentName) const
{
return GetToolMenuToolbarNameForMode(GetCurrentMode(), OutParentName);
}
FName FWorkflowCentricApplication::GetToolMenuToolbarNameForMode(const FName InModeName, FName& OutParentName) const
{
const FName BaseMenuName = FAssetEditorToolkit::GetToolMenuToolbarName(OutParentName);
if (InModeName != NAME_None)
{
OutParentName = BaseMenuName;
return *(BaseMenuName.ToString() + TEXT(".") + InModeName.ToString());
}
return BaseMenuName;
}
UToolMenu* FWorkflowCentricApplication::RegisterModeToolbarIfUnregistered(const FName InModeName)
{
FName ParentToolbarName;
const FName ModeSpecificToolbarName = GetToolMenuToolbarNameForMode(InModeName, ParentToolbarName);
if (!UToolMenus::Get()->IsMenuRegistered(ModeSpecificToolbarName))
{
return UToolMenus::Get()->RegisterMenu(ModeSpecificToolbarName, ParentToolbarName, EMultiBoxType::ToolBar);
}
return nullptr;
}
FName FWorkflowCentricApplication::GetCurrentMode() const
{
return CurrentAppModePtr.IsValid() ? CurrentAppModePtr->GetModeName() : NAME_None;
}
void FWorkflowCentricApplication::SetCurrentMode(FName NewMode)
{
const bool bModeAlreadyActive = CurrentAppModePtr.IsValid() && (NewMode == CurrentAppModePtr->GetModeName());
if (!bModeAlreadyActive)
{
check(TabManager.IsValid());
TSharedPtr<FApplicationMode> NewModePtr = ApplicationModeList.FindRef(NewMode);
LayoutExtenders.Reset();
if (NewModePtr.IsValid())
{
if (NewModePtr->LayoutExtender.IsValid())
{
LayoutExtenders.Add(NewModePtr->LayoutExtender);
}
// Deactivate the old mode
if (CurrentAppModePtr.IsValid())
{
check(TabManager.IsValid());
CurrentAppModePtr->PreDeactivateMode();
CurrentAppModePtr->DeactivateMode(TabManager);
RemoveToolbarExtender(CurrentAppModePtr->GetToolbarExtender());
RemoveAllToolbarWidgets();
}
// Unregister tab spawners
TabManager->UnregisterAllTabSpawners();
//@TODO: Should do some validation here
CurrentAppModePtr = NewModePtr;
// Establish the workspace menu category for the new mode
TabManager->ClearLocalWorkspaceMenuCategories();
TabManager->AddLocalWorkspaceMenuItem( CurrentAppModePtr->GetWorkspaceMenuCategory() );
// Activate the new layout
const TSharedRef<FTabManager::FLayout> NewLayout = CurrentAppModePtr->ActivateMode(TabManager);
RestoreFromLayout(NewLayout);
// Give the new mode a chance to do init
CurrentAppModePtr->PostActivateMode();
AddToolbarExtender(NewModePtr->GetToolbarExtender());
RegenerateMenusAndToolbars();
}
}
}
void FWorkflowCentricApplication::PushTabFactories(FWorkflowAllowedTabSet& FactorySetToPush)
{
check(TabManager.IsValid());
for (auto FactoryIt = FactorySetToPush.CreateIterator(); FactoryIt; ++FactoryIt)
{
FactoryIt.Value()->RegisterTabSpawner(TabManager.ToSharedRef(), CurrentAppModePtr.Get());
}
}
bool FWorkflowCentricApplication::OnRequestClose()
{
return FSlateApplication::Get().IsNormalExecution();
}
void FWorkflowCentricApplication::OnClose()
{
if (CurrentAppModePtr.IsValid())
{
check(TabManager.IsValid());
// Deactivate the old mode
CurrentAppModePtr->PreDeactivateMode();
CurrentAppModePtr->DeactivateMode(TabManager);
RemoveToolbarExtender(CurrentAppModePtr->GetToolbarExtender());
RemoveAllToolbarWidgets();
// Unregister tab spawners
TabManager->UnregisterAllTabSpawners();
}
}
void FWorkflowCentricApplication::AddApplicationMode(FName ModeName, TSharedRef<FApplicationMode> Mode)
{
for (int32 Index = 0; Index < ModeExtenderList.Num(); ++Index)
{
Mode = ModeExtenderList[Index].Execute(ModeName, Mode);
}
ApplicationModeList.Add(ModeName, Mode);
}
/////////////////////////////////////////////////////
#undef LOCTEXT_NAMESPACE