FReply SDockingTabWell::OnDrop( const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent )
{
	TSharedPtr<FDockingDragOperation> DragDropOperation = DragDropEvent.GetOperationAs<FDockingDragOperation>();
	if (DragDropOperation.IsValid())
	{
		if (DragDropOperation->CanDockInNode(ParentTabStackPtr.Pin().ToSharedRef(), FDockingDragOperation::DockingViaTabWell))
		{
			if ( ensure( TabBeingDraggedPtr.IsValid() ) )
			{
				// We dropped a Tab into this TabWell.
				const TSharedRef<SDockTab> TabBeingDragged = TabBeingDraggedPtr.ToSharedRef();

				// Figure out where in this TabWell to drop the Tab.				
				const int32 DropLocationIndex = ComputeChildDropIndex(MyGeometry, TabBeingDragged);

				ensure( DragDropOperation->GetTabBeingDragged().ToSharedRef() == TabBeingDragged );

				// Actually insert the new tab.
				ParentTabStackPtr.Pin()->OpenTab(TabBeingDragged, DropLocationIndex);

				// We are no longer dragging a tab.
				TabBeingDraggedPtr.Reset();

				// We knew how to handled this drop operation!
				return FReply::Handled();
			}
		}
	}

	// Someone just dropped something in here, but we have no idea what to do with it.
	return FReply::Unhandled();
}
void SDockingArea::OnDragEnter( const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent )
{
	TSharedPtr<FDockingDragOperation> DragDropOperation = DragDropEvent.GetOperationAs<FDockingDragOperation>();
	if ( DragDropOperation.IsValid() )
	{
		if ( DragDropOperation->CanDockInNode(SharedThis(this), FDockingDragOperation::DockingViaTarget) )
		{
			ShowCross();
		}		
	}

}
FReply SDockingTabWell::OnDragOver( const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent )
{
	TSharedPtr<FDockingDragOperation> DragDropOperation = DragDropEvent.GetOperationAs<FDockingDragOperation>();
	if ( DragDropOperation.IsValid() )
	{
		if (DragDropOperation->CanDockInNode(ParentTabStackPtr.Pin().ToSharedRef(), FDockingDragOperation::DockingViaTabWell))
		{
			// We are dragging the tab through a TabWell.
			// Update the position of the Tab that we are dragging in the panel.
			this->ChildBeingDraggedOffset = ComputeDraggedTabOffset(MyGeometry, DragDropEvent, TabGrabOffsetFraction);
			return FReply::Handled();
		}
	}
	return FReply::Unhandled();	
}
void SDockingTabWell::OnDragEnter( const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent )
{
	TSharedPtr<FDockingDragOperation> DragDropOperation = DragDropEvent.GetOperationAs<FDockingDragOperation>();
	if ( DragDropOperation.IsValid() )
	{
		if (DragDropOperation->CanDockInNode(ParentTabStackPtr.Pin().ToSharedRef(), FDockingDragOperation::DockingViaTabWell))
		{
			// The user dragged a tab into this TabWell.

			// Update the state of the DragDropOperation to reflect this change.
			DragDropOperation->OnTabWellEntered( SharedThis(this) );

			// Preview the position of the tab in the TabWell
			this->TabBeingDraggedPtr = DragDropOperation->GetTabBeingDragged();
			this->TabGrabOffsetFraction = DragDropOperation->GetTabGrabOffsetFraction();
			
			// The user should see the contents of the tab that we're dragging.
			ParentTabStackPtr.Pin()->SetNodeContent(DragDropOperation->GetTabBeingDragged()->GetContent(), SNullWidget::NullWidget, SNullWidget::NullWidget, SNullWidget::NullWidget);
		}
	}
}
void SDockingTabWell::OnDragLeave( const FDragDropEvent& DragDropEvent )
{
	TSharedPtr<FDockingDragOperation> DragDropOperation = DragDropEvent.GetOperationAs<FDockingDragOperation>();
	if ( DragDropOperation.IsValid() )
	{
		TSharedRef<SDockingTabStack> ParentTabStack = ParentTabStackPtr.Pin().ToSharedRef();
		TSharedPtr<SDockTab> TabBeingDragged = this->TabBeingDraggedPtr;
		// Check for TabBeingDraggedPtr validity as it may no longer be valid when dragging tabs in game
		if ( TabBeingDragged.IsValid() && DragDropOperation->CanDockInNode(ParentTabStack, FDockingDragOperation::DockingViaTabWell) )
		{
			// Update the DragAndDrop operation based on this change.
			const int32 LastForegroundTabIndex = Tabs.Find(TabBeingDragged.ToSharedRef());

			// The user is pulling a tab out of this TabWell.
			TabBeingDragged->SetParent();

			// We are no longer dragging a tab in this tab well, so stop
			// showing it in the TabWell.
			this->TabBeingDraggedPtr.Reset();

			// Also stop showing its content; switch to the last tab that was active.
			BringTabToFront( FMath::Max(LastForegroundTabIndex-1, 0) );

			// We may have removed the last tab that this DockNode had.
			if ( Tabs.Num() == 0 )
			{
				// Let the DockNode know that it is no longer needed.
				ParentTabStack->OnLastTabRemoved();
			}

			GetDockArea()->CleanUp( SDockingNode::TabRemoval_DraggedOut );

			const FGeometry& DockNodeGeometry = ParentTabStack->GetTabStackGeometry();
			DragDropOperation->OnTabWellLeft( SharedThis(this), DockNodeGeometry );
		}
	}
}