TOptional<EItemDropZone> FSequencerFolderNode::CanDrop( FSequencerDisplayNodeDragDropOp& DragDropOp, EItemDropZone ItemDropZone ) const { DragDropOp.ResetToDefaultToolTip(); if ( ItemDropZone == EItemDropZone::AboveItem ) { if ( GetParent().IsValid() ) { // When dropping above, only allow it for root level nodes. return TOptional<EItemDropZone>(); } else { // Make sure there are no folder name collisions with the root folders UMovieScene* FocusedMovieScene = GetParentTree().GetSequencer().GetFocusedMovieSceneSequence()->GetMovieScene(); TSet<FName> RootFolderNames; for ( UMovieSceneFolder* RootFolder : FocusedMovieScene->GetRootFolders() ) { RootFolderNames.Add( RootFolder->GetFolderName() ); } for ( TSharedRef<FSequencerDisplayNode> DraggedNode : DragDropOp.GetDraggedNodes() ) { if ( DraggedNode->GetType() == ESequencerNode::Folder ) { TSharedRef<FSequencerFolderNode> DraggedFolder = StaticCastSharedRef<FSequencerFolderNode>( DraggedNode ); if ( RootFolderNames.Contains( DraggedFolder->GetFolder().GetFolderName() ) ) { DragDropOp.CurrentHoverText = FText::Format( NSLOCTEXT( "SeqeuencerFolderNode", "DuplicateRootFolderDragErrorFormat", "Root folder with name '{0}' already exists." ), FText::FromName( DraggedFolder->GetFolder().GetFolderName() ) ); return TOptional<EItemDropZone>(); } } } } return TOptional<EItemDropZone>( EItemDropZone::AboveItem ); } else { // When dropping onto, don't allow dropping into the same folder, don't allow dropping // parents into children, and don't allow duplicate folder names. TSet<FName> ChildFolderNames; for ( UMovieSceneFolder* ChildFolder : GetFolder().GetChildFolders() ) { ChildFolderNames.Add( ChildFolder->GetFolderName() ); } for ( TSharedRef<FSequencerDisplayNode> DraggedNode : DragDropOp.GetDraggedNodes() ) { TSharedPtr<FSequencerDisplayNode> ParentSeqNode = DraggedNode->GetParent(); if ( ParentSeqNode.IsValid() && ParentSeqNode.Get() == this ) { DragDropOp.CurrentHoverText = NSLOCTEXT( "SeqeuencerFolderNode", "SameParentDragError", "Can't drag a node onto the same parent." ); return TOptional<EItemDropZone>(); } if ( DraggedNode->GetType() == ESequencerNode::Folder ) { TSharedRef<FSequencerFolderNode> DraggedFolder = StaticCastSharedRef<FSequencerFolderNode>( DraggedNode ); if ( ChildFolderNames.Contains( DraggedFolder->GetFolder().GetFolderName() ) ) { DragDropOp.CurrentHoverText = FText::Format( NSLOCTEXT( "SeqeuencerFolderNode", "DuplicateChildFolderDragErrorFormat", "Folder with name '{0}' already exists." ), FText::FromName( DraggedFolder->GetFolder().GetFolderName() ) ); return TOptional<EItemDropZone>(); } } } TSharedPtr<FSequencerDisplayNode> CurrentNode = SharedThis( ( FSequencerDisplayNode* )this ); while ( CurrentNode.IsValid() ) { if ( DragDropOp.GetDraggedNodes().Contains( CurrentNode ) ) { DragDropOp.CurrentHoverText = NSLOCTEXT( "SeqeuencerFolderNode", "ParentIntoChildDragError", "Can't drag a parent node into one of it's children." ); return TOptional<EItemDropZone>(); } CurrentNode = CurrentNode->GetParent(); } return TOptional<EItemDropZone>( EItemDropZone::OntoItem ); } }
void FSequencerFolderNode::Drop( const TArray<TSharedRef<FSequencerDisplayNode>>& DraggedNodes, EItemDropZone ItemDropZone ) { const FScopedTransaction Transaction( NSLOCTEXT( "SequencerFolderNode", "MoveIntoFolder", "Move items into folder." ) ); GetFolder().SetFlags(RF_Transactional); GetFolder().Modify(); for ( TSharedRef<FSequencerDisplayNode> DraggedNode : DraggedNodes ) { TSharedPtr<FSequencerDisplayNode> ParentSeqNode = DraggedNode->GetParent(); switch ( DraggedNode->GetType() ) { case ESequencerNode::Folder: { TSharedRef<FSequencerFolderNode> DraggedFolderNode = StaticCastSharedRef<FSequencerFolderNode>( DraggedNode ); UMovieScene* FocusedMovieScene = GetParentTree().GetSequencer().GetFocusedMovieSceneSequence()->GetMovieScene(); if ( ItemDropZone == EItemDropZone::OntoItem ) { GetFolder().AddChildFolder( &DraggedFolderNode->GetFolder() ); } else { FocusedMovieScene->Modify(); FocusedMovieScene->GetRootFolders().Add( &DraggedFolderNode->GetFolder() ); } if ( ParentSeqNode.IsValid() ) { checkf( ParentSeqNode->GetType() == ESequencerNode::Folder, TEXT( "Can not remove from unsupported parent node." ) ); TSharedPtr<FSequencerFolderNode> ParentFolder = StaticCastSharedPtr<FSequencerFolderNode>( ParentSeqNode ); ParentFolder->GetFolder().Modify(); ParentFolder->GetFolder().RemoveChildFolder( &DraggedFolderNode->GetFolder() ); } else { FocusedMovieScene->Modify(); FocusedMovieScene->GetRootFolders().Remove( &DraggedFolderNode->GetFolder() ); } break; } case ESequencerNode::Track: { TSharedRef<FSequencerTrackNode> DraggedTrackNode = StaticCastSharedRef<FSequencerTrackNode>( DraggedNode ); if( ItemDropZone == EItemDropZone::OntoItem ) { GetFolder().AddChildMasterTrack( DraggedTrackNode->GetTrack() ); } if ( ParentSeqNode.IsValid() ) { checkf( ParentSeqNode->GetType() == ESequencerNode::Folder, TEXT( "Can not remove from unsupported parent node." ) ); TSharedPtr<FSequencerFolderNode> ParentFolder = StaticCastSharedPtr<FSequencerFolderNode>( ParentSeqNode ); ParentFolder->GetFolder().Modify(); ParentFolder->GetFolder().RemoveChildMasterTrack( DraggedTrackNode->GetTrack() ); } break; } case ESequencerNode::Object: { TSharedRef<FSequencerObjectBindingNode> DraggedObjectBindingNode = StaticCastSharedRef<FSequencerObjectBindingNode>( DraggedNode ); if ( ItemDropZone == EItemDropZone::OntoItem ) { GetFolder().AddChildObjectBinding( DraggedObjectBindingNode->GetObjectBinding() ); } if ( ParentSeqNode.IsValid() ) { checkf( ParentSeqNode->GetType() == ESequencerNode::Folder, TEXT( "Can not remove from unsupported parent node." ) ); TSharedPtr<FSequencerFolderNode> ParentFolder = StaticCastSharedPtr<FSequencerFolderNode>( ParentSeqNode ); ParentFolder->GetFolder().Modify(); ParentFolder->GetFolder().RemoveChildObjectBinding( DraggedObjectBindingNode->GetObjectBinding() ); } break; } } } SetExpansionState( true ); ParentTree.GetSequencer().NotifyMovieSceneDataChanged( EMovieSceneDataChangeType::MovieSceneStructureItemsChanged ); }