Reworked toggle view

Previous:
- It would just hide the overlay dock widget and leave the side tabs
still visible
- Close button, toggle view action would simply collapse the dock widget
intsead of completely hiding it

Current:
- Now toggle view and collapse functionality are separated.
- Toggle view will now hide the side tab bars completely
- Close button and toggle view action will completely hide it
- Collapse view will simply hide the overlay dock container without
hiding the side tabs
- Handled logic for floating widgets and toggling view
This commit is contained in:
Syarif Fakhri 2022-09-09 12:18:41 +08:00
parent 6ae14fada3
commit 84c6afa428
8 changed files with 105 additions and 27 deletions

View File

@ -1079,12 +1079,10 @@ void CDockAreaWidget::onAutoHideToggleRequested(CDockWidget* DockWidget, bool En
if (Enable) if (Enable)
{ {
dockContainer()->createAndInitializeDockWidgetOverlayContainer(area, DockWidget); dockContainer()->createAndInitializeDockWidgetOverlayContainer(area, DockWidget);
DockWidget->toggleView(false);
} }
else else
{ {
overlayDockContainer()->moveContentsToParent(); overlayDockContainer()->moveContentsToParent();
DockWidget->toggleView(true);
} }
} }

View File

@ -1074,6 +1074,12 @@ bool DockContainerWidgetPrivate::restoreOverlayDockArea(CDockingStateReader& s,
return false; return false;
} }
bool Closed = s.attributes().value("Closed").toInt(&Ok);
if (!Ok)
{
return false;
}
s.skipCurrentElement(); s.skipCurrentElement();
CDockWidget* DockWidget = DockManager->findDockWidget(ObjectName.toString()); CDockWidget* DockWidget = DockManager->findDockWidget(ObjectName.toString());
if (!DockWidget || Testing) if (!DockWidget || Testing)
@ -1085,15 +1091,14 @@ bool DockContainerWidgetPrivate::restoreOverlayDockArea(CDockingStateReader& s,
// We hide the DockArea here to prevent the short display (the flashing) // We hide the DockArea here to prevent the short display (the flashing)
// of the dock areas during application startup // of the dock areas during application startup
DockArea->hide(); DockArea->hide();
DockWidget->setToggleViewActionChecked(false); DockWidget->setToggleViewActionChecked(!Closed);
DockWidget->setClosedState(true); DockWidget->setClosedState(Closed);
DockWidget->setProperty(internal::ClosedProperty, true); DockWidget->setProperty(internal::ClosedProperty, Closed);
DockWidget->setProperty(internal::DirtyProperty, false); DockWidget->setProperty(internal::DirtyProperty, false);
_this->sideTabBar(area)->insertSideTab(0, DockWidget->sideTabWidget()); _this->sideTabBar(area)->insertSideTab(0, DockWidget->sideTabWidget());
DockWidget->toggleView(false);
DockArea->overlayDockContainer()->addDockWidget(DockWidget); DockArea->overlayDockContainer()->addDockWidget(DockWidget);
DockWidget->sideTabWidget()->show();
DockWidget->sideTabWidget()->updateStyle(); // Needed as the side tab widget get it's left/right property from the overlay dock container which was just added DockWidget->sideTabWidget()->updateStyle(); // Needed as the side tab widget get it's left/right property from the overlay dock container which was just added
DockWidget->toggleView(Closed);
} }
if (Testing) if (Testing)

View File

