Files
UnrealEngineUWP/Engine/Source/Editor/DataLayerEditor/Private/DataLayer/SDataLayerBrowser.cpp
philippe deseve 8218e80ef1 UDataLayer deprecated in favor of UDataLayerInstance & UDataLayerAsset
UDeprecatedDataLayerInstance allows to boot level using deprecated UDataLayers
Worlds using DataLayer can run the DataLayerToAssetCommandlet to transition their existing DataLayers
FActorDataLayer interface is deprecated.
DataLayers Blueprint referencers should now use DataLayerAsset to retrieve DataLayerInstances.
DataLayer Code referencers should now use DataLayerAssets or DataLayerInstance FName to retrieve DataLayerInstances.
DataLayerLabels now only used for display/UI purpose
Relabeling DataLayers is not permitted anymore on new DataLayerInstances (allowed on UDeprecatedDataLayerInstance)
Added Changelist Validation for DataLayers
Added a column to the datalayer outliner showing any data layer errors.

#rb richard.mal jeanfrancois.dube
#preflight 623098c2050dc69468b6a297 (errors only related to lyra, which do not exist in this stream)

#ROBOMERGE-OWNER: philippe.deseve
#ROBOMERGE-AUTHOR: philippe.deseve
#ROBOMERGE-SOURCE: CL 19385808 via CL 19387392
#ROBOMERGE-BOT: UE5 (Release-Engine-Staging -> Main) (v926-19321884)

[CL 19389077 by philippe deseve in ue5-main branch]
2022-03-15 13:52:28 -04:00

