FancyMainWindow: Remove auto-hide title bars functionality

This added complexity with the hovering to get the title bars shown, and
discoverability issues with the action in the views menu to show all
title bars, and the issue that some docks then had double titles,
because we wanted some title to be shown even if the title bar is
hidden.

Instead only show the dock control buttons only on hover, which already
removes a lot visual clutter that was the main reason for the
whole exercise.

One issue is that the title is now uselessly repeated for tabbed docks.
Another is that the title bar style is ugly and not very compatible to
what we otherwise have.

Change-Id: Ib093e0a3f2f07ece74b9055015c5523994032c5a
Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
This commit is contained in:
Eike Ziller
2023-10-31 10:22:15 +01:00
parent f84e3074cd
commit d2500dc77b
7 changed files with 39 additions and 180 deletions

View File

@@ -21,7 +21,6 @@
#include <QStyleOption>
#include <QTimer>
static const char AutoHideTitleBarsKey[] = "AutoHideTitleBars";
static const char ShowCentralWidgetKey[] = "ShowCentralWidget";
static const char StateKey[] = "State";
@@ -41,9 +40,7 @@ struct FancyMainWindowPrivate
bool m_handleDockVisibilityChanges;
QAction m_showCentralWidget;
QAction m_menuSeparator1;
QAction m_menuSeparator2;
QAction m_resetLayoutAction;
QAction m_autoHideTitleBars;
};
class DockWidget : public QDockWidget
@@ -51,19 +48,11 @@ class DockWidget : public QDockWidget
public:
DockWidget(QWidget *inner, FancyMainWindow *parent, bool immutable = false);
bool eventFilter(QObject *, QEvent *event) override;
void enterEvent(QEnterEvent *event) override;
void leaveEvent(QEvent *event) override;
void handleMouseTimeout();
void handleToplevelChanged(bool floating);
FancyMainWindow *q;
private:
QPoint m_startPos;
TitleBarWidget *m_titleBar;
QTimer m_timer;
bool m_immutable = false;
};
// Stolen from QDockWidgetTitleButton
@@ -130,7 +119,8 @@ class TitleBarWidget : public QWidget
{
public:
TitleBarWidget(DockWidget *parent, const QStyleOptionDockWidget &opt)
: QWidget(parent), q(parent), m_active(true)
: QWidget(parent)
, q(parent)
{
m_titleLabel = new QLabel(this);
@@ -147,8 +137,6 @@ public:
m_closeButton->setAccessibleDescription(QDockWidget::tr("Closes the dock widget"));
#endif
setActive(false);
const int minWidth = 10;
const int maxWidth = 10000;
const int inactiveHeight = 0;
@@ -170,16 +158,23 @@ public:
setProperty("managed_titlebar", 1);
connect(parent, &QDockWidget::featuresChanged, this, [this, parent] {
m_closeButton->setVisible(parent->features().testFlag(QDockWidget::DockWidgetClosable));
m_floatButton->setVisible(parent->features().testFlag(QDockWidget::DockWidgetFloatable));
});
m_closeButton->setVisible(false);
m_floatButton->setVisible(false);
connect(parent, &QDockWidget::featuresChanged, this, [this] { updateChildren(); });
}
void enterEvent(QEnterEvent *event) override
{
setActive(true);
m_hovered = true;
QWidget::enterEvent(event);
updateChildren();
}
void leaveEvent(QEvent *event) override
{
m_hovered = false;
QWidget::leaveEvent(event);
updateChildren();
}
void setActive(bool on)
@@ -190,35 +185,29 @@ public:
void updateChildren()
{
bool clickable = isClickable();
m_titleLabel->setVisible(clickable);
m_floatButton->setVisible(clickable
m_titleLabel->setVisible(m_active);
m_floatButton->setVisible(m_active && m_hovered
&& q->features().testFlag(QDockWidget::DockWidgetFloatable));
m_closeButton->setVisible(clickable
m_closeButton->setVisible(m_active && m_hovered
&& q->features().testFlag(QDockWidget::DockWidgetClosable));
}
bool isClickable() const
{
return m_active || !q->q->autoHideTitleBars();
}
QSize sizeHint() const override
{
ensurePolished();
return isClickable() ? m_maximumActiveSize : m_maximumInactiveSize;
return m_active ? m_maximumActiveSize : m_maximumInactiveSize;
}
QSize minimumSizeHint() const override
{
ensurePolished();
return isClickable() ? m_minimumActiveSize : m_minimumInactiveSize;
return m_active ? m_minimumActiveSize : m_minimumInactiveSize;
}
private:
DockWidget *q;
bool m_active;
bool m_active = true;
bool m_hovered = false;
QSize m_minimumActiveSize;
QSize m_maximumActiveSize;
QSize m_minimumInactiveSize;
@@ -231,7 +220,8 @@ public:
};
DockWidget::DockWidget(QWidget *inner, FancyMainWindow *parent, bool immutable)
: QDockWidget(parent), q(parent), m_immutable(immutable)
: QDockWidget(parent)
, q(parent)
{
setWidget(inner);
setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable);
@@ -249,14 +239,11 @@ DockWidget::DockWidget(QWidget *inner, FancyMainWindow *parent, bool immutable)
m_titleBar->m_titleLabel->setText(title);
setTitleBarWidget(m_titleBar);
if (immutable)
if (immutable) {
m_titleBar->setActive(false);
return;
}
m_timer.setSingleShot(true);
m_timer.setInterval(500);
connect(&m_timer, &QTimer::timeout, this, &DockWidget::handleMouseTimeout);
connect(this, &QDockWidget::topLevelChanged, this, &DockWidget::handleToplevelChanged);
connect(toggleViewAction(), &QAction::triggered, this, [this] {
if (isVisible())
raise();
@@ -271,54 +258,6 @@ DockWidget::DockWidget(QWidget *inner, FancyMainWindow *parent, bool immutable)
origCloseButton, &QAbstractButton::clicked);
}
bool DockWidget::eventFilter(QObject *, QEvent *event)
{
if (!m_immutable && event->type() == QEvent::MouseMove && q->autoHideTitleBars()) {
auto me = static_cast<QMouseEvent *>(event);
int y = me->pos().y();
int x = me->pos().x();
int h = qMin(8, m_titleBar->m_floatButton->height());
if (!isFloating() && widget() && 0 <= x && x < widget()->width() && 0 <= y && y <= h) {
m_timer.start();
m_startPos = mapToGlobal(me->pos());
}
}
return false;
}
void DockWidget::enterEvent(QEnterEvent *event)
{
if (!m_immutable)
QApplication::instance()->installEventFilter(this);
QDockWidget::enterEvent(event);
}
void DockWidget::leaveEvent(QEvent *event)
{
if (!m_immutable) {
if (!isFloating()) {
m_timer.stop();
m_titleBar->setActive(false);
}
QApplication::instance()->removeEventFilter(this);
}
QDockWidget::leaveEvent(event);
}
void DockWidget::handleMouseTimeout()
{
QPoint dist = m_startPos - QCursor::pos();
if (!isFloating() && dist.manhattanLength() < 4)
m_titleBar->setActive(true);
}
void DockWidget::handleToplevelChanged(bool floating)
{
m_titleBar->setActive(floating);
}
/*!
\class Utils::FancyMainWindow
\inmodule QtCreator
@@ -331,30 +270,17 @@ void DockWidget::handleToplevelChanged(bool floating)
in a Window-menu.
*/
FancyMainWindowPrivate::FancyMainWindowPrivate(FancyMainWindow *parent) :
q(parent),
m_handleDockVisibilityChanges(true),
m_showCentralWidget(Tr::tr("Central Widget"), nullptr),
m_menuSeparator1(nullptr),
m_menuSeparator2(nullptr),
m_resetLayoutAction(Tr::tr("Reset to Default Layout"), nullptr),
m_autoHideTitleBars(Tr::tr("Automatically Hide View Title Bars"), nullptr)
FancyMainWindowPrivate::FancyMainWindowPrivate(FancyMainWindow *parent)
: q(parent)
, m_handleDockVisibilityChanges(true)
, m_showCentralWidget(Tr::tr("Central Widget"), nullptr)
, m_menuSeparator1(nullptr)
, m_resetLayoutAction(Tr::tr("Reset to Default Layout"), nullptr)
{
m_showCentralWidget.setCheckable(true);
m_showCentralWidget.setChecked(true);
m_menuSeparator1.setSeparator(true);
m_menuSeparator2.setSeparator(true);
m_autoHideTitleBars.setCheckable(true);
m_autoHideTitleBars.setChecked(true);
QObject::connect(&m_autoHideTitleBars, &QAction::toggled, q, [this](bool) {
for (QDockWidget *dock : q->dockWidgets()) {
if (auto titleBar = dynamic_cast<TitleBarWidget *>(dock->titleBarWidget()))
titleBar->updateChildren();
}
});
QObject::connect(&m_showCentralWidget, &QAction::toggled, q, [this](bool visible) {
if (q->centralWidget())
@@ -463,7 +389,6 @@ QHash<Key, QVariant> FancyMainWindow::saveSettings() const
{
QHash<Key, QVariant> settings;
settings.insert(StateKey, saveState(settingsVersion));
settings.insert(AutoHideTitleBarsKey, d->m_autoHideTitleBars.isChecked());
settings.insert(ShowCentralWidgetKey, d->m_showCentralWidget.isChecked());
for (QDockWidget *dockWidget : dockWidgets()) {
settings.insert(keyFromString(dockWidget->objectName()),
@@ -479,8 +404,6 @@ void FancyMainWindow::restoreSettings(const QHash<Key, QVariant> &settings)
if (!restoreState(ba, settingsVersion))
qWarning() << "Restoring the state of dock widgets failed.";
}
bool on = settings.value(AutoHideTitleBarsKey, true).toBool();
d->m_autoHideTitleBars.setChecked(on);
d->m_showCentralWidget.setChecked(settings.value(ShowCentralWidgetKey, true).toBool());
for (QDockWidget *widget : dockWidgets()) {
widget->setProperty(dockWidgetActiveState,
@@ -509,16 +432,6 @@ const QList<QDockWidget *> FancyMainWindow::dockWidgets() const
return result;
}
bool FancyMainWindow::autoHideTitleBars() const
{
return d->m_autoHideTitleBars.isChecked();
}
void FancyMainWindow::setAutoHideTitleBars(bool on)
{
d->m_autoHideTitleBars.setChecked(on);
}
bool FancyMainWindow::isCentralWidgetShown() const
{
return d->m_showCentralWidget.isChecked();
@@ -551,8 +464,6 @@ void FancyMainWindow::addDockActionsToMenu(QMenu *menu)
menu->addAction(action);
menu->addAction(&d->m_showCentralWidget);
menu->addAction(&d->m_menuSeparator1);
menu->addAction(&d->m_autoHideTitleBars);
menu->addAction(&d->m_menuSeparator2);
menu->addAction(&d->m_resetLayoutAction);
}
@@ -561,16 +472,6 @@ QAction *FancyMainWindow::menuSeparator1() const
return &d->m_menuSeparator1;
}
QAction *FancyMainWindow::autoHideTitleBarsAction() const
{
return &d->m_autoHideTitleBars;
}
QAction *FancyMainWindow::menuSeparator2() const
{
return &d->m_menuSeparator2;
}
QAction *FancyMainWindow::resetLayoutAction() const
{
return &d->m_resetLayoutAction;
@@ -586,9 +487,7 @@ void FancyMainWindow::setDockActionsVisible(bool v)
for (const QDockWidget *dockWidget : dockWidgets())
dockWidget->toggleViewAction()->setVisible(v);
d->m_showCentralWidget.setVisible(v);
d->m_autoHideTitleBars.setVisible(v);
d->m_menuSeparator1.setVisible(v);
d->m_menuSeparator2.setVisible(v);
d->m_resetLayoutAction.setVisible(v);
}

View File

@@ -36,15 +36,10 @@ public:
// Additional context menu actions
QAction *menuSeparator1() const;
QAction *autoHideTitleBarsAction() const;
QAction *menuSeparator2() const;
QAction *resetLayoutAction() const;
QAction *showCentralWidgetAction() const;
void addDockActionsToMenu(QMenu *menu);
bool autoHideTitleBars() const;
void setAutoHideTitleBars(bool on);
bool isCentralWidgetShown() const;
void showCentralWidget(bool on);

View File

@@ -502,7 +502,6 @@ EditorWidget::EditorWidget(const QSharedPointer<JsonSettingsDocument> &document,
, m_actionHandler(actionHandler)
{
setContextMenuPolicy(Qt::NoContextMenu);
setAutoHideTitleBars(false);
setDockNestingEnabled(true);
setDocumentMode(true);
setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::TabPosition::South);
@@ -541,13 +540,12 @@ void EditorWidget::focusInEvent(QFocusEvent *event)
void EditorWidget::addCompiler(const std::shared_ptr<SourceSettings> &sourceSettings,
const std::shared_ptr<CompilerSettings> &compilerSettings,
int idx,
QDockWidget *parentDockWidget)
int idx)
{
auto compiler = new CompilerWidget(sourceSettings, compilerSettings, m_undoStack);
compiler->setWindowTitle("Compiler #" + QString::number(idx));
compiler->setObjectName("compiler_" + QString::number(idx));
QDockWidget *dockWidget = addDockForWidget(compiler, parentDockWidget);
QDockWidget *dockWidget = addDockForWidget(compiler);
dockWidget->setFeatures(QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable);
addDockWidget(Qt::RightDockWidgetArea, dockWidget);
m_compilerWidgets.append(dockWidget);
@@ -607,18 +605,15 @@ void EditorWidget::addSourceEditor(const std::shared_ptr<SourceSettings> &source
addDockWidget(Qt::LeftDockWidgetArea, dockWidget);
sourceSettings->compilers.forEachItem<CompilerSettings>(
[this, sourceSettings, dockWidget](const std::shared_ptr<CompilerSettings> &compilerSettings,
int idx) {
addCompiler(sourceSettings, compilerSettings, idx + 1, dockWidget);
[this, sourceSettings](const std::shared_ptr<CompilerSettings> &compilerSettings, int idx) {
addCompiler(sourceSettings, compilerSettings, idx + 1);
});
sourceSettings->compilers.setItemAddedCallback<CompilerSettings>(
[this, sourceSettings, dockWidget](
const std::shared_ptr<CompilerSettings> &compilerSettings) {
[this, sourceSettings](const std::shared_ptr<CompilerSettings> &compilerSettings) {
addCompiler(sourceSettings->shared_from_this(),
compilerSettings,
sourceSettings->compilers.size(),
dockWidget);
sourceSettings->compilers.size());
});
sourceSettings->compilers.setItemRemovedCallback<CompilerSettings>(

View File

@@ -215,8 +215,7 @@ protected:
void addCompiler(const std::shared_ptr<SourceSettings> &sourceSettings,
const std::shared_ptr<CompilerSettings> &compilerSettings,
int idx,
QDockWidget *parentDockWidget);
int idx);
void addSourceEditor(const std::shared_ptr<SourceSettings> &sourceSettings);
void removeSourceEditor(const std::shared_ptr<SourceSettings> &sourceSettings);

View File

@@ -49,7 +49,6 @@ namespace Utils {
const char LAST_PERSPECTIVE_KEY[] = "LastPerspective";
const char MAINWINDOW_KEY[] = "Debugger.MainWindow";
const char AUTOHIDE_TITLEBARS_KEY[] = "AutoHideTitleBars";
const char SHOW_CENTRALWIDGET_KEY[] = "ShowCentralWidget";
const char STATE_KEY[] = "State"; // Up to 4.10
const char STATE_KEY2[] = "State2"; // From 4.11 on
@@ -286,14 +285,6 @@ DebuggerMainWindow::DebuggerMainWindow()
"Debugger.Views.Separator1", debugcontext);
cmd->setAttribute(Command::CA_Hide);
viewsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE);
cmd = ActionManager::registerAction(autoHideTitleBarsAction(),
"Debugger.Views.AutoHideTitleBars", debugcontext);
cmd->setAttribute(Command::CA_Hide);
viewsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE);
cmd = ActionManager::registerAction(menuSeparator2(),
"Debugger.Views.Separator2", debugcontext);
cmd->setAttribute(Command::CA_Hide);
viewsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE);
cmd = ActionManager::registerAction(resetLayoutAction(),
"Debugger.Views.ResetSimple", debugcontext);
cmd->setAttribute(Command::CA_Hide);
@@ -458,7 +449,6 @@ void DebuggerMainWindow::restorePersistentSettings()
d->m_lastTypePerspectiveStates.insert(type, state);
}
setAutoHideTitleBars(settings->value(AUTOHIDE_TITLEBARS_KEY, true).toBool());
showCentralWidget(settings->value(SHOW_CENTRALWIDGET_KEY, true).toBool());
d->m_persistentChangedDocks = Utils::toSet(settings->value(CHANGED_DOCK_KEY).toStringList());
settings->endGroup();
@@ -493,7 +483,6 @@ void DebuggerMainWindow::savePersistentSettings() const
settings->beginGroup(MAINWINDOW_KEY);
settings->setValue(CHANGED_DOCK_KEY, QStringList(Utils::toList(d->m_persistentChangedDocks)));
settings->setValue(STATE_KEY2, states);
settings->setValue(AUTOHIDE_TITLEBARS_KEY, autoHideTitleBars());
settings->setValue(SHOW_CENTRALWIDGET_KEY, isCentralWidgetShown());
settings->endGroup();

View File

@@ -712,16 +712,6 @@ public:
// return isDebuggableScript;
};
static void addLabel(QWidget *widget, const QString &text)
{
auto vbox = qobject_cast<QVBoxLayout *>(widget->layout());
QTC_ASSERT(vbox, return);
auto label = new QLabel(widget);
label->setText(text);
label->setContentsMargins(6, 6, 6, 6);
vbox->insertWidget(0, label);
};
void DebuggerPluginPrivate::addFontSizeAdaptation(QWidget *widget)
{
QObject::connect(TextEditorSettings::instance(),
@@ -759,7 +749,6 @@ QWidget *DebuggerPluginPrivate::createBreakpointManagerWindow(BaseTreeView *brea
auto breakpointManagerWindow = addSearch(breakpointManagerView);
breakpointManagerWindow->setWindowTitle(title);
breakpointManagerWindow->setObjectName(objectName);
addLabel(breakpointManagerWindow, breakpointManagerWindow->windowTitle());
addFontSizeAdaptation(breakpointManagerWindow);
return breakpointManagerWindow;
}
@@ -785,7 +774,6 @@ QWidget *DebuggerPluginPrivate::createEngineManagerWindow(BaseTreeView *engineMa
auto engineManagerWindow = addSearch(engineManagerView);
engineManagerWindow->setWindowTitle(title);
engineManagerWindow->setObjectName(objectName);
addLabel(engineManagerWindow, engineManagerWindow->windowTitle());
addFontSizeAdaptation(engineManagerWindow);
return engineManagerWindow;
}

View File

@@ -338,12 +338,6 @@ void FormEditorData::setupViewActions()
Command *cmd = addToolAction(m_editorWidget->menuSeparator1(), m_contexts, "FormEditor.SeparatorLock", viewMenu);
cmd->setAttribute(Command::CA_Hide);
cmd = addToolAction(m_editorWidget->autoHideTitleBarsAction(), m_contexts, "FormEditor.Locked", viewMenu);
cmd->setAttribute(Command::CA_Hide);
cmd = addToolAction(m_editorWidget->menuSeparator2(), m_contexts, "FormEditor.SeparatorReset", viewMenu);
cmd->setAttribute(Command::CA_Hide);
cmd = addToolAction(m_editorWidget->resetLayoutAction(), m_contexts, "FormEditor.ResetToDefaultLayout", viewMenu);
QObject::connect(m_editorWidget, &EditorWidget::resetLayout,