From b8ed70fa334f4644bf6a4f5707750a961f4c5ed9 Mon Sep 17 00:00:00 2001 From: mvidelgauz Date: Wed, 5 Feb 2020 09:04:27 +0200 Subject: [PATCH] Added DockAreaHideDisabledButtons configuration flag (#110) * CInvisibleButton generalized to CTitleBarButton to serve more purposes * Disabled buttons are hidden if CDockManager::DockAreaHideDisabledButtons set to true --- demo/MainWindow.cpp | 5 ++ src/DockAreaTitleBar.cpp | 186 ++++++++++++++++++++------------------- src/DockManager.cpp | 6 ++ src/DockManager.h | 6 ++ 4 files changed, 113 insertions(+), 90 deletions(-) diff --git a/demo/MainWindow.cpp b/demo/MainWindow.cpp index 8abd4db..864ad14 100644 --- a/demo/MainWindow.cpp +++ b/demo/MainWindow.cpp @@ -276,6 +276,8 @@ void MainWindowPrivate::createContent() QMenu* ViewMenu = ui.menuView; auto DockWidget = createCalendarDockWidget(ViewMenu); DockWidget->setFeature(ads::CDockWidget::DockWidgetClosable, false); + DockWidget->setFeature(ads::CDockWidget::DockWidgetMovable, false); + DockWidget->setFeature(ads::CDockWidget::DockWidgetFloatable, false); auto SpecialDockArea = DockManager->addDockWidget(ads::LeftDockWidgetArea, DockWidget); // For this Special Dock Area we want to avoid dropping on the center of it (i.e. we don't want this widget to be ever tabbified): @@ -432,6 +434,9 @@ CMainWindow::CMainWindow(QWidget *parent) : // uncomment the following line if you don't want tabs menu button on DockArea's title bar //CDockManager::setConfigFlag(CDockManager::DockAreaHasTabsMenuButton, false); + // uncomment the following line if you don't want disabled buttons to appear on DockArea's title bar + //CDockManager::setConfigFlag(CDockManager::DockAreaHideDisabledButtons, true); + // Now create the dock manager and its content d->DockManager = new CDockManager(this); diff --git a/src/DockAreaTitleBar.cpp b/src/DockAreaTitleBar.cpp index 9db076c..2884b45 100644 --- a/src/DockAreaTitleBar.cpp +++ b/src/DockAreaTitleBar.cpp @@ -55,28 +55,6 @@ namespace ads { using tTitleBarButton = QToolButton; -/** - * Some kind of dummy button that is used if certain buttons are hidden - * by dock manager config flags (i.e CDockManager::DockAreaHasCloseButton is - * disabled) - */ -class CInvisibleButton : public tTitleBarButton -{ -public: - CInvisibleButton(QWidget* parent = nullptr) - : tTitleBarButton(parent) - { - this->hide(); - } - - - virtual void setVisible(bool visible) override - { - Q_UNUSED(visible); - tTitleBarButton::setVisible(false); - } -}; - /** * Private data class of CDockAreaTitleBar class (pimpl) @@ -119,7 +97,7 @@ struct DockAreaTitleBarPrivate /** * Returns true if the given config flag is set */ - bool testConfigFlag(CDockManager::eConfigFlag Flag) const + static bool testConfigFlag(CDockManager::eConfigFlag Flag) { return CDockManager::configFlags().testFlag(Flag); } @@ -154,6 +132,55 @@ struct DockAreaTitleBarPrivate };// struct DockAreaTitleBarPrivate +/** + * Title bar button of a dock area that customizes tTitleBarButton appearance/behaviour + * according to various config flags such as: + * CDockManager::DockAreaHas_xxx_Button - if set to 'false' keeps the button always invisible + * CDockManager::DockAreaHideDisabledButtons - if set to 'true' hides button when it is disabled + */ +class CTitleBarButton : public tTitleBarButton +{ + bool Visible = true; + bool HideWhenDisabled = false; +public: + CTitleBarButton(bool visible = true, QWidget* parent = nullptr) + : tTitleBarButton(parent) + , Visible(visible) + , HideWhenDisabled(DockAreaTitleBarPrivate::testConfigFlag(CDockManager::DockAreaHideDisabledButtons)) + { + //this->setVisible(Visible); // this causes flickering and seems not to be needed TODO: investigate further and in case it IS needed fix flickering + } + + + virtual void setVisible(bool visible) override + { + // Adjust this visibility change request with our internal settings: + + // 'visible' can stay 'true' if and only if this button is configured to generaly visible: + visible = visible && this->Visible; + + // 'visible' can stay 'true' unless: this button is configured to be invisible when it is disabled and it is currently disabled: + if(visible && HideWhenDisabled) + { + visible = isEnabled(); + } + + tTitleBarButton::setVisible(visible); + } + +protected: + bool event(QEvent *ev) override + { + if(QEvent::EnabledChange == ev->type() && HideWhenDisabled) + { + // force setVisible() call + setVisible(isEnabled()); + } + + return tTitleBarButton::event(ev);; + } +}; + //============================================================================ DockAreaTitleBarPrivate::DockAreaTitleBarPrivate(CDockAreaTitleBar* _public) : @@ -168,79 +195,58 @@ void DockAreaTitleBarPrivate::createButtons() { QSizePolicy ButtonSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); - if (testConfigFlag(CDockManager::DockAreaHasTabsMenuButton)) + // Tabs menu button + TabsMenuButton = new CTitleBarButton(testConfigFlag(CDockManager::DockAreaHasTabsMenuButton)); + TabsMenuButton->setObjectName("tabsMenuButton"); + TabsMenuButton->setAutoRaise(true); + TabsMenuButton->setPopupMode(QToolButton::InstantPopup); + setTitleBarButtonIcon(TabsMenuButton, QStyle::SP_TitleBarUnshadeButton, ads::DockAreaMenuIcon); + QMenu* TabsMenu = new QMenu(TabsMenuButton); +#ifndef QT_NO_TOOLTIP + TabsMenu->setToolTipsVisible(true); +#endif + _this->connect(TabsMenu, SIGNAL(aboutToShow()), SLOT(onTabsMenuAboutToShow())); + TabsMenuButton->setMenu(TabsMenu); +#ifndef QT_NO_TOOLTIP + TabsMenuButton->setToolTip(QObject::tr("List all tabs")); +#endif + TabsMenuButton->setSizePolicy(ButtonSizePolicy); + TopLayout->addWidget(TabsMenuButton, 0); + _this->connect(TabsMenuButton->menu(), SIGNAL(triggered(QAction*)), + SLOT(onTabsMenuActionTriggered(QAction*))); + + + // Undock button + UndockButton = new CTitleBarButton(testConfigFlag(CDockManager::DockAreaHasUndockButton)); + UndockButton->setObjectName("undockButton"); + UndockButton->setAutoRaise(true); +#ifndef QT_NO_TOOLTIP + UndockButton->setToolTip(QObject::tr("Detach Group")); +#endif + setTitleBarButtonIcon(UndockButton, QStyle::SP_TitleBarNormalButton, ads::DockAreaUndockIcon); + UndockButton->setSizePolicy(ButtonSizePolicy); + TopLayout->addWidget(UndockButton, 0); + _this->connect(UndockButton, SIGNAL(clicked()), SLOT(onUndockButtonClicked())); + + // Close button + CloseButton = new CTitleBarButton(testConfigFlag(CDockManager::DockAreaHasCloseButton)); + CloseButton->setObjectName("closeButton"); + CloseButton->setAutoRaise(true); + setTitleBarButtonIcon(CloseButton, QStyle::SP_TitleBarCloseButton, ads::DockAreaCloseIcon); +#ifndef QT_NO_TOOLTIP + if (testConfigFlag(CDockManager::DockAreaCloseButtonClosesTab)) { - // Tabs menu button - TabsMenuButton = new tTitleBarButton(); - TabsMenuButton->setObjectName("tabsMenuButton"); - TabsMenuButton->setAutoRaise(true); - TabsMenuButton->setPopupMode(QToolButton::InstantPopup); - setTitleBarButtonIcon(TabsMenuButton, QStyle::SP_TitleBarUnshadeButton, ads::DockAreaMenuIcon); - QMenu* TabsMenu = new QMenu(TabsMenuButton); -#ifndef QT_NO_TOOLTIP - TabsMenu->setToolTipsVisible(true); -#endif - _this->connect(TabsMenu, SIGNAL(aboutToShow()), SLOT(onTabsMenuAboutToShow())); - TabsMenuButton->setMenu(TabsMenu); -#ifndef QT_NO_TOOLTIP - TabsMenuButton->setToolTip(QObject::tr("List all tabs")); -#endif - TabsMenuButton->setSizePolicy(ButtonSizePolicy); - TopLayout->addWidget(TabsMenuButton, 0); - _this->connect(TabsMenuButton->menu(), SIGNAL(triggered(QAction*)), - SLOT(onTabsMenuActionTriggered(QAction*))); + CloseButton->setToolTip(QObject::tr("Close Active Tab")); } else { - TabsMenuButton = new CInvisibleButton(); + CloseButton->setToolTip(QObject::tr("Close Group")); } - - - if (testConfigFlag(CDockManager::DockAreaHasUndockButton)) - { - // Undock button - UndockButton = new tTitleBarButton(); - UndockButton->setObjectName("undockButton"); - UndockButton->setAutoRaise(true); -#ifndef QT_NO_TOOLTIP - UndockButton->setToolTip(QObject::tr("Detach Group")); #endif - setTitleBarButtonIcon(UndockButton, QStyle::SP_TitleBarNormalButton, ads::DockAreaUndockIcon); - UndockButton->setSizePolicy(ButtonSizePolicy); - TopLayout->addWidget(UndockButton, 0); - _this->connect(UndockButton, SIGNAL(clicked()), SLOT(onUndockButtonClicked())); - } - else - { - UndockButton = new CInvisibleButton(); - } - - if (testConfigFlag(CDockManager::DockAreaHasCloseButton)) - { - // Close button - CloseButton = new tTitleBarButton(); - CloseButton->setObjectName("closeButton"); - CloseButton->setAutoRaise(true); - setTitleBarButtonIcon(CloseButton, QStyle::SP_TitleBarCloseButton, ads::DockAreaCloseIcon); -#ifndef QT_NO_TOOLTIP - if (testConfigFlag(CDockManager::DockAreaCloseButtonClosesTab)) - { - CloseButton->setToolTip(QObject::tr("Close Active Tab")); - } - else - { - CloseButton->setToolTip(QObject::tr("Close Group")); - } -#endif - CloseButton->setSizePolicy(ButtonSizePolicy); - CloseButton->setIconSize(QSize(16, 16)); - TopLayout->addWidget(CloseButton, 0); - _this->connect(CloseButton, SIGNAL(clicked()), SLOT(onCloseButtonClicked())); - } - else - { - CloseButton = new CInvisibleButton(); - } + CloseButton->setSizePolicy(ButtonSizePolicy); + CloseButton->setIconSize(QSize(16, 16)); + TopLayout->addWidget(CloseButton, 0); + _this->connect(CloseButton, SIGNAL(clicked()), SLOT(onCloseButtonClicked())); } diff --git a/src/DockManager.cpp b/src/DockManager.cpp index c6d5a2d..35101d3 100644 --- a/src/DockManager.cpp +++ b/src/DockManager.cpp @@ -837,6 +837,12 @@ void CDockManager::setConfigFlag(eConfigFlag Flag, bool On) internal::setFlag(StaticConfigFlags, Flag, On); } +//=========================================================================== +bool CDockManager::testConfigFlag(eConfigFlag Flag) +{ + return configFlags().testFlag(Flag); +} + //=========================================================================== CIconProvider& CDockManager::iconProvider() diff --git a/src/DockManager.h b/src/DockManager.h index c44dc84..766e182 100644 --- a/src/DockManager.h +++ b/src/DockManager.h @@ -159,6 +159,7 @@ public: AlwaysShowTabs = 0x2000,///< If this option is enabled, the tab of a dock widget is always displayed - even if it is the only visible dock widget in a floating widget. DockAreaHasUndockButton = 0x4000, //!< If the flag is set each dock area has an undock button DockAreaHasTabsMenuButton = 0x8000, //!< If the flag is set each dock area has a tabs menu button + DockAreaHideDisabledButtons = 0x10000, //!< If the flag is set disabled dock area buttons will not appear on the tollbar at all (enabling them will bring them back) DefaultConfig = ActiveTabHasCloseButton | DockAreaHasCloseButton | DockAreaHasUndockButton @@ -212,6 +213,11 @@ public: */ static void setConfigFlag(eConfigFlag Flag, bool On = true); + /** + * Returns true if the given config flag is set + */ + static bool testConfigFlag(eConfigFlag Flag); + /** * Returns the global icon provider. * The icon provider enables the use of custom icons in case using