215 lines
8.6 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "SDataLayerBrowser.h"
#include "Framework/Application/SlateApplication.h"
#include "Widgets/Input/SButton.h"
#include "SDataLayerOutliner.h"
#include "DataLayersActorDescTreeItem.h"
#include "DataLayerActorTreeItem.h"
#include "DataLayerTreeItem.h"
#include "DataLayerMode.h"
#include "WorldPartition/WorldPartitionEditorPerProjectUserSettings.h"
#include "WorldPartition/DataLayer/DataLayerInstance.h"
#include "DataLayerOutlinerIsVisibleColumn.h"
#include "DataLayerOutlinerIsLoadedInEditorColumn.h"
#include "DataLayerOutlinerDeleteButtonColumn.h"
#include "DataLayerOutlinerHasErrorColumn.h"
#include "DataLayer/DataLayerEditorSubsystem.h"
#include "WorldPartition/DataLayer/DataLayerInstance.h"
#include "WorldPartition/WorldPartitionSubsystem.h"
#include "Modules/ModuleManager.h"
#include "ScopedTransaction.h"
#include "SceneOutlinerTextInfoColumn.h"
#include "Editor.h"
#include "Widgets/Input/SMultiLineEditableTextBox.h"
#include "DetailLayoutBuilder.h"
#include "WorldPartition/DataLayer/WorldDataLayers.h"
#define LOCTEXT_NAMESPACE "DataLayer"
void SDataLayerBrowser::Construct(const FArguments& InArgs)
{
FPropertyEditorModule& PropertyModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor");
FDetailsViewArgs Args;
Args.NameAreaSettings = FDetailsViewArgs::HideNameArea;
Args.bAllowSearch = true;
Args.bAllowFavoriteSystem = true;
Args.bHideSelectionTip = true;
Args.bShowObjectLabel = true;
Args.NameAreaSettings = FDetailsViewArgs::ObjectsUseNameArea;
Args.ColumnWidth = 0.5f;
DetailsWidget = PropertyModule.CreateDetailView(Args);
DetailsWidget->SetVisibility(EVisibility::Visible);
//////////////////////////////////////////////////////////////////////////
// DataLayer Contents Header
SAssignNew(DataLayerContentsHeader, SBorder)
.BorderImage(FEditorStyle::GetBrush("DataLayerBrowser.DataLayerContentsQuickbarBackground"))
.Visibility(EVisibility::Visible);
//////////////////////////////////////////////////////////////////////////
// DataLayer Contents Section
FGetTextForItem InternalNameInfoText = FGetTextForItem::CreateLambda([](const ISceneOutlinerTreeItem& Item) -> FString
{
if (const FDataLayerTreeItem* DataLayerItem = Item.CastTo<FDataLayerTreeItem>())
{
if (const UDataLayerInstance* DataLayerInstance = DataLayerItem->GetDataLayer())
{
return DataLayerInstance->GetDataLayerFName().ToString();
}
}
else if (const FDataLayerActorTreeItem* DataLayerActorTreeItem = Item.CastTo<FDataLayerActorTreeItem>())
{
if (const AActor* Actor = DataLayerActorTreeItem->GetActor())
{
return Actor->GetFName().ToString();
}
}
else if (const FDataLayerActorDescTreeItem* ActorDescItem = Item.CastTo<FDataLayerActorDescTreeItem>())
{
if (const FWorldPartitionActorDesc* ActorDesc = ActorDescItem->ActorDescHandle.Get())
{
return ActorDesc->GetActorName().ToString();
}
}
return FString();
});
FGetTextForItem InternalInitialRuntimeStateInfoText = FGetTextForItem::CreateLambda([](const ISceneOutlinerTreeItem& Item) -> FString
{
if (const FDataLayerTreeItem* DataLayerItem = Item.CastTo<FDataLayerTreeItem>())
{
if (const UDataLayerInstance* DataLayerInstance = DataLayerItem->GetDataLayer())
{
if (DataLayerInstance->IsRuntime())
{
return GetDataLayerRuntimeStateName(DataLayerInstance->GetInitialRuntimeState());
}
}
}
return FString();
});
SAssignNew(DeprecatedDataLayerWarningBox, SMultiLineEditableTextBox)
.IsReadOnly(true)
.Font(IDetailLayoutBuilder::GetDetailFontBold())
.BackgroundColor(FEditorStyle::GetColor("ErrorReporting.WarningBackgroundColor"))
.Text(LOCTEXT("Deprecated_DataLayers", "Some data within DataLayers is deprecated. Run DataLayerToAssetCommandlet to create DataLayerInstances and DataLayer Assets for this level."))
.AutoWrapText(true)
.Visibility_Lambda([]() { return UDataLayerEditorSubsystem::Get()->HasDeprecatedDataLayers() ? EVisibility::Visible : EVisibility::Collapsed; });
FSceneOutlinerInitializationOptions InitOptions;
InitOptions.bShowHeaderRow = true;
InitOptions.bShowParentTree = true;
InitOptions.bShowCreateNewFolder = false;
InitOptions.ModeFactory = FCreateSceneOutlinerMode::CreateLambda([this](SSceneOutliner* Outliner) { return new FDataLayerMode(FDataLayerModeParams(Outliner, this, nullptr)); });
InitOptions.ColumnMap.Add(FDataLayerOutlinerIsVisibleColumn::GetID(), FSceneOutlinerColumnInfo(ESceneOutlinerColumnVisibility::Visible, 0, FCreateSceneOutlinerColumn::CreateLambda([](ISceneOutliner& InSceneOutliner) { return MakeShareable(new FDataLayerOutlinerIsVisibleColumn(InSceneOutliner)); })));
InitOptions.ColumnMap.Add(FDataLayerOutlinerIsLoadedInEditorColumn::GetID(), FSceneOutlinerColumnInfo(ESceneOutlinerColumnVisibility::Visible, 1, FCreateSceneOutlinerColumn::CreateLambda([](ISceneOutliner& InSceneOutliner) { return MakeShareable(new FDataLayerOutlinerIsLoadedInEditorColumn(InSceneOutliner)); })));
InitOptions.ColumnMap.Add(FSceneOutlinerBuiltInColumnTypes::Label(), FSceneOutlinerColumnInfo(ESceneOutlinerColumnVisibility::Visible, 2));
InitOptions.ColumnMap.Add(FDataLayerOutlinerDeleteButtonColumn::GetID(), FSceneOutlinerColumnInfo(ESceneOutlinerColumnVisibility::Visible, 10, FCreateSceneOutlinerColumn::CreateLambda([](ISceneOutliner& InSceneOutliner) { return MakeShareable(new FDataLayerOutlinerDeleteButtonColumn(InSceneOutliner)); })));
InitOptions.ColumnMap.Add("ID Name", FSceneOutlinerColumnInfo(ESceneOutlinerColumnVisibility::Invisible, 20, FCreateSceneOutlinerColumn::CreateStatic(&FTextInfoColumn::CreateTextInfoColumn, FName("ID Name"), InternalNameInfoText, FText::GetEmpty())));
InitOptions.ColumnMap.Add("Initial State", FSceneOutlinerColumnInfo(ESceneOutlinerColumnVisibility::Invisible, 20, FCreateSceneOutlinerColumn::CreateStatic(&FTextInfoColumn::CreateTextInfoColumn, FName("Initial State"), InternalInitialRuntimeStateInfoText, FText::FromString("Initial Runtime State"))));
InitOptions.ColumnMap.Add(FDataLayerOutlinerHasErrorsColumn::GetID(), FSceneOutlinerColumnInfo(ESceneOutlinerColumnVisibility::Visible, 100, FCreateSceneOutlinerColumn::CreateLambda([](ISceneOutliner& InSceneOutliner) { return MakeShareable(new FDataLayerOutlinerHasErrorsColumn(InSceneOutliner)); }), false));
DataLayerOutliner = SNew(SDataLayerOutliner, InitOptions).IsEnabled(FSlateApplication::Get().GetNormalExecutionAttribute());
SAssignNew(DataLayerContentsSection, SBorder)
.Padding(5)
.BorderImage(FEditorStyle::GetBrush("NoBrush"))
.Content()
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
[
DeprecatedDataLayerWarningBox.ToSharedRef()
]
+ SVerticalBox::Slot()
[
// Data Layer Outliner
SNew(SSplitter)
.Orientation(Orient_Vertical)
.Style(FEditorStyle::Get(), "DetailsView.Splitter")
+ SSplitter::Slot()
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
[
DataLayerOutliner.ToSharedRef()
]
]
// Details
+ SSplitter::Slot()
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.Padding(2, 4, 0, 0)
[
DetailsWidget.ToSharedRef()
]
]
]
];
//////////////////////////////////////////////////////////////////////////
// DataLayer Browser
ChildSlot
[
SAssignNew(ContentAreaBox, SVerticalBox)
.IsEnabled_Lambda([]() { return GWorld ? UWorld::IsPartitionedWorld(GWorld) : false; })
];
InitializeDataLayerBrowser();
}
void SDataLayerBrowser::SyncDataLayerBrowserToDataLayer(const UDataLayerInstance* DataLayer)
{
FSceneOutlinerTreeItemPtr Item = DataLayerOutliner->GetTreeItem(DataLayer);
if (Item.IsValid())
{
DataLayerOutliner->SetItemSelection(Item, true, ESelectInfo::OnMouseClick);
FSceneOutlinerTreeItemPtr Parent = Item->GetParent();
while(Parent.IsValid())
{
DataLayerOutliner->SetItemExpansion(Parent, true);
Parent = Parent->GetParent();
};
}
}
void SDataLayerBrowser::OnSelectionChanged(TSet<TWeakObjectPtr<const UDataLayerInstance>>& InSelectedDataLayersSet)
{
SelectedDataLayersSet = InSelectedDataLayersSet;
TArray<UObject*> SelectedDataLayers;
for (const auto& WeakDataLayer : SelectedDataLayersSet)
{
if (WeakDataLayer.IsValid())
{
UDataLayerInstance* DataLayer = const_cast<UDataLayerInstance*>(WeakDataLayer.Get());
SelectedDataLayers.Add(DataLayer);
}
}
DetailsWidget->SetObjects(SelectedDataLayers, /*bForceRefresh*/ true);
}
void SDataLayerBrowser::InitializeDataLayerBrowser()
{
ContentAreaBox->ClearChildren();
ContentAreaBox->AddSlot()
.AutoHeight()
.FillHeight(1.0f)
[
DataLayerContentsSection.ToSharedRef()
];
ContentAreaBox->AddSlot()
.AutoHeight()
.VAlign(VAlign_Bottom)
.MaxHeight(23)
[
DataLayerContentsHeader.ToSharedRef()
];
}
#undef LOCTEXT_NAMESPACE