2021-03-10 12:35:33 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "ActorDescTreeItem.h"
2022-01-21 14:29:12 -05:00
# include "WorldPartition/WorldPartition.h"
2021-03-10 12:35:33 -04:00
# include "WorldPartition/WorldPartitionActorDesc.h"
# include "Widgets/DeclarativeSyntaxSupport.h"
# include "Layout/WidgetPath.h"
# include "Framework/Application/MenuStack.h"
# include "Framework/Application/SlateApplication.h"
# include "Editor.h"
# include "ScopedTransaction.h"
# include "SceneOutlinerPublicTypes.h"
# include "SceneOutlinerDragDrop.h"
# include "SceneOutlinerStandaloneTypes.h"
# include "Widgets/Text/SInlineEditableTextBlock.h"
# include "ActorEditorUtils.h"
# include "ClassIconFinder.h"
# include "ISceneOutliner.h"
# include "ISceneOutlinerMode.h"
# include "Logging/MessageLog.h"
# include "SSocketChooser.h"
2021-03-30 11:16:04 -04:00
# include "ToolMenus.h"
# include "LevelEditorViewport.h"
2021-03-10 12:35:33 -04:00
# define LOCTEXT_NAMESPACE "SceneOutliner_ActorDescTreeItem"
2022-05-20 10:13:02 -04:00
const FSceneOutlinerTreeItemType FActorDescTreeItem : : Type ( & IActorBaseTreeItem : : Type ) ;
2021-03-10 12:35:33 -04:00
struct SActorDescTreeLabel : FSceneOutlinerCommonLabelData , public SCompoundWidget
{
SLATE_BEGIN_ARGS ( SActorDescTreeLabel ) { }
SLATE_END_ARGS ( )
2021-03-30 11:16:04 -04:00
void Construct ( const FArguments & InArgs , FActorDescTreeItem & ActorDescItem , ISceneOutliner & SceneOutliner , const STableRow < FSceneOutlinerTreeItemPtr > & InRow )
2021-03-10 12:35:33 -04:00
{
WeakSceneOutliner = StaticCastSharedRef < ISceneOutliner > ( SceneOutliner . AsShared ( ) ) ;
TreeItemPtr = StaticCastSharedRef < FActorDescTreeItem > ( ActorDescItem . AsShared ( ) ) ;
HighlightText = SceneOutliner . GetFilterHighlightText ( ) ;
TSharedPtr < SInlineEditableTextBlock > InlineTextBlock ;
auto MainContent = SNew ( SHorizontalBox )
// Main actor desc label
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
[
SAssignNew ( InlineTextBlock , SInlineEditableTextBlock )
. Text ( this , & SActorDescTreeLabel : : GetDisplayText )
2021-03-30 11:16:04 -04:00
. ToolTipText ( this , & SActorDescTreeLabel : : GetTooltipText )
. HighlightText ( HighlightText )
. ColorAndOpacity ( this , & SActorDescTreeLabel : : GetForegroundColor )
. OnTextCommitted ( this , & SActorDescTreeLabel : : OnLabelCommitted )
. OnVerifyTextChanged ( this , & SActorDescTreeLabel : : OnVerifyItemLabelChanged )
. IsSelected ( FIsSelected : : CreateSP ( & InRow , & STableRow < FSceneOutlinerTreeItemPtr > : : IsSelectedExclusively ) )
. IsReadOnly_Lambda ( [ Item = ActorDescItem . AsShared ( ) , this ] ( )
{
return ! CanExecuteRenameRequest ( Item . Get ( ) ) ;
} )
2021-03-10 12:35:33 -04:00
]
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
. Padding ( 0.0f , 0.f , 3.0f , 0.0f )
[
SNew ( STextBlock )
. Text ( this , & SActorDescTreeLabel : : GetTypeText )
2021-03-30 11:16:04 -04:00
. Visibility ( this , & SActorDescTreeLabel : : GetTypeTextVisibility )
. HighlightText ( HighlightText )
2021-03-10 12:35:33 -04:00
] ;
if ( WeakSceneOutliner . Pin ( ) - > GetMode ( ) - > IsInteractive ( ) )
{
ActorDescItem . RenameRequestEvent . BindSP ( InlineTextBlock . Get ( ) , & SInlineEditableTextBlock : : EnterEditingMode ) ;
}
ChildSlot
[
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
2021-03-30 11:16:04 -04:00
. AutoWidth ( )
. VAlign ( VAlign_Center )
. Padding ( FSceneOutlinerDefaultTreeItemMetrics : : IconPadding ( ) )
[
SNew ( SBox )
. WidthOverride ( FSceneOutlinerDefaultTreeItemMetrics : : IconSize ( ) )
. HeightOverride ( FSceneOutlinerDefaultTreeItemMetrics : : IconSize ( ) )
[
SNew ( SImage )
. Image ( this , & SActorDescTreeLabel : : GetIcon )
. ToolTipText ( this , & SActorDescTreeLabel : : GetIconTooltip )
. ColorAndOpacity ( FSlateColor : : UseForeground ( ) )
]
]
2021-03-10 12:35:33 -04:00
2021-03-30 11:16:04 -04:00
+ SHorizontalBox : : Slot ( )
. FillWidth ( 1.0f )
. VAlign ( VAlign_Center )
. Padding ( 0.0f , 0.0f )
[
MainContent
]
2021-03-10 12:35:33 -04:00
] ;
}
private :
TWeakPtr < FActorDescTreeItem > TreeItemPtr ;
TAttribute < FText > HighlightText ;
FText GetDisplayText ( ) const
{
if ( TSharedPtr < FActorDescTreeItem > TreeItem = TreeItemPtr . Pin ( ) )
{
2022-01-12 13:39:39 -05:00
if ( const FWorldPartitionActorDesc * ActorDesc = TreeItem - > ActorDescHandle . Get ( ) )
2021-03-10 12:35:33 -04:00
{
FFormatNamedArguments Args ;
2022-05-10 10:22:54 -04:00
Args . Add ( TEXT ( " ActorLabel " ) , FText : : FromString ( TreeItem - > GetDisplayString ( ) ) ) ;
2022-05-20 10:13:02 -04:00
if ( UWorldPartition * WorldPartition = Cast < UWorldPartition > ( ActorDesc - > GetContainer ( ) ) ; WorldPartition - > IsActorPinned ( ActorDesc - > GetGuid ( ) ) )
{
Args . Add ( TEXT ( " UnloadState " ) , LOCTEXT ( " UnloadedDataLayer " , " (Unloaded DataLayer) " ) ) ;
}
else
{
Args . Add ( TEXT ( " UnloadState " ) , LOCTEXT ( " UnloadedActorLabel " , " (Unloaded) " ) ) ;
}
return FText : : Format ( LOCTEXT ( " UnloadedActorDisplay " , " {ActorLabel} {UnloadState} " ) , Args ) ;
2021-03-10 12:35:33 -04:00
}
}
return FText ( ) ;
}
FText GetTooltipText ( ) const
{
return FText ( ) ;
}
FText GetTypeText ( ) const
{
if ( TSharedPtr < FActorDescTreeItem > TreeItem = TreeItemPtr . Pin ( ) )
{
2022-01-12 13:39:39 -05:00
if ( const FWorldPartitionActorDesc * ActorDesc = TreeItem - > ActorDescHandle . Get ( ) )
2021-03-10 12:35:33 -04:00
{
2022-05-05 14:10:10 -04:00
return FText : : FromName ( ActorDesc - > GetDisplayClassName ( ) ) ;
2021-03-10 12:35:33 -04:00
}
}
return FText ( ) ;
}
EVisibility GetTypeTextVisibility ( ) const
{
return HighlightText . Get ( ) . IsEmpty ( ) ? EVisibility : : Collapsed : EVisibility : : Visible ;
}
const FSlateBrush * GetIcon ( ) const
{
TSharedPtr < FActorDescTreeItem > TreeItem = TreeItemPtr . Pin ( ) ;
if ( TreeItem . IsValid ( ) & & WeakSceneOutliner . IsValid ( ) )
{
2022-01-12 13:39:39 -05:00
if ( const FWorldPartitionActorDesc * ActorDesc = TreeItem - > ActorDescHandle . Get ( ) )
2021-03-10 12:35:33 -04:00
{
2022-05-05 14:10:10 -04:00
const FName IconName = ActorDesc - > GetNativeClass ( ) ;
2021-03-10 12:35:33 -04:00
const FSlateBrush * CachedBrush = WeakSceneOutliner . Pin ( ) - > GetCachedIconForClass ( IconName ) ;
if ( CachedBrush ! = nullptr )
{
return CachedBrush ;
}
else if ( IconName ! = NAME_None )
{
2022-05-05 14:10:10 -04:00
const FSlateBrush * FoundSlateBrush = FSlateIconFinder : : FindIconForClass ( ActorDesc - > GetActorNativeClass ( ) ) . GetIcon ( ) ;
2021-03-10 12:35:33 -04:00
WeakSceneOutliner . Pin ( ) - > CacheIconForClass ( IconName , FoundSlateBrush ) ;
return FoundSlateBrush ;
}
}
}
return nullptr ;
}
const FSlateBrush * GetIconOverlay ( ) const
{
return nullptr ;
}
FText GetIconTooltip ( ) const
{
return FText ( ) ;
}
virtual FSlateColor GetForegroundColor ( ) const override
{
if ( const auto TreeItem = TreeItemPtr . Pin ( ) )
{
if ( auto BaseColor = FSceneOutlinerCommonLabelData : : GetForegroundColor ( * TreeItem ) )
{
return BaseColor . GetValue ( ) ;
}
}
return FSceneOutlinerCommonLabelData : : DarkColor ;
}
bool OnVerifyItemLabelChanged ( const FText & , FText & )
{
// don't allow label change for unloaded actor items
return false ;
}
void OnLabelCommitted ( const FText & InLabel , ETextCommit : : Type InCommitInfo )
{
// not supported.
}
} ;
2021-04-07 15:33:55 -04:00
FActorDescTreeItem : : FActorDescTreeItem ( const FGuid & InActorGuid , UActorDescContainer * Container )
2022-05-20 10:13:02 -04:00
: IActorBaseTreeItem ( Type )
2022-01-12 13:39:39 -05:00
, ActorDescHandle ( Container , InActorGuid )
2021-04-29 14:57:23 -04:00
, ActorGuid ( InActorGuid )
2021-03-10 12:35:33 -04:00
{
2021-04-07 15:33:55 -04:00
ID = FSceneOutlinerTreeItemID ( InActorGuid ) ;
2021-04-28 10:56:38 -04:00
2022-01-12 13:39:39 -05:00
if ( const FWorldPartitionActorDesc * const ActorDesc = ActorDescHandle . Get ( ) )
2021-04-28 10:56:38 -04:00
{
DisplayString = ActorDesc - > GetActorLabel ( ) . ToString ( ) ;
}
else
{
DisplayString = LOCTEXT ( " ActorLabelForMissingActor " , " (Deleted Actor) " ) . ToString ( ) ;
}
2021-03-10 12:35:33 -04:00
}
FSceneOutlinerTreeItemID FActorDescTreeItem : : GetID ( ) const
{
return ID ;
}
FString FActorDescTreeItem : : GetDisplayString ( ) const
{
2021-04-28 10:56:38 -04:00
return DisplayString ;
2021-03-10 12:35:33 -04:00
}
bool FActorDescTreeItem : : CanInteract ( ) const
{
2021-03-30 11:16:04 -04:00
return ActorDescHandle . IsValid ( ) ;
2021-03-10 12:35:33 -04:00
}
TSharedRef < SWidget > FActorDescTreeItem : : GenerateLabelWidget ( ISceneOutliner & Outliner , const STableRow < FSceneOutlinerTreeItemPtr > & InRow )
{
return SNew ( SActorDescTreeLabel , * this , Outliner , InRow ) ;
}
2021-03-30 11:16:04 -04:00
void FActorDescTreeItem : : FocusActorBounds ( ) const
{
2022-01-12 13:39:39 -05:00
if ( FWorldPartitionActorDesc const * ActorDesc = ActorDescHandle . Get ( ) )
2021-03-30 11:16:04 -04:00
{
if ( FLevelEditorViewportClient * LevelViewportClient = GCurrentLevelEditingViewportClient )
{
LevelViewportClient - > FocusViewportOnBox ( ActorDesc - > GetBounds ( ) , false ) ;
}
}
}
void FActorDescTreeItem : : GenerateContextMenu ( UToolMenu * Menu , SSceneOutliner & )
{
FToolMenuSection & Section = Menu - > AddSection ( " Section " ) ;
Section . AddMenuEntry ( " FocusActorBounds " , LOCTEXT ( " FocusActorBounds " , " Focus Actor Bounds " ) , FText ( ) , FSlateIcon ( ) , FUIAction ( FExecuteAction : : CreateSP ( this , & FActorDescTreeItem : : FocusActorBounds ) ) ) ;
}
2021-03-10 12:35:33 -04:00
bool FActorDescTreeItem : : GetVisibility ( ) const
{
return true ;
}
2021-05-03 15:49:00 -04:00
bool FActorDescTreeItem : : GetPinnedState ( ) const
{
if ( ActorDescHandle . IsValid ( ) )
{
2022-01-21 14:29:12 -05:00
UWorldPartition * WorldPartition = Cast < UWorldPartition > ( ActorDescHandle - > GetContainer ( ) ) ;
return WorldPartition ? WorldPartition - > IsActorPinned ( GetGuid ( ) ) : false ;
2021-05-03 15:49:00 -04:00
}
return false ;
}
2021-03-10 12:35:33 -04:00
# undef LOCTEXT_NAMESPACE