diff --git a/src/DockWidgetBase.cpp b/src/DockWidgetBase.cpp index 9a56c558..e59a4051 100644 --- a/src/DockWidgetBase.cpp +++ b/src/DockWidgetBase.cpp @@ -489,10 +489,12 @@ void DockWidgetBase::setAffinities(const QStringList &affinityNames) d->affinities = affinities; } -void DockWidgetBase::minimizeToSideBar() +void DockWidgetBase::moveToSideBar() { - if (MainWindowBase *m = mainWindow()) + if (MainWindowBase *m = mainWindow()) { + m->moveToSideBar(this); m->overlayOnSideBar(this); + } } FloatingWindow *DockWidgetBase::morphIntoFloatingWindow() diff --git a/src/DockWidgetBase.h b/src/DockWidgetBase.h index 7f1a7f59..b6a7927a 100644 --- a/src/DockWidgetBase.h +++ b/src/DockWidgetBase.h @@ -344,8 +344,10 @@ public: * It will be undocked from current layout. It's previous docked position will be remembered. * * This action is only available if the dock widget is docked into a MainWindow. + * The dockwidget will initially be visible and overlayed on top of the current layout (this is + * the auto-hide feature). */ - void minimizeToSideBar(); + void moveToSideBar(); Q_SIGNALS: ///@brief signal emitted when the parent changed diff --git a/src/MainWindowBase.cpp b/src/MainWindowBase.cpp index 88fb4e4a..5e12a356 100644 --- a/src/MainWindowBase.cpp +++ b/src/MainWindowBase.cpp @@ -219,12 +219,12 @@ SideBarLocation MainWindowBase::Private::preferredSideBar(DockWidgetBase *dw) co return SideBarLocation::South; } -void MainWindowBase::minimizeToSideBar(DockWidgetBase *dw) +void MainWindowBase::moveToSideBar(DockWidgetBase *dw) { - minimizeToSideBar(dw, d->preferredSideBar(dw)); + moveToSideBar(dw, d->preferredSideBar(dw)); } -void MainWindowBase::minimizeToSideBar(DockWidgetBase *dw, SideBarLocation location) +void MainWindowBase::moveToSideBar(DockWidgetBase *dw, SideBarLocation location) { if (SideBar *sb = sideBar(location)) { dw->forceClose(); @@ -237,15 +237,9 @@ void MainWindowBase::minimizeToSideBar(DockWidgetBase *dw, SideBarLocation locat void MainWindowBase::overlayOnSideBar(DockWidgetBase *dw) { - overlayOnSideBar(dw, d->preferredSideBar(dw)); -} - -void MainWindowBase::overlayOnSideBar(DockWidgetBase *dw, SideBarLocation location) -{ - SideBar *sb = sideBar(location); - if (!sb) { - // Shouldn't happen - qWarning() << Q_FUNC_INFO << "Overlaying not supported, probably disabled in Config::self().flags()"; + const SideBar *sb = sideBarForDockWidget(dw); + if (sb == nullptr) { + qWarning() << Q_FUNC_INFO << "You need to add the dock widget to the sidebar before you can overlay it"; return; } @@ -254,23 +248,26 @@ void MainWindowBase::overlayOnSideBar(DockWidgetBase *dw, SideBarLocation locati return; } - // We only support one overlay at a time, remove any existing one + // We only support one overlay at a time, remove any existing overlay clearSideBarOverlay(); - if (!sb->contains(dw)) - sb->addDockWidget(dw); - - // Detach in case it's docked to a main window - dw->forceClose(); - auto frame = Config::self().frameworkWidgetFactory()->createFrame(this, FrameOption_IsOverlayed); frame->addWidget(dw); - frame->QWidgetAdapter::setGeometry(d->rectForOverlay(frame, location)); + frame->QWidgetAdapter::setGeometry(d->rectForOverlay(frame, sb->location())); frame->QWidgetAdapter::show(); d->m_overlayedDockWidget = dw; } +void MainWindowBase::toggleOverlayOnSideBar(DockWidgetBase *dw) +{ + const bool wasOverlayed = d->m_overlayedDockWidget == dw; + clearSideBarOverlay(); + if (!wasOverlayed) { + overlayOnSideBar(dw); + } +} + void MainWindowBase::clearSideBarOverlay() { if (!d->m_overlayedDockWidget) diff --git a/src/MainWindowBase.h b/src/MainWindowBase.h index 2149acc8..a3a9c684 100644 --- a/src/MainWindowBase.h +++ b/src/MainWindowBase.h @@ -132,14 +132,22 @@ public: /// sub-tree. void layoutParentContainerEqually(DockWidgetBase *dockWidget); - ///@brief Minimizes dock widget @p into the side bar. - ///The DockWidget will be hidden and show a button in the side bar. - void minimizeToSideBar(DockWidgetBase *dw); - void minimizeToSideBar(DockWidgetBase *dw, SideBarLocation); + ///@brief Moves the dock widget into one of the MainWindow's sidebar. + /// Means the dock widget is removed from the layout, and the sidebar shows a button that if pressed + /// will toggle the dock widget's visibility as an overlay over the layout. This is the auto-hide + /// functionality. + /// + /// The chosen side bar will depend on some heuristics, mostly proximity. + void moveToSideBar(DockWidgetBase *dw); + + /// @brief overload that allows to specify which sidebar to use, instead of using heuristics. + void moveToSideBar(DockWidgetBase *dw, SideBarLocation); ///@brief Shows the dock widget overlayed on top of the main window, placed next to the sidebar void overlayOnSideBar(DockWidgetBase *dw); - void overlayOnSideBar(DockWidgetBase *dw, SideBarLocation); + + ///@brief Shows or hides an overlay. It's assumed the dock widget is already in a side-bar. + void toggleOverlayOnSideBar(DockWidgetBase *dw); /// @brief closes any overlayed dock widget. The sidebar still displays them as button. void clearSideBarOverlay(); diff --git a/src/private/SideBar.cpp b/src/private/SideBar.cpp index f82a0d56..20e1d0da 100644 --- a/src/private/SideBar.cpp +++ b/src/private/SideBar.cpp @@ -64,8 +64,7 @@ bool SideBar::contains(DockWidgetBase *dw) const void SideBar::onButtonClicked(DockWidgetBase *dw) { - dw->show(); - removeDockWidget(dw); + m_mainWindow->toggleOverlayOnSideBar(dw); } void SideBar::onDockWidgetDestroyed(QObject *dw) @@ -93,6 +92,11 @@ bool SideBar::isEmpty() const return m_dockWidgets.isEmpty(); } +SideBarLocation SideBar::location() const +{ + return m_location; +} + MainWindowBase *SideBar::mainWindow() const { return m_mainWindow; diff --git a/src/private/TitleBar.cpp b/src/private/TitleBar.cpp index c48b918e..5707d5c0 100644 --- a/src/private/TitleBar.cpp +++ b/src/private/TitleBar.cpp @@ -342,7 +342,7 @@ void TitleBar::onAutoHideClicked() if (m_frame) { const auto &dockwidgets = m_frame->dockWidgets(); for (DockWidgetBase *dw : dockwidgets) - dw->minimizeToSideBar(); + dw->moveToSideBar(); } else { // Doesn't happen qWarning() << Q_FUNC_INFO << "Minimize not supported on floating windows"; diff --git a/src/private/widgets/SideBarWidget.cpp b/src/private/widgets/SideBarWidget.cpp index 37a2d67c..e0ddd0e7 100644 --- a/src/private/widgets/SideBarWidget.cpp +++ b/src/private/widgets/SideBarWidget.cpp @@ -37,9 +37,8 @@ void SideBarWidget::addDockWidget_Impl(DockWidgetBase *dw) button->setText(dw->title()); connect(dw, &DockWidgetBase::titleChanged, button, &QToolButton::setText); connect(dw, &QObject::destroyed, button, &QObject::deleteLater); - connect(button, &QAbstractButton::clicked, this, [this, button, dw] { + connect(button, &QAbstractButton::clicked, this, [this, dw] { onButtonClicked(dw); - button->deleteLater(); }); const int count = m_layout->count();