Allow switching tabs via context menu in the tabs area

This change allows you to switch tabs via the context menu. The context
menu only shows up if you click on the empty area beside the tabs.

Can be tested with `--allow-switch-tabs-via-menu` option in the example.

Fixes #232
Signed-off-by: Waqar Ahmed <waqar.ahmed@kdab.com>
This commit is contained in:
Waqar Ahmed
2021-09-08 15:09:41 +05:00
committed by Sergio Martins
parent 8307598d5d
commit 7af2095f2f
5 changed files with 49 additions and 2 deletions

View File

@@ -120,13 +120,17 @@ int main(int argc, char **argv)
parser.addOption(dontCloseBeforeRestore); parser.addOption(dontCloseBeforeRestore);
QCommandLineOption showButtonsInTabBarIfTitleBarHidden("show-buttons-in-tabbar-if-titlebar-hidden", QCommandLineOption showButtonsInTabBarIfTitleBarHidden("show-buttons-in-tabbar-if-titlebar-hidden",
QCoreApplication::translate("main", "If we're not using title bars we'll still show the close and float button in the tab bar")); QCoreApplication::translate("main", "If we're not using title bars we'll still show the close and float button in the tab bar"));
parser.addOption(showButtonsInTabBarIfTitleBarHidden); parser.addOption(showButtonsInTabBarIfTitleBarHidden);
QCommandLineOption centralWidget("central-widget", QCommandLineOption centralWidget("central-widget",
QCoreApplication::translate("main", "The main window will have a non-detachable central widget")); QCoreApplication::translate("main", "The main window will have a non-detachable central widget"));
parser.addOption(centralWidget); parser.addOption(centralWidget);
QCommandLineOption ctxtMenuOnTabs("allow-switch-tabs-via-menu",
QCoreApplication::translate("main", "Allow switching tabs via context menu in tabs area"));
parser.addOption(ctxtMenuOnTabs);
#if defined(DOCKS_DEVELOPER_MODE) #if defined(DOCKS_DEVELOPER_MODE)
parser.addOption(centralFrame); parser.addOption(centralFrame);
@@ -237,6 +241,9 @@ int main(int argc, char **argv)
if (parser.isSet(tabsHaveCloseButton)) if (parser.isSet(tabsHaveCloseButton))
flags |= KDDockWidgets::Config::Flag_TabsHaveCloseButton; flags |= KDDockWidgets::Config::Flag_TabsHaveCloseButton;
if (parser.isSet(ctxtMenuOnTabs))
flags |= KDDockWidgets::Config::Flag_AllowSwitchingTabsViaMenu;
if (parser.isSet(doubleClickMaximize)) if (parser.isSet(doubleClickMaximize))
flags |= KDDockWidgets::Config::Flag_DoubleClickMaximizes; flags |= KDDockWidgets::Config::Flag_DoubleClickMaximizes;

View File

@@ -83,6 +83,7 @@ public:
Flag_KeepAboveIfNotUtilityWindow = 0x10000, ///< Only meaningful if Flag_DontUseUtilityFloatingWindows is set. If floating windows are normal windows, you might still want them to keep above and not minimize when you focus the main window. Flag_KeepAboveIfNotUtilityWindow = 0x10000, ///< Only meaningful if Flag_DontUseUtilityFloatingWindows is set. If floating windows are normal windows, you might still want them to keep above and not minimize when you focus the main window.
Flag_CloseOnlyCurrentTab = 0x20000, ///< The TitleBar's close button will only close the current tab, instead of all of them Flag_CloseOnlyCurrentTab = 0x20000, ///< The TitleBar's close button will only close the current tab, instead of all of them
Flag_ShowButtonsOnTabBarIfTitleBarHidden = 0x40000, ///< When using Flag_HideTitleBarWhenTabsVisible the close/float buttons disappear with the title bar. With Flag_ShowButtonsOnTabBarIfHidden they'll be shown in the tab bar. Flag_ShowButtonsOnTabBarIfTitleBarHidden = 0x40000, ///< When using Flag_HideTitleBarWhenTabsVisible the close/float buttons disappear with the title bar. With Flag_ShowButtonsOnTabBarIfHidden they'll be shown in the tab bar.
Flag_AllowSwitchingTabsViaMenu = 0x80000, ///< Allow switching tabs via a context menu when right clicking on the tab area
Flag_Default = Flag_AeroSnapWithClientDecos ///< The defaults Flag_Default = Flag_AeroSnapWithClientDecos ///< The defaults
}; };
Q_DECLARE_FLAGS(Flags, Flag) Q_DECLARE_FLAGS(Flags, Flag)

