Files
UnrealEngineUWP/Engine/Source/Editor/ContentBrowser/Private/ContentBrowserSingleton.cpp

547 lines
17 KiB
C++
Raw Normal View History

// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
#include "ContentBrowserPCH.h"
#include "ContentBrowserModule.h"
#include "ObjectTools.h"
#include "WorkspaceMenuStructureModule.h"
#include "IDocumentation.h"
Merging using UE4-Fortnite-To-UE4 from CL 2261973 Includes the following engine-level changes (among others; biggest change is enabling world assets by default): CL 2252857 added dynamic allocations for path finding, removed hardcoded limit of 128 polys in path corridor CL 2256142 Added support for native arrays in JSON object converter. - Permissive in treating arrays of size 1 and scalars as equivalent - Excess elements in JSON are ignored. Serialization succeeds but a warning is logged CL 2256073 Fixed a bug in ARecastNavMesh::BatchRaycast resulting in NaN hit locations CL 2253797 #UE4 More aggressively setting RF_Public and RF_Standalone flags on maps and ensuring world names match package names. This is necessary because umaps are currently being managed outside of the content browser and it is causing a few issues. Also, packages containing maps now synthesize asset data when the package contains absolutely no asset data (probably because the UWorld in it was not RF_Public at the time it was saved due to a previous bug). CL 2258142 #UE4 Added a GC during map load that reclaims memory allocated during load/init. This is needed to finish the load on low-memory devices in games that allocate more memory after load. CL 2247003 Added homing to ProjectileMovementComponent - Homing requires both a bool and a target component to be set, the strength is determined by a customizable variable - Both homing and gravity are now applied in the new virtual function "CalculateAcceleration" CL 2247249 Moved the homing modification to acceleration occur in a separate function specifically for homing CL 2257043 - Guard net dormancy calls against executing on clients, based on thread with DaveR and JohnP; This particular case was the result of an intentionally client-authoritative actor calling the dormancy functions via inheritance CL 2245629 #UE4 - fixed json TryGetNumber to round negatives appropriately CL 2255312 #UE4 Enabling World Assets by default. CL 2260956 Analytics ET now loads HTTP at StartupModule so the module will be available during ShutdownModule to flush events CL 2245571 GenericTeamAgentInterface can now retrieve attitude of an agent towards a given actor #UE4 - Made PerceptionSystem's sight sense take advantage of that CL 2246897 Fixed perception listeners not being removed from the PerceptionSystem on Owner's end play #UE4 - addresses TTP#343392 CL 2260634 added more debug data for NaN in crowd simulation CL 2248387 Added possibility to debug multiple EQS queries with GameplayDebugger. #ue4 Fixed network replication from bandwidth point of view for data in GameplayDebugger. #ue4 CL 2253281 Added additional information to the visual logger for UBTCompositeNode::DoDecoratorsAllowExecution - We now keep track of whether a decorator allows execution, in addition to the existing log for not allowing execution CL 2255310 #UE4 The world browser module now listens to WorldAdded/WorldDestroyed events instead of WorldInit/WorldCleanup events. Worlds can be initialized without being the editor world and this handles that case. CL 2258256 #UE4 Replacing the SOpenLevelDialog with a new generic SAssetDialog. This dialog will be used as a generic Open or Save As dialog for assets. [CL 2266822 by Billy Bramer in Main branch]
2014-08-21 20:30:51 -04:00
#include "Editor/MainFrame/Public/MainFrame.h"
#include "SAssetDialog.h"
#include "TutorialMetaData.h"
#include "SDockTab.h"
#include "NativeClassHierarchy.h"
#define LOCTEXT_NAMESPACE "ContentBrowser"
FContentBrowserSingleton::FContentBrowserSingleton()
: SettingsStringID(0)
{
// Register the tab spawners for all content browsers
const FSlateIcon ContentBrowserIcon(FEditorStyle::GetStyleSetName(), "ContentBrowser.TabIcon");
const IWorkspaceMenuStructure& MenuStructure = WorkspaceMenu::GetMenuStructure();
TSharedRef<FWorkspaceItem> ContentBrowserGroup = MenuStructure.GetToolsCategory()->AddGroup(
LOCTEXT( "WorkspaceMenu_ContentBrowserCategory", "Content Browser" ),
LOCTEXT( "ContentBrowserMenuTooltipText", "Open a Content Browser tab." ),
ContentBrowserIcon,
true);
for ( int32 BrowserIdx = 0; BrowserIdx < ARRAY_COUNT(ContentBrowserTabIDs); BrowserIdx++ )
{
const FName TabID = FName(*FString::Printf(TEXT("ContentBrowserTab%d"), BrowserIdx + 1));
ContentBrowserTabIDs[BrowserIdx] = TabID;
const FText DefaultDisplayName = GetContentBrowserLabelWithIndex( BrowserIdx );
FGlobalTabmanager::Get()->RegisterNomadTabSpawner( TabID, FOnSpawnTab::CreateRaw(this, &FContentBrowserSingleton::SpawnContentBrowserTab, BrowserIdx) )
.SetDisplayName(DefaultDisplayName)
.SetTooltipText( LOCTEXT( "ContentBrowserMenuTooltipText", "Open a Content Browser tab." ) )
.SetGroup( ContentBrowserGroup )
.SetIcon(ContentBrowserIcon);
}
// Register a couple legacy tab ids
FGlobalTabmanager::Get()->AddLegacyTabType( "LevelEditorContentBrowser", "ContentBrowserTab1" );
FGlobalTabmanager::Get()->AddLegacyTabType( "MajorContentBrowserTab", "ContentBrowserTab2" );
// Register to be notified when properties are edited
FEditorDelegates::LoadSelectedAssetsIfNeeded.AddRaw(this, &FContentBrowserSingleton::OnEditorLoadSelectedAssetsIfNeeded);
}
FContentBrowserSingleton::~FContentBrowserSingleton()
{
FEditorDelegates::LoadSelectedAssetsIfNeeded.RemoveAll(this);
if ( FSlateApplication::IsInitialized() )
{
for ( int32 BrowserIdx = 0; BrowserIdx < ARRAY_COUNT(ContentBrowserTabIDs); BrowserIdx++ )
{
FGlobalTabmanager::Get()->UnregisterNomadTabSpawner( ContentBrowserTabIDs[BrowserIdx] );
}
}
}
TSharedRef<SWidget> FContentBrowserSingleton::CreateAssetPicker(const FAssetPickerConfig& AssetPickerConfig)
{
return SNew( SAssetPicker )
.IsEnabled( FSlateApplication::Get().GetNormalExecutionAttribute() )
.AssetPickerConfig(AssetPickerConfig);
}
TSharedRef<SWidget> FContentBrowserSingleton::CreatePathPicker(const FPathPickerConfig& PathPickerConfig)
{
return SNew( SPathPicker )
.IsEnabled( FSlateApplication::Get().GetNormalExecutionAttribute() )
.PathPickerConfig(PathPickerConfig);
}
TSharedRef<class SWidget> FContentBrowserSingleton::CreateCollectionPicker(const FCollectionPickerConfig& CollectionPickerConfig)
{
return SNew( SCollectionPicker )
.IsEnabled( FSlateApplication::Get().GetNormalExecutionAttribute() )
.CollectionPickerConfig(CollectionPickerConfig);
}
void FContentBrowserSingleton::CreateOpenAssetDialog(const FOpenAssetDialogConfig& InConfig,
const FOnAssetsChosenForOpen& InOnAssetsChosenForOpen,
const FOnAssetDialogCancelled& InOnAssetDialogCancelled)
Merging using UE4-Fortnite-To-UE4 from CL 2261973 Includes the following engine-level changes (among others; biggest change is enabling world assets by default): CL 2252857 added dynamic allocations for path finding, removed hardcoded limit of 128 polys in path corridor CL 2256142 Added support for native arrays in JSON object converter. - Permissive in treating arrays of size 1 and scalars as equivalent - Excess elements in JSON are ignored. Serialization succeeds but a warning is logged CL 2256073 Fixed a bug in ARecastNavMesh::BatchRaycast resulting in NaN hit locations CL 2253797 #UE4 More aggressively setting RF_Public and RF_Standalone flags on maps and ensuring world names match package names. This is necessary because umaps are currently being managed outside of the content browser and it is causing a few issues. Also, packages containing maps now synthesize asset data when the package contains absolutely no asset data (probably because the UWorld in it was not RF_Public at the time it was saved due to a previous bug). CL 2258142 #UE4 Added a GC during map load that reclaims memory allocated during load/init. This is needed to finish the load on low-memory devices in games that allocate more memory after load. CL 2247003 Added homing to ProjectileMovementComponent - Homing requires both a bool and a target component to be set, the strength is determined by a customizable variable - Both homing and gravity are now applied in the new virtual function "CalculateAcceleration" CL 2247249 Moved the homing modification to acceleration occur in a separate function specifically for homing CL 2257043 - Guard net dormancy calls against executing on clients, based on thread with DaveR and JohnP; This particular case was the result of an intentionally client-authoritative actor calling the dormancy functions via inheritance CL 2245629 #UE4 - fixed json TryGetNumber to round negatives appropriately CL 2255312 #UE4 Enabling World Assets by default. CL 2260956 Analytics ET now loads HTTP at StartupModule so the module will be available during ShutdownModule to flush events CL 2245571 GenericTeamAgentInterface can now retrieve attitude of an agent towards a given actor #UE4 - Made PerceptionSystem's sight sense take advantage of that CL 2246897 Fixed perception listeners not being removed from the PerceptionSystem on Owner's end play #UE4 - addresses TTP#343392 CL 2260634 added more debug data for NaN in crowd simulation CL 2248387 Added possibility to debug multiple EQS queries with GameplayDebugger. #ue4 Fixed network replication from bandwidth point of view for data in GameplayDebugger. #ue4 CL 2253281 Added additional information to the visual logger for UBTCompositeNode::DoDecoratorsAllowExecution - We now keep track of whether a decorator allows execution, in addition to the existing log for not allowing execution CL 2255310 #UE4 The world browser module now listens to WorldAdded/WorldDestroyed events instead of WorldInit/WorldCleanup events. Worlds can be initialized without being the editor world and this handles that case. CL 2258256 #UE4 Replacing the SOpenLevelDialog with a new generic SAssetDialog. This dialog will be used as a generic Open or Save As dialog for assets. [CL 2266822 by Billy Bramer in Main branch]
2014-08-21 20:30:51 -04:00
{
const bool bModal = false;
TSharedRef<SAssetDialog> AssetDialog = SNew(SAssetDialog, InConfig);
AssetDialog->SetOnAssetsChosenForOpen(InOnAssetsChosenForOpen);
AssetDialog->SetOnAssetDialogCancelled(InOnAssetDialogCancelled);
Merging using UE4-Fortnite-To-UE4 from CL 2261973 Includes the following engine-level changes (among others; biggest change is enabling world assets by default): CL 2252857 added dynamic allocations for path finding, removed hardcoded limit of 128 polys in path corridor CL 2256142 Added support for native arrays in JSON object converter. - Permissive in treating arrays of size 1 and scalars as equivalent - Excess elements in JSON are ignored. Serialization succeeds but a warning is logged CL 2256073 Fixed a bug in ARecastNavMesh::BatchRaycast resulting in NaN hit locations CL 2253797 #UE4 More aggressively setting RF_Public and RF_Standalone flags on maps and ensuring world names match package names. This is necessary because umaps are currently being managed outside of the content browser and it is causing a few issues. Also, packages containing maps now synthesize asset data when the package contains absolutely no asset data (probably because the UWorld in it was not RF_Public at the time it was saved due to a previous bug). CL 2258142 #UE4 Added a GC during map load that reclaims memory allocated during load/init. This is needed to finish the load on low-memory devices in games that allocate more memory after load. CL 2247003 Added homing to ProjectileMovementComponent - Homing requires both a bool and a target component to be set, the strength is determined by a customizable variable - Both homing and gravity are now applied in the new virtual function "CalculateAcceleration" CL 2247249 Moved the homing modification to acceleration occur in a separate function specifically for homing CL 2257043 - Guard net dormancy calls against executing on clients, based on thread with DaveR and JohnP; This particular case was the result of an intentionally client-authoritative actor calling the dormancy functions via inheritance CL 2245629 #UE4 - fixed json TryGetNumber to round negatives appropriately CL 2255312 #UE4 Enabling World Assets by default. CL 2260956 Analytics ET now loads HTTP at StartupModule so the module will be available during ShutdownModule to flush events CL 2245571 GenericTeamAgentInterface can now retrieve attitude of an agent towards a given actor #UE4 - Made PerceptionSystem's sight sense take advantage of that CL 2246897 Fixed perception listeners not being removed from the PerceptionSystem on Owner's end play #UE4 - addresses TTP#343392 CL 2260634 added more debug data for NaN in crowd simulation CL 2248387 Added possibility to debug multiple EQS queries with GameplayDebugger. #ue4 Fixed network replication from bandwidth point of view for data in GameplayDebugger. #ue4 CL 2253281 Added additional information to the visual logger for UBTCompositeNode::DoDecoratorsAllowExecution - We now keep track of whether a decorator allows execution, in addition to the existing log for not allowing execution CL 2255310 #UE4 The world browser module now listens to WorldAdded/WorldDestroyed events instead of WorldInit/WorldCleanup events. Worlds can be initialized without being the editor world and this handles that case. CL 2258256 #UE4 Replacing the SOpenLevelDialog with a new generic SAssetDialog. This dialog will be used as a generic Open or Save As dialog for assets. [CL 2266822 by Billy Bramer in Main branch]
2014-08-21 20:30:51 -04:00
SharedCreateAssetDialogWindow(AssetDialog, InConfig, bModal);
}
TArray<FAssetData> FContentBrowserSingleton::CreateModalOpenAssetDialog(const FOpenAssetDialogConfig& InConfig)
{
struct FModalResults
{
void OnAssetsChosenForOpen(const TArray<FAssetData>& SelectedAssets)
{
SavedResults = SelectedAssets;
}
TArray<FAssetData> SavedResults;
};
FModalResults ModalWindowResults;
FOnAssetsChosenForOpen OnAssetsChosenForOpenDelegate = FOnAssetsChosenForOpen::CreateRaw(&ModalWindowResults, &FModalResults::OnAssetsChosenForOpen);
const bool bModal = true;
TSharedRef<SAssetDialog> AssetDialog = SNew(SAssetDialog, InConfig);
AssetDialog->SetOnAssetsChosenForOpen(OnAssetsChosenForOpenDelegate);
SharedCreateAssetDialogWindow(AssetDialog, InConfig, bModal);
return ModalWindowResults.SavedResults;
}
void FContentBrowserSingleton::CreateSaveAssetDialog(const FSaveAssetDialogConfig& InConfig,
const FOnObjectPathChosenForSave& InOnObjectPathChosenForSave,
const FOnAssetDialogCancelled& InOnAssetDialogCancelled)
Merging using UE4-Fortnite-To-UE4 from CL 2261973 Includes the following engine-level changes (among others; biggest change is enabling world assets by default): CL 2252857 added dynamic allocations for path finding, removed hardcoded limit of 128 polys in path corridor CL 2256142 Added support for native arrays in JSON object converter. - Permissive in treating arrays of size 1 and scalars as equivalent - Excess elements in JSON are ignored. Serialization succeeds but a warning is logged CL 2256073 Fixed a bug in ARecastNavMesh::BatchRaycast resulting in NaN hit locations CL 2253797 #UE4 More aggressively setting RF_Public and RF_Standalone flags on maps and ensuring world names match package names. This is necessary because umaps are currently being managed outside of the content browser and it is causing a few issues. Also, packages containing maps now synthesize asset data when the package contains absolutely no asset data (probably because the UWorld in it was not RF_Public at the time it was saved due to a previous bug). CL 2258142 #UE4 Added a GC during map load that reclaims memory allocated during load/init. This is needed to finish the load on low-memory devices in games that allocate more memory after load. CL 2247003 Added homing to ProjectileMovementComponent - Homing requires both a bool and a target component to be set, the strength is determined by a customizable variable - Both homing and gravity are now applied in the new virtual function "CalculateAcceleration" CL 2247249 Moved the homing modification to acceleration occur in a separate function specifically for homing CL 2257043 - Guard net dormancy calls against executing on clients, based on thread with DaveR and JohnP; This particular case was the result of an intentionally client-authoritative actor calling the dormancy functions via inheritance CL 2245629 #UE4 - fixed json TryGetNumber to round negatives appropriately CL 2255312 #UE4 Enabling World Assets by default. CL 2260956 Analytics ET now loads HTTP at StartupModule so the module will be available during ShutdownModule to flush events CL 2245571 GenericTeamAgentInterface can now retrieve attitude of an agent towards a given actor #UE4 - Made PerceptionSystem's sight sense take advantage of that CL 2246897 Fixed perception listeners not being removed from the PerceptionSystem on Owner's end play #UE4 - addresses TTP#343392 CL 2260634 added more debug data for NaN in crowd simulation CL 2248387 Added possibility to debug multiple EQS queries with GameplayDebugger. #ue4 Fixed network replication from bandwidth point of view for data in GameplayDebugger. #ue4 CL 2253281 Added additional information to the visual logger for UBTCompositeNode::DoDecoratorsAllowExecution - We now keep track of whether a decorator allows execution, in addition to the existing log for not allowing execution CL 2255310 #UE4 The world browser module now listens to WorldAdded/WorldDestroyed events instead of WorldInit/WorldCleanup events. Worlds can be initialized without being the editor world and this handles that case. CL 2258256 #UE4 Replacing the SOpenLevelDialog with a new generic SAssetDialog. This dialog will be used as a generic Open or Save As dialog for assets. [CL 2266822 by Billy Bramer in Main branch]
2014-08-21 20:30:51 -04:00
{
const bool bModal = false;
TSharedRef<SAssetDialog> AssetDialog = SNew(SAssetDialog, InConfig);
AssetDialog->SetOnObjectPathChosenForSave(InOnObjectPathChosenForSave);
AssetDialog->SetOnAssetDialogCancelled(InOnAssetDialogCancelled);
Merging using UE4-Fortnite-To-UE4 from CL 2261973 Includes the following engine-level changes (among others; biggest change is enabling world assets by default): CL 2252857 added dynamic allocations for path finding, removed hardcoded limit of 128 polys in path corridor CL 2256142 Added support for native arrays in JSON object converter. - Permissive in treating arrays of size 1 and scalars as equivalent - Excess elements in JSON are ignored. Serialization succeeds but a warning is logged CL 2256073 Fixed a bug in ARecastNavMesh::BatchRaycast resulting in NaN hit locations CL 2253797 #UE4 More aggressively setting RF_Public and RF_Standalone flags on maps and ensuring world names match package names. This is necessary because umaps are currently being managed outside of the content browser and it is causing a few issues. Also, packages containing maps now synthesize asset data when the package contains absolutely no asset data (probably because the UWorld in it was not RF_Public at the time it was saved due to a previous bug). CL 2258142 #UE4 Added a GC during map load that reclaims memory allocated during load/init. This is needed to finish the load on low-memory devices in games that allocate more memory after load. CL 2247003 Added homing to ProjectileMovementComponent - Homing requires both a bool and a target component to be set, the strength is determined by a customizable variable - Both homing and gravity are now applied in the new virtual function "CalculateAcceleration" CL 2247249 Moved the homing modification to acceleration occur in a separate function specifically for homing CL 2257043 - Guard net dormancy calls against executing on clients, based on thread with DaveR and JohnP; This particular case was the result of an intentionally client-authoritative actor calling the dormancy functions via inheritance CL 2245629 #UE4 - fixed json TryGetNumber to round negatives appropriately CL 2255312 #UE4 Enabling World Assets by default. CL 2260956 Analytics ET now loads HTTP at StartupModule so the module will be available during ShutdownModule to flush events CL 2245571 GenericTeamAgentInterface can now retrieve attitude of an agent towards a given actor #UE4 - Made PerceptionSystem's sight sense take advantage of that CL 2246897 Fixed perception listeners not being removed from the PerceptionSystem on Owner's end play #UE4 - addresses TTP#343392 CL 2260634 added more debug data for NaN in crowd simulation CL 2248387 Added possibility to debug multiple EQS queries with GameplayDebugger. #ue4 Fixed network replication from bandwidth point of view for data in GameplayDebugger. #ue4 CL 2253281 Added additional information to the visual logger for UBTCompositeNode::DoDecoratorsAllowExecution - We now keep track of whether a decorator allows execution, in addition to the existing log for not allowing execution CL 2255310 #UE4 The world browser module now listens to WorldAdded/WorldDestroyed events instead of WorldInit/WorldCleanup events. Worlds can be initialized without being the editor world and this handles that case. CL 2258256 #UE4 Replacing the SOpenLevelDialog with a new generic SAssetDialog. This dialog will be used as a generic Open or Save As dialog for assets. [CL 2266822 by Billy Bramer in Main branch]
2014-08-21 20:30:51 -04:00
SharedCreateAssetDialogWindow(AssetDialog, InConfig, bModal);
}
FString FContentBrowserSingleton::CreateModalSaveAssetDialog(const FSaveAssetDialogConfig& InConfig)
{
struct FModalResults
{
void OnObjectPathChosenForSave(const FString& ObjectPath)
{
SavedResult = ObjectPath;
}
FString SavedResult;
};
FModalResults ModalWindowResults;
FOnObjectPathChosenForSave OnObjectPathChosenForSaveDelegate = FOnObjectPathChosenForSave::CreateRaw(&ModalWindowResults, &FModalResults::OnObjectPathChosenForSave);
const bool bModal = true;
TSharedRef<SAssetDialog> AssetDialog = SNew(SAssetDialog, InConfig);
AssetDialog->SetOnObjectPathChosenForSave(OnObjectPathChosenForSaveDelegate);
SharedCreateAssetDialogWindow(AssetDialog, InConfig, bModal);
return ModalWindowResults.SavedResult;
}
bool FContentBrowserSingleton::HasPrimaryContentBrowser() const
{
if ( PrimaryContentBrowser.IsValid() )
{
// There is a primary content browser
return true;
}
else
{
for (int32 BrowserIdx = 0; BrowserIdx < AllContentBrowsers.Num(); ++BrowserIdx)
{
if ( AllContentBrowsers[BrowserIdx].IsValid() )
{
// There is at least one valid content browser
return true;
}
}
// There were no valid content browsers
return false;
}
}
void FContentBrowserSingleton::FocusPrimaryContentBrowser(bool bFocusSearch)
{
// See if the primary content browser is still valid
if ( !PrimaryContentBrowser.IsValid() )
{
ChooseNewPrimaryBrowser();
}
if ( PrimaryContentBrowser.IsValid() )
{
FocusContentBrowser( PrimaryContentBrowser.Pin() );
}
else
{
// If we couldn't find a primary content browser, open one
SummonNewBrowser();
}
// Do we also want to focus on the search box of the content browser?
if ( bFocusSearch && PrimaryContentBrowser.IsValid() )
{
PrimaryContentBrowser.Pin()->SetKeyboardFocusOnSearch();
}
}
void FContentBrowserSingleton::CreateNewAsset(const FString& DefaultAssetName, const FString& PackagePath, UClass* AssetClass, UFactory* Factory)
{
FocusPrimaryContentBrowser(false);
if ( PrimaryContentBrowser.IsValid() )
{
PrimaryContentBrowser.Pin()->CreateNewAsset(DefaultAssetName, PackagePath, AssetClass, Factory);
}
}
void FContentBrowserSingleton::SyncBrowserToAssets(const TArray<FAssetData>& AssetDataList, bool bAllowLockedBrowsers)
{
TSharedPtr<SContentBrowser> ContentBrowserToSync;
if ( !PrimaryContentBrowser.IsValid() )
{
ChooseNewPrimaryBrowser();
}
if ( PrimaryContentBrowser.IsValid() && (bAllowLockedBrowsers || !PrimaryContentBrowser.Pin()->IsLocked()) )
{
// If the primary content browser is not locked, sync it
ContentBrowserToSync = PrimaryContentBrowser.Pin();
}
else
{
// If there is no primary or it is locked, find the first non-locked valid browser
for (int32 BrowserIdx = 0; BrowserIdx < AllContentBrowsers.Num(); ++BrowserIdx)
{
if ( AllContentBrowsers[BrowserIdx].IsValid() && (bAllowLockedBrowsers || !AllContentBrowsers[BrowserIdx].Pin()->IsLocked()) )
{
ContentBrowserToSync = AllContentBrowsers[BrowserIdx].Pin();
break;
}
}
}
if ( !ContentBrowserToSync.IsValid() )
{
// There are no valid, unlocked browsers, attempt to summon a new one.
SummonNewBrowser(bAllowLockedBrowsers);
// Now try to find a non-locked valid browser again, now that a new one may exist
for (int32 BrowserIdx = 0; BrowserIdx < AllContentBrowsers.Num(); ++BrowserIdx)
{
if ( AllContentBrowsers[BrowserIdx].IsValid() && (bAllowLockedBrowsers || !AllContentBrowsers[BrowserIdx].Pin()->IsLocked()) )
{
ContentBrowserToSync = AllContentBrowsers[BrowserIdx].Pin();
break;
}
}
}
if ( ContentBrowserToSync.IsValid() )
{
// Finally, focus and sync the browser that was found
FocusContentBrowser(ContentBrowserToSync);
ContentBrowserToSync->SyncToAssets(AssetDataList);
}
else
{
UE_LOG( LogContentBrowser, Log, TEXT( "Unable to sync content browser, all browsers appear to be locked" ) );
}
}
void FContentBrowserSingleton::SyncBrowserToAssets(const TArray<UObject*>& AssetList, bool bAllowLockedBrowsers)
{
// Convert UObject* array to FAssetData array
TArray<FAssetData> AssetDataList;
for (int32 AssetIdx = 0; AssetIdx < AssetList.Num(); ++AssetIdx)
{
if ( AssetList[AssetIdx] )
{
AssetDataList.Add( FAssetData(AssetList[AssetIdx]) );
}
}
SyncBrowserToAssets(AssetDataList, bAllowLockedBrowsers);
}
void FContentBrowserSingleton::GetSelectedAssets(TArray<FAssetData>& SelectedAssets)
{
if ( PrimaryContentBrowser.IsValid() )
{
PrimaryContentBrowser.Pin()->GetSelectedAssets(SelectedAssets);
}
}
void FContentBrowserSingleton::OnEditorLoadSelectedAssetsIfNeeded()
{
if ( PrimaryContentBrowser.IsValid() )
{
PrimaryContentBrowser.Pin()->LoadSelectedObjectsIfNeeded();
}
}
FContentBrowserSingleton& FContentBrowserSingleton::Get()
{
static const FName ModuleName = "ContentBrowser";
FContentBrowserModule& Module = FModuleManager::GetModuleChecked<FContentBrowserModule>(ModuleName);
return static_cast<FContentBrowserSingleton&>(Module.Get());
}
void FContentBrowserSingleton::SetPrimaryContentBrowser(const TSharedRef<SContentBrowser>& NewPrimaryBrowser)
{
if ( PrimaryContentBrowser.IsValid() && PrimaryContentBrowser.Pin().ToSharedRef() == NewPrimaryBrowser )
{
// This is already the primary content browser
return;
}
if ( PrimaryContentBrowser.IsValid() )
{
PrimaryContentBrowser.Pin()->SetIsPrimaryContentBrowser(false);
}
PrimaryContentBrowser = NewPrimaryBrowser;
NewPrimaryBrowser->SetIsPrimaryContentBrowser(true);
}
void FContentBrowserSingleton::ContentBrowserClosed(const TSharedRef<SContentBrowser>& ClosedBrowser)
{
// Find the browser in the all browsers list
for (int32 BrowserIdx = AllContentBrowsers.Num() - 1; BrowserIdx >= 0; --BrowserIdx)
{
if ( !AllContentBrowsers[BrowserIdx].IsValid() || AllContentBrowsers[BrowserIdx].Pin() == ClosedBrowser )
{
AllContentBrowsers.RemoveAt(BrowserIdx);
}
}
if ( !PrimaryContentBrowser.IsValid() || ClosedBrowser == PrimaryContentBrowser.Pin() )
{
ChooseNewPrimaryBrowser();
}
BrowserToLastKnownTabManagerMap.Add(ClosedBrowser->GetInstanceName(), ClosedBrowser->GetTabManager());
}
TSharedRef<FNativeClassHierarchy> FContentBrowserSingleton::GetNativeClassHierarchy()
{
if(!NativeClassHierarchy.IsValid())
{
NativeClassHierarchy = MakeShareable(new FNativeClassHierarchy());
}
return NativeClassHierarchy.ToSharedRef();
}
Merging using UE4-Fortnite-To-UE4 from CL 2261973 Includes the following engine-level changes (among others; biggest change is enabling world assets by default): CL 2252857 added dynamic allocations for path finding, removed hardcoded limit of 128 polys in path corridor CL 2256142 Added support for native arrays in JSON object converter. - Permissive in treating arrays of size 1 and scalars as equivalent - Excess elements in JSON are ignored. Serialization succeeds but a warning is logged CL 2256073 Fixed a bug in ARecastNavMesh::BatchRaycast resulting in NaN hit locations CL 2253797 #UE4 More aggressively setting RF_Public and RF_Standalone flags on maps and ensuring world names match package names. This is necessary because umaps are currently being managed outside of the content browser and it is causing a few issues. Also, packages containing maps now synthesize asset data when the package contains absolutely no asset data (probably because the UWorld in it was not RF_Public at the time it was saved due to a previous bug). CL 2258142 #UE4 Added a GC during map load that reclaims memory allocated during load/init. This is needed to finish the load on low-memory devices in games that allocate more memory after load. CL 2247003 Added homing to ProjectileMovementComponent - Homing requires both a bool and a target component to be set, the strength is determined by a customizable variable - Both homing and gravity are now applied in the new virtual function "CalculateAcceleration" CL 2247249 Moved the homing modification to acceleration occur in a separate function specifically for homing CL 2257043 - Guard net dormancy calls against executing on clients, based on thread with DaveR and JohnP; This particular case was the result of an intentionally client-authoritative actor calling the dormancy functions via inheritance CL 2245629 #UE4 - fixed json TryGetNumber to round negatives appropriately CL 2255312 #UE4 Enabling World Assets by default. CL 2260956 Analytics ET now loads HTTP at StartupModule so the module will be available during ShutdownModule to flush events CL 2245571 GenericTeamAgentInterface can now retrieve attitude of an agent towards a given actor #UE4 - Made PerceptionSystem's sight sense take advantage of that CL 2246897 Fixed perception listeners not being removed from the PerceptionSystem on Owner's end play #UE4 - addresses TTP#343392 CL 2260634 added more debug data for NaN in crowd simulation CL 2248387 Added possibility to debug multiple EQS queries with GameplayDebugger. #ue4 Fixed network replication from bandwidth point of view for data in GameplayDebugger. #ue4 CL 2253281 Added additional information to the visual logger for UBTCompositeNode::DoDecoratorsAllowExecution - We now keep track of whether a decorator allows execution, in addition to the existing log for not allowing execution CL 2255310 #UE4 The world browser module now listens to WorldAdded/WorldDestroyed events instead of WorldInit/WorldCleanup events. Worlds can be initialized without being the editor world and this handles that case. CL 2258256 #UE4 Replacing the SOpenLevelDialog with a new generic SAssetDialog. This dialog will be used as a generic Open or Save As dialog for assets. [CL 2266822 by Billy Bramer in Main branch]
2014-08-21 20:30:51 -04:00
void FContentBrowserSingleton::SharedCreateAssetDialogWindow(const TSharedRef<SAssetDialog>& AssetDialog, const FSharedAssetDialogConfig& InConfig, bool bModal) const
{
const FVector2D DefaultWindowSize(1152.0f, 648.0f);
const FVector2D WindowSize = InConfig.WindowSizeOverride.IsZero() ? DefaultWindowSize : InConfig.WindowSizeOverride;
const FText WindowTitle = InConfig.DialogTitleOverride.IsEmpty() ? LOCTEXT("GenericAssetDialogWindowHeader", "Asset Dialog") : InConfig.DialogTitleOverride;
TSharedRef<SWindow> DialogWindow =
SNew(SWindow)
.Title(WindowTitle)
.ClientSize(WindowSize);
DialogWindow->SetContent(AssetDialog);
IMainFrameModule& MainFrameModule = FModuleManager::LoadModuleChecked<IMainFrameModule>(TEXT("MainFrame"));
const TSharedPtr<SWindow>& MainFrameParentWindow = MainFrameModule.GetParentWindow();
if (MainFrameParentWindow.IsValid())
{
if (bModal)
{
FSlateApplication::Get().AddModalWindow(DialogWindow, MainFrameParentWindow.ToSharedRef());
}
else if (FGlobalTabmanager::Get()->GetRootWindow().IsValid())
Merging using UE4-Fortnite-To-UE4 from CL 2261973 Includes the following engine-level changes (among others; biggest change is enabling world assets by default): CL 2252857 added dynamic allocations for path finding, removed hardcoded limit of 128 polys in path corridor CL 2256142 Added support for native arrays in JSON object converter. - Permissive in treating arrays of size 1 and scalars as equivalent - Excess elements in JSON are ignored. Serialization succeeds but a warning is logged CL 2256073 Fixed a bug in ARecastNavMesh::BatchRaycast resulting in NaN hit locations CL 2253797 #UE4 More aggressively setting RF_Public and RF_Standalone flags on maps and ensuring world names match package names. This is necessary because umaps are currently being managed outside of the content browser and it is causing a few issues. Also, packages containing maps now synthesize asset data when the package contains absolutely no asset data (probably because the UWorld in it was not RF_Public at the time it was saved due to a previous bug). CL 2258142 #UE4 Added a GC during map load that reclaims memory allocated during load/init. This is needed to finish the load on low-memory devices in games that allocate more memory after load. CL 2247003 Added homing to ProjectileMovementComponent - Homing requires both a bool and a target component to be set, the strength is determined by a customizable variable - Both homing and gravity are now applied in the new virtual function "CalculateAcceleration" CL 2247249 Moved the homing modification to acceleration occur in a separate function specifically for homing CL 2257043 - Guard net dormancy calls against executing on clients, based on thread with DaveR and JohnP; This particular case was the result of an intentionally client-authoritative actor calling the dormancy functions via inheritance CL 2245629 #UE4 - fixed json TryGetNumber to round negatives appropriately CL 2255312 #UE4 Enabling World Assets by default. CL 2260956 Analytics ET now loads HTTP at StartupModule so the module will be available during ShutdownModule to flush events CL 2245571 GenericTeamAgentInterface can now retrieve attitude of an agent towards a given actor #UE4 - Made PerceptionSystem's sight sense take advantage of that CL 2246897 Fixed perception listeners not being removed from the PerceptionSystem on Owner's end play #UE4 - addresses TTP#343392 CL 2260634 added more debug data for NaN in crowd simulation CL 2248387 Added possibility to debug multiple EQS queries with GameplayDebugger. #ue4 Fixed network replication from bandwidth point of view for data in GameplayDebugger. #ue4 CL 2253281 Added additional information to the visual logger for UBTCompositeNode::DoDecoratorsAllowExecution - We now keep track of whether a decorator allows execution, in addition to the existing log for not allowing execution CL 2255310 #UE4 The world browser module now listens to WorldAdded/WorldDestroyed events instead of WorldInit/WorldCleanup events. Worlds can be initialized without being the editor world and this handles that case. CL 2258256 #UE4 Replacing the SOpenLevelDialog with a new generic SAssetDialog. This dialog will be used as a generic Open or Save As dialog for assets. [CL 2266822 by Billy Bramer in Main branch]
2014-08-21 20:30:51 -04:00
{
FSlateApplication::Get().AddWindowAsNativeChild(DialogWindow, MainFrameParentWindow.ToSharedRef());
}
else
{
FSlateApplication::Get().AddWindow(DialogWindow);
}
Merging using UE4-Fortnite-To-UE4 from CL 2261973 Includes the following engine-level changes (among others; biggest change is enabling world assets by default): CL 2252857 added dynamic allocations for path finding, removed hardcoded limit of 128 polys in path corridor CL 2256142 Added support for native arrays in JSON object converter. - Permissive in treating arrays of size 1 and scalars as equivalent - Excess elements in JSON are ignored. Serialization succeeds but a warning is logged CL 2256073 Fixed a bug in ARecastNavMesh::BatchRaycast resulting in NaN hit locations CL 2253797 #UE4 More aggressively setting RF_Public and RF_Standalone flags on maps and ensuring world names match package names. This is necessary because umaps are currently being managed outside of the content browser and it is causing a few issues. Also, packages containing maps now synthesize asset data when the package contains absolutely no asset data (probably because the UWorld in it was not RF_Public at the time it was saved due to a previous bug). CL 2258142 #UE4 Added a GC during map load that reclaims memory allocated during load/init. This is needed to finish the load on low-memory devices in games that allocate more memory after load. CL 2247003 Added homing to ProjectileMovementComponent - Homing requires both a bool and a target component to be set, the strength is determined by a customizable variable - Both homing and gravity are now applied in the new virtual function "CalculateAcceleration" CL 2247249 Moved the homing modification to acceleration occur in a separate function specifically for homing CL 2257043 - Guard net dormancy calls against executing on clients, based on thread with DaveR and JohnP; This particular case was the result of an intentionally client-authoritative actor calling the dormancy functions via inheritance CL 2245629 #UE4 - fixed json TryGetNumber to round negatives appropriately CL 2255312 #UE4 Enabling World Assets by default. CL 2260956 Analytics ET now loads HTTP at StartupModule so the module will be available during ShutdownModule to flush events CL 2245571 GenericTeamAgentInterface can now retrieve attitude of an agent towards a given actor #UE4 - Made PerceptionSystem's sight sense take advantage of that CL 2246897 Fixed perception listeners not being removed from the PerceptionSystem on Owner's end play #UE4 - addresses TTP#343392 CL 2260634 added more debug data for NaN in crowd simulation CL 2248387 Added possibility to debug multiple EQS queries with GameplayDebugger. #ue4 Fixed network replication from bandwidth point of view for data in GameplayDebugger. #ue4 CL 2253281 Added additional information to the visual logger for UBTCompositeNode::DoDecoratorsAllowExecution - We now keep track of whether a decorator allows execution, in addition to the existing log for not allowing execution CL 2255310 #UE4 The world browser module now listens to WorldAdded/WorldDestroyed events instead of WorldInit/WorldCleanup events. Worlds can be initialized without being the editor world and this handles that case. CL 2258256 #UE4 Replacing the SOpenLevelDialog with a new generic SAssetDialog. This dialog will be used as a generic Open or Save As dialog for assets. [CL 2266822 by Billy Bramer in Main branch]
2014-08-21 20:30:51 -04:00
}
else
{
if (ensureMsgf(!bModal, TEXT("Could not create asset dialog because modal windows must have a parent and this was called at a time where the mainframe window does not exist.")))
{
FSlateApplication::Get().AddWindow(DialogWindow);
}
}
}
void FContentBrowserSingleton::ChooseNewPrimaryBrowser()
{
// Find the first valid browser and trim any invalid browsers along the way
for (int32 BrowserIdx = 0; BrowserIdx < AllContentBrowsers.Num(); ++BrowserIdx)
{
if ( AllContentBrowsers[BrowserIdx].IsValid() )
{
SetPrimaryContentBrowser(AllContentBrowsers[BrowserIdx].Pin().ToSharedRef());
break;
}
else
{
// Trim any invalid content browsers
AllContentBrowsers.RemoveAt(BrowserIdx);
BrowserIdx--;
}
}
}
void FContentBrowserSingleton::FocusContentBrowser(const TSharedPtr<SContentBrowser>& BrowserToFocus)
{
if ( BrowserToFocus.IsValid() )
{
TSharedRef<SContentBrowser> Browser = BrowserToFocus.ToSharedRef();
TSharedPtr<FTabManager> TabManager = Browser->GetTabManager();
if ( TabManager.IsValid() )
{
TabManager->InvokeTab(Browser->GetInstanceName());
}
}
}
void FContentBrowserSingleton::SummonNewBrowser(bool bAllowLockedBrowsers)
{
TSet<FName> OpenBrowserIDs;
// Find all currently open browsers to help find the first open slot
for (int32 BrowserIdx = AllContentBrowsers.Num() - 1; BrowserIdx >= 0; --BrowserIdx)
{
const TWeakPtr<SContentBrowser>& Browser = AllContentBrowsers[BrowserIdx];
if ( Browser.IsValid() )
{
OpenBrowserIDs.Add(Browser.Pin()->GetInstanceName());
}
}
FName NewTabName;
for ( int32 BrowserIdx = 0; BrowserIdx < ARRAY_COUNT(ContentBrowserTabIDs); BrowserIdx++ )
{
FName TestTabID = ContentBrowserTabIDs[BrowserIdx];
if ( !OpenBrowserIDs.Contains(TestTabID) && (bAllowLockedBrowsers || !IsLocked(TestTabID)) )
{
// Found the first index that is not currently open
NewTabName = TestTabID;
break;
}
}
if ( NewTabName != NAME_None )
{
const TWeakPtr<FTabManager>& TabManagerToInvoke = BrowserToLastKnownTabManagerMap.FindRef(NewTabName);
if ( TabManagerToInvoke.IsValid() )
{
TabManagerToInvoke.Pin()->InvokeTab(NewTabName);
}
else
{
FGlobalTabmanager::Get()->InvokeTab(NewTabName);
}
}
else
{
// No available slots... don't summon anything
}
}
TSharedRef<SDockTab> FContentBrowserSingleton::SpawnContentBrowserTab( const FSpawnTabArgs& SpawnTabArgs, int32 BrowserIdx )
{
TAttribute<FText> Label = TAttribute<FText>::Create( TAttribute<FText>::FGetter::CreateRaw( this, &FContentBrowserSingleton::GetContentBrowserTabLabel, BrowserIdx ) );
TSharedRef<SDockTab> NewTab = SNew(SDockTab)
.TabRole(ETabRole::NomadTab)
.Label( Label )
.ToolTip( IDocumentation::Get()->CreateToolTip( Label, nullptr, "Shared/ContentBrowser", "Tab" ) );
TSharedRef<SContentBrowser> NewBrowser =
SNew( SContentBrowser, SpawnTabArgs.GetTabId().TabType )
.IsEnabled( FSlateApplication::Get().GetNormalExecutionAttribute() )
.ContainingTab( NewTab );
AllContentBrowsers.Add(NewBrowser);
if ( !PrimaryContentBrowser.IsValid() )
{
ChooseNewPrimaryBrowser();
}
// Add wrapper for tutorial highlighting
TSharedRef<SBox> Wrapper =
SNew(SBox)
.AddMetaData<FTutorialMetaData>(FTutorialMetaData(TEXT("ContentBrowser"), TEXT("ContentBrowserTab1")))
[
NewBrowser
];
NewTab->SetContent( Wrapper );
return NewTab;
}
bool FContentBrowserSingleton::IsLocked(const FName& InstanceName) const
{
// First try all the open browsers, as their locked state might be newer than the configs
for (int32 AllBrowsersIdx = AllContentBrowsers.Num() - 1; AllBrowsersIdx >= 0; --AllBrowsersIdx)
{
const TWeakPtr<SContentBrowser>& Browser = AllContentBrowsers[AllBrowsersIdx];
if ( Browser.IsValid() && Browser.Pin()->GetInstanceName() == InstanceName )
{
return Browser.Pin()->IsLocked();
}
}
// Fallback to getting the locked state from the config instead
bool bIsLocked = false;
GConfig->GetBool(*SContentBrowser::SettingsIniSection, *(InstanceName.ToString() + TEXT(".Locked")), bIsLocked, GEditorPerProjectIni);
return bIsLocked;
}
FText FContentBrowserSingleton::GetContentBrowserLabelWithIndex( int32 BrowserIdx )
{
return FText::Format(LOCTEXT("ContentBrowserTabNameWithIndex", "Content Browser {0}"), FText::AsNumber(BrowserIdx + 1));
}
FText FContentBrowserSingleton::GetContentBrowserTabLabel(int32 BrowserIdx)
{
int32 NumOpenContentBrowsers = 0;
for (int32 AllBrowsersIdx = AllContentBrowsers.Num() - 1; AllBrowsersIdx >= 0; --AllBrowsersIdx)
{
const TWeakPtr<SContentBrowser>& Browser = AllContentBrowsers[AllBrowsersIdx];
if ( Browser.IsValid() )
{
NumOpenContentBrowsers++;
}
else
{
AllContentBrowsers.RemoveAt(AllBrowsersIdx);
}
}
if ( NumOpenContentBrowsers > 1 )
{
return GetContentBrowserLabelWithIndex( BrowserIdx );
}
else
{
return LOCTEXT("ContentBrowserTabName", "Content Browser");
}
}
#undef LOCTEXT_NAMESPACE