You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
444 lines
10 KiB
C++
444 lines
10 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "SequencerSelection.h"
|
|
#include "MovieSceneSection.h"
|
|
#include "DisplayNodes/SequencerObjectBindingNode.h"
|
|
#include "DisplayNodes/SequencerTrackNode.h"
|
|
#include "SequencerCommonHelpers.h"
|
|
|
|
FSequencerSelection::FSequencerSelection()
|
|
: SerialNumber(0)
|
|
, SuspendBroadcastCount(0)
|
|
, bOutlinerNodeSelectionChangedBroadcastPending(false)
|
|
, bEmptySelectedOutlinerNodesWithSectionsPending(false)
|
|
{
|
|
}
|
|
|
|
const TSet<FSequencerSelectedKey>& FSequencerSelection::GetSelectedKeys() const
|
|
{
|
|
return SelectedKeys;
|
|
}
|
|
|
|
const TSet<TWeakObjectPtr<UMovieSceneSection>>& FSequencerSelection::GetSelectedSections() const
|
|
{
|
|
return SelectedSections;
|
|
}
|
|
|
|
const TSet<TSharedRef<FSequencerDisplayNode>>& FSequencerSelection::GetSelectedOutlinerNodes() const
|
|
{
|
|
return SelectedOutlinerNodes;
|
|
}
|
|
|
|
const TSet<TSharedRef<FSequencerDisplayNode>>& FSequencerSelection::GetNodesWithSelectedKeysOrSections() const
|
|
{
|
|
return NodesWithSelectedKeysOrSections;
|
|
}
|
|
|
|
FSequencerSelection::FOnSelectionChanged& FSequencerSelection::GetOnKeySelectionChanged()
|
|
{
|
|
return OnKeySelectionChanged;
|
|
}
|
|
|
|
FSequencerSelection::FOnSelectionChanged& FSequencerSelection::GetOnSectionSelectionChanged()
|
|
{
|
|
return OnSectionSelectionChanged;
|
|
}
|
|
|
|
FSequencerSelection::FOnSelectionChanged& FSequencerSelection::GetOnOutlinerNodeSelectionChanged()
|
|
{
|
|
return OnOutlinerNodeSelectionChanged;
|
|
}
|
|
|
|
FSequencerSelection::FOnSelectionChanged& FSequencerSelection::GetOnNodesWithSelectedKeysOrSectionsChanged()
|
|
{
|
|
return OnNodesWithSelectedKeysOrSectionsChanged;
|
|
}
|
|
|
|
FSequencerSelection::FOnSelectionChangedObjectGuids& FSequencerSelection::GetOnOutlinerNodeSelectionChangedObjectGuids()
|
|
{
|
|
return OnOutlinerNodeSelectionChangedObjectGuids;
|
|
}
|
|
|
|
TArray<FGuid> FSequencerSelection::GetBoundObjectsGuids()
|
|
{
|
|
TArray<FGuid> OutGuids;
|
|
TSet<TSharedRef<FSequencerDisplayNode>> SelectedNodes = GetNodesWithSelectedKeysOrSections();
|
|
if (SelectedNodes.Num() == 0)
|
|
{
|
|
SelectedNodes = GetSelectedOutlinerNodes();
|
|
}
|
|
for (TSharedRef<FSequencerDisplayNode> Node : SelectedNodes)
|
|
{
|
|
TSharedPtr<FSequencerObjectBindingNode> ObjectNode = Node->FindParentObjectBindingNode();
|
|
if (Node->GetType() == ESequencerNode::Object)
|
|
{
|
|
ObjectNode = StaticCastSharedRef<FSequencerObjectBindingNode>(Node);
|
|
}
|
|
else
|
|
{
|
|
ObjectNode = Node->FindParentObjectBindingNode();
|
|
}
|
|
|
|
if (ObjectNode.IsValid())
|
|
{
|
|
OutGuids.Add(ObjectNode->GetObjectBinding());
|
|
}
|
|
}
|
|
|
|
return OutGuids;
|
|
}
|
|
|
|
TArray<UMovieSceneTrack*> FSequencerSelection::GetSelectedTracks() const
|
|
{
|
|
TArray<UMovieSceneTrack*> OutTracks;
|
|
|
|
for (const TSharedRef<FSequencerDisplayNode>& SelectedNode : SelectedOutlinerNodes)
|
|
{
|
|
TSharedPtr<FSequencerDisplayNode> CurrentNode = SelectedNode;
|
|
while (CurrentNode.IsValid() && CurrentNode->GetType() != ESequencerNode::Track)
|
|
{
|
|
CurrentNode = CurrentNode->GetParent();
|
|
}
|
|
|
|
if (CurrentNode.IsValid())
|
|
{
|
|
UMovieSceneTrack* SelectedTrack = StaticCastSharedPtr<FSequencerTrackNode>(CurrentNode)->GetTrack();
|
|
if (SelectedTrack != nullptr)
|
|
{
|
|
OutTracks.Add(SelectedTrack);
|
|
}
|
|
}
|
|
}
|
|
|
|
return OutTracks;
|
|
}
|
|
|
|
void FSequencerSelection::AddToSelection(const FSequencerSelectedKey& Key)
|
|
{
|
|
++SerialNumber;
|
|
|
|
SelectedKeys.Add(Key);
|
|
if ( IsBroadcasting() )
|
|
{
|
|
OnKeySelectionChanged.Broadcast();
|
|
OnOutlinerNodeSelectionChangedObjectGuids.Broadcast();
|
|
|
|
// Deselect any outliner nodes that aren't within the trunk of this key
|
|
TArray<UMovieSceneSection*> Sections;
|
|
Sections.Add(Key.Section);
|
|
|
|
EmptySelectedOutlinerNodesWithoutSections(Sections);
|
|
}
|
|
else
|
|
{
|
|
bEmptySelectedOutlinerNodesWithSectionsPending = true;
|
|
}
|
|
}
|
|
|
|
void FSequencerSelection::AddToSelection(UMovieSceneSection* Section)
|
|
{
|
|
++SerialNumber;
|
|
|
|
SelectedSections.Add(Section);
|
|
if ( IsBroadcasting() )
|
|
{
|
|
OnSectionSelectionChanged.Broadcast();
|
|
OnOutlinerNodeSelectionChangedObjectGuids.Broadcast();
|
|
|
|
// Deselect any outliner nodes that aren't within the trunk of this section
|
|
if (Section)
|
|
{
|
|
TArray<UMovieSceneSection*> Sections;
|
|
Sections.Add(Section);
|
|
|
|
EmptySelectedOutlinerNodesWithoutSections(Sections);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bEmptySelectedOutlinerNodesWithSectionsPending = true;
|
|
}
|
|
}
|
|
|
|
void FSequencerSelection::AddToSelection(TSharedRef<FSequencerDisplayNode> OutlinerNode)
|
|
{
|
|
++SerialNumber;
|
|
|
|
SelectedOutlinerNodes.Add(OutlinerNode);
|
|
if ( IsBroadcasting() )
|
|
{
|
|
OnOutlinerNodeSelectionChanged.Broadcast();
|
|
OnOutlinerNodeSelectionChangedObjectGuids.Broadcast();
|
|
}
|
|
EmptySelectedKeys();
|
|
EmptySelectedSections();
|
|
EmptyNodesWithSelectedKeysOrSections();
|
|
}
|
|
|
|
void FSequencerSelection::AddToSelection(const TArray<TSharedRef<FSequencerDisplayNode>>& OutlinerNodes)
|
|
{
|
|
++SerialNumber;
|
|
|
|
SelectedOutlinerNodes.Append(OutlinerNodes);
|
|
if (IsBroadcasting())
|
|
{
|
|
OnOutlinerNodeSelectionChanged.Broadcast();
|
|
OnOutlinerNodeSelectionChangedObjectGuids.Broadcast();
|
|
}
|
|
EmptySelectedKeys();
|
|
EmptySelectedSections();
|
|
EmptyNodesWithSelectedKeysOrSections();
|
|
}
|
|
|
|
void FSequencerSelection::AddToNodesWithSelectedKeysOrSections(TSharedRef<FSequencerDisplayNode> OutlinerNode)
|
|
{
|
|
++SerialNumber;
|
|
|
|
NodesWithSelectedKeysOrSections.Add(OutlinerNode);
|
|
if ( IsBroadcasting() )
|
|
{
|
|
++SerialNumber;
|
|
OnNodesWithSelectedKeysOrSectionsChanged.Broadcast();
|
|
OnOutlinerNodeSelectionChangedObjectGuids.Broadcast();
|
|
}
|
|
}
|
|
|
|
|
|
void FSequencerSelection::RemoveFromSelection(const FSequencerSelectedKey& Key)
|
|
{
|
|
++SerialNumber;
|
|
|
|
SelectedKeys.Remove(Key);
|
|
if ( IsBroadcasting() )
|
|
{
|
|
OnKeySelectionChanged.Broadcast();
|
|
}
|
|
}
|
|
|
|
void FSequencerSelection::RemoveFromSelection(UMovieSceneSection* Section)
|
|
{
|
|
++SerialNumber;
|
|
|
|
SelectedSections.Remove(Section);
|
|
if ( IsBroadcasting() )
|
|
{
|
|
OnSectionSelectionChanged.Broadcast();
|
|
}
|
|
}
|
|
|
|
void FSequencerSelection::RemoveFromSelection(TSharedRef<FSequencerDisplayNode> OutlinerNode)
|
|
{
|
|
++SerialNumber;
|
|
|
|
SelectedOutlinerNodes.Remove(OutlinerNode);
|
|
if ( IsBroadcasting() )
|
|
{
|
|
OnOutlinerNodeSelectionChanged.Broadcast();
|
|
}
|
|
}
|
|
|
|
void FSequencerSelection::RemoveFromNodesWithSelectedKeysOrSections(TSharedRef<FSequencerDisplayNode> OutlinerNode)
|
|
{
|
|
++SerialNumber;
|
|
|
|
NodesWithSelectedKeysOrSections.Remove(OutlinerNode);
|
|
if ( IsBroadcasting() )
|
|
{
|
|
OnNodesWithSelectedKeysOrSectionsChanged.Broadcast();
|
|
}
|
|
}
|
|
|
|
bool FSequencerSelection::IsSelected(const FSequencerSelectedKey& Key) const
|
|
{
|
|
return SelectedKeys.Contains(Key);
|
|
}
|
|
|
|
bool FSequencerSelection::IsSelected(UMovieSceneSection* Section) const
|
|
{
|
|
return SelectedSections.Contains(Section);
|
|
}
|
|
|
|
bool FSequencerSelection::IsSelected(TSharedRef<FSequencerDisplayNode> OutlinerNode) const
|
|
{
|
|
return SelectedOutlinerNodes.Contains(OutlinerNode);
|
|
}
|
|
|
|
bool FSequencerSelection::NodeHasSelectedKeysOrSections(TSharedRef<FSequencerDisplayNode> OutlinerNode) const
|
|
{
|
|
return NodesWithSelectedKeysOrSections.Contains(OutlinerNode);
|
|
}
|
|
|
|
void FSequencerSelection::Empty()
|
|
{
|
|
++SerialNumber;
|
|
|
|
EmptySelectedKeys();
|
|
EmptySelectedSections();
|
|
EmptySelectedOutlinerNodes();
|
|
EmptyNodesWithSelectedKeysOrSections();
|
|
}
|
|
|
|
void FSequencerSelection::EmptySelectedKeys()
|
|
{
|
|
if (!SelectedKeys.Num())
|
|
{
|
|
return;
|
|
}
|
|
|
|
++SerialNumber;
|
|
|
|
SelectedKeys.Empty();
|
|
if ( IsBroadcasting() )
|
|
{
|
|
OnKeySelectionChanged.Broadcast();
|
|
}
|
|
}
|
|
|
|
void FSequencerSelection::EmptySelectedSections()
|
|
{
|
|
if (!SelectedSections.Num())
|
|
{
|
|
return;
|
|
}
|
|
|
|
++SerialNumber;
|
|
|
|
SelectedSections.Empty();
|
|
if ( IsBroadcasting() )
|
|
{
|
|
OnSectionSelectionChanged.Broadcast();
|
|
}
|
|
}
|
|
|
|
void FSequencerSelection::EmptySelectedOutlinerNodes()
|
|
{
|
|
if (!SelectedOutlinerNodes.Num())
|
|
{
|
|
return;
|
|
}
|
|
|
|
++SerialNumber;
|
|
|
|
SelectedOutlinerNodes.Empty();
|
|
if ( IsBroadcasting() )
|
|
{
|
|
OnOutlinerNodeSelectionChanged.Broadcast();
|
|
}
|
|
}
|
|
|
|
void FSequencerSelection::EmptyNodesWithSelectedKeysOrSections()
|
|
{
|
|
if (!NodesWithSelectedKeysOrSections.Num())
|
|
{
|
|
return;
|
|
}
|
|
|
|
++SerialNumber;
|
|
|
|
NodesWithSelectedKeysOrSections.Empty();
|
|
if ( IsBroadcasting() )
|
|
{
|
|
OnNodesWithSelectedKeysOrSectionsChanged.Broadcast();
|
|
}
|
|
}
|
|
|
|
/** Suspend or resume broadcast of selection changing */
|
|
void FSequencerSelection::SuspendBroadcast()
|
|
{
|
|
SuspendBroadcastCount++;
|
|
}
|
|
|
|
void FSequencerSelection::ResumeBroadcast()
|
|
{
|
|
SuspendBroadcastCount--;
|
|
checkf(SuspendBroadcastCount >= 0, TEXT("Suspend/Resume broadcast mismatch!"));
|
|
}
|
|
|
|
bool FSequencerSelection::IsBroadcasting()
|
|
{
|
|
return SuspendBroadcastCount == 0;
|
|
}
|
|
|
|
void FSequencerSelection::EmptySelectedOutlinerNodesWithoutSections(const TArray<UMovieSceneSection*>& Sections)
|
|
{
|
|
TSet<TSharedRef<FSequencerDisplayNode>> LocalSelectedOutlinerNodes = SelectedOutlinerNodes;
|
|
|
|
SuspendBroadcast();
|
|
bool bRemoved = false;
|
|
for (auto SelectedOutlinerNode : LocalSelectedOutlinerNodes)
|
|
{
|
|
TSet<TSharedRef<FSequencerDisplayNode> > TrunkNodes;
|
|
TrunkNodes.Add(SelectedOutlinerNode);
|
|
SequencerHelpers::GetDescendantNodes(SelectedOutlinerNode, TrunkNodes);
|
|
|
|
bool bFoundMatch = false;
|
|
for (auto TrunkIt = TrunkNodes.CreateConstIterator(); TrunkIt && !bFoundMatch; ++TrunkIt)
|
|
{
|
|
TSet<TWeakObjectPtr<UMovieSceneSection>> AllSections;
|
|
SequencerHelpers::GetAllSections(*TrunkIt, AllSections);
|
|
|
|
for (auto SectionIt = AllSections.CreateConstIterator(); SectionIt && !bFoundMatch; ++SectionIt)
|
|
{
|
|
if (Sections.Contains(*SectionIt))
|
|
{
|
|
bFoundMatch = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!bFoundMatch)
|
|
{
|
|
RemoveFromSelection(SelectedOutlinerNode);
|
|
bRemoved = true;
|
|
}
|
|
}
|
|
ResumeBroadcast();
|
|
|
|
if (bRemoved)
|
|
{
|
|
++SerialNumber;
|
|
|
|
OnOutlinerNodeSelectionChanged.Broadcast();
|
|
}
|
|
}
|
|
|
|
void FSequencerSelection::RequestOutlinerNodeSelectionChangedBroadcast()
|
|
{
|
|
bOutlinerNodeSelectionChangedBroadcastPending = true;
|
|
}
|
|
|
|
void FSequencerSelection::Tick()
|
|
{
|
|
if ( bOutlinerNodeSelectionChangedBroadcastPending && IsBroadcasting() )
|
|
{
|
|
bOutlinerNodeSelectionChangedBroadcastPending = false;
|
|
OnOutlinerNodeSelectionChanged.Broadcast();
|
|
}
|
|
|
|
if ( bEmptySelectedOutlinerNodesWithSectionsPending && IsBroadcasting() )
|
|
{
|
|
bEmptySelectedOutlinerNodesWithSectionsPending = false;
|
|
|
|
TArray<UMovieSceneSection*> Sections;
|
|
for (TWeakObjectPtr<UMovieSceneSection> SelectedSection : SelectedSections)
|
|
{
|
|
if (SelectedSection.IsValid())
|
|
{
|
|
Sections.Add(SelectedSection.Get());
|
|
}
|
|
}
|
|
|
|
for (FSequencerSelectedKey SelectedKey : SelectedKeys)
|
|
{
|
|
if (SelectedKey.IsValid() && !Sections.Contains(SelectedKey.Section))
|
|
{
|
|
Sections.Add(SelectedKey.Section);
|
|
}
|
|
}
|
|
|
|
EmptySelectedOutlinerNodesWithoutSections(Sections);
|
|
}
|
|
}
|
|
|