From dd5d463dff66e801831bf0a642d3a08d61ba013e Mon Sep 17 00:00:00 2001 From: roey borsteinas Date: Tue, 23 Mar 2021 19:03:31 -0400 Subject: [PATCH] SceneOutliner: deleted actors now display a cached label instead of the generic "(Deleted Actor)" label. #rb patrick.enfedaque #ROBOMERGE-SOURCE: CL 15778783 in //UE5/Release-5.0-EarlyAccess/... #ROBOMERGE-BOT: STARSHIP (Release-5.0-EarlyAccess -> Main) (v783-15756269) [CL 15787307 by roey borsteinas in ue5-main branch] --- .../SceneOutliner/Private/ActorTreeItem.cpp | 41 +++++++++++++------ .../SceneOutliner/Private/SSceneOutliner.cpp | 2 + .../SceneOutliner/Public/ActorTreeItem.h | 3 ++ .../Public/ISceneOutlinerTreeItem.h | 2 + 4 files changed, 35 insertions(+), 13 deletions(-) diff --git a/Engine/Source/Editor/SceneOutliner/Private/ActorTreeItem.cpp b/Engine/Source/Editor/SceneOutliner/Private/ActorTreeItem.cpp index bb4868601da2..187c67a73e7c 100644 --- a/Engine/Source/Editor/SceneOutliner/Private/ActorTreeItem.cpp +++ b/Engine/Source/Editor/SceneOutliner/Private/ActorTreeItem.cpp @@ -111,22 +111,26 @@ private: TWeakPtr TreeItemPtr; TWeakObjectPtr ActorPtr; TAttribute HighlightText; - + FText GetDisplayText() const { - const AActor* Actor = ActorPtr.Get(); - if (const ALevelInstance* LevelInstanceActor = Cast(Actor)) + if (const FSceneOutlinerTreeItemPtr TreeItem = TreeItemPtr.Pin()) { - if (LevelInstanceActor->IsDirty() && !bInEditingMode) + const AActor* Actor = ActorPtr.Get(); + if (const ALevelInstance* LevelInstanceActor = Cast(Actor)) { - FFormatNamedArguments Args; - Args.Add(TEXT("ActorLabel"), FText::FromString(LevelInstanceActor->GetActorLabel())); - Args.Add(TEXT("EditTag"), LOCTEXT("EditingLevelInstanceLabel", "*")); - return FText::Format(LOCTEXT("LevelInstanceDisplay", "{ActorLabel}{EditTag}"), Args); + if (LevelInstanceActor->IsDirty() && !bInEditingMode) + { + FFormatNamedArguments Args; + Args.Add(TEXT("ActorLabel"), FText::FromString(TreeItem->GetDisplayString())); + Args.Add(TEXT("EditTag"), LOCTEXT("EditingLevelInstanceLabel", "*")); + return FText::Format(LOCTEXT("LevelInstanceDisplay", "{ActorLabel}{EditTag}"), Args); + } } + return FText::FromString(TreeItem->GetDisplayString()); } - return Actor ? FText::FromString(Actor->GetActorLabel()) : LOCTEXT("ActorLabelForMissingActor", "(Deleted Actor)"); + return FText(); } FText GetTooltipText() const @@ -189,7 +193,7 @@ private: } else { - return nullptr; + return FSlateIconFinder::FindIconForClass(AActor::StaticClass()).GetOptionalIcon(); } } @@ -340,6 +344,9 @@ FActorTreeItem::FActorTreeItem(AActor* InActor) , Actor(InActor) , ID(InActor) { + check(InActor); + ActorLabel = InActor->GetActorLabel(); + bExistsInCurrentWorldAndPIE = GEditor->ObjectsThatExistInEditorWorld.Get(InActor); } @@ -350,8 +357,7 @@ FSceneOutlinerTreeItemID FActorTreeItem::GetID() const FString FActorTreeItem::GetDisplayString() const { - const AActor* ActorPtr = Actor.Get(); - return ActorPtr ? ActorPtr->GetActorLabel() : LOCTEXT("ActorLabelForMissingActor", "(Deleted Actor)").ToString(); + return ActorLabel; } bool FActorTreeItem::CanInteract() const @@ -388,7 +394,16 @@ void FActorTreeItem::OnVisibilityChanged(const bool bNewVisibility) bool FActorTreeItem::GetVisibility() const { - return Actor.IsValid() && !Actor->IsTemporarilyHiddenInEditor(true); + // We want deleted actors to appear as if they are visible to minimize visual clutter. + return !Actor.IsValid() || !Actor->IsTemporarilyHiddenInEditor(true); +} + +void FActorTreeItem::OnLabelChanged() +{ + if (Actor.IsValid()) + { + ActorLabel = Actor->GetActorLabel(); + } } #undef LOCTEXT_NAMESPACE diff --git a/Engine/Source/Editor/SceneOutliner/Private/SSceneOutliner.cpp b/Engine/Source/Editor/SceneOutliner/Private/SSceneOutliner.cpp index 5f6dd39a7352..945f3b1da753 100644 --- a/Engine/Source/Editor/SceneOutliner/Private/SSceneOutliner.cpp +++ b/Engine/Source/Editor/SceneOutliner/Private/SSceneOutliner.cpp @@ -1654,6 +1654,8 @@ void SSceneOutliner::OnItemLabelChanged(FSceneOutlinerTreeItemPtr ChangedItem) // If the item already exists if (FSceneOutlinerTreeItemPtr* ExistingItem = TreeItemMap.Find(ChangedItem->GetID())) { + (*ExistingItem)->OnLabelChanged(); + // The changed item flags will have been set already if (!ChangedItem->Flags.bIsFilteredOut) { diff --git a/Engine/Source/Editor/SceneOutliner/Public/ActorTreeItem.h b/Engine/Source/Editor/SceneOutliner/Public/ActorTreeItem.h index 6defff1e9b75..6871cd431ae0 100644 --- a/Engine/Source/Editor/SceneOutliner/Public/ActorTreeItem.h +++ b/Engine/Source/Editor/SceneOutliner/Public/ActorTreeItem.h @@ -45,8 +45,11 @@ public: virtual void OnVisibilityChanged(const bool bNewVisibility) override; virtual bool HasVisibilityInfo() const override { return true; } virtual bool GetVisibility() const override; + virtual void OnLabelChanged() override; /* End ISceneOutlinerTreeItem Implementation */ public: /** true if this item exists in both the current world and PIE. */ bool bExistsInCurrentWorldAndPIE; + /** Cached actor label */ + FString ActorLabel; }; diff --git a/Engine/Source/Editor/SceneOutliner/Public/ISceneOutlinerTreeItem.h b/Engine/Source/Editor/SceneOutliner/Public/ISceneOutlinerTreeItem.h index 6ff338c3b5ae..f72a44931816 100644 --- a/Engine/Source/Editor/SceneOutliner/Public/ISceneOutlinerTreeItem.h +++ b/Engine/Source/Editor/SceneOutliner/Public/ISceneOutlinerTreeItem.h @@ -147,4 +147,6 @@ public: /** Query this items visibility state. Only called if the item type has visibility info */ virtual bool GetVisibility() const { return false; } + /** Called when this item's label has changed */ + virtual void OnLabelChanged() {} };