You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
Copying //Tasks/UE5/Dev-SequencerMVVM2 to Main (//UE5/Main) @20364093 #preflight 628866dfb94f739b152c1e29 #preflight 628866e4585e8f793ee80943 #rb ludovic.chabant, andrew.rodham #fyi ludovic.chabant, andrew.rodham, andrew.porter #jira UE-105322 [CL 20364493 by Max Chen in ue5-main branch]
626 lines
20 KiB
C++
626 lines
20 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "Modules/ModuleManager.h"
|
|
#include "Textures/SlateIcon.h"
|
|
#include "EditorModeRegistry.h"
|
|
#include "Toolkits/AssetEditorToolkit.h"
|
|
#include "IMovieRendererInterface.h"
|
|
#include "ISequencer.h"
|
|
#include "ISequencerModule.h"
|
|
#include "SequencerCommands.h"
|
|
#include "ISequencerObjectChangeListener.h"
|
|
#include "Sequencer.h"
|
|
#include "SequencerCustomizationManager.h"
|
|
#include "SequencerEdMode.h"
|
|
#include "SequencerObjectChangeListener.h"
|
|
#include "IDetailKeyframeHandler.h"
|
|
#include "IDetailTreeNode.h"
|
|
#include "IDetailsView.h"
|
|
#include "Tree/CurveEditorTreeFilter.h"
|
|
#include "AnimatedPropertyKey.h"
|
|
#include "MovieSceneSignedObject.h"
|
|
|
|
#include "MVVM/CurveEditorIntegrationExtension.h"
|
|
#include "MVVM/FolderModelStorageExtension.h"
|
|
#include "MVVM/ObjectBindingModelStorageExtension.h"
|
|
#include "MVVM/SectionModelStorageExtension.h"
|
|
#include "MVVM/TrackModelStorageExtension.h"
|
|
#include "MVVM/TrackRowModelStorageExtension.h"
|
|
#include "MVVM/ViewModels/SequenceModel.h"
|
|
|
|
#include "ToolMenus.h"
|
|
#include "ContentBrowserMenuContexts.h"
|
|
#include "SequencerUtilities.h"
|
|
#include "FileHelpers.h"
|
|
#include "LevelSequence.h"
|
|
|
|
|
|
#include "Misc/CoreDelegates.h"
|
|
#include "UnrealEdGlobals.h"
|
|
#include "Editor/UnrealEdEngine.h"
|
|
#include "Editor/TransBuffer.h"
|
|
|
|
#if !IS_MONOLITHIC
|
|
UE::MovieScene::FEntityManager*& GEntityManagerForDebugging = UE::MovieScene::GEntityManagerForDebuggingVisualizers;
|
|
#endif
|
|
|
|
|
|
|
|
#define LOCTEXT_NAMESPACE "SequencerEditor"
|
|
|
|
|
|
namespace UE
|
|
{
|
|
namespace Sequencer
|
|
{
|
|
|
|
struct FDeferredSignedObjectChangeHandler : UE::MovieScene::IDeferredSignedObjectChangeHandler, FGCObject
|
|
{
|
|
FDeferredSignedObjectChangeHandler()
|
|
{
|
|
Init();
|
|
}
|
|
|
|
~FDeferredSignedObjectChangeHandler()
|
|
{
|
|
if (UTransBuffer* TransBuffer = WeakBuffer.Get())
|
|
{
|
|
TransBuffer->OnTransactionStateChanged().RemoveAll(this);
|
|
}
|
|
}
|
|
|
|
void Init()
|
|
{
|
|
UTransBuffer* TransBuffer = GUnrealEd ? Cast<UTransBuffer>(GUnrealEd->Trans) : nullptr;
|
|
if (TransBuffer)
|
|
{
|
|
WeakBuffer = TransBuffer;
|
|
TransBuffer->OnTransactionStateChanged().AddRaw(this, &FDeferredSignedObjectChangeHandler::OnTransactionStateChanged);
|
|
if (TransBuffer->IsActive())
|
|
{
|
|
DeferTransactionChanges.Emplace();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FCoreDelegates::OnPostEngineInit.AddLambda([this]{ this->Init(); });
|
|
}
|
|
}
|
|
|
|
void OnTransactionStateChanged(const FTransactionContext& TransactionContext, ETransactionStateEventType TransactionState)
|
|
{
|
|
/** A transaction has been started. This will be followed by a TransactionCanceled or TransactionFinalized event. */
|
|
switch (TransactionState)
|
|
{
|
|
case ETransactionStateEventType::TransactionStarted:
|
|
case ETransactionStateEventType::UndoRedoStarted:
|
|
DeferTransactionChanges.Emplace();
|
|
break;
|
|
|
|
case ETransactionStateEventType::TransactionCanceled:
|
|
case ETransactionStateEventType::TransactionFinalized:
|
|
case ETransactionStateEventType::UndoRedoFinalized:
|
|
DeferTransactionChanges.Reset();
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Flush() override
|
|
{
|
|
for (TWeakObjectPtr<UMovieSceneSignedObject> WeakObject : SignedObjects)
|
|
{
|
|
if (UMovieSceneSignedObject* Object = WeakObject.Get())
|
|
{
|
|
Object->BroadcastChanged();
|
|
}
|
|
}
|
|
SignedObjects.Empty();
|
|
}
|
|
|
|
void DeferMarkAsChanged(UMovieSceneSignedObject* SignedObject) override
|
|
{
|
|
SignedObjects.Add(SignedObject);
|
|
}
|
|
|
|
void AddReferencedObjects( FReferenceCollector& Collector ) override
|
|
{
|
|
for (TWeakObjectPtr<UMovieSceneSignedObject> WeakObject : SignedObjects)
|
|
{
|
|
if (UMovieSceneSignedObject* Object = WeakObject.Get())
|
|
{
|
|
Collector.AddReferencedObject(Object);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CreateImplicitScopedModifyDefer() override
|
|
{
|
|
ensure(!DeferImplicitChanges.IsSet());
|
|
DeferImplicitChanges.Emplace();
|
|
return true;
|
|
}
|
|
|
|
void ResetImplicitScopedModifyDefer() override
|
|
{
|
|
DeferImplicitChanges.Reset();
|
|
}
|
|
|
|
FString GetReferencerName() const override
|
|
{
|
|
return TEXT("FDeferredSignedObjectChangeHandler");
|
|
}
|
|
|
|
TSet<TWeakObjectPtr<UMovieSceneSignedObject>> SignedObjects;
|
|
TWeakObjectPtr<UTransBuffer> WeakBuffer;
|
|
TOptional<UE::MovieScene::FScopedSignedObjectModifyDefer> DeferTransactionChanges;
|
|
TOptional<UE::MovieScene::FScopedSignedObjectModifyDefer> DeferImplicitChanges;
|
|
};
|
|
|
|
} // namespace Sequencer
|
|
} // namespace UE
|
|
|
|
|
|
// Destructor defined in CPP to avoid having to #include SequencerChannelInterface.h in the main module definition
|
|
ISequencerModule::~ISequencerModule()
|
|
{
|
|
}
|
|
|
|
ECurveEditorTreeFilterType ISequencerModule::GetSequencerSelectionFilterType()
|
|
{
|
|
static ECurveEditorTreeFilterType FilterType = FCurveEditorTreeFilter::RegisterFilterType();
|
|
return FilterType;
|
|
}
|
|
|
|
static TSharedPtr<IDetailKeyframeHandler> GetKeyframeHandler(TWeakPtr<IDetailTreeNode> OwnerTreeNode)
|
|
{
|
|
TSharedPtr<IDetailTreeNode> OwnerTreeNodePtr = OwnerTreeNode.Pin();
|
|
if (!OwnerTreeNodePtr.IsValid())
|
|
{
|
|
return TSharedPtr<IDetailKeyframeHandler>();
|
|
}
|
|
|
|
IDetailsView* DetailsView = OwnerTreeNodePtr->GetNodeDetailsView();
|
|
if (DetailsView == nullptr)
|
|
{
|
|
return TSharedPtr<IDetailKeyframeHandler>();
|
|
}
|
|
|
|
return DetailsView->GetKeyframeHandler();
|
|
}
|
|
|
|
static bool IsKeyframeButtonVisible(TWeakPtr<IDetailTreeNode> OwnerTreeNode, TSharedPtr<IPropertyHandle> PropertyHandle)
|
|
{
|
|
TSharedPtr<IDetailKeyframeHandler> KeyframeHandler = GetKeyframeHandler(OwnerTreeNode);
|
|
if (!KeyframeHandler.IsValid() || !PropertyHandle.IsValid())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
const UClass* ObjectClass = PropertyHandle->GetOuterBaseClass();
|
|
if (ObjectClass == nullptr)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return KeyframeHandler->IsPropertyKeyable(ObjectClass, *PropertyHandle);
|
|
}
|
|
|
|
static bool IsKeyframeButtonEnabled(TWeakPtr<IDetailTreeNode> OwnerTreeNode)
|
|
{
|
|
TSharedPtr<IDetailKeyframeHandler> KeyframeHandler = GetKeyframeHandler(OwnerTreeNode);
|
|
if (!KeyframeHandler.IsValid())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return KeyframeHandler->IsPropertyKeyingEnabled();
|
|
}
|
|
|
|
static void OnAddKeyframeClicked(TWeakPtr<IDetailTreeNode> OwnerTreeNode, TSharedPtr<IPropertyHandle> PropertyHandle)
|
|
{
|
|
TSharedPtr<IDetailKeyframeHandler> KeyframeHandler = GetKeyframeHandler(OwnerTreeNode);
|
|
if (!KeyframeHandler.IsValid() || !PropertyHandle.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
KeyframeHandler->OnKeyPropertyClicked(*PropertyHandle);
|
|
}
|
|
|
|
static void RegisterKeyframeExtensionHandler(const FOnGenerateGlobalRowExtensionArgs& Args, TArray<FPropertyRowExtensionButton>& OutExtensionButtons)
|
|
{
|
|
// local copy for capturing in handlers below
|
|
TSharedPtr<IPropertyHandle> PropertyHandle = Args.PropertyHandle;
|
|
if (!PropertyHandle.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
static FSlateIcon CreateKeyIcon(FAppStyle::Get().GetStyleSetName(), "Sequencer.AddKey.Details");
|
|
|
|
TWeakPtr<IDetailTreeNode> OwnerTreeNode = Args.OwnerTreeNode;
|
|
|
|
FPropertyRowExtensionButton& CreateKey = OutExtensionButtons.AddDefaulted_GetRef();
|
|
CreateKey.Icon = CreateKeyIcon;
|
|
CreateKey.Label = NSLOCTEXT("PropertyEditor", "CreateKey", "Create Key");
|
|
CreateKey.ToolTip = NSLOCTEXT("PropertyEditor", "CreateKeyToolTip", "Add a keyframe for this property.");
|
|
CreateKey.UIAction = FUIAction(
|
|
FExecuteAction::CreateStatic(&OnAddKeyframeClicked, OwnerTreeNode, PropertyHandle),
|
|
FCanExecuteAction::CreateStatic(&IsKeyframeButtonEnabled, OwnerTreeNode),
|
|
FGetActionCheckState(),
|
|
FIsActionButtonVisible::CreateStatic(&IsKeyframeButtonVisible, OwnerTreeNode, PropertyHandle)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* SequencerModule implementation (private)
|
|
*/
|
|
class FSequencerModule
|
|
: public ISequencerModule
|
|
{
|
|
public:
|
|
|
|
// ISequencerModule interface
|
|
|
|
virtual TSharedRef<ISequencer> CreateSequencer(const FSequencerInitParams& InitParams) override
|
|
{
|
|
TSharedRef<FSequencer> Sequencer = MakeShared<FSequencer>();
|
|
TSharedRef<ISequencerObjectChangeListener> ObjectChangeListener = MakeShared<FSequencerObjectChangeListener>(Sequencer);
|
|
|
|
OnPreSequencerInit.Broadcast(Sequencer, ObjectChangeListener, InitParams);
|
|
|
|
Sequencer->InitSequencer(InitParams, ObjectChangeListener, TrackEditorDelegates, EditorObjectBindingDelegates);
|
|
|
|
OnSequencerCreated.Broadcast(Sequencer);
|
|
|
|
return Sequencer;
|
|
}
|
|
|
|
virtual FDelegateHandle RegisterTrackEditor( FOnCreateTrackEditor InOnCreateTrackEditor, TArrayView<FAnimatedPropertyKey> AnimatedPropertyTypes ) override
|
|
{
|
|
TrackEditorDelegates.Add( InOnCreateTrackEditor );
|
|
FDelegateHandle Handle = TrackEditorDelegates.Last().GetHandle();
|
|
for (const FAnimatedPropertyKey& Key : AnimatedPropertyTypes)
|
|
{
|
|
PropertyAnimators.Add(Key);
|
|
}
|
|
|
|
if (AnimatedPropertyTypes.Num() > 0)
|
|
{
|
|
FAnimatedTypeCache CachedTypes;
|
|
CachedTypes.FactoryHandle = Handle;
|
|
for (const FAnimatedPropertyKey& Key : AnimatedPropertyTypes)
|
|
{
|
|
CachedTypes.AnimatedTypes.Add(Key);
|
|
}
|
|
AnimatedTypeCache.Add(CachedTypes);
|
|
}
|
|
return Handle;
|
|
}
|
|
|
|
virtual void UnRegisterTrackEditor( FDelegateHandle InHandle ) override
|
|
{
|
|
TrackEditorDelegates.RemoveAll( [=](const FOnCreateTrackEditor& Delegate){ return Delegate.GetHandle() == InHandle; } );
|
|
int32 CacheIndex = AnimatedTypeCache.IndexOfByPredicate([=](const FAnimatedTypeCache& In) { return In.FactoryHandle == InHandle; });
|
|
if (CacheIndex != INDEX_NONE)
|
|
{
|
|
for (const FAnimatedPropertyKey& Key : AnimatedTypeCache[CacheIndex].AnimatedTypes)
|
|
{
|
|
PropertyAnimators.Remove(Key);
|
|
}
|
|
AnimatedTypeCache.RemoveAtSwap(CacheIndex);
|
|
}
|
|
}
|
|
|
|
virtual FDelegateHandle RegisterTrackModel(FOnCreateTrackModel InCreator) override
|
|
{
|
|
TrackModelDelegates.Add(InCreator);
|
|
return TrackModelDelegates.Last().GetHandle();
|
|
}
|
|
|
|
virtual void UnregisterTrackModel(FDelegateHandle InHandle) override
|
|
{
|
|
TrackModelDelegates.RemoveAll([=](const FOnCreateTrackModel& Delegate) { return Delegate.GetHandle() == InHandle; });
|
|
}
|
|
|
|
virtual FDelegateHandle RegisterOnSequencerCreated(FOnSequencerCreated::FDelegate InOnSequencerCreated) override
|
|
{
|
|
return OnSequencerCreated.Add(InOnSequencerCreated);
|
|
}
|
|
|
|
virtual void UnregisterOnSequencerCreated(FDelegateHandle InHandle) override
|
|
{
|
|
OnSequencerCreated.Remove(InHandle);
|
|
}
|
|
|
|
virtual FDelegateHandle RegisterOnPreSequencerInit(FOnPreSequencerInit::FDelegate InOnPreSequencerInit) override
|
|
{
|
|
return OnPreSequencerInit.Add(InOnPreSequencerInit);
|
|
}
|
|
|
|
virtual void UnregisterOnPreSequencerInit(FDelegateHandle InHandle) override
|
|
{
|
|
OnPreSequencerInit.Remove(InHandle);
|
|
}
|
|
|
|
virtual FDelegateHandle RegisterEditorObjectBinding(FOnCreateEditorObjectBinding InOnCreateEditorObjectBinding) override
|
|
{
|
|
EditorObjectBindingDelegates.Add(InOnCreateEditorObjectBinding);
|
|
return EditorObjectBindingDelegates.Last().GetHandle();
|
|
}
|
|
|
|
virtual void UnRegisterEditorObjectBinding(FDelegateHandle InHandle) override
|
|
{
|
|
EditorObjectBindingDelegates.RemoveAll([=](const FOnCreateEditorObjectBinding& Delegate) { return Delegate.GetHandle() == InHandle; });
|
|
}
|
|
|
|
void RegisterMenus()
|
|
{
|
|
UToolMenus* ToolMenus = UToolMenus::Get();
|
|
UToolMenu* Menu = ToolMenus->ExtendMenu("ContentBrowser.AssetContextMenu.LevelSequence");
|
|
if (!Menu)
|
|
{
|
|
return;
|
|
}
|
|
|
|
FToolMenuSection& Section = Menu->FindOrAddSection("GetAssetActions");
|
|
Section.AddDynamicEntry("SequencerActions", FNewToolMenuSectionDelegate::CreateLambda([](FToolMenuSection& InSection)
|
|
{
|
|
UContentBrowserAssetContextMenuContext* Context = InSection.FindContext<UContentBrowserAssetContextMenuContext>();
|
|
if (!Context)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ULevelSequence* LevelSequence = Context->SelectedObjects.Num() == 1 ? Cast<ULevelSequence>(Context->SelectedObjects[0]) : nullptr;
|
|
if (LevelSequence)
|
|
{
|
|
// if this LevelSequence has associated maps, offer to load them
|
|
TArray<FString> AssociatedMaps = FSequencerUtilities::GetAssociatedMapPackages(LevelSequence);
|
|
|
|
if(AssociatedMaps.Num()>0)
|
|
{
|
|
InSection.AddSubMenu(
|
|
"SequencerOpenMap_Label",
|
|
LOCTEXT("SequencerOpenMap_Label", "Open Map"),
|
|
LOCTEXT("SequencerOpenMap_Tooltip", "Open a map associated with this Level Sequence Asset"),
|
|
FNewMenuDelegate::CreateLambda(
|
|
[AssociatedMaps](FMenuBuilder& SubMenuBuilder)
|
|
{
|
|
for (const FString& AssociatedMap : AssociatedMaps)
|
|
{
|
|
SubMenuBuilder.AddMenuEntry(
|
|
FText::FromString(FPaths::GetBaseFilename(AssociatedMap)),
|
|
FText(),
|
|
FSlateIcon(FAppStyle::GetAppStyleSetName(), "LevelEditor.Tabs.Levels"),
|
|
FExecuteAction::CreateLambda(
|
|
[AssociatedMap]
|
|
{
|
|
FEditorFileUtils::LoadMap(AssociatedMap);
|
|
}
|
|
)
|
|
);
|
|
}
|
|
}
|
|
),
|
|
false,
|
|
FSlateIcon(FAppStyle::GetAppStyleSetName(), "LevelEditor.Tabs.Levels")
|
|
);
|
|
}
|
|
}
|
|
}));
|
|
}
|
|
|
|
virtual void StartupModule() override
|
|
{
|
|
using namespace UE::Sequencer;
|
|
using namespace UE::MovieScene;
|
|
|
|
if (GIsEditor)
|
|
{
|
|
FEditorModeRegistry::Get().RegisterMode<FSequencerEdMode>(
|
|
FSequencerEdMode::EM_SequencerMode,
|
|
NSLOCTEXT("Sequencer", "SequencerEditMode", "Sequencer Mode"),
|
|
FSlateIcon(),
|
|
false);
|
|
|
|
if (UToolMenus::TryGet())
|
|
{
|
|
FSequencerCommands::Register();
|
|
RegisterMenus();
|
|
}
|
|
else
|
|
{
|
|
FCoreDelegates::OnPostEngineInit.AddStatic(&FSequencerCommands::Register);
|
|
FCoreDelegates::OnPostEngineInit.AddRaw(this, &FSequencerModule::RegisterMenus);
|
|
}
|
|
|
|
UMovieSceneSignedObject::SetDeferredHandler(MakeUnique<FDeferredSignedObjectChangeHandler>());
|
|
|
|
FPropertyEditorModule& EditModule = FModuleManager::Get().GetModuleChecked<FPropertyEditorModule>("PropertyEditor");
|
|
OnGetGlobalRowExtensionHandle = EditModule.GetGlobalRowExtensionDelegate().AddStatic(&RegisterKeyframeExtensionHandler);
|
|
}
|
|
|
|
FSequenceModel::CreateExtensionsEvent.AddLambda(
|
|
[&](FSequenceModel* InModel)
|
|
{
|
|
InModel->AddDynamicExtension(FCurveEditorIntegrationExtension::ID);
|
|
InModel->AddDynamicExtension(FFolderModelStorageExtension::ID);
|
|
InModel->AddDynamicExtension(FObjectBindingModelStorageExtension::ID);
|
|
InModel->AddDynamicExtension(FTrackModelStorageExtension::ID, TrackModelDelegates);
|
|
InModel->AddDynamicExtension(FTrackRowModelStorageExtension::ID);
|
|
InModel->AddDynamicExtension(FSectionModelStorageExtension::ID);
|
|
}
|
|
);
|
|
|
|
ObjectBindingContextMenuExtensibilityManager = MakeShareable( new FExtensibilityManager );
|
|
AddTrackMenuExtensibilityManager = MakeShareable( new FExtensibilityManager );
|
|
ToolBarExtensibilityManager = MakeShareable(new FExtensibilityManager);
|
|
ActionsMenuExtensibilityManager = MakeShareable(new FExtensibilityManager);
|
|
|
|
SequencerCustomizationManager = MakeShareable(new FSequencerCustomizationManager);
|
|
}
|
|
|
|
virtual void ShutdownModule() override
|
|
{
|
|
if (GIsEditor)
|
|
{
|
|
UMovieSceneSignedObject::SetDeferredHandler(nullptr);
|
|
|
|
FSequencerCommands::Unregister();
|
|
|
|
if (FPropertyEditorModule* EditModulePtr = FModuleManager::Get().GetModulePtr<FPropertyEditorModule>("PropertyEditor"))
|
|
{
|
|
EditModulePtr->GetGlobalRowExtensionDelegate().Remove(OnGetGlobalRowExtensionHandle);
|
|
}
|
|
|
|
FEditorModeRegistry::Get().UnregisterMode(FSequencerEdMode::EM_SequencerMode);
|
|
}
|
|
}
|
|
|
|
virtual void RegisterPropertyAnimator(FAnimatedPropertyKey Key) override
|
|
{
|
|
PropertyAnimators.Add(Key);
|
|
}
|
|
|
|
virtual void UnRegisterPropertyAnimator(FAnimatedPropertyKey Key) override
|
|
{
|
|
PropertyAnimators.Remove(Key);
|
|
}
|
|
|
|
virtual bool CanAnimateProperty(FProperty* Property) override
|
|
{
|
|
if (PropertyAnimators.Contains(FAnimatedPropertyKey::FromProperty(Property)))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
FObjectPropertyBase* ObjectProperty = CastField<FObjectPropertyBase>(Property);
|
|
|
|
// Check each level of the property hierarchy
|
|
FFieldClass* PropertyType = Property->GetClass();
|
|
while (PropertyType && PropertyType != FProperty::StaticClass())
|
|
{
|
|
FAnimatedPropertyKey Key = FAnimatedPropertyKey::FromPropertyTypeName(PropertyType->GetFName());
|
|
|
|
// For object properties, check each parent type of the object (ie, so a track that animates UBaseClass ptrs can be used with a UDerivedClass property)
|
|
UClass* ClassType = (ObjectProperty && ObjectProperty->PropertyClass) ? ObjectProperty->PropertyClass->GetSuperClass() : nullptr;
|
|
while (ClassType)
|
|
{
|
|
Key.ObjectTypeName = ClassType->GetFName();
|
|
if (PropertyAnimators.Contains(Key))
|
|
{
|
|
return true;
|
|
}
|
|
ClassType = ClassType->GetSuperClass();
|
|
}
|
|
|
|
Key.ObjectTypeName = NAME_None;
|
|
if (PropertyAnimators.Contains(Key))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
// Look at the property's super class
|
|
PropertyType = PropertyType->GetSuperClass();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
virtual TSharedPtr<FExtensibilityManager> GetObjectBindingContextMenuExtensibilityManager() const override { return ObjectBindingContextMenuExtensibilityManager; }
|
|
virtual TSharedPtr<FExtensibilityManager> GetAddTrackMenuExtensibilityManager() const override { return AddTrackMenuExtensibilityManager; }
|
|
virtual TSharedPtr<FExtensibilityManager> GetToolBarExtensibilityManager() const override { return ToolBarExtensibilityManager; }
|
|
virtual TSharedPtr<FExtensibilityManager> GetActionsMenuExtensibilityManager() const override { return ActionsMenuExtensibilityManager; }
|
|
|
|
virtual TSharedPtr<FSequencerCustomizationManager> GetSequencerCustomizationManager() const override { return SequencerCustomizationManager; }
|
|
|
|
|
|
virtual FDelegateHandle RegisterMovieRenderer(TUniquePtr<IMovieRendererInterface>&& InMovieRenderer) override
|
|
{
|
|
FDelegateHandle NewHandle(FDelegateHandle::GenerateNewHandle);
|
|
MovieRenderers.Add(FMovieRendererEntry{ NewHandle, MoveTemp(InMovieRenderer) });
|
|
return NewHandle;
|
|
}
|
|
|
|
virtual void UnregisterMovieRenderer(FDelegateHandle InDelegateHandle) override
|
|
{
|
|
MovieRenderers.RemoveAll([InDelegateHandle](const FMovieRendererEntry& In){ return In.Handle == InDelegateHandle; });
|
|
}
|
|
|
|
virtual IMovieRendererInterface* GetMovieRenderer(const FString& InMovieRendererName) override
|
|
{
|
|
for (const FMovieRendererEntry& MovieRenderer : MovieRenderers)
|
|
{
|
|
if (MovieRenderer.Renderer->GetDisplayName() == InMovieRendererName)
|
|
{
|
|
return MovieRenderer.Renderer.Get();
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
virtual TArray<FString> GetMovieRendererNames() override
|
|
{
|
|
TArray<FString> MovieRendererNames;
|
|
for (const FMovieRendererEntry& MovieRenderer : MovieRenderers)
|
|
{
|
|
MovieRendererNames.Add(MovieRenderer.Renderer->GetDisplayName());
|
|
}
|
|
return MovieRendererNames;
|
|
}
|
|
|
|
private:
|
|
|
|
TSet<FAnimatedPropertyKey> PropertyAnimators;
|
|
|
|
/** List of auto-key handler delegates sequencers will execute when they are created */
|
|
TArray< FOnCreateTrackEditor > TrackEditorDelegates;
|
|
|
|
/** List of object binding handler delegates sequencers will execute when they are created */
|
|
TArray< FOnCreateEditorObjectBinding > EditorObjectBindingDelegates;
|
|
|
|
/** List of track model creators */
|
|
TArray<FOnCreateTrackModel> TrackModelDelegates;
|
|
|
|
/** Global details row extension delegate; */
|
|
FDelegateHandle OnGetGlobalRowExtensionHandle;
|
|
|
|
/** Multicast delegate used to notify others of sequencer initialization params and allow modification. */
|
|
FOnPreSequencerInit OnPreSequencerInit;
|
|
|
|
/** Multicast delegate used to notify others of sequencer creations */
|
|
FOnSequencerCreated OnSequencerCreated;
|
|
|
|
struct FAnimatedTypeCache
|
|
{
|
|
FDelegateHandle FactoryHandle;
|
|
TArray<FAnimatedPropertyKey, TInlineAllocator<4>> AnimatedTypes;
|
|
};
|
|
|
|
/** Map of all track editor factories to property types that they have registered to animated */
|
|
TArray<FAnimatedTypeCache> AnimatedTypeCache;
|
|
|
|
TSharedPtr<FExtensibilityManager> ObjectBindingContextMenuExtensibilityManager;
|
|
TSharedPtr<FExtensibilityManager> AddTrackMenuExtensibilityManager;
|
|
TSharedPtr<FExtensibilityManager> ToolBarExtensibilityManager;
|
|
TSharedPtr<FExtensibilityManager> ActionsMenuExtensibilityManager;
|
|
|
|
TSharedPtr<FSequencerCustomizationManager> SequencerCustomizationManager;
|
|
|
|
struct FMovieRendererEntry
|
|
{
|
|
FDelegateHandle Handle;
|
|
TUniquePtr<IMovieRendererInterface> Renderer;
|
|
};
|
|
|
|
/** Array of movie renderers */
|
|
TArray<FMovieRendererEntry> MovieRenderers;
|
|
};
|
|
|
|
IMPLEMENT_MODULE(FSequencerModule, Sequencer);
|
|
|
|
#undef LOCTEXT_NAMESPACE
|