@ -90,11 +90,6 @@ protected:
*/ */
void deleteOverlayWidgets(); 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
*/ */
@ -329,6 +324,12 @@ public:
*/ */
CSideTabBar* sideTabBar(CDockWidgetSideTab::SideTabBarArea area) const; CSideTabBar* sideTabBar(CDockWidgetSideTab::SideTabBarArea area) const;
/**
* Access function for overlay widgets
*/
QList<COverlayDockContainer*> overlayWidgets() const;
Q_SIGNALS: Q_SIGNALS:
/** /**
* This signal is emitted if one or multiple dock areas has been added to * This signal is emitted if one or multiple dock areas has been added to

View File

@ -191,7 +191,7 @@ void DockFocusControllerPrivate::updateDockWidgetFocus(CDockWidget* DockWidget)
if (old && old->overlayDockContainer() && old->overlayDockContainer()->isVisible() && old != FocusedDockWidget) if (old && old->overlayDockContainer() && old->overlayDockContainer()->isVisible() && old != FocusedDockWidget)
{ {
old->toggleView(false); old->overlayDockContainer()->collapseView(true);
} }
if (old == DockWidget && !ForceFocusChangedSignal) if (old == DockWidget && !ForceFocusChangedSignal)

View File

@ -873,8 +873,7 @@ COverlayDockContainer* CDockManager::addOverlayDockWidgetToContainer(CDockWidget
{ {
d->DockWidgetsMap.insert(Dockwidget->objectName(), Dockwidget); d->DockWidgetsMap.insert(Dockwidget->objectName(), Dockwidget);
auto container = DockContainerWidget->createAndInitializeDockWidgetOverlayContainer(area, Dockwidget); auto container = DockContainerWidget->createAndInitializeDockWidgetOverlayContainer(area, Dockwidget);
container->dockAreaWidget()->toggleView(false); container->collapseView(true);
Dockwidget->toggleView(false);
Q_EMIT dockWidgetAdded(Dockwidget); Q_EMIT dockWidgetAdded(Dockwidget);
return container; return container;

View File

@ -118,6 +118,12 @@ struct DockWidgetPrivate
*/ */
void updateParentDockArea(); void updateParentDockArea();
/**
* Closes all overlayed dock widgets if there are no more opened dock areas
* This prevents the overlayed dock widgets from being pinned to an empty dock area
*/
void closeOverlayDockWidgetsIfNeeded();
/** /**
* Setup the top tool bar * Setup the top tool bar
*/ */
@ -187,9 +193,10 @@ void DockWidgetPrivate::showDockWidget()
FloatingWidget->show(); FloatingWidget->show();
} }
if (DockArea->isOverlayed()) // If this widget is pinned and there are no opened dock widgets, unpin the overlay widget by moving it's contents to parent container
if (Container->openedDockWidgets().count() == 0 && DockArea->isOverlayed())
{ {
DockArea->overlayDockContainer()->show(); DockArea->overlayDockContainer()->moveContentsToParent();
} }
} }
} }
@ -200,17 +207,14 @@ void DockWidgetPrivate::hideDockWidget()
{ {
TabWidget->hide(); TabWidget->hide();
updateParentDockArea(); updateParentDockArea();
closeOverlayDockWidgetsIfNeeded();
if (Features.testFlag(CDockWidget::DeleteContentOnClose)) if (Features.testFlag(CDockWidget::DeleteContentOnClose))
{ {
Widget->deleteLater(); Widget->deleteLater();
Widget = nullptr; Widget = nullptr;
} }
if (DockArea->isOverlayed())
{
DockArea->overlayDockContainer()->hide();
}
} }
@ -239,6 +243,22 @@ void DockWidgetPrivate::updateParentDockArea()
} }
} }
void DockWidgetPrivate::closeOverlayDockWidgetsIfNeeded()
{
if (_this->dockContainer() && _this->dockContainer()->openedDockWidgets().isEmpty())
{
for (auto overlayWidget : _this->dockContainer()->overlayWidgets())
{
if (overlayWidget->dockWidget() == _this)
{
continue;
}
overlayWidget->dockWidget()->toggleView(false);
}
}
}
//============================================================================ //============================================================================
void DockWidgetPrivate::setupToolBar() void DockWidgetPrivate::setupToolBar()
@ -611,6 +631,8 @@ void CDockWidget::toggleViewInternal(bool Open)
CDockWidget* TopLevelDockWidgetBefore = DockContainer CDockWidget* TopLevelDockWidgetBefore = DockContainer
? DockContainer->topLevelDockWidget() : nullptr; ? DockContainer->topLevelDockWidget() : nullptr;
d->Closed = !Open;
if (Open) if (Open)
{ {
d->showDockWidget(); d->showDockWidget();
@ -619,7 +641,7 @@ void CDockWidget::toggleViewInternal(bool Open)
{ {
d->hideDockWidget(); d->hideDockWidget();
} }
d->Closed = !Open;
d->ToggleViewAction->blockSignals(true); d->ToggleViewAction->blockSignals(true);
d->ToggleViewAction->setChecked(Open); d->ToggleViewAction->setChecked(Open);
d->ToggleViewAction->blockSignals(false); d->ToggleViewAction->blockSignals(false);
@ -628,6 +650,11 @@ void CDockWidget::toggleViewInternal(bool Open)
d->DockArea->toggleDockWidgetView(this, Open); d->DockArea->toggleDockWidgetView(this, Open);
} }
if (d->DockArea->isOverlayed())
{
d->DockArea->overlayDockContainer()->toggleView(Open);
}
if (Open && TopLevelDockWidgetBefore) if (Open && TopLevelDockWidgetBefore)
{ {
CDockWidget::emitTopLevelEventForWidget(TopLevelDockWidgetBefore, false); CDockWidget::emitTopLevelEventForWidget(TopLevelDockWidgetBefore, false);
@ -1051,9 +1078,8 @@ void CDockWidget::onDockWidgetSideTabClicked()
} }
overlayContainer->raise(); overlayContainer->raise();
const auto show = !overlayContainer->isVisible(); const auto shouldCollapse = overlayContainer->isVisible();
overlayContainer->setVisible(show); overlayContainer->collapseView(shouldCollapse);
toggleView(show);
if (overlayContainer->isVisible()) if (overlayContainer->isVisible())
{ {
// d->DockManager->setDockWidgetFocused(this) does not // d->DockManager->setDockWidgetFocused(this) does not

View File

@ -281,6 +281,43 @@ bool COverlayDockContainer::restoreState(CDockingStateReader& s, bool Testing)
return true; return true;
} }
void COverlayDockContainer::toggleView(bool Enable)
{
if (Enable)
{
const auto dockWidget = d->DockWidget;
if (dockWidget)
{
dockWidget->sideTabWidget()->show();
}
}
else
{
const auto dockWidget = d->DockWidget;
if (dockWidget)
{
dockWidget->sideTabWidget()->hide();
}
hide();
}
}
void COverlayDockContainer::collapseView(bool Enable)
{
if (Enable)
{
hide();
d->DockArea->hide();
d->DockWidget->hide();
}
else
{
show();
d->DockArea->show();
d->DockWidget->show();
}
}
//============================================================================ //============================================================================
bool COverlayDockContainer::areaExistsInConfig(CDockWidgetSideTab::SideTabBarArea area) bool COverlayDockContainer::areaExistsInConfig(CDockWidgetSideTab::SideTabBarArea area)

View File

@ -126,6 +126,18 @@ public:
*/ */
bool restoreState(CDockingStateReader& Stream, bool Testing); bool restoreState(CDockingStateReader& Stream, bool Testing);
/*
* Toggles the overlay dock container widget
* This will also hide the side tab widget
*/
void toggleView(bool Enable);
/*
* Collapses the overlay dock container widget
* Does not hide the side tab widget
*/
void collapseView(bool Enable);
/* /*
* Convenience function fr determining if area exists in config * Convenience function fr determining if area exists in config
*/ */