From fde133c25e14dfed257dd2eca4fdaf86fe372e79 Mon Sep 17 00:00:00 2001 From: Syarif Fakhri Date: Tue, 6 Sep 2022 17:42:26 +0800 Subject: [PATCH] Fix a bug where overlay widgets from another container widget would not be correctly transferred into the container widget that it's dragged into. --- src/DockAreaWidget.cpp | 2 -- src/DockContainerWidget.cpp | 49 ++++++++++++++++++++++++++++++++++-- src/DockContainerWidget.h | 29 +++++++++++++++++++++ src/DockManager.cpp | 32 +---------------------- src/DockManager.h | 17 ------------- src/OverlayDockContainer.cpp | 8 +++--- src/OverlayDockContainer.h | 2 +- 7 files changed, 82 insertions(+), 57 deletions(-) diff --git a/src/DockAreaWidget.cpp b/src/DockAreaWidget.cpp index 6026486..245efc0 100644 --- a/src/DockAreaWidget.cpp +++ b/src/DockAreaWidget.cpp @@ -1028,8 +1028,6 @@ void CDockAreaWidget::onAutoHideToggleRequested(CDockWidget* DockWidget, bool En { if (Enable) { - dockContainer()->sideTabBar(area)->insertSideTab(0, DockWidget->sideTabWidget()); - DockWidget->sideTabWidget()->show(); dockContainer()->createAndInitializeDockWidgetOverlayContainer(area, DockWidget); toggleView(false); } diff --git a/src/DockContainerWidget.cpp b/src/DockContainerWidget.cpp index bd261af..7f970b2 100644 --- a/src/DockContainerWidget.cpp +++ b/src/DockContainerWidget.cpp @@ -137,6 +137,7 @@ public: QPointer DockManager; unsigned int zOrderIndex = 0; QList DockAreas; + QList OverlayWidgets; QMap SideTabBarWidgets; QGridLayout* Layout = nullptr; QSplitter* RootSplitter = nullptr; @@ -1467,6 +1468,13 @@ CDockContainerWidget::~CDockContainerWidget() { d->DockManager->removeDockContainer(this); } + + auto OverlayWidgets = d->OverlayWidgets; + for (auto OverlayWidget : OverlayWidgets) + { + delete OverlayWidget; + } + delete d; } @@ -1509,7 +1517,7 @@ COverlayDockContainer* CDockContainerWidget::createAndInitializeDockWidgetOverla sideTabBar(area)->insertSideTab(0, DockWidget->sideTabWidget()); DockWidget->sideTabWidget()->show(); - const auto dockContainer = new COverlayDockContainer(DockWidget, area); + const auto dockContainer = new COverlayDockContainer(DockWidget, area, this); dockContainer->hide(); return dockContainer; } @@ -1584,6 +1592,23 @@ bool CDockContainerWidget::event(QEvent *e) } +//============================================================================ +void CDockContainerWidget::deleteOverlayWidgets() +{ + for (auto OverlayWidget : d->OverlayWidgets) + { + OverlayWidget->cleanupAndDelete(); + } + d->OverlayWidgets.clear(); +} + +//============================================================================ +QList CDockContainerWidget::overlayWidgets() const +{ + return d->OverlayWidgets; +} + + //============================================================================ void CDockContainerWidget::addDockArea(CDockAreaWidget* DockAreaWidget, DockWidgetArea area) @@ -1758,6 +1783,14 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi auto ContainerDropArea = d->DockManager->containerOverlay()->dropAreaUnderCursor(); bool Dropped = false; + // Handle any overlay widgets + // todo: cleanup - move into own func? + auto overlayWidgets = FloatingWidget->dockContainer()->overlayWidgets(); + for (const auto overlayWidget : overlayWidgets) + { + createAndInitializeDockWidgetOverlayContainer(overlayWidget->sideTabBarArea(), overlayWidget->dockWidget()); + } + if (DockArea) { auto dropOverlay = d->DockManager->dockAreaOverlay(); @@ -2084,13 +2117,25 @@ QList CDockContainerWidget::dockWidgets() const return Result; } - //============================================================================ void CDockContainerWidget::updateSplitterHandles(QSplitter* splitter) { d->updateSplitterHandles(splitter); } +//============================================================================ +void CDockContainerWidget::registerOverlayWidget(COverlayDockContainer* OverlayWidget) +{ + d->OverlayWidgets.append(OverlayWidget); + Q_EMIT overlayWidgetCreated(OverlayWidget); + ADS_PRINT("d->OverlayWidgets.count() " << d->OverlayWidgets.count()); +} + +//============================================================================ +void CDockContainerWidget::removeOverlayWidget(COverlayDockContainer* OverlayWidget) +{ + d->OverlayWidgets.removeAll(OverlayWidget); +} //============================================================================ CDockWidget::DockWidgetFeatures CDockContainerWidget::features() const diff --git a/src/DockContainerWidget.h b/src/DockContainerWidget.h index 9d93b6f..281602d 100644 --- a/src/DockContainerWidget.h +++ b/src/DockContainerWidget.h @@ -83,6 +83,17 @@ protected: */ virtual bool event(QEvent *e) override; + /* + * Delete function for resetting the overlay widget list + * Used during restore + */ + void deleteOverlayWidgets(); + + /** + * Access function for overlay widgets + */ + QList overlayWidgets() const; + /** * Access function for the internal root splitter */ @@ -177,6 +188,19 @@ protected: */ void updateSplitterHandles(QSplitter* splitter); + /** + * Registers the given floating widget in the internal list of + * overlay widgets + */ + void registerOverlayWidget(COverlayDockContainer* OverlayWidget); + + /** + * Remove the given overlay widget from the list of registered overlay + * widgets + */ + void removeOverlayWidget(COverlayDockContainer* OverlayWidget); + + public: /** @@ -312,6 +336,11 @@ Q_SIGNALS: */ void dockAreasAdded(); + /** + * This signal is emitted, if a new overlay widget has been created. + */ + void overlayWidgetCreated(ads::COverlayDockContainer* OverlayWidget); + /** * This signal is emitted if one or multiple dock areas has been removed */ diff --git a/src/DockManager.cpp b/src/DockManager.cpp index 4f4787d..2213016 100644 --- a/src/DockManager.cpp +++ b/src/DockManager.cpp @@ -100,7 +100,6 @@ struct DockManagerPrivate CDockManager* _this; QList FloatingWidgets; QList HiddenFloatingWidgets; - QList OverlayWidgets; QList Containers; CDockOverlay* ContainerOverlay; CDockOverlay* DockAreaOverlay; @@ -148,15 +147,6 @@ struct DockManagerPrivate } } - void deleteOverlayWidgets() - { - for (auto OverlayWidget : OverlayWidgets) - { - OverlayWidget->cleanupAndDelete(); - } - OverlayWidgets.clear(); - } - void markDockWidgetsDirty() { for (auto DockWidget : DockWidgetsMap) @@ -441,7 +431,7 @@ bool DockManagerPrivate::restoreState(const QByteArray& State, int version) // Hide updates of floating widgets from use hideFloatingWidgets(); - deleteOverlayWidgets(); + _this->deleteOverlayWidgets(); markDockWidgetsDirty(); if (!restoreStateFromXml(state, version)) @@ -539,12 +529,6 @@ CDockManager::~CDockManager() delete FloatingWidget; } - auto OverlayWidgets = d->OverlayWidgets; - for (auto OverlayWidget : OverlayWidgets) - { - delete OverlayWidget; - } - delete d; } @@ -636,14 +620,6 @@ void CDockManager::registerFloatingWidget(CFloatingDockContainer* FloatingWidget ADS_PRINT("d->FloatingWidgets.count() " << d->FloatingWidgets.count()); } -//============================================================================ -void CDockManager::registerOverlayWidget(COverlayDockContainer* OverlayWidget) -{ - d->OverlayWidgets.append(OverlayWidget); - Q_EMIT overlayWidgetCreated(OverlayWidget); - ADS_PRINT("d->OverlayWidgets.count() " << d->OverlayWidgets.count()); -} - //============================================================================ void CDockManager::removeFloatingWidget(CFloatingDockContainer* FloatingWidget) @@ -651,12 +627,6 @@ void CDockManager::removeFloatingWidget(CFloatingDockContainer* FloatingWidget) d->FloatingWidgets.removeAll(FloatingWidget); } -//============================================================================ -void CDockManager::removeOverlayWidget(COverlayDockContainer* OverlayWidget) -{ - d->OverlayWidgets.removeAll(OverlayWidget); -} - //============================================================================ void CDockManager::registerDockContainer(CDockContainerWidget* DockContainer) { diff --git a/src/DockManager.h b/src/DockManager.h index 272aa19..88dcdf9 100644 --- a/src/DockManager.h +++ b/src/DockManager.h @@ -94,24 +94,12 @@ protected: */ void registerFloatingWidget(CFloatingDockContainer* FloatingWidget); - /** - * Registers the given floating widget in the internal list of - * overlay widgets - */ - void registerOverlayWidget(COverlayDockContainer* OverlayWidget); - /** * Remove the given floating widget from the list of registered floating * widgets */ void removeFloatingWidget(CFloatingDockContainer* FloatingWidget); - /** - * Remove the given overlay widget from the list of registered overlay - * widgets - */ - void removeOverlayWidget(COverlayDockContainer* OverlayWidget); - /** * Registers the given dock container widget */ @@ -639,11 +627,6 @@ Q_SIGNALS: */ void floatingWidgetCreated(ads::CFloatingDockContainer* FloatingWidget); - /** - * This signal is emitted, if a new overlay widget has been created. - */ - void overlayWidgetCreated(ads::COverlayDockContainer* OverlayWidget); - /** * This signal is emitted, if a new DockArea has been created. * An application can use this signal to set custom icons or custom diff --git a/src/OverlayDockContainer.cpp b/src/OverlayDockContainer.cpp index 0eaf84d..812c969 100644 --- a/src/OverlayDockContainer.cpp +++ b/src/OverlayDockContainer.cpp @@ -113,7 +113,7 @@ COverlayDockContainer::COverlayDockContainer(CDockManager* DockManager, SideTabB updateMask(); updateSize(); - DockManager->registerOverlayWidget(this); + parent->registerOverlayWidget(this); d->DockArea->installEventFilter(this); parent->installEventFilter(this); @@ -140,8 +140,8 @@ void COverlayDockContainer::updateSize() } //============================================================================ -COverlayDockContainer::COverlayDockContainer(CDockWidget* DockWidget, SideTabBarArea area) : - COverlayDockContainer(DockWidget->dockManager(), area, DockWidget->dockContainer() != nullptr ? DockWidget->dockContainer() : DockWidget->dockManager()) +COverlayDockContainer::COverlayDockContainer(CDockWidget* DockWidget, SideTabBarArea area, CDockContainerWidget* parent) : + COverlayDockContainer(DockWidget->dockManager(), area, parent) { addDockWidget(DockWidget); } @@ -156,7 +156,7 @@ COverlayDockContainer::~COverlayDockContainer() if (d->DockManager) { - d->DockManager->removeOverlayWidget(this); + parentContainer()->removeOverlayWidget(this); } delete d; diff --git a/src/OverlayDockContainer.h b/src/OverlayDockContainer.h index e826e9c..ad42e4d 100644 --- a/src/OverlayDockContainer.h +++ b/src/OverlayDockContainer.h @@ -70,7 +70,7 @@ public: /** * Create overlay widget with the given dock widget */ - COverlayDockContainer(CDockWidget* DockWidget, SideTabBarArea area); + COverlayDockContainer(CDockWidget* DockWidget, SideTabBarArea area, CDockContainerWidget* parent); /** * Virtual Destructor