/** * Invoked when the drag and drop operation has ended. * * @param bDropWasHandled true when the drop was handled by some widget; false otherwise */ void FDockingDragOperation::OnDrop( bool bDropWasHandled, const FPointerEvent& MouseEvent ) { check(CursorDecoratorWindow.IsValid()); const FVector2D WindowSize = CursorDecoratorWindow->GetSizeInScreen(); TabBeingDragged->SetDraggedOverDockArea( NULL ); if (!bDropWasHandled) { DroppedOntoNothing(); } else { // The event was handled, so we HAVE to have some window that we dropped onto. TSharedRef<SWindow> WindowDroppedInto = MouseEvent.GetWindow(); // Let every widget under this tab manager know that this tab has found a new home. TSharedPtr<SWindow> NewWindow = ( TabOwnerAreaOfOrigin->GetParentWindow() == WindowDroppedInto ) // Tab dropped into same window as before, meaning there is no NewWindow. ? TSharedPtr<SWindow>() // Tab was dropped into a different window, so the tab manager needs to know in order to re-parent child windows. : WindowDroppedInto; TabOwnerAreaOfOrigin->GetTabManager()->GetPrivateApi().OnTabRelocated( TabBeingDragged.ToSharedRef(), WindowDroppedInto ); } // Destroy the CursorDecoratorWindow by calling the base class implementation because we are relocating the content into a more permanent home. FDragDropOperation::OnDrop(bDropWasHandled, MouseEvent); TabBeingDragged.Reset(); }
/** * Invoked when the drag and drop operation has ended. * * @param bDropWasHandled true when the drop was handled by some widget; false otherwise */ void FDockingDragOperation::OnDrop( bool bDropWasHandled, const FPointerEvent& MouseEvent ) { check(CursorDecoratorWindow.IsValid()); const FVector2D WindowSize = CursorDecoratorWindow->GetSizeInScreen(); // Destroy the CursorDecoratorWindow by calling the base class implementation because we are relocating the content into a more permanent home. FDragDropOperation::OnDrop(bDropWasHandled, MouseEvent); TabBeingDragged->SetDraggedOverDockArea( NULL ); if (!bDropWasHandled) { // If we dropped the tab into an existing DockNode then it would have handled the DropEvent. // We are here because that didn't happen, so make a new window with a new DockNode and drop the tab into that. const FVector2D PositionToDrop = MouseEvent.GetScreenSpacePosition() - GetDecoratorOffsetFromCursor(); TSharedRef<FTabManager> MyTabManager = TabBeingDragged->GetTabManager(); TSharedPtr<SWindow> NewWindowParent = MyTabManager->GetPrivateApi().GetParentWindow(); TSharedRef<SWindow> NewWindow = SNew(SWindow) .Title( FGlobalTabmanager::Get()->GetApplicationTitle() ) .AutoCenter(EAutoCenter::None) .ScreenPosition( PositionToDrop ) // Make room for the title bar; otherwise windows will get progressive smaller whenver you float them. .ClientSize( SWindow::ComputeWindowSizeForContent( WindowSize ) ) .CreateTitleBar(false); TSharedPtr<SDockingTabStack> NewDockNode; if ( TabBeingDragged->GetTabRole() == ETabRole::NomadTab ) { TabBeingDragged->SetTabManager(FGlobalTabmanager::Get()); } // Create a new dockarea TSharedRef<SDockingArea> NewDockArea = SNew(SDockingArea, TabBeingDragged->GetTabManager(), FTabManager::NewPrimaryArea()) . ParentWindow( NewWindow ) . InitialContent ( SAssignNew(NewDockNode, SDockingTabStack, FTabManager::NewStack()) ); if (TabBeingDragged->GetTabRole() == ETabRole::MajorTab || TabBeingDragged->GetTabRole() == ETabRole::NomadTab) { TSharedPtr<SWindow> RootWindow = FGlobalTabmanager::Get()->GetRootWindow(); if ( RootWindow.IsValid() ) { // We have a root window, so all MajorTabs are nested under it. FSlateApplication::Get().AddWindowAsNativeChild( NewWindow, RootWindow.ToSharedRef() )->SetContent(NewDockArea); } else { // App tabs get put in top-level windows. They show up on the taskbar. FSlateApplication::Get().AddWindow( NewWindow )->SetContent(NewDockArea); } } else { // Other tab types are placed in child windows. Their life is controlled by the top-level windows. // They do not show up on the taskbar. if ( NewWindowParent.IsValid() ) { FSlateApplication::Get().AddWindowAsNativeChild( NewWindow, NewWindowParent.ToSharedRef() )->SetContent(NewDockArea); } else { FSlateApplication::Get().AddWindow( NewWindow )->SetContent(NewDockArea); } } // Do this after the window parenting so that the window title is set correctly NewDockNode->OpenTab(TabBeingDragged.ToSharedRef()); // Let every widget under this tab manager know that this tab has found a new home. TabOwnerAreaOfOrigin->GetTabManager()->GetPrivateApi().OnTabRelocated( TabBeingDragged.ToSharedRef(), NewWindow ); } else { // The event was handled, so we HAVE to have some window that we dropped onto. TSharedRef<SWindow> WindowDroppedInto = MouseEvent.GetWindow(); // Let every widget under this tab manager know that this tab has found a new home. TSharedPtr<SWindow> NewWindow = ( TabOwnerAreaOfOrigin->GetParentWindow() == WindowDroppedInto ) // Tab dropped into same window as before, meaning there is no NewWindow. ? TSharedPtr<SWindow>() // Tab was dropped into a different window, so the tab manager needs to know in order to re-parent child windows. : WindowDroppedInto; TabOwnerAreaOfOrigin->GetTabManager()->GetPrivateApi().OnTabRelocated( TabBeingDragged.ToSharedRef(), WindowDroppedInto ); } }