// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "Containers/Array.h" #include "Containers/ContainerAllocationPolicies.h" #include "HAL/PlatformCrt.h" #include "ISectionLayoutBuilder.h" #include "MVVM/ViewModelPtr.h" #include "MVVM/ViewModels/ViewModelHierarchy.h" #include "MVVM/ViewModels/ViewModelIterators.h" #include "Templates/Invoke.h" #include "Templates/SharedPointer.h" #include "Templates/TypeHash.h" #include "UObject/NameTypes.h" class FText; class ISequencerSection; namespace UE::Sequencer { class FViewModel; } struct FMovieSceneChannelHandle; namespace UE { namespace Sequencer { class FSectionModel; struct FHierarchicalModelListRefresher { FHierarchicalModelListRefresher(); FHierarchicalModelListRefresher(TSharedPtr InRoot, FViewModelChildren InExistingChildren); bool IsValid() const; void Reset(); void Link(TSharedPtr Item); void RecurseInto(TSharedPtr Item, FViewModelChildren InExistingChildren); TSharedPtr GetCurrentParent() const; EViewModelListType GetCurrentType() const; void Pop(); template TSharedPtr FindItem(Predicate&& InPredicate) const { TViewModelPtr Model = FindExistingItem(InPredicate); return Model ? Model : FindRecycledItem(InPredicate); } template TSharedPtr FindExistingItem(Predicate&& InPredicate) const { // Look for existing children for (const TViewModelPtr& Item : ListData.Last().Children.IterateSubList()) { if (Invoke(InPredicate, *Item)) { return Item; } } return nullptr; } template TViewModelPtr FindRecycledItem(Predicate&& InPredicate) const { // Look for recycled children for (const TViewModelPtr& Item : ListData.Last().Parent->GetChildrenOfType(EViewModelListType::Recycled)) { if (Invoke(InPredicate, *Item)) { return Item; } } return nullptr; } private: void ConditionalRecycleChildren(const TSharedPtr& InModel, FViewModelChildren InExistingChildren); struct FListData { explicit FListData(TSharedPtr InParent, const FViewModelChildren& InExistingChildren); // The data model that owns the list we're refreshing. TSharedPtr Parent; // The list we're refreshing. FViewModelChildren Children; // The tail of the list we're refreshing. TSharedPtr AttachTail; }; TArray> ListData; TArray> RecycledLists; }; class FTrackModelLayoutBuilder : private ISectionLayoutBuilder { public: FTrackModelLayoutBuilder(TSharedPtr InSharedOutlinerRoot); ~FTrackModelLayoutBuilder(); void RefreshLayout(TSharedPtr InSection); public: // ISectionLayoutBuilder interface virtual void PushCategory( FName CategoryName, const FText& DisplayLabel, FGetMovieSceneTooltipText GetGroupTooltipTextDelegate, TFunction(FName, const FText&)> OptionalFactory ) override; virtual void SetTopLevelChannel( const FMovieSceneChannelHandle& Channel, TFunction(FName, const FSectionModel&, const FMovieSceneChannelHandle&)> OptionalFactory ) override; virtual void AddChannel( const FMovieSceneChannelHandle& Channel, TFunction(FName, const FSectionModel&, const FMovieSceneChannelHandle&)> OptionalFactory ) override; virtual void PopCategory() override; private: void AddChannel( const FMovieSceneChannelHandle& Channel, bool bIsTopLevel, TFunction(FName, const FSectionModel&, const FMovieSceneChannelHandle&)> OptionalFactory ); private: TSharedPtr Root; FHierarchicalModelListRefresher OutlinerList; FHierarchicalModelListRefresher TrackAreaList; TSharedPtr Section; }; } // namespace Sequencer } // namespace UE