refactor: Decouple moveToSideBar from overlaying

overlaying just shows/hides the overlay, and not requires
the dock widget was added to the sidebar before
This commit is contained in:
Sergio Martins
2020-09-20 13:44:04 +01:00
parent c85873c6ce
commit 2659ddb76b
7 changed files with 45 additions and 33 deletions

View File

@@ -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()

View File

@@ -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

View File

@@ -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)

View File

@@ -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();

View File

@@ -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;

View File

@@ -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";

View File

@@ -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();