2020-07-22 09:35:57 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "ActorModeInteractive.h"
# include "Engine/Selection.h"
# include "Editor.h"
# include "ActorTreeItem.h"
2022-05-10 14:20:42 -04:00
# include "LevelEditor.h"
# include "Modules/ModuleManager.h"
2020-07-22 09:35:57 -04:00
2020-08-13 10:46:40 -04:00
FActorModeInteractive : : FActorModeInteractive ( const FActorModeParams & Params )
: FActorMode ( Params )
2020-07-22 09:35:57 -04:00
{
2020-07-28 09:25:56 -04:00
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 ) ;
2021-08-23 23:22:27 -04:00
FCoreUObjectDelegates : : OnObjectsReplaced . AddRaw ( this , & FActorModeInteractive : : OnObjectsReplaced ) ;
2021-03-17 14:56:21 -04:00
FCoreUObjectDelegates : : PostLoadMapWithWorld . AddRaw ( this , & FActorModeInteractive : : OnPostLoadMapWithWorld ) ;
2020-07-28 09:25:56 -04:00
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 ) ;
2021-08-23 23:22:27 -04:00
FCoreUObjectDelegates : : OnObjectsReplaced . RemoveAll ( this ) ;
2021-03-17 14:56:21 -04:00
FCoreUObjectDelegates : : PostLoadMapWithWorld . RemoveAll ( this ) ;
2020-07-28 09:25:56 -04:00
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 ( ) )
2020-07-22 09:35:57 -04:00
{
SceneOutliner - > FullRefresh ( ) ;
}
2021-01-20 15:45:44 -04:00
// If the SceneOutliner's reentrant flag is set, the selection change has already been handled in the outliner class
else if ( ! SceneOutliner - > GetIsReentrant ( ) )
2020-07-22 09:35:57 -04:00
{
2020-07-28 09:25:56 -04:00
SceneOutliner - > ClearSelection ( ) ;
SceneOutliner - > RefreshSelection ( ) ;
2020-07-22 09:35:57 -04:00
2022-05-10 14:20:42 -04:00
// 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
2020-07-28 09:25:56 -04:00
if ( const AActor * LastSelectedActor = GEditor - > GetSelectedActors ( ) - > GetBottom < AActor > ( ) )
2020-07-22 09:35:57 -04:00
{
2020-07-28 09:25:56 -04:00
if ( FSceneOutlinerTreeItemPtr TreeItem = SceneOutliner - > GetTreeItem ( LastSelectedActor , false ) )
2020-07-22 09:35:57 -04:00
{
2022-05-10 14:20:42 -04:00
if ( bAlwaysFrameSelection )
{
SceneOutliner - > ScrollItemIntoView ( TreeItem ) ;
}
2020-07-28 09:25:56 -04:00
}
else
{
2022-05-10 14:20:42 -04:00
SceneOutliner : : ENewItemAction : : Type Action = bAlwaysFrameSelection ? SceneOutliner : : ENewItemAction : : ScrollIntoView : SceneOutliner : : ENewItemAction : : Select ;
SceneOutliner - > OnItemAdded ( LastSelectedActor , Action ) ;
2020-07-22 09:35:57 -04:00
}
}
}
2020-07-28 09:25:56 -04:00
}
2020-07-22 09:35:57 -04:00
2020-07-28 09:25:56 -04:00
void FActorModeInteractive : : OnLevelActorRequestsRename ( const AActor * Actor )
{
2022-05-10 14:20:42 -04:00
TWeakPtr < ILevelEditor > LevelEditor = FModuleManager : : GetModuleChecked < FLevelEditorModule > ( TEXT ( " LevelEditor " ) ) . GetLevelEditorInstance ( ) ;
if ( TSharedPtr < ILevelEditor > LevelEditorPin = LevelEditor . Pin ( ) )
2020-07-22 09:35:57 -04:00
{
2022-05-10 14:20:42 -04:00
/* 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 ( ) )
2020-07-22 09:35:57 -04:00
{
2022-05-10 14:20:42 -04:00
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 ) ;
}
}
2020-07-22 09:35:57 -04:00
}
}
2020-07-28 09:25:56 -04:00
}
2020-07-22 09:35:57 -04:00
2021-03-17 14:56:21 -04:00
void FActorModeInteractive : : OnPostLoadMapWithWorld ( UWorld * World )
{
SceneOutliner - > FullRefresh ( ) ;
}
2020-07-28 09:25:56 -04:00
void FActorModeInteractive : : OnActorLabelChanged ( AActor * ChangedActor )
{
if ( ! ensure ( ChangedActor ) )
2020-07-22 09:35:57 -04:00
{
2020-07-28 09:25:56 -04:00
return ;
}
2020-07-22 09:35:57 -04:00
2020-07-28 09:25:56 -04:00
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 ) )
2020-07-22 09:35:57 -04:00
{
2020-07-28 09:25:56 -04:00
SceneOutliner - > OnItemLabelChanged ( Item ) ;
2020-07-22 09:35:57 -04:00
}
}
2020-07-28 09:25:56 -04:00
}
2021-08-23 23:22:27 -04:00
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 ) ;
}
}
}
}