Fix a bug where overlay widgets from another container widget

would not be correctly transferred into the container widget that it's
dragged into.
This commit is contained in:
Syarif Fakhri 2022-09-06 17:42:26 +08:00
parent 6e35a9e7a7
commit fde133c25e
7 changed files with 82 additions and 57 deletions

View File

@ -1028,8 +1028,6 @@ void CDockAreaWidget::onAutoHideToggleRequested(CDockWidget* DockWidget, bool En
{ {
if (Enable) if (Enable)
{ {
dockContainer()->sideTabBar(area)->insertSideTab(0, DockWidget->sideTabWidget());
DockWidget->sideTabWidget()->show();
dockContainer()->createAndInitializeDockWidgetOverlayContainer(area, DockWidget); dockContainer()->createAndInitializeDockWidgetOverlayContainer(area, DockWidget);
toggleView(false); toggleView(false);
} }

View File

@ -137,6 +137,7 @@ public:
QPointer<CDockManager> DockManager; QPointer<CDockManager> DockManager;
unsigned int zOrderIndex = 0; unsigned int zOrderIndex = 0;
QList<CDockAreaWidget*> DockAreas; QList<CDockAreaWidget*> DockAreas;
QList<COverlayDockContainer*> OverlayWidgets;
QMap<SideTabBarArea, CSideTabBar*> SideTabBarWidgets; QMap<SideTabBarArea, CSideTabBar*> SideTabBarWidgets;
QGridLayout* Layout = nullptr; QGridLayout* Layout = nullptr;
QSplitter* RootSplitter = nullptr; QSplitter* RootSplitter = nullptr;
@ -1467,6 +1468,13 @@ CDockContainerWidget::~CDockContainerWidget()
{ {
d->DockManager->removeDockContainer(this); d->DockManager->removeDockContainer(this);
} }
auto OverlayWidgets = d->OverlayWidgets;
for (auto OverlayWidget : OverlayWidgets)
{
delete OverlayWidget;
}
delete d; delete d;
} }
@ -1509,7 +1517,7 @@ COverlayDockContainer* CDockContainerWidget::createAndInitializeDockWidgetOverla
sideTabBar(area)->insertSideTab(0, DockWidget->sideTabWidget()); sideTabBar(area)->insertSideTab(0, DockWidget->sideTabWidget());
DockWidget->sideTabWidget()->show(); DockWidget->sideTabWidget()->show();
const auto dockContainer = new COverlayDockContainer(DockWidget, area); const auto dockContainer = new COverlayDockContainer(DockWidget, area, this);
dockContainer->hide(); dockContainer->hide();
return dockContainer; 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<COverlayDockContainer*> CDockContainerWidget::overlayWidgets() const
{
return d->OverlayWidgets;
}
//============================================================================ //============================================================================
void CDockContainerWidget::addDockArea(CDockAreaWidget* DockAreaWidget, void CDockContainerWidget::addDockArea(CDockAreaWidget* DockAreaWidget,
DockWidgetArea area) DockWidgetArea area)
@ -1758,6 +1783,14 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
auto ContainerDropArea = d->DockManager->containerOverlay()->dropAreaUnderCursor(); auto ContainerDropArea = d->DockManager->containerOverlay()->dropAreaUnderCursor();
bool Dropped = false; 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) if (DockArea)
{ {
auto dropOverlay = d->DockManager->dockAreaOverlay(); auto dropOverlay = d->DockManager->dockAreaOverlay();
@ -2084,13 +2117,25 @@ QList<CDockWidget*> CDockContainerWidget::dockWidgets() const
return Result; return Result;
} }
//============================================================================ //============================================================================
void CDockContainerWidget::updateSplitterHandles(QSplitter* splitter) void CDockContainerWidget::updateSplitterHandles(QSplitter* splitter)
{ {
d->updateSplitterHandles(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 CDockWidget::DockWidgetFeatures CDockContainerWidget::features() const

View File

@ -83,6 +83,17 @@ protected:
*/ */
virtual bool event(QEvent *e) override; 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<COverlayDockContainer*> overlayWidgets() const;
/** /**
* Access function for the internal root splitter * Access function for the internal root splitter
*/ */
@ -177,6 +188,19 @@ protected:
*/ */
void updateSplitterHandles(QSplitter* splitter); 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: public:
/** /**
@ -312,6 +336,11 @@ Q_SIGNALS:
*/ */
void dockAreasAdded(); 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 * This signal is emitted if one or multiple dock areas has been removed
*/ */

View File

@ -100,7 +100,6 @@ struct DockManagerPrivate
CDockManager* _this; CDockManager* _this;
QList<CFloatingDockContainer*> FloatingWidgets; QList<CFloatingDockContainer*> FloatingWidgets;
QList<CFloatingDockContainer*> HiddenFloatingWidgets; QList<CFloatingDockContainer*> HiddenFloatingWidgets;
QList<COverlayDockContainer*> OverlayWidgets;
QList<CDockContainerWidget*> Containers; QList<CDockContainerWidget*> Containers;
CDockOverlay* ContainerOverlay; CDockOverlay* ContainerOverlay;
CDockOverlay* DockAreaOverlay; CDockOverlay* DockAreaOverlay;
@ -148,15 +147,6 @@ struct DockManagerPrivate
} }
} }
void deleteOverlayWidgets()
{
for (auto OverlayWidget : OverlayWidgets)
{
OverlayWidget->cleanupAndDelete();
}
OverlayWidgets.clear();
}
void markDockWidgetsDirty() void markDockWidgetsDirty()
{ {
for (auto DockWidget : DockWidgetsMap) for (auto DockWidget : DockWidgetsMap)
@ -441,7 +431,7 @@ bool DockManagerPrivate::restoreState(const QByteArray& State, int version)
// Hide updates of floating widgets from use // Hide updates of floating widgets from use
hideFloatingWidgets(); hideFloatingWidgets();
deleteOverlayWidgets(); _this->deleteOverlayWidgets();
markDockWidgetsDirty(); markDockWidgetsDirty();
if (!restoreStateFromXml(state, version)) if (!restoreStateFromXml(state, version))
@ -539,12 +529,6 @@ CDockManager::~CDockManager()
delete FloatingWidget; delete FloatingWidget;
} }
auto OverlayWidgets = d->OverlayWidgets;
for (auto OverlayWidget : OverlayWidgets)
{
delete OverlayWidget;
}
delete d; delete d;
} }
@ -636,14 +620,6 @@ void CDockManager::registerFloatingWidget(CFloatingDockContainer* FloatingWidget
ADS_PRINT("d->FloatingWidgets.count() " << d->FloatingWidgets.count()); 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) void CDockManager::removeFloatingWidget(CFloatingDockContainer* FloatingWidget)
@ -651,12 +627,6 @@ void CDockManager::removeFloatingWidget(CFloatingDockContainer* FloatingWidget)
d->FloatingWidgets.removeAll(FloatingWidget); d->FloatingWidgets.removeAll(FloatingWidget);
} }
//============================================================================
void CDockManager::removeOverlayWidget(COverlayDockContainer* OverlayWidget)
{
d->OverlayWidgets.removeAll(OverlayWidget);
}
//============================================================================ //============================================================================
void CDockManager::registerDockContainer(CDockContainerWidget* DockContainer) void CDockManager::registerDockContainer(CDockContainerWidget* DockContainer)
{ {

View File

@ -94,24 +94,12 @@ protected:
*/ */
void registerFloatingWidget(CFloatingDockContainer* FloatingWidget); 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 * Remove the given floating widget from the list of registered floating
* widgets * widgets
*/ */
void removeFloatingWidget(CFloatingDockContainer* FloatingWidget); 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 * Registers the given dock container widget
*/ */
@ -639,11 +627,6 @@ Q_SIGNALS:
*/ */
void floatingWidgetCreated(ads::CFloatingDockContainer* FloatingWidget); 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. * This signal is emitted, if a new DockArea has been created.
* An application can use this signal to set custom icons or custom * An application can use this signal to set custom icons or custom

View File

@ -113,7 +113,7 @@ COverlayDockContainer::COverlayDockContainer(CDockManager* DockManager, SideTabB
updateMask(); updateMask();
updateSize(); updateSize();
DockManager->registerOverlayWidget(this); parent->registerOverlayWidget(this);
d->DockArea->installEventFilter(this); d->DockArea->installEventFilter(this);
parent->installEventFilter(this); parent->installEventFilter(this);
@ -140,8 +140,8 @@ void COverlayDockContainer::updateSize()
} }
//============================================================================ //============================================================================
COverlayDockContainer::COverlayDockContainer(CDockWidget* DockWidget, SideTabBarArea area) : COverlayDockContainer::COverlayDockContainer(CDockWidget* DockWidget, SideTabBarArea area, CDockContainerWidget* parent) :
COverlayDockContainer(DockWidget->dockManager(), area, DockWidget->dockContainer() != nullptr ? DockWidget->dockContainer() : DockWidget->dockManager()) COverlayDockContainer(DockWidget->dockManager(), area, parent)
{ {
addDockWidget(DockWidget); addDockWidget(DockWidget);
} }
@ -156,7 +156,7 @@ COverlayDockContainer::~COverlayDockContainer()
if (d->DockManager) if (d->DockManager)
{ {
d->DockManager->removeOverlayWidget(this); parentContainer()->removeOverlayWidget(this);
} }
delete d; delete d;

View File

@ -70,7 +70,7 @@ public:
/** /**
* Create overlay widget with the given dock widget * Create overlay widget with the given dock widget
*/ */
COverlayDockContainer(CDockWidget* DockWidget, SideTabBarArea area); COverlayDockContainer(CDockWidget* DockWidget, SideTabBarArea area, CDockContainerWidget* parent);
/** /**
* Virtual Destructor * Virtual Destructor