UMovieSceneTrack* UMovieScene::FindTrack( TSubclassOf<UMovieSceneTrack> TrackClass, const FGuid& ObjectGuid, FName UniqueTrackName ) const { UMovieSceneTrack* FoundTrack = NULL; check( UniqueTrackName != NAME_None && ObjectGuid.IsValid() ) for( int32 ObjectBindingIndex = 0; ObjectBindingIndex < ObjectBindings.Num(); ++ObjectBindingIndex ) { const FMovieSceneObjectBinding& ObjectBinding = ObjectBindings[ObjectBindingIndex]; if( ObjectBinding.GetObjectGuid() == ObjectGuid ) { const TArray<UMovieSceneTrack*>& Tracks = ObjectBinding.GetTracks(); for( int32 TrackIndex = 0; TrackIndex < Tracks.Num(); ++TrackIndex ) { UMovieSceneTrack* Track = Tracks[TrackIndex]; if( Track->GetClass() == TrackClass && Track->GetTrackName() == UniqueTrackName ) { FoundTrack = Track; break; } } } } return FoundTrack; }
TSharedRef<ISequencerSection> F2DTransformTrackEditor::MakeSectionInterface( UMovieSceneSection& SectionObject, UMovieSceneTrack& Track ) { check( SupportsType( SectionObject.GetOuter()->GetClass() ) ); UClass* SectionClass = SectionObject.GetOuter()->GetClass(); return MakeShareable( new F2DTransformSection( SectionObject, Track.GetTrackName() ) ); }
void FSequencerNodeTree::Update() { // @todo Sequencer - This update pass is too aggressive. Some nodes may still be valid Empty(); UMovieScene* MovieScene = Sequencer.GetFocusedMovieSceneSequence()->GetMovieScene(); TArray< TSharedRef<FSequencerDisplayNode> > NewRootNodes; // Get the master tracks so we can get sections from them const TArray<UMovieSceneTrack*>& MasterTracks = MovieScene->GetMasterTracks(); for( UMovieSceneTrack* Track : MasterTracks ) { UMovieSceneTrack& TrackRef = *Track; TSharedRef<FTrackNode> SectionNode = MakeShareable( new FTrackNode( TrackRef.GetTrackName(), TrackRef, NULL, *this ) ); NewRootNodes.Add( SectionNode ); MakeSectionInterfaces( TrackRef, SectionNode ); SectionNode->PinNode(); } const TArray<FMovieSceneBinding>& Bindings = MovieScene->GetBindings(); TMap<FGuid, const FMovieSceneBinding*> GuidToBindingMap; for (const FMovieSceneBinding& Binding : Bindings) { GuidToBindingMap.Add(Binding.GetObjectGuid(), &Binding); } // Make nodes for all object bindings TArray< TSharedRef<FSequencerDisplayNode> > NewObjectNodes; for( const FMovieSceneBinding& Binding : Bindings ) { TSharedRef<FObjectBindingNode> ObjectBindingNode = AddObjectBinding( Binding.GetName(), Binding.GetObjectGuid(), GuidToBindingMap, NewObjectNodes ); const TArray<UMovieSceneTrack*>& Tracks = Binding.GetTracks(); for( UMovieSceneTrack* Track : Tracks ) { UMovieSceneTrack& TrackRef = *Track; FName SectionName = TrackRef.GetTrackName(); check( SectionName != NAME_None ); TSharedRef<FTrackNode> SectionAreaNode = ObjectBindingNode->AddSectionAreaNode( SectionName, TrackRef ); MakeSectionInterfaces( TrackRef, SectionAreaNode ); } } struct FObjectNodeSorter { bool operator()( const TSharedRef<FSequencerDisplayNode>& A, const TSharedRef<FSequencerDisplayNode>& B ) const { if (A->GetType() == ESequencerNode::Object && B->GetType() != ESequencerNode::Object) { return true; } if (A->GetType() != ESequencerNode::Object && B->GetType() == ESequencerNode::Object) { return false; } return A->GetDisplayName().ToString() < B->GetDisplayName().ToString(); } }; NewObjectNodes.Sort( FObjectNodeSorter() ); for (TSharedRef<FSequencerDisplayNode> NewObjectNode : NewObjectNodes) { NewObjectNode->SortChildNodes(FObjectNodeSorter()); } NewRootNodes.Append(NewObjectNodes); // Look for a shot track. It will always come first if it exists UMovieSceneTrack* ShotTrack = MovieScene->GetShotTrack(); if( ShotTrack ) { TSharedRef<FTrackNode> SectionNode = MakeShareable( new FTrackNode( ShotTrack->GetTrackName(), *ShotTrack, NULL, *this ) ); // Shot track always comes first RootNodes.Add( SectionNode ); MakeSectionInterfaces( *ShotTrack, SectionNode ); SectionNode->PinNode(); } // Add all other nodes after the shot track RootNodes.Append( NewRootNodes ); // Set up virtual offsets, and expansion states float VerticalOffset = 0.f; for (auto& Node : RootNodes) { Node->Traverse_ParentFirst([&](FSequencerDisplayNode& InNode){ float VerticalTop = VerticalOffset; VerticalOffset += InNode.GetNodeHeight() + InNode.GetNodePadding().Combined(); InNode.Initialize(VerticalTop, VerticalOffset); return true; }); } // Re-filter the tree after updating // @todo Sequencer - Newly added sections may need to be visible even when there is a filter FilterNodes( FilterString ); }
TSharedRef<ISequencerSection> FBytePropertyTrackEditor::MakeSectionInterface( UMovieSceneSection& SectionObject, UMovieSceneTrack& Track ) { return MakeShareable( new FBytePropertySection( SectionObject, Track.GetTrackName(), Cast<UMovieSceneByteTrack>( SectionObject.GetOuter() )->GetEnum() ) ); }
TSharedRef<ISequencerSection> FSubMovieSceneTrackEditor::MakeSectionInterface( UMovieSceneSection& SectionObject, UMovieSceneTrack& Track ) { return MakeShareable( new FSubMovieSceneSection( GetSequencer(), SectionObject, Track.GetTrackName() ) ); }
FSequencerTrackNode::FSequencerTrackNode(UMovieSceneTrack& InAssociatedTrack, ISequencerTrackEditor& InAssociatedEditor, bool bInCanBeDragged, TSharedPtr<FSequencerDisplayNode> InParentNode, FSequencerNodeTree& InParentTree) : FSequencerDisplayNode(InAssociatedTrack.GetTrackName(), InParentNode, InParentTree) , AssociatedEditor(InAssociatedEditor) , AssociatedTrack(&InAssociatedTrack) , bCanBeDragged(bInCanBeDragged) { }