// 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" #include "Styling/AppStyle.h" #define LOCTEXT_NAMESPACE "DataLayer" void SDataLayerBrowser::Construct(const FArguments& InArgs) { FPropertyEditorModule& PropertyModule = FModuleManager::LoadModuleChecked("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(FAppStyle::GetBrush("DataLayerBrowser.DataLayerContentsQuickbarBackground")) .Visibility(EVisibility::Visible); ////////////////////////////////////////////////////////////////////////// // DataLayer Contents Section FGetTextForItem InternalNameInfoText = FGetTextForItem::CreateLambda([](const ISceneOutlinerTreeItem& Item) -> FString { if (const FDataLayerTreeItem* DataLayerItem = Item.CastTo()) { if (const UDataLayerInstance* DataLayerInstance = DataLayerItem->GetDataLayer()) { return DataLayerInstance->GetDataLayerFName().ToString(); } } else if (const FDataLayerActorTreeItem* DataLayerActorTreeItem = Item.CastTo()) { if (const AActor* Actor = DataLayerActorTreeItem->GetActor()) { return Actor->GetFName().ToString(); } } else if (const FDataLayerActorDescTreeItem* ActorDescItem = Item.CastTo()) { 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()) { if (const UDataLayerInstance* DataLayerInstance = DataLayerItem->GetDataLayer()) { if (DataLayerInstance->IsRuntime()) { return GetDataLayerRuntimeStateName(DataLayerInstance->GetInitialRuntimeState()); } } } return FString(); }); SAssignNew(DeprecatedDataLayerWarningBox, SMultiLineEditableTextBox) .IsReadOnly(true) .Font(IDetailLayoutBuilder::GetDetailFontBold()) .BackgroundColor(FAppStyle::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.bShowTransient = true; 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(FAppStyle::GetBrush("NoBrush")) .Content() [ SNew(SVerticalBox) + SVerticalBox::Slot() .AutoHeight() [ DeprecatedDataLayerWarningBox.ToSharedRef() ] + SVerticalBox::Slot() [ // Data Layer Outliner SNew(SSplitter) .Orientation(Orient_Vertical) .Style(FAppStyle::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>& InSelectedDataLayersSet) { SelectedDataLayersSet = InSelectedDataLayersSet; TArray SelectedDataLayers; for (const auto& WeakDataLayer : SelectedDataLayersSet) { if (WeakDataLayer.IsValid()) { UDataLayerInstance* DataLayer = const_cast(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