Use sidebar buttons for hiding/showing dock areas

So far, if a mode includes navigation widget placeholders, these are
used for the sidebar toggle buttons, otherwise the buttons are disabled.

Now, if a mode does not include navigation widget placeholders, but the
mode has a FancyMainWindow attached, use the buttons to hide or show the
corresponding dock widget area (left or right).

Since QMainWindow does not really support "hiding a dock widget area",
the FancyMainWindow needs to track that state manually, by tracking the
dock widgets that were visible before "hiding the dock widget area".

Also, if a dock widget is dragged into a "hidden" area, or a widget is
made visible or "unfloated" into that area, show the other widgets in the
area again as well, "unhiding" the area.

Since the mode widgets that have a mainwindow somewhere usually wrap
that into a splitter for the output panes, and the Design mode is
actually a stack widget, IMode needs another method that returns the
appropriate FancyMainWindow if available.

The patch implements this for Widget Designer.

Change-Id: I03531f4d5130c846ff5d65831b1c9be210e1c561
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Eike Ziller
2023-11-24 09:26:31 +01:00
parent 09e94ae4ac
commit a35deb1532
10 changed files with 230 additions and 47 deletions

View File

@@ -7,16 +7,22 @@
#include "coreplugintr.h"
#include "icontext.h"
#include "icore.h"
#include "imode.h"
#include "inavigationwidgetfactory.h"
#include "modemanager.h"
#include "navigationsubwidget.h"
#include <utils/algorithm.h>
#include <utils/fancymainwindow.h>
#include <utils/qtcassert.h>
#include <utils/utilsicons.h>
#include <aggregation/aggregate.h>
#include <QAction>
#include <QCoreApplication>
#include <QDebug>
#include <QDockWidget>
#include <QHBoxLayout>
#include <QResizeEvent>
#include <QStandardItemModel>
@@ -107,7 +113,7 @@ void NavigationWidgetPlaceHolder::currentModeAboutToChange(Id mode)
setCurrent(m_side, nullptr);
navigationWidget->setParent(nullptr);
navigationWidget->hide();
navigationWidget->placeHolderChanged(nullptr);
navigationWidget->placeHolderChanged();
}
if (m_mode == mode) {
@@ -118,7 +124,7 @@ void NavigationWidgetPlaceHolder::currentModeAboutToChange(Id mode)
applyStoredSize();
setVisible(navigationWidget->isShown());
navigationWidget->placeHolderChanged(this);
navigationWidget->placeHolderChanged();
}
}
@@ -142,6 +148,7 @@ struct NavigationWidgetPrivate
QHash<QAction *, Id> m_actionMap;
QHash<Id, Command *> m_commandMap;
QStandardItemModel *m_factoryModel;
FancyMainWindow *m_mainWindow = nullptr;
bool m_shown;
int m_width;
@@ -185,6 +192,11 @@ NavigationWidget::NavigationWidget(QAction *toggleSideBarAction, Side side) :
NavigationWidgetPrivate::s_instanceLeft = this;
else
NavigationWidgetPrivate::s_instanceRight = this;
connect(ModeManager::instance(),
&ModeManager::currentModeChanged,
this,
&NavigationWidget::updateMode);
}
NavigationWidget::~NavigationWidget()
@@ -243,7 +255,7 @@ void NavigationWidget::setFactories(const QList<INavigationWidgetFactory *> &fac
d->m_factoryModel->appendRow(newRow);
}
d->m_factoryModel->sort(0);
updateToggleText();
updateToggleAction();
}
Key NavigationWidget::settingsGroup() const
@@ -261,23 +273,41 @@ QAbstractItemModel *NavigationWidget::factoryModel() const
return d->m_factoryModel;
}
void NavigationWidget::updateToggleText()
void NavigationWidget::updateMode()
{
bool haveData = d->m_factoryModel->rowCount();
d->m_toggleSideBarAction->setVisible(haveData);
d->m_toggleSideBarAction->setEnabled(haveData && NavigationWidgetPlaceHolder::current(d->m_side));
IMode *currentMode = ModeManager::currentMode();
FancyMainWindow *mainWindow = currentMode ? currentMode->mainWindow() : nullptr;
if (d->m_mainWindow == mainWindow)
return;
if (d->m_mainWindow)
disconnect(d->m_mainWindow, nullptr, this, nullptr);
d->m_mainWindow = mainWindow;
if (d->m_mainWindow)
connect(d->m_mainWindow,
&FancyMainWindow::dockWidgetsChanged,
this,
&NavigationWidget::updateToggleAction);
updateToggleAction();
}
const char *trToolTip = d->m_side == Side::Left
? (isShown() ? Constants::TR_HIDE_LEFT_SIDEBAR : Constants::TR_SHOW_LEFT_SIDEBAR)
: (isShown() ? Constants::TR_HIDE_RIGHT_SIDEBAR : Constants::TR_SHOW_RIGHT_SIDEBAR);
void NavigationWidget::updateToggleAction()
{
d->m_toggleSideBarAction->setVisible(toggleActionVisible());
d->m_toggleSideBarAction->setEnabled(toggleActionEnabled());
d->m_toggleSideBarAction->setChecked(toggleActionChecked());
const char *trToolTip = d->m_side == Side::Left ? (d->m_toggleSideBarAction->isChecked()
? Constants::TR_HIDE_LEFT_SIDEBAR
: Constants::TR_SHOW_LEFT_SIDEBAR)
: (d->m_toggleSideBarAction->isChecked()
? Constants::TR_HIDE_RIGHT_SIDEBAR
: Constants::TR_SHOW_RIGHT_SIDEBAR);
d->m_toggleSideBarAction->setToolTip(Tr::tr(trToolTip));
}
void NavigationWidget::placeHolderChanged(NavigationWidgetPlaceHolder *holder)
void NavigationWidget::placeHolderChanged()
{
d->m_toggleSideBarAction->setChecked(holder && isShown());
updateToggleText();
updateToggleAction();
}
void NavigationWidget::resizeEvent(QResizeEvent *re)
@@ -376,6 +406,37 @@ void NavigationWidget::closeSubWidget(Internal::NavigationSubWidget *subWidget)
}
}
bool NavigationWidget::toggleActionVisible() const
{
const bool haveData = d->m_factoryModel->rowCount();
return haveData || d->m_mainWindow;
}
static Qt::DockWidgetArea dockAreaForSide(Side side)
{
return side == Side::Left ? Qt::LeftDockWidgetArea : Qt::RightDockWidgetArea;
}
bool NavigationWidget::toggleActionEnabled() const
{
const bool haveData = d->m_factoryModel->rowCount();
if (haveData && NavigationWidgetPlaceHolder::current(d->m_side))
return true;
if (!d->m_mainWindow)
return false;
return d->m_mainWindow->isDockAreaAvailable(dockAreaForSide(d->m_side));
}
bool NavigationWidget::toggleActionChecked() const
{
const bool haveData = d->m_factoryModel->rowCount();
if (haveData && NavigationWidgetPlaceHolder::current(d->m_side))
return d->m_shown;
if (!d->m_mainWindow)
return false;
return d->m_mainWindow->isDockAreaVisible(dockAreaForSide(d->m_side));
}
static QString defaultFirstView(Side side)
{
return side == Side::Left ? QString("Projects") : QString("Outline");
@@ -498,19 +559,22 @@ void NavigationWidget::closeSubWidgets()
void NavigationWidget::setShown(bool b)
{
if (d->m_shown == b)
return;
bool haveData = d->m_factoryModel->rowCount();
d->m_shown = b;
NavigationWidgetPlaceHolder *current = NavigationWidgetPlaceHolder::current(d->m_side);
if (current) {
bool visible = d->m_shown && haveData;
current->setVisible(visible);
d->m_toggleSideBarAction->setChecked(visible);
if (!current && d->m_mainWindow) {
// mode without placeholder but with main window
d->m_mainWindow->setDockAreaVisible(dockAreaForSide(d->m_side), b);
} else {
d->m_toggleSideBarAction->setChecked(false);
// mode with navigation widget placeholder or e.g. during startup/settings restore
if (d->m_shown == b)
return;
const bool haveData = d->m_factoryModel->rowCount();
d->m_shown = b;
if (current) {
const bool visible = d->m_shown && haveData;
current->setVisible(visible);
}
}
updateToggleText();
updateToggleAction();
}
bool NavigationWidget::isShown() const