Files
UnrealEngineUWP/Engine/Source/Editor/MainFrame/Private/Frame/MainFrameHandler.cpp
Gines Hidalgo d751ad2d5f #jira UETOOL-1721
Enhacement JIRA UETOOL-1721: Introduced the capability to load/save/remove Editor UI Layouts, so that the user can customize the Editor and save/share it accross machines or people.
Additional enhancements: Re-loading a layout no longer requires the whole editor to restart. Instead, only the tabs are closed and re-populated (only creating a small "flash" in the editor rather than restarting it).
Previous Editor bugs fixed:
 - Bug 1: AssetEditorToolkit.cpp::FAssetEditorToolkit::RestoreFromLayout was wrongly saving the layout in GEditorIni rather than GEditorLayoutIni.
 - Bug 2: When the layout is saved, the instance ID of the custom toolkits was being saved as well. Given that this number keep increasing after each custom tab is created (no matter if the previous ones were already closed), the editor will keep thinking that the loaded layout is no longer the currrent layout. Fix in TabManager.h::FTabId::ToString().
 - Bug 3: FLayoutSaveRestore::SaveToConfig was taking as input argument FString rather than const FString&.
#rb rex.hill, chris.gagnon

[CL 8129300 by Gines Hidalgo in Dev-Editor branch]
2019-08-20 15:18:28 -04:00

123 lines
4.4 KiB
C++

// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
#include "Frame/MainFrameHandler.h"
#include "HAL/FileManager.h"
#include "ThumbnailRendering/ThumbnailManager.h"
#include "Frame/RootWindowLocation.h"
#include "Widgets/Docking/SDockTab.h"
#include "HAL/PlatformApplicationMisc.h"
void FMainFrameHandler::ShutDownEditor()
{
FEditorDelegates::OnShutdownPostPackagesSaved.Broadcast();
// Any pending autosaves should not happen. A tick will go by before the editor shuts down and we want to avoid auto-saving during this time.
GUnrealEd->GetPackageAutoSaver().ResetAutoSaveTimer();
GEditor->RequestEndPlayMap();
// End any play on console/PC games still happening
GEditor->EndPlayOnLocalPc();
// Cancel any current Launch On in progress
GEditor->CancelPlayingViaLauncher();
//Broadcast we are closing the editor
GEditor->BroadcastEditorClose();
TSharedPtr<SWindow> RootWindow = RootWindowPtr.Pin();
// Save root window placement so we can restore it.
if (!GUsingNullRHI && RootWindow.IsValid())
{
FSlateRect WindowRect = RootWindow->GetNonMaximizedRectInScreen();
if (!RootWindow->HasOSWindowBorder())
{
// If the window has a specified border size, shrink its screen size by that amount to prevent it from growing
// over multiple shutdowns
const FMargin WindowBorder = RootWindow->GetNonMaximizedWindowBorderSize();
WindowRect.Right -= WindowBorder.Left + WindowBorder.Right;
WindowRect.Bottom -= WindowBorder.Top + WindowBorder.Bottom;
}
// Save without any DPI Scale so we can save the position and scale in a DPI independent way
const float DPIScale = FPlatformApplicationMisc::GetDPIScaleFactorAtPoint(WindowRect.Left, WindowRect.Top);
FRootWindowLocation RootWindowLocation(FVector2D(WindowRect.Left, WindowRect.Top)/ DPIScale, WindowRect.GetSize() / DPIScale, RootWindow->IsWindowMaximized());
RootWindowLocation.SaveToIni();
}
// Save the visual state of the editor before we even
// ask whether we can shut down.
TSharedRef<FGlobalTabmanager> GlobalTabManager = FGlobalTabmanager::Get();
if (FUnrealEdMisc::Get().IsSavingLayoutOnClosedAllowed())
{
GlobalTabManager->SaveAllVisualState();
}
// Clear the callback for destructionfrom the main tab; otherwise it will re-enter this shutdown function.
if (MainTabPtr.IsValid())
{
MainTabPtr.Pin()->SetOnTabClosed(SDockTab::FOnTabClosedCallback());
}
if (RootWindow.IsValid())
{
RootWindow->SetRequestDestroyWindowOverride(FRequestDestroyWindowOverride());
RootWindow->RequestDestroyWindow();
}
// Save out any config settings for the editor so they don't get lost
GEditor->SaveConfig();
GLevelEditorModeTools().SaveConfig();
// Delete user settings, if requested
if (FUnrealEdMisc::Get().IsDeletePreferences())
{
IFileManager::Get().Delete(*GEditorPerProjectIni);
}
// Take a screenshot of this project for the project browser
if (FApp::HasProjectName())
{
const FString ExistingBaseFilename = FString(FApp::GetProjectName()) + TEXT(".png");
const FString ExistingScreenshotFilename = FPaths::Combine(*FPaths::ProjectDir(), *ExistingBaseFilename);
// If there is already a screenshot, no need to take an auto screenshot
if (!FPaths::FileExists(ExistingScreenshotFilename))
{
const FString ScreenShotFilename = FPaths::Combine(*FPaths::ProjectSavedDir(), TEXT("AutoScreenshot.png"));
FViewport* Viewport = GEditor->GetActiveViewport();
if (Viewport)
{
UThumbnailManager::CaptureProjectThumbnail(Viewport, ScreenShotFilename, false);
}
}
}
// Shut down the editor
// NOTE: We can't close the editor from within this stack frame as it will cause various DLLs
// (such as MainFrame) to become unloaded out from underneath the code pointer. We'll shut down
// as soon as it's safe to do so.
// Note this is the only place in slate that should be calling QUIT_EDITOR
GEngine->DeferredCommands.Add(TEXT("QUIT_EDITOR"));
}
void FMainFrameHandler::EnableTabClosedDelegate()
{
if (MainTabPtr.IsValid())
{
MainTabPtr.Pin()->SetOnTabClosed(SDockTab::FOnTabClosedCallback::CreateRaw(this, &FMainFrameHandler::ShutDownEditor));
MainTabPtr.Pin()->SetCanCloseTab(SDockTab::FCanCloseTab::CreateRaw(this, &FMainFrameHandler::CanCloseTab));
}
}
void FMainFrameHandler::DisableTabClosedDelegate()
{
if (MainTabPtr.IsValid())
{
MainTabPtr.Pin()->SetOnTabClosed(SDockTab::FOnTabClosedCallback());
MainTabPtr.Pin()->SetCanCloseTab(SDockTab::FCanCloseTab());
}
}