From 541db8e214f247ea0767e098cb186e96e5dc8a39 Mon Sep 17 00:00:00 2001 From: Uwe Kindler Date: Mon, 12 Feb 2024 08:11:56 +0100 Subject: [PATCH] Fixed wrong hiding/showing of dock area title bar buttons when DockAreaHideDisabledButtons flag is enabled --- src/DockAreaTitleBar.cpp | 75 +++++++++++++++++++++++++++++++++------- src/DockAreaTitleBar.h | 31 ++++++++++++++++- src/DockAreaWidget.cpp | 24 +++++++++---- 3 files changed, 111 insertions(+), 19 deletions(-) diff --git a/src/DockAreaTitleBar.cpp b/src/DockAreaTitleBar.cpp index ee050f6..6e7a8d5 100644 --- a/src/DockAreaTitleBar.cpp +++ b/src/DockAreaTitleBar.cpp @@ -179,7 +179,8 @@ void DockAreaTitleBarPrivate::createButtons() QSizePolicy ButtonSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); // Tabs menu button - TabsMenuButton = new CTitleBarButton(testConfigFlag(CDockManager::DockAreaHasTabsMenuButton)); + TabsMenuButton = new CTitleBarButton(testConfigFlag(CDockManager::DockAreaHasTabsMenuButton), + false, TitleBarButtonTabsMenu); TabsMenuButton->setObjectName("tabsMenuButton"); TabsMenuButton->setAutoRaise(true); TabsMenuButton->setPopupMode(QToolButton::InstantPopup); @@ -197,7 +198,8 @@ void DockAreaTitleBarPrivate::createButtons() SLOT(onTabsMenuActionTriggered(QAction*))); // Undock button - UndockButton = new CTitleBarButton(testConfigFlag(CDockManager::DockAreaHasUndockButton)); + UndockButton = new CTitleBarButton(testConfigFlag(CDockManager::DockAreaHasUndockButton), + true, TitleBarButtonUndock); UndockButton->setObjectName("detachGroupButton"); UndockButton->setAutoRaise(true); internal::setToolTip(UndockButton, QObject::tr("Detach Group")); @@ -208,7 +210,8 @@ void DockAreaTitleBarPrivate::createButtons() // AutoHide Button const auto autoHideEnabled = testAutoHideConfigFlag(CDockManager::AutoHideFeatureEnabled); - AutoHideButton = new CTitleBarButton(testAutoHideConfigFlag(CDockManager::DockAreaHasAutoHideButton) && autoHideEnabled); + AutoHideButton = new CTitleBarButton(testAutoHideConfigFlag(CDockManager::DockAreaHasAutoHideButton) && autoHideEnabled, + true, TitleBarButtonAutoHide); AutoHideButton->setObjectName("dockAreaAutoHideButton"); AutoHideButton->setAutoRaise(true); internal::setToolTip(AutoHideButton, _this->titleBarButtonToolTip(TitleBarButtonAutoHide)); @@ -220,7 +223,8 @@ void DockAreaTitleBarPrivate::createButtons() _this->connect(AutoHideButton, SIGNAL(clicked()), SLOT(onAutoHideButtonClicked())); // Minimize button - MinimizeButton = new CTitleBarButton(testAutoHideConfigFlag(CDockManager::AutoHideHasMinimizeButton)); + MinimizeButton = new CTitleBarButton(testAutoHideConfigFlag(CDockManager::AutoHideHasMinimizeButton), + false, TitleBarButtonMinimize); MinimizeButton->setObjectName("dockAreaMinimizeButton"); MinimizeButton->setAutoRaise(true); MinimizeButton->setVisible(false); @@ -231,7 +235,8 @@ void DockAreaTitleBarPrivate::createButtons() _this->connect(MinimizeButton, SIGNAL(clicked()), SLOT(minimizeAutoHideContainer())); // Close button - CloseButton = new CTitleBarButton(testConfigFlag(CDockManager::DockAreaHasCloseButton)); + CloseButton = new CTitleBarButton(testConfigFlag(CDockManager::DockAreaHasCloseButton), + true, TitleBarButtonClose); CloseButton->setObjectName("dockAreaCloseButton"); CloseButton->setAutoRaise(true); internal::setButtonIcon(CloseButton, QStyle::SP_TitleBarCloseButton, ads::DockAreaCloseIcon); @@ -510,7 +515,7 @@ void CDockAreaTitleBar::updateDockWidgetActionsButtons() int InsertIndex = indexOf(d->TabsMenuButton); for (auto Action : Actions) { - auto Button = new CTitleBarButton(true, this); + auto Button = new CTitleBarButton(true, false, TitleBarButtonTabsMenu, this); Button->setDefaultAction(Action); Button->setAutoRaise(true); Button->setPopupMode(QToolButton::InstantPopup); @@ -856,10 +861,25 @@ void CDockAreaTitleBar::showAutoHideControls(bool Show) //============================================================================ -CTitleBarButton::CTitleBarButton(bool showInTitleBar, QWidget* parent) +bool CDockAreaTitleBar::isAutoHide() const +{ + return d->DockArea && d->DockArea->isAutoHide(); +} + + +//============================================================================ +CDockAreaWidget* CDockAreaTitleBar::dockAreaWidget() const +{ + return d->DockArea; +} + + +//============================================================================ +CTitleBarButton::CTitleBarButton(bool showInTitleBar, bool hideWhenDisabled, TitleBarButton ButtonId, QWidget* parent) : tTitleBarButton(parent), ShowInTitleBar(showInTitleBar), - HideWhenDisabled(CDockManager::testConfigFlag(CDockManager::DockAreaHideDisabledButtons)) + HideWhenDisabled(CDockManager::testConfigFlag(CDockManager::DockAreaHideDisabledButtons) && hideWhenDisabled), + TitleBarButtonId(ButtonId) { setFocusPolicy(Qt::NoFocus); } @@ -894,16 +914,47 @@ void CTitleBarButton::setShowInTitleBar(bool Show) //============================================================================ bool CTitleBarButton::event(QEvent *ev) { - if (QEvent::EnabledChange == ev->type() && HideWhenDisabled) + if (QEvent::EnabledChange != ev->type() || !HideWhenDisabled || !ShowInTitleBar) { - // force setVisible() call - // Calling setVisible() directly here doesn't work well when button is expected to be shown first time - QMetaObject::invokeMethod(this, "setVisible", Qt::QueuedConnection, Q_ARG(bool, isEnabled())); + return Super::event(ev); } + bool Show = true; + if (isInAutoHideArea()) + { + switch (TitleBarButtonId) + { + case TitleBarButtonClose: Show = CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideHasCloseButton); break; + case TitleBarButtonUndock: Show = false; break; + default: + break; + } + } + + // force setVisible() call - Calling setVisible() directly here doesn't + // work well when button is expected to be shown first time + QMetaObject::invokeMethod(this, "setVisible", Qt::QueuedConnection, + Q_ARG(bool, isEnabledTo(this->parentWidget()) & Show)); + return Super::event(ev); } + +//============================================================================ +CDockAreaTitleBar* CTitleBarButton::titleBar() const +{ + return qobject_cast(parentWidget()); +} + + +//============================================================================ +bool CTitleBarButton::isInAutoHideArea() const +{ + auto TitleBar = titleBar(); + return TitleBar && TitleBar->isAutoHide(); +} + + //============================================================================ CSpacerWidget::CSpacerWidget(QWidget* Parent /*= 0*/) : Super(Parent) { diff --git a/src/DockAreaTitleBar.h b/src/DockAreaTitleBar.h index 77c8f94..f4179d9 100644 --- a/src/DockAreaTitleBar.h +++ b/src/DockAreaTitleBar.h @@ -43,6 +43,7 @@ class CDockAreaTabBar; class CDockAreaWidget; struct DockAreaTitleBarPrivate; class CElidingLabel; +class CDockAreaTitleBar; using tTitleBarButton = QToolButton; @@ -59,10 +60,12 @@ class CTitleBarButton : public tTitleBarButton private: bool ShowInTitleBar = true; bool HideWhenDisabled = false; + TitleBarButton TitleBarButtonId; public: using Super = tTitleBarButton; - CTitleBarButton(bool ShowInTitleBar = true, QWidget* parent = nullptr); + CTitleBarButton(bool ShowInTitleBar, bool HideWhenDisabled, TitleBarButton ButtonId, + QWidget* parent = nullptr); /** * Adjust this visibility change request with our internal settings: @@ -74,6 +77,22 @@ public: */ void setShowInTitleBar(bool Show); + /** + * Identifier for the title bar button + */ + TitleBarButton buttonId() const {return TitleBarButtonId;} + + /** + * Return the title bar that contains this button + */ + CDockAreaTitleBar* titleBar() const; + + /** + * Returns true, if the button is in a title bar in an auto hide area + */ + bool isInAutoHideArea() const; + + protected: /** * Handle EnabledChanged signal to set button invisible if the configured @@ -169,6 +188,11 @@ public: */ CElidingLabel* autoHideTitleLabel() const; + /** + * Returns the dock area widget that contains this title bar + */ + CDockAreaWidget* dockAreaWidget() const; + /** * Updates the visibility of the dock widget actions in the title bar */ @@ -215,6 +239,11 @@ public: */ void showAutoHideControls(bool Show); + /** + * Returns true, if the auto hide controls are visible + */ + bool isAutoHide() const; + Q_SIGNALS: /** * This signal is emitted if a tab in the tab bar is clicked by the user diff --git a/src/DockAreaWidget.cpp b/src/DockAreaWidget.cpp index b289415..aa6d16d 100644 --- a/src/DockAreaWidget.cpp +++ b/src/DockAreaWidget.cpp @@ -370,10 +370,21 @@ void DockAreaWidgetPrivate::updateTitleBarButtonStates() return; } - TitleBar->button(TitleBarButtonClose)->setEnabled( - _this->features().testFlag(CDockWidget::DockWidgetClosable)); - TitleBar->button(TitleBarButtonUndock)->setEnabled( - _this->features().testFlag(CDockWidget::DockWidgetFloatable)); + if (_this->isAutoHide()) + { + if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideHasCloseButton)) + { + TitleBar->button(TitleBarButtonClose)->setEnabled( + _this->features().testFlag(CDockWidget::DockWidgetClosable)); + } + } + else + { + TitleBar->button(TitleBarButtonUndock)->setEnabled( + _this->features().testFlag(CDockWidget::DockWidgetFloatable)); + TitleBar->button(TitleBarButtonClose)->setEnabled( + _this->features().testFlag(CDockWidget::DockWidgetClosable)); + } TitleBar->button(TitleBarButtonAutoHide)->setEnabled( _this->features().testFlag(CDockWidget::DockWidgetPinnable)); TitleBar->updateDockWidgetActionsButtons(); @@ -393,7 +404,7 @@ void DockAreaWidgetPrivate::updateTitleBarButtonVisibility(bool IsTopLevel) bool IsAutoHide = _this->isAutoHide(); if (IsAutoHide) { - bool ShowCloseButton = CDockManager::autoHideConfigFlags().testFlag(CDockManager::AutoHideHasCloseButton); + bool ShowCloseButton = CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideHasCloseButton); TitleBar->button(TitleBarButtonClose)->setVisible(ShowCloseButton); TitleBar->button(TitleBarButtonAutoHide)->setVisible(true); TitleBar->button(TitleBarButtonUndock)->setVisible(false); @@ -410,7 +421,8 @@ void DockAreaWidgetPrivate::updateTitleBarButtonVisibility(bool IsTopLevel) else { TitleBar->button(TitleBarButtonClose)->setVisible(true); - TitleBar->button(TitleBarButtonAutoHide)->setVisible(true); + bool ShowAutoHideButton = CDockManager::testAutoHideConfigFlag(CDockManager::DockAreaHasAutoHideButton); + TitleBar->button(TitleBarButtonAutoHide)->setVisible(ShowAutoHideButton); TitleBar->button(TitleBarButtonUndock)->setVisible(true); TitleBar->button(TitleBarButtonTabsMenu)->setVisible(true); }