You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
Port ActorBrowsingMode over to the new Editor Config system to have separate settings for each outliner Enable Stacked Hierarchy Headers by default Add the ability to disable framing selection Add the ability to get the most recently used outliner from the level editor Fix a bug where renaming an item on one outliner would sometimes execute the rename on a different outliner #rb richard.malo #jira UETOOL-5014 #preflight 627aa9811e74993343331221 [CL 20126651 by aditya ravichandran in ue5-main branch]
149 lines
5.2 KiB
C++
149 lines
5.2 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "ActorModeInteractive.h"
|
|
#include "Engine/Selection.h"
|
|
#include "Editor.h"
|
|
#include "ActorTreeItem.h"
|
|
#include "LevelEditor.h"
|
|
#include "Modules/ModuleManager.h"
|
|
|
|
FActorModeInteractive::FActorModeInteractive(const FActorModeParams& Params)
|
|
: FActorMode(Params)
|
|
{
|
|
USelection::SelectionChangedEvent.AddRaw(this, &FActorModeInteractive::OnLevelSelectionChanged);
|
|
USelection::SelectObjectEvent.AddRaw(this, &FActorModeInteractive::OnLevelSelectionChanged);
|
|
|
|
FEditorDelegates::MapChange.AddRaw(this, &FActorModeInteractive::OnMapChange);
|
|
FEditorDelegates::NewCurrentLevel.AddRaw(this, &FActorModeInteractive::OnNewCurrentLevel);
|
|
|
|
FCoreDelegates::OnActorLabelChanged.AddRaw(this, &FActorModeInteractive::OnActorLabelChanged);
|
|
FCoreUObjectDelegates::OnObjectsReplaced.AddRaw(this, &FActorModeInteractive::OnObjectsReplaced);
|
|
FCoreUObjectDelegates::PostLoadMapWithWorld.AddRaw(this, &FActorModeInteractive::OnPostLoadMapWithWorld);
|
|
GEngine->OnLevelActorRequestRename().AddRaw(this, &FActorModeInteractive::OnLevelActorRequestsRename);
|
|
}
|
|
|
|
FActorModeInteractive::~FActorModeInteractive()
|
|
{
|
|
USelection::SelectionChangedEvent.RemoveAll(this);
|
|
USelection::SelectObjectEvent.RemoveAll(this);
|
|
|
|
FEditorDelegates::MapChange.RemoveAll(this);
|
|
FEditorDelegates::NewCurrentLevel.RemoveAll(this);
|
|
|
|
FCoreDelegates::OnActorLabelChanged.RemoveAll(this);
|
|
FCoreUObjectDelegates::OnObjectsReplaced.RemoveAll(this);
|
|
FCoreUObjectDelegates::PostLoadMapWithWorld.RemoveAll(this);
|
|
GEngine->OnLevelActorRequestRename().RemoveAll(this);
|
|
}
|
|
|
|
void FActorModeInteractive::OnMapChange(uint32 MapFlags)
|
|
{
|
|
// Instruct the scene outliner to generate a new hierarchy
|
|
SceneOutliner->FullRefresh();
|
|
}
|
|
|
|
void FActorModeInteractive::OnNewCurrentLevel()
|
|
{
|
|
// Instruct the scene outliner to generate a new hierarchy
|
|
SceneOutliner->FullRefresh();
|
|
}
|
|
|
|
void FActorModeInteractive::OnLevelSelectionChanged(UObject* Obj)
|
|
{
|
|
const FSceneOutlinerFilterInfo* ShowOnlySelectedActorsFilter = FilterInfoMap.Find(TEXT("ShowOnlySelectedActors"));
|
|
|
|
// Since there is no way to know which items were removed/added to a selection, we must force a full refresh to handle this
|
|
if (ShowOnlySelectedActorsFilter && ShowOnlySelectedActorsFilter->IsFilterActive())
|
|
{
|
|
SceneOutliner->FullRefresh();
|
|
}
|
|
// If the SceneOutliner's reentrant flag is set, the selection change has already been handled in the outliner class
|
|
else if (!SceneOutliner->GetIsReentrant())
|
|
{
|
|
SceneOutliner->ClearSelection();
|
|
SceneOutliner->RefreshSelection();
|
|
|
|
// Scroll last item into view if Selection Framing is enabled - this means if we are multi-selecting, we show newest selection. @TODO Not perfect though
|
|
if (const AActor* LastSelectedActor = GEditor->GetSelectedActors()->GetBottom<AActor>())
|
|
{
|
|
if (FSceneOutlinerTreeItemPtr TreeItem = SceneOutliner->GetTreeItem(LastSelectedActor, false))
|
|
{
|
|
if(bAlwaysFrameSelection)
|
|
{
|
|
SceneOutliner->ScrollItemIntoView(TreeItem);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SceneOutliner::ENewItemAction::Type Action = bAlwaysFrameSelection ? SceneOutliner::ENewItemAction::ScrollIntoView : SceneOutliner::ENewItemAction::Select;
|
|
|
|
SceneOutliner->OnItemAdded(LastSelectedActor, Action);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void FActorModeInteractive::OnLevelActorRequestsRename(const AActor* Actor)
|
|
{
|
|
TWeakPtr<ILevelEditor> LevelEditor = FModuleManager::GetModuleChecked<FLevelEditorModule>(TEXT("LevelEditor")).GetLevelEditorInstance();
|
|
|
|
if(TSharedPtr<ILevelEditor> LevelEditorPin = LevelEditor.Pin())
|
|
{
|
|
/* We want to execute the rename on the most recently used outliner
|
|
* TODO: Add a way to pop-out the outliner the rename is done on
|
|
*/
|
|
if(SceneOutliner == LevelEditorPin->GetMostRecentlyUsedSceneOutliner().Get())
|
|
{
|
|
const TArray<FSceneOutlinerTreeItemPtr>& SelectedItems = SceneOutliner->GetSelectedItems();
|
|
if (SelectedItems.Num() > 0)
|
|
{
|
|
// Ensure that the item we want to rename is visible in the tree
|
|
FSceneOutlinerTreeItemPtr ItemToRename = SelectedItems[SelectedItems.Num() - 1];
|
|
if (SceneOutliner->CanExecuteRenameRequest(*ItemToRename) && ItemToRename->CanInteract())
|
|
{
|
|
SceneOutliner->SetPendingRenameItem(ItemToRename);
|
|
SceneOutliner->ScrollItemIntoView(ItemToRename);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void FActorModeInteractive::OnPostLoadMapWithWorld(UWorld* World)
|
|
{
|
|
SceneOutliner->FullRefresh();
|
|
}
|
|
|
|
void FActorModeInteractive::OnActorLabelChanged(AActor* ChangedActor)
|
|
{
|
|
if (!ensure(ChangedActor))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (IsActorDisplayable(ChangedActor) && RepresentingWorld.Get() == ChangedActor->GetWorld())
|
|
{
|
|
// Force create the item otherwise the outliner may not be notified of a change to the item if it is filtered out
|
|
if (FSceneOutlinerTreeItemPtr Item = CreateItemFor<FActorTreeItem>(ChangedActor, true))
|
|
{
|
|
SceneOutliner->OnItemLabelChanged(Item);
|
|
}
|
|
}
|
|
}
|
|
|
|
void FActorModeInteractive::OnObjectsReplaced(const TMap<UObject*, UObject*>& ReplacementMap)
|
|
{
|
|
for (const TPair<UObject*, UObject*>& Pair : ReplacementMap)
|
|
{
|
|
AActor* Actor = Cast<AActor>(Pair.Value);
|
|
if (Actor && RepresentingWorld.Get() == Actor->GetWorld() && IsActorDisplayable(Actor))
|
|
{
|
|
if (FSceneOutlinerTreeItemPtr Item = CreateItemFor<FActorTreeItem>(Actor, true))
|
|
{
|
|
SceneOutliner->OnItemLabelChanged(Item);
|
|
}
|
|
}
|
|
}
|
|
}
|