mirror of
https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git
synced 2024-12-25 23:51:33 +08:00
Add ability to customize the DockArea Title Bar and DockWidget Tab context menu
This commit is contained in:
parent
509b2356d1
commit
f2378636e2
@ -75,18 +75,17 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "DockManager.h"
|
|
||||||
#include "DockWidget.h"
|
|
||||||
#include "DockAreaWidget.h"
|
|
||||||
#include "DockAreaTitleBar.h"
|
|
||||||
#include "DockAreaTabBar.h"
|
#include "DockAreaTabBar.h"
|
||||||
#include "FloatingDockContainer.h"
|
#include "DockAreaTitleBar.h"
|
||||||
|
#include "DockAreaWidget.h"
|
||||||
#include "DockComponentsFactory.h"
|
#include "DockComponentsFactory.h"
|
||||||
#include "StatusDialog.h"
|
#include "DockManager.h"
|
||||||
#include "DockSplitter.h"
|
#include "DockSplitter.h"
|
||||||
|
#include "DockWidget.h"
|
||||||
|
#include "FloatingDockContainer.h"
|
||||||
#include "ImageViewer.h"
|
#include "ImageViewer.h"
|
||||||
|
#include "MyDockAreaTitleBar.h"
|
||||||
|
#include "StatusDialog.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a random number from 0 to highest - 1
|
* Returns a random number from 0 to highest - 1
|
||||||
@ -147,7 +146,7 @@ public:
|
|||||||
using Super = ads::CDockComponentsFactory;
|
using Super = ads::CDockComponentsFactory;
|
||||||
ads::CDockAreaTitleBar* createDockAreaTitleBar(ads::CDockAreaWidget* DockArea) const override
|
ads::CDockAreaTitleBar* createDockAreaTitleBar(ads::CDockAreaWidget* DockArea) const override
|
||||||
{
|
{
|
||||||
auto TitleBar = new ads::CDockAreaTitleBar(DockArea);
|
auto TitleBar = new MyDockAreaTitleBar(DockArea);
|
||||||
auto CustomButton = new QToolButton(DockArea);
|
auto CustomButton = new QToolButton(DockArea);
|
||||||
CustomButton->setToolTip(QObject::tr("Help"));
|
CustomButton->setToolTip(QObject::tr("Help"));
|
||||||
CustomButton->setIcon(svgIcon(":/adsdemo/images/help_outline.svg"));
|
CustomButton->setIcon(svgIcon(":/adsdemo/images/help_outline.svg"));
|
||||||
|
34
demo/MyDockAreaTitleBar.h
Normal file
34
demo/MyDockAreaTitleBar.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
//
|
||||||
|
// Created by fuga on 08 nov 2024.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef QTADS_MYDOCKAREATITLEBAR_H
|
||||||
|
#define QTADS_MYDOCKAREATITLEBAR_H
|
||||||
|
|
||||||
|
#include <DockAreaTitleBar.h>
|
||||||
|
|
||||||
|
class MyDockAreaTitleBar : public ads::CDockAreaTitleBar {
|
||||||
|
public:
|
||||||
|
explicit MyDockAreaTitleBar(ads::CDockAreaWidget* parent)
|
||||||
|
: CDockAreaTitleBar(parent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
QMenu* buildContextMenu(QMenu*) override
|
||||||
|
{
|
||||||
|
auto menu = ads::CDockAreaTitleBar::buildContextMenu(nullptr);
|
||||||
|
menu->addSeparator();
|
||||||
|
auto action = menu->addAction(tr("Format HardDrive"));
|
||||||
|
|
||||||
|
connect(action, &QAction::triggered, this, [this](){
|
||||||
|
QMessageBox msgBox;
|
||||||
|
msgBox.setText("No, just kidding");
|
||||||
|
msgBox.setStandardButtons(QMessageBox::Abort);
|
||||||
|
msgBox.setDefaultButton(QMessageBox::Abort);
|
||||||
|
msgBox.exec();
|
||||||
|
});
|
||||||
|
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QTADS_MYDOCKAREATITLEBAR_H
|
@ -765,24 +765,35 @@ void CDockAreaTitleBar::contextMenuEvent(QContextMenuEvent* ev)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool isAutoHide = d->DockArea->isAutoHide();
|
auto Menu = buildContextMenu(nullptr);
|
||||||
|
Menu->exec(ev->globalPos());
|
||||||
|
delete Menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenu* CDockAreaTitleBar::buildContextMenu(QMenu *Menu)
|
||||||
|
{
|
||||||
|
const bool isAutoHide = d->DockArea->isAutoHide();
|
||||||
const bool isTopLevelArea = d->DockArea->isTopLevelArea();
|
const bool isTopLevelArea = d->DockArea->isTopLevelArea();
|
||||||
QAction* Action;
|
QAction* Action;
|
||||||
QMenu Menu(this);
|
if (Menu == nullptr)
|
||||||
if (!isTopLevelArea)
|
{
|
||||||
|
Menu = new QMenu(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isTopLevelArea)
|
||||||
{
|
{
|
||||||
Action = Menu.addAction(isAutoHide ? tr("Detach") : tr("Detach Group"),
|
Action = Menu->addAction(isAutoHide ? tr("Detach") : tr("Detach Group"),
|
||||||
this, SLOT(onUndockButtonClicked()));
|
this, SLOT(onUndockButtonClicked()));
|
||||||
Action->setEnabled(d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable));
|
Action->setEnabled(d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable));
|
||||||
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideFeatureEnabled))
|
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideFeatureEnabled))
|
||||||
{
|
{
|
||||||
Action = Menu.addAction(isAutoHide ? tr("Unpin (Dock)") : tr("Pin Group"), this, SLOT(onAutoHideDockAreaActionClicked()));
|
Action = Menu->addAction(isAutoHide ? tr("Unpin (Dock)") : tr("Pin Group"), this, SLOT(onAutoHideDockAreaActionClicked()));
|
||||||
auto AreaIsPinnable = d->DockArea->features().testFlag(CDockWidget::DockWidgetPinnable);
|
auto AreaIsPinnable = d->DockArea->features().testFlag(CDockWidget::DockWidgetPinnable);
|
||||||
Action->setEnabled(AreaIsPinnable);
|
Action->setEnabled(AreaIsPinnable);
|
||||||
|
|
||||||
if (!isAutoHide)
|
if (!isAutoHide)
|
||||||
{
|
{
|
||||||
auto menu = Menu.addMenu(tr("Pin Group To..."));
|
auto menu = Menu->addMenu(tr("Pin Group To..."));
|
||||||
menu->setEnabled(AreaIsPinnable);
|
menu->setEnabled(AreaIsPinnable);
|
||||||
d->createAutoHideToAction(tr("Top"), SideBarTop, menu);
|
d->createAutoHideToAction(tr("Top"), SideBarTop, menu);
|
||||||
d->createAutoHideToAction(tr("Left"), SideBarLeft, menu);
|
d->createAutoHideToAction(tr("Left"), SideBarLeft, menu);
|
||||||
@ -790,28 +801,27 @@ void CDockAreaTitleBar::contextMenuEvent(QContextMenuEvent* ev)
|
|||||||
d->createAutoHideToAction(tr("Bottom"), SideBarBottom, menu);
|
d->createAutoHideToAction(tr("Bottom"), SideBarBottom, menu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Menu.addSeparator();
|
Menu->addSeparator();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAutoHide)
|
if (isAutoHide)
|
||||||
{
|
{
|
||||||
Action = Menu.addAction(tr("Minimize"), this, SLOT(minimizeAutoHideContainer()));
|
Action = Menu->addAction(tr("Minimize"), this, SLOT(minimizeAutoHideContainer()));
|
||||||
Action = Menu.addAction(tr("Close"), this, SLOT(onAutoHideCloseActionTriggered()));
|
Action = Menu->addAction(tr("Close"), this, SLOT(onAutoHideCloseActionTriggered()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Action = Menu.addAction(isAutoHide ? tr("Close") : tr("Close Group"), this, SLOT(onCloseButtonClicked()));
|
Action = Menu->addAction(isAutoHide ? tr("Close") : tr("Close Group"), this, SLOT(onCloseButtonClicked()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Action->setEnabled(d->DockArea->features().testFlag(CDockWidget::DockWidgetClosable));
|
Action->setEnabled(d->DockArea->features().testFlag(CDockWidget::DockWidgetClosable));
|
||||||
if (!isAutoHide && !isTopLevelArea)
|
if (!isAutoHide && !isTopLevelArea)
|
||||||
{
|
{
|
||||||
Action = Menu.addAction(tr("Close Other Groups"), d->DockArea, SLOT(closeOtherAreas()));
|
Action = Menu->addAction(tr("Close Other Groups"), d->DockArea, SLOT(closeOtherAreas()));
|
||||||
}
|
}
|
||||||
Menu.exec(ev->globalPos());
|
return Menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
void CDockAreaTitleBar::insertWidget(int index, QWidget *widget)
|
void CDockAreaTitleBar::insertWidget(int index, QWidget *widget)
|
||||||
{
|
{
|
||||||
|
@ -249,6 +249,20 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool isAutoHide() const;
|
bool isAutoHide() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fills the provided menu with standard entries. If a nullptr is passed, a
|
||||||
|
* new menu is created and filled with standard entries.
|
||||||
|
* This function is called from the actual version of contextMenuEvent, but
|
||||||
|
* can be called from any code. Caller is responsible of deleting the created
|
||||||
|
* object.
|
||||||
|
*
|
||||||
|
* @param menu The QMenu to fill with standard entries. If nullptr, a new
|
||||||
|
* QMenu will be created.
|
||||||
|
* @return The filled QMenu, either the provided one or a newly created one if
|
||||||
|
* nullptr was passed.
|
||||||
|
*/
|
||||||
|
virtual QMenu *buildContextMenu(QMenu *);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
/**
|
/**
|
||||||
* This signal is emitted if a tab in the tab bar is clicked by the user
|
* This signal is emitted if a tab in the tab bar is clicked by the user
|
||||||
|
@ -529,26 +529,34 @@ void CDockWidgetTab::contextMenuEvent(QContextMenuEvent* ev)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto Menu = buildContextMenu(nullptr);
|
||||||
d->saveDragStartMousePosition(ev->globalPos());
|
d->saveDragStartMousePosition(ev->globalPos());
|
||||||
|
Menu->exec(ev->globalPos());
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenu* CDockWidgetTab::buildContextMenu(QMenu *Menu)
|
||||||
|
{
|
||||||
|
if (Menu == nullptr) {
|
||||||
|
Menu = new QMenu(this);
|
||||||
|
}
|
||||||
|
|
||||||
const bool isFloatable = d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable);
|
const bool isFloatable = d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable);
|
||||||
const bool isNotOnlyTabInContainer = !d->DockArea->dockContainer()->hasTopLevelDockWidget();
|
const bool isNotOnlyTabInContainer = !d->DockArea->dockContainer()->hasTopLevelDockWidget();
|
||||||
const bool isTopLevelArea = d->DockArea->isTopLevelArea();
|
const bool isTopLevelArea = d->DockArea->isTopLevelArea();
|
||||||
const bool isDetachable = isFloatable && isNotOnlyTabInContainer;
|
const bool isDetachable = isFloatable && isNotOnlyTabInContainer;
|
||||||
QAction* Action;
|
QAction* Action;
|
||||||
QMenu Menu(this);
|
|
||||||
|
|
||||||
if (!isTopLevelArea)
|
if (!isTopLevelArea)
|
||||||
{
|
{
|
||||||
Action = Menu.addAction(tr("Detach"), this, SLOT(detachDockWidget()));
|
Action = Menu->addAction(tr("Detach"), this, SLOT(detachDockWidget()));
|
||||||
Action->setEnabled(isDetachable);
|
Action->setEnabled(isDetachable);
|
||||||
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideFeatureEnabled))
|
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideFeatureEnabled))
|
||||||
{
|
{
|
||||||
Action = Menu.addAction(tr("Pin"), this, SLOT(autoHideDockWidget()));
|
Action = Menu->addAction(tr("Pin"), this, SLOT(autoHideDockWidget()));
|
||||||
auto IsPinnable = d->DockWidget->features().testFlag(CDockWidget::DockWidgetPinnable);
|
auto IsPinnable = d->DockWidget->features().testFlag(CDockWidget::DockWidgetPinnable);
|
||||||
Action->setEnabled(IsPinnable);
|
Action->setEnabled(IsPinnable);
|
||||||
|
|
||||||
auto menu = Menu.addMenu(tr("Pin To..."));
|
auto menu = Menu->addMenu(tr("Pin To..."));
|
||||||
menu->setEnabled(IsPinnable);
|
menu->setEnabled(IsPinnable);
|
||||||
d->createAutoHideToAction(tr("Top"), SideBarTop, menu);
|
d->createAutoHideToAction(tr("Top"), SideBarTop, menu);
|
||||||
d->createAutoHideToAction(tr("Left"), SideBarLeft, menu);
|
d->createAutoHideToAction(tr("Left"), SideBarLeft, menu);
|
||||||
@ -557,17 +565,16 @@ void CDockWidgetTab::contextMenuEvent(QContextMenuEvent* ev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Menu.addSeparator();
|
Menu->addSeparator();
|
||||||
Action = Menu.addAction(tr("Close"), this, SIGNAL(closeRequested()));
|
Action = Menu->addAction(tr("Close"), this, SIGNAL(closeRequested()));
|
||||||
Action->setEnabled(isClosable());
|
Action->setEnabled(isClosable());
|
||||||
if (d->DockArea->openDockWidgetsCount() > 1)
|
if (d->DockArea->openDockWidgetsCount() > 1)
|
||||||
{
|
{
|
||||||
Action = Menu.addAction(tr("Close Others"), this, SIGNAL(closeOtherTabsRequested()));
|
Action = Menu->addAction(tr("Close Others"), this, SIGNAL(closeOtherTabsRequested()));
|
||||||
}
|
}
|
||||||
Menu.exec(ev->globalPos());
|
|
||||||
|
return Menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
bool CDockWidgetTab::isActiveTab() const
|
bool CDockWidgetTab::isActiveTab() const
|
||||||
{
|
{
|
||||||
|
@ -186,6 +186,20 @@ public:
|
|||||||
*/
|
*/
|
||||||
eDragState dragState() const;
|
eDragState dragState() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fills the provided menu with standard entries. If a nullptr is passed, a
|
||||||
|
* new menu is created and filled with standard entries.
|
||||||
|
* This function is called from the actual version of contextMenuEvent, but
|
||||||
|
* can be called from any code. Caller is responsible of deleting the created
|
||||||
|
* object.
|
||||||
|
*
|
||||||
|
* @param menu The QMenu to fill with standard entries. If nullptr, a new
|
||||||
|
* QMenu will be created.
|
||||||
|
* @return The filled QMenu, either the provided one or a newly created one if
|
||||||
|
* nullptr was passed.
|
||||||
|
*/
|
||||||
|
virtual QMenu *buildContextMenu(QMenu *);
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
virtual void setVisible(bool visible) override;
|
virtual void setVisible(bool visible) override;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user