2020-10-28 06:51:40 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "SDataLayerBrowser.h"
2022-08-30 23:03:03 -04:00
# include "Containers/Array.h"
# include "Containers/Map.h"
# include "Containers/UnrealString.h"
# include "DataLayer/DataLayerEditorSubsystem.h"
2020-10-28 06:51:40 -04:00
# include "DataLayerActorTreeItem.h"
# include "DataLayerMode.h"
# include "DataLayerOutlinerDeleteButtonColumn.h"
2024-02-26 12:27:21 -05:00
# include "DataLayerOutlinerDebugColorColumn.h"
2022-03-15 13:52:28 -04:00
# include "DataLayerOutlinerHasErrorColumn.h"
2022-08-30 23:03:03 -04:00
# include "DataLayerOutlinerIsLoadedInEditorColumn.h"
# include "DataLayerOutlinerIsVisibleColumn.h"
# include "DataLayerTreeItem.h"
# include "DataLayersActorDescTreeItem.h"
# include "Delegates/Delegate.h"
2022-03-15 13:52:28 -04:00
# include "DetailLayoutBuilder.h"
2022-08-30 23:03:03 -04:00
# include "DetailsViewArgs.h"
# include "Engine/World.h"
# include "Fonts/SlateFontInfo.h"
# include "Framework/Application/SlateApplication.h"
# include "GameFramework/Actor.h"
# include "HAL/PlatformCrt.h"
# include "IDetailsView.h"
# include "ISceneOutlinerTreeItem.h"
# include "Internationalization/Internationalization.h"
# include "Internationalization/Text.h"
# include "Layout/Children.h"
# include "Layout/Margin.h"
# include "Layout/Visibility.h"
# include "Math/Color.h"
# include "Misc/Attribute.h"
# include "Modules/ModuleManager.h"
# include "PropertyEditorModule.h"
# include "SDataLayerOutliner.h"
# include "SSceneOutliner.h"
# include "SceneOutlinerFwd.h"
# include "SceneOutlinerPublicTypes.h"
# include "SceneOutlinerTextInfoColumn.h"
# include "SlotBase.h"
2022-05-09 13:51:26 -04:00
# include "Styling/AppStyle.h"
2022-08-30 23:03:03 -04:00
# include "Styling/SlateColor.h"
# include "Types/SlateEnums.h"
# include "UObject/NameTypes.h"
# include "UObject/WeakObjectPtr.h"
# include "Widgets/Input/SMultiLineEditableTextBox.h"
# include "Widgets/Layout/SBorder.h"
# include "Widgets/Layout/SSplitter.h"
# include "Widgets/SBoxPanel.h"
# include "WorldPartition/DataLayer/DataLayerInstance.h"
# include "WorldPartition/WorldPartitionActorDesc.h"
# include "WorldPartition/WorldPartitionHandle.h"
2023-02-28 08:35:38 -05:00
# include "Editor.h"
2022-08-30 23:03:03 -04:00
2022-08-30 23:04:40 -04:00
class ISceneOutliner ;
2022-08-30 23:03:03 -04:00
class UObject ;
2020-10-28 06:51:40 -04:00
# define LOCTEXT_NAMESPACE "DataLayer"
void SDataLayerBrowser : : Construct ( const FArguments & InArgs )
{
2021-01-27 13:03:11 -04:00
FPropertyEditorModule & PropertyModule = FModuleManager : : LoadModuleChecked < FPropertyEditorModule > ( " PropertyEditor " ) ;
FDetailsViewArgs Args ;
Args . NameAreaSettings = FDetailsViewArgs : : HideNameArea ;
2021-11-07 23:43:01 -05:00
Args . bAllowSearch = true ;
Args . bAllowFavoriteSystem = true ;
2021-01-27 13:03:11 -04:00
Args . bHideSelectionTip = true ;
2021-11-07 23:43:01 -05:00
Args . bShowObjectLabel = true ;
Args . NameAreaSettings = FDetailsViewArgs : : ObjectsUseNameArea ;
Args . ColumnWidth = 0.5f ;
2021-01-27 13:03:11 -04:00
DetailsWidget = PropertyModule . CreateDetailView ( Args ) ;
DetailsWidget - > SetVisibility ( EVisibility : : Visible ) ;
2020-10-28 06:51:40 -04:00
//////////////////////////////////////////////////////////////////////////
// DataLayer Contents Header
SAssignNew ( DataLayerContentsHeader , SBorder )
2022-05-09 13:12:28 -04:00
. BorderImage ( FAppStyle : : GetBrush ( " DataLayerBrowser.DataLayerContentsQuickbarBackground " ) )
2021-11-07 23:43:01 -05:00
. Visibility ( EVisibility : : Visible ) ;
2020-10-28 06:51:40 -04:00
//////////////////////////////////////////////////////////////////////////
// DataLayer Contents Section
2021-11-07 23:43:01 -05:00
FGetTextForItem InternalNameInfoText = FGetTextForItem : : CreateLambda ( [ ] ( const ISceneOutlinerTreeItem & Item ) - > FString
{
if ( const FDataLayerTreeItem * DataLayerItem = Item . CastTo < FDataLayerTreeItem > ( ) )
{
2022-03-15 13:52:28 -04:00
if ( const UDataLayerInstance * DataLayerInstance = DataLayerItem - > GetDataLayer ( ) )
2021-11-07 23:43:01 -05:00
{
2022-03-15 13:52:28 -04:00
return DataLayerInstance - > GetDataLayerFName ( ) . ToString ( ) ;
2021-11-07 23:43:01 -05:00
}
}
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 > ( ) )
{
2024-02-07 15:42:38 -05:00
if ( const FWorldPartitionActorDescInstance * ActorDescInstance = * ActorDescItem - > ActorDescHandle )
2021-11-07 23:43:01 -05:00
{
2024-04-25 14:13:20 -04:00
return ActorDescInstance - > GetActorNameString ( ) ;
2021-11-07 23:43:01 -05:00
}
}
return FString ( ) ;
} ) ;
2021-11-26 12:24:24 -05:00
FGetTextForItem InternalInitialRuntimeStateInfoText = FGetTextForItem : : CreateLambda ( [ ] ( const ISceneOutlinerTreeItem & Item ) - > FString
{
if ( const FDataLayerTreeItem * DataLayerItem = Item . CastTo < FDataLayerTreeItem > ( ) )
{
2022-03-15 13:52:28 -04:00
if ( const UDataLayerInstance * DataLayerInstance = DataLayerItem - > GetDataLayer ( ) )
2021-11-26 12:24:24 -05:00
{
2022-03-15 13:52:28 -04:00
if ( DataLayerInstance - > IsRuntime ( ) )
2021-11-26 12:24:24 -05:00
{
2022-03-15 13:52:28 -04:00
return GetDataLayerRuntimeStateName ( DataLayerInstance - > GetInitialRuntimeState ( ) ) ;
2021-11-26 12:24:24 -05:00
}
}
}
return FString ( ) ;
} ) ;
2022-03-15 13:52:28 -04:00
SAssignNew ( DeprecatedDataLayerWarningBox , SMultiLineEditableTextBox )
. IsReadOnly ( true )
. Font ( IDetailLayoutBuilder : : GetDetailFontBold ( ) )
2022-05-09 13:51:26 -04:00
. BackgroundColor ( FAppStyle : : GetColor ( " ErrorReporting.WarningBackgroundColor " ) )
2022-03-15 13:52:28 -04:00
. 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 ; } ) ;
2020-10-28 06:51:40 -04:00
FSceneOutlinerInitializationOptions InitOptions ;
2024-02-26 12:27:21 -05:00
InitOptions . OutlinerIdentifier = TEXT ( " DataLayerEditorOutliner " ) ;
2021-11-07 23:43:01 -05:00
InitOptions . bShowHeaderRow = true ;
2020-10-28 06:51:40 -04:00
InitOptions . bShowParentTree = true ;
InitOptions . bShowCreateNewFolder = false ;
2022-05-10 10:22:54 -04:00
InitOptions . bShowTransient = true ;
2020-10-28 06:51:40 -04:00
InitOptions . ModeFactory = FCreateSceneOutlinerMode : : CreateLambda ( [ this ] ( SSceneOutliner * Outliner ) { return new FDataLayerMode ( FDataLayerModeParams ( Outliner , this , nullptr ) ) ; } ) ;
2021-11-07 23:43:01 -05:00
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 ) ) ; } ) ) ) ;
2020-10-28 06:51:40 -04:00
InitOptions . ColumnMap . Add ( FSceneOutlinerBuiltInColumnTypes : : Label ( ) , FSceneOutlinerColumnInfo ( ESceneOutlinerColumnVisibility : : Visible , 2 ) ) ;
2021-11-07 23:43:01 -05:00
InitOptions . ColumnMap . Add ( FDataLayerOutlinerDeleteButtonColumn : : GetID ( ) , FSceneOutlinerColumnInfo ( ESceneOutlinerColumnVisibility : : Visible , 10 , FCreateSceneOutlinerColumn : : CreateLambda ( [ ] ( ISceneOutliner & InSceneOutliner ) { return MakeShareable ( new FDataLayerOutlinerDeleteButtonColumn ( InSceneOutliner ) ) ; } ) ) ) ;
2021-11-26 12:24:24 -05:00
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 " ) ) ) ) ;
2022-03-15 13:52:28 -04:00
InitOptions . ColumnMap . Add ( FDataLayerOutlinerHasErrorsColumn : : GetID ( ) , FSceneOutlinerColumnInfo ( ESceneOutlinerColumnVisibility : : Visible , 100 , FCreateSceneOutlinerColumn : : CreateLambda ( [ ] ( ISceneOutliner & InSceneOutliner ) { return MakeShareable ( new FDataLayerOutlinerHasErrorsColumn ( InSceneOutliner ) ) ; } ) , false ) ) ;
2024-02-26 12:27:21 -05:00
InitOptions . ColumnMap . Add ( FDataLayerOutlinerDebugColorColumn : : GetID ( ) , FSceneOutlinerColumnInfo ( ESceneOutlinerColumnVisibility : : Invisible , 100 , FCreateSceneOutlinerColumn : : CreateLambda ( [ ] ( ISceneOutliner & InSceneOutliner ) { return MakeShareable ( new FDataLayerOutlinerDebugColorColumn ( InSceneOutliner ) ) ; } ) ) ) ;
2021-01-27 13:03:11 -04:00
DataLayerOutliner = SNew ( SDataLayerOutliner , InitOptions ) . IsEnabled ( FSlateApplication : : Get ( ) . GetNormalExecutionAttribute ( ) ) ;
2020-10-28 06:51:40 -04:00
SAssignNew ( DataLayerContentsSection , SBorder )
. Padding ( 5 )
2022-05-09 13:12:28 -04:00
. BorderImage ( FAppStyle : : GetBrush ( " NoBrush " ) )
2020-10-28 06:51:40 -04:00
. Content ( )
[
2022-03-15 13:52:28 -04:00
SNew ( SVerticalBox )
+ SVerticalBox : : Slot ( )
. AutoHeight ( )
2021-01-27 13:03:11 -04:00
[
2022-03-15 13:52:28 -04:00
DeprecatedDataLayerWarningBox . ToSharedRef ( )
2021-01-27 13:03:11 -04:00
]
2022-03-15 13:52:28 -04:00
+ SVerticalBox : : Slot ( )
2021-01-27 13:03:11 -04:00
[
2022-03-15 13:52:28 -04:00
// Data Layer Outliner
SNew ( SSplitter )
. Orientation ( Orient_Vertical )
2022-05-09 13:51:26 -04:00
. Style ( FAppStyle : : Get ( ) , " DetailsView.Splitter " )
2022-03-15 13:52:28 -04:00
+ SSplitter : : Slot ( )
2021-01-27 13:03:11 -04:00
[
2022-03-15 13:52:28 -04:00
SNew ( SVerticalBox )
+ SVerticalBox : : Slot ( )
[
DataLayerOutliner . ToSharedRef ( )
]
]
// Details
+ SSplitter : : Slot ( )
[
SNew ( SVerticalBox )
+ SVerticalBox : : Slot ( )
. Padding ( 2 , 4 , 0 , 0 )
[
DetailsWidget . ToSharedRef ( )
]
2021-01-27 13:03:11 -04:00
]
]
2020-10-28 06:51:40 -04:00
] ;
//////////////////////////////////////////////////////////////////////////
// DataLayer Browser
ChildSlot
[
SAssignNew ( ContentAreaBox , SVerticalBox )
2023-02-28 08:35:38 -05:00
. IsEnabled_Lambda ( [ ] ( )
{
if ( UWorld * World = GEditor ? GEditor - > GetEditorWorldContext ( ) . World ( ) : nullptr )
{
if ( ULevel * CurrentLevel = World - > GetCurrentLevel ( ) & & World - > GetCurrentLevel ( ) ! = World - > PersistentLevel ? World - > GetCurrentLevel ( ) : nullptr )
{
World = CurrentLevel - > GetTypedOuter < UWorld > ( ) ;
}
return UWorld : : IsPartitionedWorld ( World ) ;
}
return false ;
} )
2020-10-28 06:51:40 -04:00
] ;
2021-11-07 23:43:01 -05:00
InitializeDataLayerBrowser ( ) ;
}
2022-03-15 13:52:28 -04:00
void SDataLayerBrowser : : SyncDataLayerBrowserToDataLayer ( const UDataLayerInstance * DataLayer )
2021-11-07 23:43:01 -05:00
{
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 ( ) ;
} ;
}
2020-10-28 06:51:40 -04:00
}
2022-03-15 13:52:28 -04:00
void SDataLayerBrowser : : OnSelectionChanged ( TSet < TWeakObjectPtr < const UDataLayerInstance > > & InSelectedDataLayersSet )
2021-01-27 13:03:11 -04:00
{
SelectedDataLayersSet = InSelectedDataLayersSet ;
TArray < UObject * > SelectedDataLayers ;
for ( const auto & WeakDataLayer : SelectedDataLayersSet )
{
if ( WeakDataLayer . IsValid ( ) )
{
2022-03-15 13:52:28 -04:00
UDataLayerInstance * DataLayer = const_cast < UDataLayerInstance * > ( WeakDataLayer . Get ( ) ) ;
2021-11-07 23:43:01 -05:00
SelectedDataLayers . Add ( DataLayer ) ;
2021-01-27 13:03:11 -04:00
}
}
DetailsWidget - > SetObjects ( SelectedDataLayers , /*bForceRefresh*/ true ) ;
}
2020-10-28 06:51:40 -04:00
2021-11-07 23:43:01 -05:00
void SDataLayerBrowser : : InitializeDataLayerBrowser ( )
2020-10-28 06:51:40 -04:00
{
ContentAreaBox - > ClearChildren ( ) ;
ContentAreaBox - > AddSlot ( )
. AutoHeight ( )
. FillHeight ( 1.0f )
[
DataLayerContentsSection . ToSharedRef ( )
] ;
ContentAreaBox - > AddSlot ( )
. AutoHeight ( )
. VAlign ( VAlign_Bottom )
. MaxHeight ( 23 )
[
DataLayerContentsHeader . ToSharedRef ( )
] ;
}
# undef LOCTEXT_NAMESPACE