From 1be8f2861de7e00f22c8de63ff920adcd675535d Mon Sep 17 00:00:00 2001 From: Uwe Kindler Date: Wed, 27 Nov 2019 12:00:04 +0100 Subject: [PATCH] Continued implementation of transparent docking --- src/DockContainerWidget.cpp | 87 +++++++++++++++++++++++++++++++---- src/FloatingDockContainer.cpp | 1 - src/FloatingOverlay.cpp | 43 ++++++++++++++--- src/FloatingOverlay.h | 4 +- 4 files changed, 118 insertions(+), 17 deletions(-) diff --git a/src/DockContainerWidget.cpp b/src/DockContainerWidget.cpp index 37c044e..44bba5b 100644 --- a/src/DockContainerWidget.cpp +++ b/src/DockContainerWidget.cpp @@ -170,6 +170,12 @@ public: */ void moveToNewSection(QWidget* Widget, CDockAreaWidget* TargetArea, DockWidgetArea area); + /** + * Moves the dock widget or dock area given in Widget parameter to a + * a dock area in container + */ + void moveToContainer(QWidget* Widgett, DockWidgetArea area); + /** * Creates a new tab for a widget dropped into the center of a section */ @@ -550,15 +556,82 @@ void DockContainerWidgetPrivate::moveIntoCenterOfSection(QWidget* Widget, CDockA //============================================================================ -void DockContainerWidgetPrivate::moveToNewSection(QWidget* Widget, CDockAreaWidget* TargetArea, DockWidgetArea area) +void DockContainerWidgetPrivate::moveToNewSection(QWidget* Widget, CDockAreaWidget* TargetDockArea, DockWidgetArea area) { // Dropping into center means all dock widgets in the dropped floating // widget will become tabs of the drop area if (CenterDockWidgetArea == area) { - moveIntoCenterOfSection(Widget, TargetArea); + moveIntoCenterOfSection(Widget, TargetDockArea); return; } + + + CDockWidget* DroppedDockWidget = qobject_cast(Widget); + CDockAreaWidget* DroppedDockArea = qobject_cast(Widget); + CDockAreaWidget* NewDockArea; + if (DroppedDockWidget) + { + NewDockArea = new CDockAreaWidget(DockManager, _this); + CDockAreaWidget* OldDockArea = DroppedDockWidget->dockAreaWidget(); + if (OldDockArea) + { + OldDockArea->removeDockWidget(DroppedDockWidget); + } + NewDockArea->addDockWidget(DroppedDockWidget); + } + else + { + DroppedDockArea->dockContainer()->removeDockArea(DroppedDockArea); + NewDockArea = DroppedDockArea; + } + + auto InsertParam = internal::dockAreaInsertParameters(area); + QSplitter* TargetAreaSplitter = internal::findParent(TargetDockArea); + int index = TargetAreaSplitter ->indexOf(TargetDockArea); + if (TargetAreaSplitter->orientation() == InsertParam.orientation()) + { + ADS_PRINT("TargetAreaSplitter->orientation() == InsertParam.orientation()"); + TargetAreaSplitter->insertWidget(index + InsertParam.insertOffset(), NewDockArea); + } + else + { + ADS_PRINT("TargetAreaSplitter->orientation() != InsertParam.orientation()"); + QSplitter* NewSplitter = newSplitter(InsertParam.orientation()); + NewSplitter->addWidget(TargetDockArea); + insertWidgetIntoSplitter(NewSplitter, NewDockArea, InsertParam.append()); + TargetAreaSplitter->insertWidget(index, NewSplitter); + } + + addDockAreasToList({NewDockArea}); +} + + +//============================================================================ +void DockContainerWidgetPrivate::moveToContainer(QWidget* Widget, DockWidgetArea area) +{ + CDockWidget* DroppedDockWidget = qobject_cast(Widget); + CDockAreaWidget* DroppedDockArea = qobject_cast(Widget); + CDockAreaWidget* NewDockArea; + if (DroppedDockWidget) + { + NewDockArea = new CDockAreaWidget(DockManager, _this); + CDockAreaWidget* OldDockArea = DroppedDockWidget->dockAreaWidget(); + if (OldDockArea) + { + OldDockArea->removeDockWidget(DroppedDockWidget); + } + NewDockArea->addDockWidget(DroppedDockWidget); + } + else + { + DroppedDockArea->dockContainer()->removeDockArea(DroppedDockArea); + NewDockArea = DroppedDockArea; + } + + addDockArea(NewDockArea, area); + //NewDockArea->updateTitleBarVisibility(); + LastAddedAreaCache[areaIdToIndex(area)] = NewDockArea; } @@ -907,9 +980,7 @@ void DockContainerWidgetPrivate::addDockArea(CDockAreaWidget* NewDockArea, DockW RootSplitter = NewSplitter; } - appendDockAreas({NewDockArea}); - NewDockArea->updateTitleBarVisibility(); - emitDockAreasAdded(); + addDockAreasToList({NewDockArea}); } @@ -1305,7 +1376,7 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi //============================================================================ -void CDockContainerWidget::dropWidget(QWidget* DockWidget, const QPoint& TargetPos) +void CDockContainerWidget::dropWidget(QWidget* Widget, const QPoint& TargetPos) { ADS_PRINT("CDockContainerWidget::dropFloatingWidget"); CDockAreaWidget* DockArea = dockAreaAt(TargetPos); @@ -1327,7 +1398,7 @@ void CDockContainerWidget::dropWidget(QWidget* DockWidget, const QPoint& TargetP if (dropArea != InvalidDockWidgetArea) { ADS_PRINT("Dock Area Drop Content: " << dropArea); - d->moveToNewSection(DockWidget, DockArea, dropArea); + d->moveToNewSection(Widget, DockArea, dropArea); } } @@ -1338,7 +1409,7 @@ void CDockContainerWidget::dropWidget(QWidget* DockWidget, const QPoint& TargetP ADS_PRINT("Container Drop Content: " << dropArea); if (dropArea != InvalidDockWidgetArea) { - //d->dropIntoContainer(FloatingWidget, dropArea); + d->moveToContainer(Widget, dropArea); } } diff --git a/src/FloatingDockContainer.cpp b/src/FloatingDockContainer.cpp index ddca794..eb2cab9 100644 --- a/src/FloatingDockContainer.cpp +++ b/src/FloatingDockContainer.cpp @@ -517,7 +517,6 @@ void CFloatingDockContainer::startFloating(const QPoint &DragStartMousePos, #endif moveFloating(); show(); - } //============================================================================ diff --git a/src/FloatingOverlay.cpp b/src/FloatingOverlay.cpp index b941c07..134195a 100644 --- a/src/FloatingOverlay.cpp +++ b/src/FloatingOverlay.cpp @@ -32,11 +32,14 @@ struct FloatingOverlayPrivate { CFloatingOverlay *_this; QWidget* Content; + CDockAreaWidget* ContentSourceArea = nullptr; + CDockContainerWidget* ContenSourceContainer = nullptr; QPoint DragStartMousePosition; CDockManager* DockManager; CDockContainerWidget *DropContainer = nullptr; qreal WindowOpacity; bool Hidden = false; + bool IgnoreMouseEvents = false; /** @@ -89,6 +92,8 @@ void FloatingOverlayPrivate::updateDropOverlays(const QPoint &GlobalPos) DropContainer = TopContainer; auto ContainerOverlay = DockManager->containerOverlay(); auto DockAreaOverlay = DockManager->dockAreaOverlay(); + auto DockDropArea = DockAreaOverlay->dropAreaUnderCursor(); + auto ContainerDropArea = ContainerOverlay->dropAreaUnderCursor(); if (!TopContainer) { @@ -104,7 +109,7 @@ void FloatingOverlayPrivate::updateDropOverlays(const QPoint &GlobalPos) DockWidgetArea ContainerArea = ContainerOverlay->showOverlay(TopContainer); ContainerOverlay->enableDropPreview(ContainerArea != InvalidDockWidgetArea); auto DockArea = TopContainer->dockAreaAt(GlobalPos); - if (DockArea && DockArea->isVisible() && VisibleDockAreas > 0) + if (DockArea && DockArea->isVisible() && VisibleDockAreas > 0 && DockArea != ContentSourceArea) { DockAreaOverlay->enableDropPreview(true); DockAreaOverlay->setAllowedAreas( @@ -129,10 +134,12 @@ void FloatingOverlayPrivate::updateDropOverlays(const QPoint &GlobalPos) else { DockAreaOverlay->hideOverlay(); + if (DockArea == ContentSourceArea && InvalidDockWidgetArea == ContainerDropArea) + { + DropContainer = nullptr; + } } - auto DockDropArea = DockAreaOverlay->dropAreaUnderCursor(); - auto ContainerDropArea = ContainerOverlay->dropAreaUnderCursor(); setHidden(DockDropArea != InvalidDockWidgetArea || ContainerDropArea != InvalidDockWidgetArea); } @@ -165,18 +172,25 @@ CFloatingOverlay::CFloatingOverlay(QWidget* Content, QWidget* parent) : //============================================================================ -CFloatingOverlay::CFloatingOverlay(CDockWidget* Content, QWidget* parent) +CFloatingOverlay::CFloatingOverlay(CDockWidget* Content) : CFloatingOverlay((QWidget*)Content, Content->dockManager()) { d->DockManager = Content->dockManager(); + if (Content->dockAreaWidget()->openDockWidgetsCount() == 1) + { + d->ContentSourceArea = Content->dockAreaWidget(); + d->ContenSourceContainer = Content->dockContainer(); + } } //============================================================================ -CFloatingOverlay::CFloatingOverlay(CDockAreaWidget* Content, QWidget* parent) +CFloatingOverlay::CFloatingOverlay(CDockAreaWidget* Content) : CFloatingOverlay((QWidget*)Content, Content->dockManager()) { d->DockManager = Content->dockManager(); + d->ContentSourceArea = Content; + d->ContenSourceContainer = Content->dockContainer(); } @@ -224,7 +238,7 @@ void CFloatingOverlay::moveEvent(QMoveEvent *event) bool CFloatingOverlay::eventFilter(QObject *watched, QEvent *event) { Q_UNUSED(watched); - if (event->type() == QEvent::MouseButtonRelease) + if (event->type() == QEvent::MouseButtonRelease && !d->IgnoreMouseEvents) { ADS_PRINT("FloatingWidget::eventFilter QEvent::MouseButtonRelease"); std::cout << "CFloatingOverlay::eventFilter QEvent::MouseButtonRelease" << std::endl; @@ -234,10 +248,27 @@ bool CFloatingOverlay::eventFilter(QObject *watched, QEvent *event) d->DropContainer->dropWidget(d->Content, QCursor::pos()); d->DropContainer = nullptr; } + else + { + CDockWidget* DockWidget = qobject_cast(d->Content); + CFloatingDockContainer* FloatingWidget; + if (DockWidget) + { + FloatingWidget = new CFloatingDockContainer(DockWidget); + } + else + { + CDockAreaWidget* DockArea = qobject_cast(d->Content); + FloatingWidget = new CFloatingDockContainer(DockArea); + } + FloatingWidget->setGeometry(this->geometry()); + FloatingWidget->show(); + } this->close(); d->DockManager->containerOverlay()->hideOverlay(); d->DockManager->dockAreaOverlay()->hideOverlay(); + d->IgnoreMouseEvents = true; } return false; diff --git a/src/FloatingOverlay.h b/src/FloatingOverlay.h index 0af761f..9a3a3df 100644 --- a/src/FloatingOverlay.h +++ b/src/FloatingOverlay.h @@ -41,8 +41,8 @@ protected: public: using Super = QRubberBand; - CFloatingOverlay(CDockWidget* Content, QWidget* parent = nullptr); - CFloatingOverlay(CDockAreaWidget* Content, QWidget* parent = nullptr); + CFloatingOverlay(CDockWidget* Content); + CFloatingOverlay(CDockAreaWidget* Content); /** * Delete private data