Fixed emission of top level changed signal to properly support transparent docking

This commit is contained in:
Uwe Kindler 2019-11-27 15:50:18 +01:00
parent 3cd12ce1d3
commit 8ea7c265a7
4 changed files with 74 additions and 24 deletions

View File

@ -81,6 +81,12 @@ namespace ads
{ {
static unsigned int zOrderCounter = 0; static unsigned int zOrderCounter = 0;
enum eDropMode
{
DropModeIntoArea,///< drop widget into a dock area
DropModeIntoContainer,///< drop into container
DropModeInvalid///< invalid mode - do not drop
};
/** /**
* Converts dock area ID to an index for array access * Converts dock area ID to an index for array access
@ -234,6 +240,11 @@ public:
*/ */
void dumpRecursive(int level, QWidget* widget); void dumpRecursive(int level, QWidget* widget);
/**
* Calculate the drop mode from the given target position
*/
eDropMode getDropMode(const QPoint& TargetPos);
/** /**
* Initializes the visible dock area count variable if it is not initialized * Initializes the visible dock area count variable if it is not initialized
* yet * yet
@ -312,6 +323,46 @@ DockContainerWidgetPrivate::DockContainerWidgetPrivate(CDockContainerWidget* _pu
} }
//============================================================================
eDropMode DockContainerWidgetPrivate::getDropMode(const QPoint& TargetPos)
{
CDockAreaWidget* DockArea = _this->dockAreaAt(TargetPos);
auto dropArea = InvalidDockWidgetArea;
auto ContainerDropArea = DockManager->containerOverlay()->dropAreaUnderCursor();
if (DockArea)
{
auto dropOverlay = DockManager->dockAreaOverlay();
dropOverlay->setAllowedAreas(AllDockAreas);
dropArea = dropOverlay->showOverlay(DockArea);
if (ContainerDropArea != InvalidDockWidgetArea &&
ContainerDropArea != dropArea)
{
dropArea = InvalidDockWidgetArea;
}
if (dropArea != InvalidDockWidgetArea)
{
ADS_PRINT("Dock Area Drop Content: " << dropArea);
return DropModeIntoArea;
}
}
// mouse is over container
if (InvalidDockWidgetArea == dropArea)
{
dropArea = ContainerDropArea;
ADS_PRINT("Container Drop Content: " << dropArea);
if (dropArea != InvalidDockWidgetArea)
{
return DropModeIntoContainer;
}
}
return DropModeInvalid;
}
//============================================================================ //============================================================================
void DockContainerWidgetPrivate::onVisibleDockAreaCountChanged() void DockContainerWidgetPrivate::onVisibleDockAreaCountChanged()
{ {
@ -340,8 +391,6 @@ void DockContainerWidgetPrivate::dropIntoContainer(CFloatingDockContainer* Float
CDockContainerWidget* FloatingDockContainer = FloatingWidget->dockContainer(); CDockContainerWidget* FloatingDockContainer = FloatingWidget->dockContainer();
auto NewDockAreas = FloatingDockContainer->findChildren<CDockAreaWidget*>( auto NewDockAreas = FloatingDockContainer->findChildren<CDockAreaWidget*>(
QString(), Qt::FindChildrenRecursively); QString(), Qt::FindChildrenRecursively);
CDockWidget* SingleDroppedDockWidget = FloatingDockContainer->topLevelDockWidget();
CDockWidget* SingleDockWidget = _this->topLevelDockWidget();
QSplitter* Splitter = RootSplitter; QSplitter* Splitter = RootSplitter;
if (DockAreas.count() <= 1) if (DockAreas.count() <= 1)
@ -378,8 +427,6 @@ void DockContainerWidgetPrivate::dropIntoContainer(CFloatingDockContainer* Float
RootSplitter = Splitter; RootSplitter = Splitter;
addDockAreasToList(NewDockAreas); addDockAreasToList(NewDockAreas);
FloatingWidget->deleteLater(); FloatingWidget->deleteLater();
CDockWidget::emitTopLevelEventForWidget(SingleDroppedDockWidget, false);
CDockWidget::emitTopLevelEventForWidget(SingleDockWidget, false);
// If we dropped the floating widget into the main dock container that does // If we dropped the floating widget into the main dock container that does
// not contain any dock widgets, then splitter is invisible and we need to // not contain any dock widgets, then splitter is invisible and we need to
@ -613,6 +660,7 @@ void DockContainerWidgetPrivate::moveToContainer(QWidget* Widget, DockWidgetArea
CDockWidget* DroppedDockWidget = qobject_cast<CDockWidget*>(Widget); CDockWidget* DroppedDockWidget = qobject_cast<CDockWidget*>(Widget);
CDockAreaWidget* DroppedDockArea = qobject_cast<CDockAreaWidget*>(Widget); CDockAreaWidget* DroppedDockArea = qobject_cast<CDockAreaWidget*>(Widget);
CDockAreaWidget* NewDockArea; CDockAreaWidget* NewDockArea;
if (DroppedDockWidget) if (DroppedDockWidget)
{ {
NewDockArea = new CDockAreaWidget(DockManager, _this); NewDockArea = new CDockAreaWidget(DockManager, _this);
@ -630,7 +678,6 @@ void DockContainerWidgetPrivate::moveToContainer(QWidget* Widget, DockWidgetArea
} }
addDockArea(NewDockArea, area); addDockArea(NewDockArea, area);
//NewDockArea->updateTitleBarVisibility();
LastAddedAreaCache[areaIdToIndex(area)] = NewDockArea; LastAddedAreaCache[areaIdToIndex(area)] = NewDockArea;
} }
@ -1324,11 +1371,11 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
const QPoint& TargetPos) const QPoint& TargetPos)
{ {
ADS_PRINT("CDockContainerWidget::dropFloatingWidget"); ADS_PRINT("CDockContainerWidget::dropFloatingWidget");
CDockWidget* SingleDroppedDockWidget = FloatingWidget->topLevelDockWidget();
CDockWidget* SingleDockWidget = topLevelDockWidget();
CDockAreaWidget* DockArea = dockAreaAt(TargetPos); CDockAreaWidget* DockArea = dockAreaAt(TargetPos);
auto dropArea = InvalidDockWidgetArea; auto dropArea = InvalidDockWidgetArea;
auto ContainerDropArea = d->DockManager->containerOverlay()->dropAreaUnderCursor(); auto ContainerDropArea = d->DockManager->containerOverlay()->dropAreaUnderCursor();
CDockWidget* FloatingTopLevelDockWidget = FloatingWidget->topLevelDockWidget();
CDockWidget* TopLevelDockWidget = topLevelDockWidget();
if (DockArea) if (DockArea)
{ {
@ -1359,19 +1406,13 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
} }
} }
// If we dropped a floating widget with only one single dock widget, then we
// drop a top level widget that changes from floating to docked now
CDockWidget::emitTopLevelEventForWidget(SingleDroppedDockWidget, false);
// If there was a top level widget before the drop, then it is not top // If there was a top level widget before the drop, then it is not top
// level widget anymore // level widget anymore
if (TopLevelDockWidget) CDockWidget::emitTopLevelEventForWidget(SingleDockWidget, false);
{
TopLevelDockWidget->emitTopLevelChanged(false);
}
// If we drop a floating widget with only one single dock widget, then we
// drop a top level widget that changes from floating to docked now
if (FloatingTopLevelDockWidget)
{
FloatingTopLevelDockWidget->emitTopLevelChanged(false);
}
} }
@ -1379,10 +1420,10 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
void CDockContainerWidget::dropWidget(QWidget* Widget, const QPoint& TargetPos) void CDockContainerWidget::dropWidget(QWidget* Widget, const QPoint& TargetPos)
{ {
ADS_PRINT("CDockContainerWidget::dropFloatingWidget"); ADS_PRINT("CDockContainerWidget::dropFloatingWidget");
CDockWidget* SingleDockWidget = topLevelDockWidget();
CDockAreaWidget* DockArea = dockAreaAt(TargetPos); CDockAreaWidget* DockArea = dockAreaAt(TargetPos);
auto dropArea = InvalidDockWidgetArea; auto dropArea = InvalidDockWidgetArea;
auto ContainerDropArea = d->DockManager->containerOverlay()->dropAreaUnderCursor(); auto ContainerDropArea = d->DockManager->containerOverlay()->dropAreaUnderCursor();
CDockWidget* TopLevelDockWidget = topLevelDockWidget();
if (DockArea) if (DockArea)
{ {
@ -1415,10 +1456,7 @@ void CDockContainerWidget::dropWidget(QWidget* Widget, const QPoint& TargetPos)
// If there was a top level widget before the drop, then it is not top // If there was a top level widget before the drop, then it is not top
// level widget anymore // level widget anymore
if (TopLevelDockWidget) CDockWidget::emitTopLevelEventForWidget(SingleDockWidget, false);
{
TopLevelDockWidget->emitTopLevelChanged(false);
}
} }

View File

@ -52,6 +52,7 @@ struct DockManagerPrivate;
class CFloatingDockContainer; class CFloatingDockContainer;
struct FloatingDockContainerPrivate; struct FloatingDockContainerPrivate;
class CDockContainerWidget; class CDockContainerWidget;
class DockContainerWidgetPrivate;
class CDockOverlay; class CDockOverlay;
class CDockAreaTabBar; class CDockAreaTabBar;
class CDockWidgetTab; class CDockWidgetTab;
@ -80,6 +81,7 @@ private:
friend class CFloatingDockContainer; friend class CFloatingDockContainer;
friend struct FloatingDockContainerPrivate; friend struct FloatingDockContainerPrivate;
friend class CDockContainerWidget; friend class CDockContainerWidget;
friend class DockContainerWidgetPrivate;
friend class CDockAreaTabBar; friend class CDockAreaTabBar;
friend class CDockWidgetTab; friend class CDockWidgetTab;
friend struct DockAreaWidgetPrivate; friend struct DockAreaWidgetPrivate;

View File

@ -270,7 +270,7 @@ bool DockWidgetTabPrivate::startFloating(eDragState DraggingState)
{ {
FloatingWidget->startFloating(DragStartMousePosition, Size, DraggingInactive, nullptr); FloatingWidget->startFloating(DragStartMousePosition, Size, DraggingInactive, nullptr);
} }
DockWidget->emitTopLevelChanged(true);
return true; return true;
} }

View File

@ -275,6 +275,11 @@ CFloatingDockContainer::CFloatingDockContainer(CDockAreaWidget *DockArea) :
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
d->TitleBar->enableCloseButton(isClosable()); d->TitleBar->enableCloseButton(isClosable());
#endif #endif
auto TopLevelDockWidget = topLevelDockWidget();
if (TopLevelDockWidget)
{
TopLevelDockWidget->emitTopLevelChanged(true);
}
} }
//============================================================================ //============================================================================
@ -285,6 +290,11 @@ CFloatingDockContainer::CFloatingDockContainer(CDockWidget *DockWidget) :
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
d->TitleBar->enableCloseButton(isClosable()); d->TitleBar->enableCloseButton(isClosable());
#endif #endif
auto TopLevelDockWidget = topLevelDockWidget();
if (TopLevelDockWidget)
{
TopLevelDockWidget->emitTopLevelChanged(true);
}
} }
//============================================================================ //============================================================================