View File

@@ -27,6 +27,7 @@
#include <QTabBar> #include <QTabBar>
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QAbstractButton> #include <QAbstractButton>
#include <QMenu>
using namespace KDDockWidgets; using namespace KDDockWidgets;
@@ -38,6 +39,9 @@ TabWidgetWidget::TabWidgetWidget(Frame *parent)
setTabBar(static_cast<QTabBar *>(m_tabBar->asWidget())); setTabBar(static_cast<QTabBar *>(m_tabBar->asWidget()));
setTabsClosable(Config::self().flags() & Config::Flag_TabsHaveCloseButton); setTabsClosable(Config::self().flags() & Config::Flag_TabsHaveCloseButton);
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, &QTabWidget::customContextMenuRequested, this, &TabWidgetWidget::showContextMenu);
// In case tabs closable is set by the factory, a tabClosedRequested() is emitted when the user presses [x] // In case tabs closable is set by the factory, a tabClosedRequested() is emitted when the user presses [x]
connect(this, &QTabWidget::tabCloseRequested, this, [this](int index) { connect(this, &QTabWidget::tabCloseRequested, this, [this](int index) {
if (DockWidgetBase *dw = dockwidgetAt(index)) { if (DockWidgetBase *dw = dockwidgetAt(index)) {
@@ -201,3 +205,34 @@ void TabWidgetWidget::updateMargins()
m_cornerWidgetLayout->setContentsMargins(QMargins(0, 0, 2, 0) * factor); m_cornerWidgetLayout->setContentsMargins(QMargins(0, 0, 2, 0) * factor);
m_cornerWidgetLayout->setSpacing(int(2 * factor)); m_cornerWidgetLayout->setSpacing(int(2 * factor));
} }
void TabWidgetWidget::showContextMenu(QPoint pos)
{
if (!(Config::self().flags() & Config::Flag_AllowSwitchingTabsViaMenu))
return;
QTabBar *tabBar = QTabWidget::tabBar();
// We dont want context menu if there is only one tab
if (tabBar->count() <= 1)
return;
// Click on a tab => No menu
if (tabBar->tabAt(pos) >= 0)
return;
// Right click is allowed only on the tabs area
QRect tabAreaRect = tabBar->rect();
tabAreaRect.setWidth(this->width());
if (!tabAreaRect.contains(pos))
return;
QMenu menu(this);
for (int i = 0; i < tabBar->count(); ++i) {
QAction *action = menu.addAction(tabText(i), this, [this, i] {
setCurrentIndex(i);
});
if (i == currentIndex())
action->setDisabled(true);
}
menu.exec(mapToGlobal(pos));
}

View File

@@ -65,6 +65,10 @@ protected:
DockWidgetBase *dockwidgetAt(int index) const override; DockWidgetBase *dockwidgetAt(int index) const override;
int currentIndex() const override; int currentIndex() const override;
/// @brief Shows the context menu. Override to implement your own context menu.
/// By default it's used to honour Config::Flag_AllowSwitchingTabsViaMenu
virtual void showContextMenu(QPoint pos);
private: private:
void updateMargins(); void updateMargins();
void setupTabBarButtons(); void setupTabBarButtons();