// Copyright Epic Games, Inc. All Rights Reserved. #include "Scripting/SequencerModuleOutlinerScriptingObject.h" #include "Scripting/ViewModelScriptingStruct.h" #include "MVVM/ViewModels/SequencerEditorViewModel.h" #include "MVVM/ViewModels/SequencerOutlinerViewModel.h" #include "MVVM/ViewModels/ViewModel.h" #include "MVVM/ViewModels/ViewModelIterators.h" #include "MVVM/ViewModels/ObjectBindingModel.h" #include "MVVM/ViewModels/OutlinerViewModel.h" #include "MVVM/ViewModels/EditorViewModel.h" #include "MVVM/ViewModelPtr.h" #include "Containers/Array.h" #include "Misc/FrameNumber.h" #include "MovieScene.h" #include "ObjectBindingTagCache.h" #include "Sequencer.h" #include "SequencerCommonHelpers.h" #include UE_INLINE_GENERATED_CPP_BY_NAME(SequencerModuleOutlinerScriptingObject) #define LOCTEXT_NAMESPACE "SequencerModuleOutlinerScriptingObject" TArray USequencerModuleOutlinerScriptingObject::GetSections(const TArray& InNodes) const { using namespace UE::Sequencer; TViewModelPtr Outliner = CastViewModel(WeakOutliner.Pin()); if (!Outliner) { FFrame::KismetExecutionMessage(*LOCTEXT("OutlinerInvalid", "Outliner is no longer valid.").ToString(), ELogVerbosity::Error); return TArray(); } TSet > AllSections; TArray> Nodes; for (const FSequencerViewModelScriptingStruct& InNode : InNodes) { FViewModelPtr Item = InNode.WeakViewModel.ImplicitPin(); if (Item) { SequencerHelpers::GetAllSections(Item, AllSections); } } TArray Sections; for (TWeakObjectPtr WeakSection : AllSections) { if (WeakSection.IsValid()) { Sections.Add(WeakSection.Get()); } } return Sections; } FFrameNumber USequencerModuleOutlinerScriptingObject::GetNextKey(const TArray& InNodes, FFrameNumber FrameNumber, EMovieSceneTimeUnit TimeUnit) const { using namespace UE::Sequencer; TViewModelPtr Outliner = CastViewModel(WeakOutliner.Pin()); if (!Outliner) { FFrame::KismetExecutionMessage(*LOCTEXT("OutlinerInvalid", "Outliner is no longer valid.").ToString(), ELogVerbosity::Error); return FFrameNumber(); } TRange Range = TRange::All(); TArray> Nodes; for (const FSequencerViewModelScriptingStruct& InNode : InNodes) { FViewModelPtr Item = InNode.WeakViewModel.ImplicitPin(); if (Item) { Nodes.Add(Item.ToSharedRef()); } } return Outliner->GetNextKey(Nodes, FrameNumber, TimeUnit, Range); } FFrameNumber USequencerModuleOutlinerScriptingObject::GetPreviousKey(const TArray& InNodes, FFrameNumber FrameNumber, EMovieSceneTimeUnit TimeUnit) const { using namespace UE::Sequencer; TViewModelPtr Outliner = CastViewModel(WeakOutliner.Pin()); if (!Outliner) { FFrame::KismetExecutionMessage(*LOCTEXT("OutlinerInvalid", "Outliner is no longer valid.").ToString(), ELogVerbosity::Error); return FFrameNumber(); } TRange Range = TRange::All(); TArray> Nodes; for (const FSequencerViewModelScriptingStruct& InNode : InNodes) { TViewModelPtr Item = InNode.WeakViewModel.ImplicitPin(); if (Item) { Nodes.Add(Item.ToSharedRef()); } } return Outliner->GetPreviousKey(Nodes, FrameNumber, TimeUnit, Range); } void USequencerModuleOutlinerScriptingObject::AddBindingTags(const TArray& InNodes, const TArray& TagNames) { using namespace UE::Sequencer; TSharedPtr Sequencer = GetSequencer(); if (!Sequencer) { FFrame::KismetExecutionMessage(*LOCTEXT("SequencerInvalid", "Sequencer is no longer valid.").ToString(), ELogVerbosity::Error); return; } UMovieSceneSequence* Sequence = Sequencer->GetFocusedMovieSceneSequence(); UMovieScene* MovieScene = Sequence ? Sequence->GetMovieScene() : nullptr; if (!MovieScene) { FFrame::KismetExecutionMessage(*LOCTEXT("MovieSceneInvalid", "Movie Scene is not an object binding.").ToString(), ELogVerbosity::Error); return; } for (const FSequencerViewModelScriptingStruct& InNode : InNodes) { TViewModelPtr ObjectBindingModel = CastViewModel(InNode.WeakViewModel.Pin()); if (!ObjectBindingModel) { FFrame::KismetExecutionMessage(*LOCTEXT("NodeInvalid", "Node is not an object binding.").ToString(), ELogVerbosity::Error); return; } const FGuid& ObjectID = ObjectBindingModel->GetObjectGuid(); FMovieSceneSequenceIDRef SequenceID = Sequencer->GetFocusedTemplateID(); for (const FName& TagName : TagNames) { UE::MovieScene::FFixedObjectBindingID BindingID(ObjectID, SequenceID); MovieScene->TagBinding(TagName, BindingID); } } } void USequencerModuleOutlinerScriptingObject::RemoveBindingTags(const TArray& InNodes, const TArray& TagNames) { using namespace UE::Sequencer; TSharedPtr Sequencer = GetSequencer(); if (!Sequencer) { FFrame::KismetExecutionMessage(*LOCTEXT("SequencerInvalid", "Sequencer is no longer valid.").ToString(), ELogVerbosity::Error); return; } UMovieSceneSequence* Sequence = Sequencer->GetFocusedMovieSceneSequence(); UMovieScene* MovieScene = Sequence ? Sequence->GetMovieScene() : nullptr; if (!MovieScene) { FFrame::KismetExecutionMessage(*LOCTEXT("MovieSceneInvalid", "Movie Scene is not an object binding.").ToString(), ELogVerbosity::Error); return; } for (const FSequencerViewModelScriptingStruct& InNode : InNodes) { TViewModelPtr ObjectBindingModel = CastViewModel(InNode.WeakViewModel.Pin()); if (!ObjectBindingModel) { FFrame::KismetExecutionMessage(*LOCTEXT("NodeInvalid", "Node is not an object binding.").ToString(), ELogVerbosity::Error); return; } const FGuid& ObjectID = ObjectBindingModel->GetObjectGuid(); FMovieSceneSequenceIDRef SequenceID = Sequencer->GetFocusedTemplateID(); for (const FName& TagName : TagNames) { UE::MovieScene::FFixedObjectBindingID BindingID(ObjectID, SequenceID); MovieScene->UntagBinding(TagName, BindingID); } } } TArray USequencerModuleOutlinerScriptingObject::GetBindingTags(FSequencerViewModelScriptingStruct InNode) { using namespace UE::Sequencer; TArray Tags; TSharedPtr Sequencer = GetSequencer(); if (!Sequencer) { FFrame::KismetExecutionMessage(*LOCTEXT("SequencerInvalid", "Sequencer is no longer valid.").ToString(), ELogVerbosity::Error); return Tags; } UMovieSceneSequence* Sequence = Sequencer->GetFocusedMovieSceneSequence(); UMovieScene* MovieScene = Sequence ? Sequence->GetMovieScene() : nullptr; if (!MovieScene) { FFrame::KismetExecutionMessage(*LOCTEXT("MovieSceneInvalid", "Movie Scene is not an object binding.").ToString(), ELogVerbosity::Error); return Tags; } TViewModelPtr ObjectBindingModel = CastViewModel(InNode.WeakViewModel.Pin()); if (!ObjectBindingModel) { FFrame::KismetExecutionMessage(*LOCTEXT("NodeInvalid", "Node is not an object binding.").ToString(), ELogVerbosity::Error); return Tags; } const FGuid& ObjectID = ObjectBindingModel->GetObjectGuid(); FMovieSceneSequenceIDRef SequenceID = Sequencer->GetFocusedTemplateID(); UE::MovieScene::FFixedObjectBindingID BindingID(ObjectID, SequenceID); for (auto It = Sequencer->GetObjectBindingTagCache()->IterateTags(BindingID); It; ++It) { Tags.Add(It.Value()); } return Tags; } TSharedPtr USequencerModuleOutlinerScriptingObject::GetSequencer() { using namespace UE::Sequencer; TViewModelPtr Outliner = CastViewModel(WeakOutliner.Pin()); if (!Outliner) { FFrame::KismetExecutionMessage(*LOCTEXT("SequencerOutlinerInvalid", "Sequencer Outliner is no longer valid.").ToString(), ELogVerbosity::Error); return nullptr; } TViewModelPtr Editor = CastViewModel(Outliner->GetEditor()); if (!Editor) { FFrame::KismetExecutionMessage(*LOCTEXT("SequencerEditorInvalid", "Sequencer Editor is no longer valid.").ToString(), ELogVerbosity::Error); return nullptr; } TSharedPtr Sequencer = Editor->GetSequencerImpl(); return Sequencer; } #undef LOCTEXT_NAMESPACE