FKeyAreaLayout::FKeyAreaLayout(FSequencerDisplayNode& InNode, int32 InSectionIndex) { TotalHeight = 0.f; float LastPadding = 0.f; auto SetupKeyArea = [&](FSequencerDisplayNode& Node){ if (Node.GetType() == ESequencerNode::KeyArea) { Elements.Add(FKeyAreaLayoutElement::FromKeyAreaNode(StaticCastSharedRef<FSectionKeyAreaNode>(Node.AsShared()), InSectionIndex, TotalHeight)); } else if (!Node.IsExpanded()) { Elements.Add(FKeyAreaLayoutElement::FromGroup(Node.UpdateKeyGrouping(InSectionIndex), TotalHeight, Node.GetNodeHeight())); } }; // First, layout the parent { FSequencerDisplayNode* LayoutNode = &InNode; if (InNode.GetType() == ESequencerNode::Track) { TSharedPtr<FSequencerDisplayNode> KeyAreaNode = static_cast<FTrackNode&>(InNode).GetTopLevelKeyNode(); if (KeyAreaNode.IsValid()) { LayoutNode = KeyAreaNode.Get(); } } SetupKeyArea(*LayoutNode); LastPadding = LayoutNode->GetNodePadding().Bottom; TotalHeight += LayoutNode->GetNodeHeight() + LastPadding; } // Then any children InNode.TraverseVisible_ParentFirst([&](FSequencerDisplayNode& Node){ TotalHeight += Node.GetNodePadding().Top; SetupKeyArea(Node); LastPadding = Node.GetNodePadding().Bottom; TotalHeight += Node.GetNodeHeight() + LastPadding; return true; }, false); // Remove the padding from the bottom TotalHeight -= LastPadding; }
TSharedPtr<FSequencerTrackNode> GetParentTrackNode(FSequencerDisplayNode& In) { FSequencerDisplayNode* Current = &In; while(Current && Current->GetType() != ESequencerNode::Object) { if (Current->GetType() == ESequencerNode::Track) { return StaticCastSharedRef<FSequencerTrackNode>(Current->AsShared()); } Current = Current->GetParent().Get(); } return nullptr; }
void FSequencerNodeTree::SaveExpansionState( const FSequencerDisplayNode& Node, bool bExpanded ) { UMovieScene* MovieScene = Sequencer.GetFocusedMovieScene(); FMovieSceneEditorData& EditorData = MovieScene->GetEditorData(); if( bExpanded ) { EditorData.CollapsedSequencerNodes.Remove( Node.GetPathName() ); } else { // Collapsed nodes are stored instead of expanded so that new nodes are expanded by default EditorData.CollapsedSequencerNodes.AddUnique( Node.GetPathName() ) ; } }
void FSequencerNodeTree::SaveExpansionState( const FSequencerDisplayNode& Node, bool bExpanded ) { // @todo Sequencer - This should be moved to the sequence level UMovieScene* MovieScene = Sequencer.GetFocusedMovieSceneSequence()->GetMovieScene(); FMovieSceneEditorData& EditorData = MovieScene->GetEditorData(); EditorData.ExpansionStates.Add( Node.GetPathName(), FMovieSceneExpansionState(bExpanded) ); }
bool FSequencerNodeTree::GetSavedExpansionState( const FSequencerDisplayNode& Node ) const { // @todo Sequencer - This should be moved to the sequence level UMovieScene* MovieScene = Sequencer.GetFocusedMovieSceneSequence()->GetMovieScene(); FMovieSceneEditorData& EditorData = MovieScene->GetEditorData(); FMovieSceneExpansionState* ExpansionState = EditorData.ExpansionStates.Find( Node.GetPathName() ); return ExpansionState ? ExpansionState->bExpanded : GetDefaultExpansionState(Node); }
bool FSequencerNodeTree::GetSavedExpansionState( const FSequencerDisplayNode& Node ) const { UMovieScene* MovieScene = Sequencer.GetFocusedMovieScene(); FMovieSceneEditorData& EditorData = MovieScene->GetEditorData(); // Collapsed nodes are stored instead of expanded so that new nodes are expanded by default bool bCollapsed = EditorData.CollapsedSequencerNodes.Contains( Node.GetPathName() ); return !bCollapsed; }
FGroupedKeyArea::FGroupedKeyArea(FSequencerDisplayNode& InNode, int32 InSectionIndex) : Section(nullptr) { // Calling this virtual function is safe here, as it's just called through standard name-lookup, not runtime dispatch FGroupedKeyCollection::InitializeRecursive(InNode, InSectionIndex); for (const TSharedPtr<IKeyArea>& KeyArea : KeyAreas) { auto* OwningSection = KeyArea->GetOwningSection(); // Ensure they all belong to the same section ensure(!Section || Section == OwningSection); Section = OwningSection; } if (Section) { IndexKey = FIndexKey(InNode.GetPathName(), Section); UpdateIndex(); } }
void FGroupedKeyCollection::InitializeRecursive(FSequencerDisplayNode& InNode, int32 InSectionIndex, float DuplicateThreshold) { KeyAreas.Reset(); Groups.Reset(); TArray<TSharedRef<FSequencerSectionKeyAreaNode>> AllKeyAreaNodes; AllKeyAreaNodes.Reserve(36); InNode.GetChildKeyAreaNodesRecursively(AllKeyAreaNodes); for (const auto& Node : AllKeyAreaNodes) { TSharedPtr<IKeyArea> KeyArea = Node->GetKeyArea(InSectionIndex); if (KeyArea.IsValid()) { AddKeyArea(KeyArea.ToSharedRef()); } } RemoveDuplicateKeys(DuplicateThreshold); }
FSectionLayout::FSectionLayout(FSequencerDisplayNode& InNode, int32 InSectionIndex) { float VerticalOffset = 0.f; auto SetupKeyArea = [&](FSequencerDisplayNode& Node){ if (Node.GetType() == ESequencerNode::KeyArea) { Elements.Add(FSectionLayoutElement::FromKeyAreaNode( StaticCastSharedRef<FSequencerSectionKeyAreaNode>(Node.AsShared()), InSectionIndex, VerticalOffset )); } else if (Node.GetType() == ESequencerNode::Track && static_cast<FSequencerTrackNode&>(Node).GetTopLevelKeyNode().IsValid()) { Elements.Add(FSectionLayoutElement::FromTrack( StaticCastSharedRef<FSequencerTrackNode>(Node.AsShared()), InSectionIndex, VerticalOffset )); } else if (!Node.IsExpanded()) { Elements.Add(FSectionLayoutElement::FromGroup( Node.AsShared(), Node.UpdateKeyGrouping(InSectionIndex), VerticalOffset )); } else { // It's benign space Elements.Add(FSectionLayoutElement::EmptySpace( Node.AsShared(), VerticalOffset )); } }; // First, layout the parent { VerticalOffset += InNode.GetNodePadding().Top; SetupKeyArea(InNode); VerticalOffset += InNode.GetNodeHeight() + InNode.GetNodePadding().Bottom; } // Then any children InNode.TraverseVisible_ParentFirst([&](FSequencerDisplayNode& Node){ VerticalOffset += Node.GetNodePadding().Top; SetupKeyArea(Node); VerticalOffset += Node.GetNodeHeight() + Node.GetNodePadding().Bottom; return true; }, false); }
bool FSequencerNodeTree::GetDefaultExpansionState( const FSequencerDisplayNode& Node ) const { // For now, all types except categories and key areas are expanded by default return Node.GetType() != ESequencerNode::Category && Node.GetType() != ESequencerNode::KeyArea; }
bool FSequencerNodeTree::GetDefaultExpansionState( const FSequencerDisplayNode& Node ) const { // For now, only object nodes are expanded by default return Node.GetType() == ESequencerNode::Object; }