mirror of
https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git
synced 2024-12-25 07:31:33 +08:00
Fixed proper hiding of dock areas without any visible content when dragging out singkle widgets, prevente single dock widget from dragging if it is the last dock widget in a floating widget
This commit is contained in:
parent
b93e723a83
commit
6ec38b48ef
@ -49,6 +49,7 @@
|
||||
#include "DockManager.h"
|
||||
#include "DockOverlay.h"
|
||||
#include "DockAreaTabBar.h"
|
||||
#include "DockSplitter.h"
|
||||
|
||||
|
||||
namespace ads
|
||||
@ -76,7 +77,6 @@ struct DockAreaWidgetPrivate
|
||||
QPushButton* CloseButton;
|
||||
int TabsLayoutInitCount;
|
||||
CDockManager* DockManager = nullptr;
|
||||
QVector<CDockWidget*> OpenDockWidgets;
|
||||
bool MenuOutdated = true;
|
||||
|
||||
/**
|
||||
@ -216,7 +216,7 @@ void DockAreaWidgetPrivate::updateTabBar()
|
||||
return;
|
||||
}
|
||||
|
||||
if (Container->isFloating() && (Container->dockAreaCount() == 1) && (_this->count() == 1))
|
||||
if (Container->isFloating() && (Container->dockAreaCount() == 1) && (_this->dockWidgetsCount() == 1))
|
||||
{
|
||||
TitleBar->setVisible(false);
|
||||
}
|
||||
@ -380,6 +380,13 @@ void CDockAreaWidget::removeDockWidget(CDockWidget* DockWidget)
|
||||
dockContainer()->removeDockArea(this);
|
||||
this->deleteLater();;
|
||||
}
|
||||
else if (!NextDockWidget)
|
||||
{
|
||||
// if contents layout is not empty but there are no more open dock
|
||||
// widgets, then we need to hide the dock area because it does not
|
||||
// contain any visible content
|
||||
hideAreaWithNoVisibleContent();
|
||||
}
|
||||
|
||||
d->updateTabBar();
|
||||
DockWidget->setDockArea(nullptr);
|
||||
@ -387,6 +394,42 @@ void CDockAreaWidget::removeDockWidget(CDockWidget* DockWidget)
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockAreaWidget::hideAreaWithNoVisibleContent()
|
||||
{
|
||||
this->hide();
|
||||
|
||||
// Hide empty parent splitter
|
||||
auto Splitter = internal::findParent<CDockSplitter*>(this);
|
||||
while (Splitter && Splitter->isVisible())
|
||||
{
|
||||
if (!Splitter->hasVisibleContent())
|
||||
{
|
||||
Splitter->hide();
|
||||
}
|
||||
Splitter = internal::findParent<CDockSplitter*>(Splitter);
|
||||
}
|
||||
|
||||
//Hide empty floating widget
|
||||
CDockContainerWidget* Container = this->dockContainer();
|
||||
if (Container->isFloating() && Container->openedDockAreas().isEmpty())
|
||||
{
|
||||
CFloatingDockContainer* FloatingWidget = internal::findParent<CFloatingDockContainer*>(Container);
|
||||
FloatingWidget->hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockAreaWidget::hideAreaIfNoVisibleContent()
|
||||
{
|
||||
if (openedDockWidgets().isEmpty())
|
||||
{
|
||||
hideAreaIfNoVisibleContent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockAreaWidget::onDockWidgetTitleClicked()
|
||||
{
|
||||
@ -512,6 +555,21 @@ QList<CDockWidget*> CDockAreaWidget::dockWidgets() const
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
int CDockAreaWidget::openDockWidgetsCount() const
|
||||
{
|
||||
int Count = 0;
|
||||
for (int i = 0; i < d->ContentsLayout->count(); ++i)
|
||||
{
|
||||
if (!dockWidget(i)->isClosed())
|
||||
{
|
||||
++Count;
|
||||
}
|
||||
}
|
||||
return Count;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
QList<CDockWidget*> CDockAreaWidget::openedDockWidgets() const
|
||||
{
|
||||
@ -544,7 +602,7 @@ int CDockAreaWidget::indexOfContentByTitlePos(const QPoint& p, QWidget* exclude)
|
||||
|
||||
|
||||
//============================================================================
|
||||
int CDockAreaWidget::count() const
|
||||
int CDockAreaWidget::dockWidgetsCount() const
|
||||
{
|
||||
return d->ContentsLayout->count();
|
||||
}
|
||||
|
@ -118,6 +118,19 @@ protected:
|
||||
*/
|
||||
int index(CDockWidget* DockWidget);
|
||||
|
||||
/**
|
||||
* Call this function, if you already know, that the dock does not
|
||||
* contain any visible content (any open dock widgets).
|
||||
*/
|
||||
void hideAreaWithNoVisibleContent();
|
||||
|
||||
/**
|
||||
* This function checks, if the dock area has visible content, that means
|
||||
* if any dock widget is open, and then calls hideAreaWithNoVisibleContent()
|
||||
* if it does not find any visible content
|
||||
*/
|
||||
void hideAreaIfNoVisibleContent();
|
||||
|
||||
public:
|
||||
/**
|
||||
* Default Constructor
|
||||
@ -150,22 +163,27 @@ public:
|
||||
*/
|
||||
QRect contentAreaGeometry() const;
|
||||
|
||||
/**
|
||||
* Returns the number of dock widgets in this area
|
||||
*/
|
||||
int dockWidgetsCount() const;
|
||||
|
||||
/**
|
||||
* Returns a list of all dock widgets in this dock area.
|
||||
* This list contains open and closed dock widgets.
|
||||
*/
|
||||
QList<CDockWidget*> dockWidgets() const;
|
||||
|
||||
/**
|
||||
* Returns the number of dock widgets in this area
|
||||
*/
|
||||
int openDockWidgetsCount() const;
|
||||
|
||||
/**
|
||||
* Returns a list of dock widgets that are not closed
|
||||
*/
|
||||
QList<CDockWidget*> openedDockWidgets() const;
|
||||
|
||||
/**
|
||||
* Returns the number of dock widgets in this area
|
||||
*/
|
||||
int count() const;
|
||||
|
||||
/**
|
||||
* Returns a dock widget by its index
|
||||
*/
|
||||
|
@ -537,7 +537,7 @@ bool DockContainerWidgetPrivate::restoreDockArea(QXmlStreamReader& s,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!DockArea->count())
|
||||
if (!DockArea->dockWidgetsCount())
|
||||
{
|
||||
delete DockArea;
|
||||
DockArea = nullptr;
|
||||
@ -1073,9 +1073,11 @@ QSplitter* CDockContainerWidget::rootSplitter() const
|
||||
//============================================================================
|
||||
void CDockContainerWidget::dumpLayout()
|
||||
{
|
||||
#if (ADS_DEBUG_LEVEL > 0)
|
||||
qDebug("\n\nDumping layout --------------------------");
|
||||
d->dumpRecursive(0, d->RootSplitter);
|
||||
qDebug("--------------------------\n\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -91,11 +91,6 @@ struct DockWidgetPrivate
|
||||
*/
|
||||
void hideDockWidget();
|
||||
|
||||
/**
|
||||
* Hides a parent splitter if all dock widgets in the splitter are closed
|
||||
*/
|
||||
void hideEmptyParentSplitters();
|
||||
|
||||
/**
|
||||
* Hides a dock area if all dock widgets in the area are closed.
|
||||
* This function updates the current selected tab and hides the parent
|
||||
@ -103,12 +98,6 @@ struct DockWidgetPrivate
|
||||
*/
|
||||
void updateParentDockArea();
|
||||
|
||||
/**
|
||||
* Hides a floating widget if all dock areas are empty - that means,
|
||||
* if all dock widgets in all dock areas are closed
|
||||
*/
|
||||
void hideEmptyFloatingWidget();
|
||||
|
||||
/**
|
||||
* Setup the top tool bar
|
||||
*/
|
||||
@ -165,23 +154,6 @@ void DockWidgetPrivate::hideDockWidget()
|
||||
{
|
||||
TabWidget->hide();
|
||||
updateParentDockArea();
|
||||
hideEmptyParentSplitters();
|
||||
hideEmptyFloatingWidget();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void DockWidgetPrivate::hideEmptyParentSplitters()
|
||||
{
|
||||
auto Splitter = internal::findParent<CDockSplitter*>(_this);
|
||||
while (Splitter && Splitter->isVisible())
|
||||
{
|
||||
if (!Splitter->hasVisibleContent())
|
||||
{
|
||||
Splitter->hide();
|
||||
}
|
||||
Splitter = internal::findParent<CDockSplitter*>(Splitter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -195,19 +167,7 @@ void DockWidgetPrivate::updateParentDockArea()
|
||||
}
|
||||
else
|
||||
{
|
||||
DockArea->hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void DockWidgetPrivate::hideEmptyFloatingWidget()
|
||||
{
|
||||
CDockContainerWidget* Container = _this->dockContainer();
|
||||
if (Container->isFloating() && Container->openedDockAreas().isEmpty())
|
||||
{
|
||||
CFloatingDockContainer* FloatingWidget = internal::findParent<CFloatingDockContainer*>(Container);
|
||||
FloatingWidget->hide();
|
||||
DockArea->hideAreaWithNoVisibleContent();
|
||||
}
|
||||
}
|
||||
|
||||
@ -385,7 +345,7 @@ bool CDockWidget::isFloating() const
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dockContainer()->dockArea(0)->count() != 1)
|
||||
if (dockContainer()->dockArea(0)->dockWidgetsCount() != 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -164,13 +164,13 @@ bool DockWidgetTabPrivate::startFloating()
|
||||
{
|
||||
qDebug() << "isFloating " << DockWidget->dockContainer()->isFloating();
|
||||
qDebug() << "areaCount " << DockWidget->dockContainer()->dockAreaCount();
|
||||
qDebug() << "widgetCount " << DockWidget->dockAreaWidget()->count();
|
||||
qDebug() << "widgetCount " << DockWidget->dockAreaWidget()->dockWidgetsCount();
|
||||
// if this is the last dock widget inside of this floating widget,
|
||||
// then it does not make any sense, to make it floating because
|
||||
// it is already floating
|
||||
if (DockWidget->dockContainer()->isFloating()
|
||||
&& (DockWidget->dockContainer()->visibleDockAreaCount() == 1)
|
||||
&& (DockWidget->dockAreaWidget()->count() == 1))
|
||||
&& (DockWidget->dockAreaWidget()->dockWidgetsCount() == 1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -179,7 +179,7 @@ bool DockWidgetTabPrivate::startFloating()
|
||||
DragState = DraggingFloatingWidget;
|
||||
QSize Size = DockArea->size();
|
||||
CFloatingDockContainer* FloatingWidget = nullptr;
|
||||
if (DockArea->count() > 1)
|
||||
if (DockArea->dockWidgetsCount() > 1)
|
||||
{
|
||||
// If section widget has multiple tabs, we take only one tab
|
||||
FloatingWidget = new CFloatingDockContainer(DockWidget);
|
||||
@ -248,7 +248,7 @@ void CDockWidgetTab::mouseReleaseEvent(QMouseEvent* ev)
|
||||
int toIndex = d->DockArea->indexOfContentByTitlePos(pos, this);
|
||||
if (-1 == toIndex)
|
||||
{
|
||||
toIndex = d->DockArea->count() - 1;
|
||||
toIndex = d->DockArea->dockWidgetsCount() - 1;
|
||||
}
|
||||
qDebug() << "Move tab from " << fromIndex << " to " << toIndex;
|
||||
d->DockArea->reorderDockWidget(fromIndex, toIndex);
|
||||
@ -294,6 +294,16 @@ void CDockWidgetTab::mouseMoveEvent(QMouseEvent* ev)
|
||||
bool MouseInsideTitleArea = d->titleAreaGeometryContains(ev->globalPos());
|
||||
if (!MouseInsideTitleArea)
|
||||
{
|
||||
// If this is the last dock area in a dock container with only
|
||||
// one single dock widget it does not make sense to move it to a new
|
||||
// floating widget and leave this one empty
|
||||
if (d->DockArea->dockContainer()->isFloating()
|
||||
&& d->DockArea->openDockWidgetsCount() == 1
|
||||
&& d->DockArea->dockContainer()->visibleDockAreaCount() == 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Floating is only allowed for widgets that are movable
|
||||
if (d->DockWidget->features().testFlag(CDockWidget::DockWidgetMovable))
|
||||
{
|
||||
@ -301,7 +311,7 @@ void CDockWidgetTab::mouseMoveEvent(QMouseEvent* ev)
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (d->DockArea->count() > 1
|
||||
else if (d->DockArea->openDockWidgetsCount() > 1
|
||||
&& (ev->pos() - d->DragStartMousePosition).manhattanLength() >= QApplication::startDragDistance()) // Wait a few pixels before start moving
|
||||
{
|
||||
d->DragState = DraggingTab;
|
||||
@ -381,7 +391,7 @@ void CDockWidgetTab::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
// If this is the last dock area in a dock container it does not make
|
||||
// sense to move it to a new floating widget and leave this one
|
||||
// empty
|
||||
if (!d->DockArea->dockContainer()->isFloating() || d->DockArea->count() > 1)
|
||||
if (!d->DockArea->dockContainer()->isFloating() || d->DockArea->dockWidgetsCount() > 1)
|
||||
{
|
||||
d->startFloating();
|
||||
}
|
||||
|
@ -409,7 +409,9 @@ bool CFloatingDockContainer::event(QEvent *e)
|
||||
break;
|
||||
}
|
||||
|
||||
#if (ADS_DEBUG_LEVEL > 0)
|
||||
qDebug() << "CFloatingDockContainer::event " << e->type();
|
||||
#endif
|
||||
return QWidget::event(e);
|
||||
}
|
||||
|
||||
@ -520,7 +522,7 @@ bool CFloatingDockContainer::hasSingleDockWidget() const
|
||||
return false;
|
||||
}
|
||||
|
||||
return d->DockContainer->dockArea(0)->count() == 1;
|
||||
return d->DockContainer->dockArea(0)->dockWidgetsCount() == 1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -39,6 +39,8 @@
|
||||
#define ADS_EXPORT Q_DECL_IMPORT
|
||||
#endif
|
||||
|
||||
#define ADS_DEBUG_LEVEL 0
|
||||
|
||||
class QSplitter;
|
||||
|
||||
namespace ads
|
||||
|
Loading…
Reference in New Issue
Block a user