Properly implemented DockAreaTitle bar to encapsulate title bar functionality

This commit is contained in:
Uwe Kindler 2018-10-12 14:51:57 +02:00
parent 9bfb3fbea1
commit 11e5f9c95a
7 changed files with 53 additions and 186 deletions

View File

@ -467,16 +467,12 @@ bool CDockAreaTabBar::eventFilter(QObject *watched, QEvent *event)
return Result;
}
if (event->type() == QEvent::Hide)
{
return Result;
}
int TabIndex = d->TabsLayout->indexOf(Tab);
switch (event->type())
{
case QEvent::Hide: emit tabClosed(TabIndex); break;
case QEvent::Show: emit tabOpened(TabIndex); break;
case QEvent::Hide:
emit tabClosed(d->TabsLayout->indexOf(Tab)); break;
case QEvent::Show:
emit tabOpened(d->TabsLayout->indexOf(Tab)); break;
default:
break;
}

View File

@ -83,7 +83,7 @@ void DockAreaTitleBarPrivate::createButtons()
_this->connect(TabsMenu, SIGNAL(aboutToShow()), SLOT(onTabsMenuAboutToShow()));
TabsMenuButton->setMenu(TabsMenu);
TopLayout->addWidget(TabsMenuButton, 0);
TabsMenuButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
TabsMenuButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
_this->connect(TabsMenuButton->menu(), SIGNAL(triggered(QAction*)),
SLOT(onTabsMenuActionTriggered(QAction*)));
@ -92,7 +92,7 @@ void DockAreaTitleBarPrivate::createButtons()
CloseButton->setFlat(true);
CloseButton->setIcon(_this->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
CloseButton->setToolTip(QObject::tr("Close"));
CloseButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
CloseButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
TopLayout->addWidget(CloseButton, 0);
_this->connect(CloseButton, SIGNAL(clicked()), SLOT(onCloseButtonClicked()));
}
@ -103,10 +103,12 @@ void DockAreaTitleBarPrivate::createTabBar()
{
TabBar = new CDockAreaTabBar(DockArea);
TopLayout->addWidget(TabBar);
_this->connect(TabBar, SIGNAL(tabClosed()), SLOT(markTabsMenuOutdated()));
_this->connect(TabBar, SIGNAL(tabOpened()), SLOT(markTabsMenuOutdated()));
_this->connect(TabBar, SIGNAL(tabInserted()), SLOT(markTabsMenuOutdated()));
_this->connect(TabBar, SIGNAL(tabRemoved()), SLOT(markTabsMenuOutdated()));
_this->connect(TabBar, SIGNAL(tabClosed(int)), SLOT(markTabsMenuOutdated()));
_this->connect(TabBar, SIGNAL(tabOpened(int)), SLOT(markTabsMenuOutdated()));
_this->connect(TabBar, SIGNAL(tabInserted(int)), SLOT(markTabsMenuOutdated()));
_this->connect(TabBar, SIGNAL(removingTab(int)), SLOT(markTabsMenuOutdated()));
_this->connect(TabBar, SIGNAL(tabMoved(int, int)), SLOT(markTabsMenuOutdated()));
_this->connect(TabBar, SIGNAL(currentChanged(int)), SLOT(onCurrentTabChanged(int)));
}
@ -193,6 +195,14 @@ void CDockAreaTitleBar::onTabsMenuActionTriggered(QAction* Action)
}
//============================================================================
void CDockAreaTitleBar::onCurrentTabChanged(int Index)
{
CDockWidget* DockWidget = d->TabBar->tab(Index)->dockWidget();
d->CloseButton->setVisible(DockWidget->features().testFlag(CDockWidget::DockWidgetClosable));
}
} // namespace ads
//---------------------------------------------------------------------------

View File

@ -33,6 +33,7 @@ private slots:
void onTabsMenuAboutToShow();
void onCloseButtonClicked();
void onTabsMenuActionTriggered(QAction* Action);
void onCurrentTabChanged(int Index);
public:
using Super = QFrame;

View File

@ -52,6 +52,7 @@
#include "DockOverlay.h"
#include "DockAreaTabBar.h"
#include "DockSplitter.h"
#include "DockAreaTitleBar.h"
#include <iostream>
@ -209,14 +210,9 @@ struct DockAreaWidgetPrivate
{
CDockAreaWidget* _this;
QBoxLayout* Layout;
QFrame* TitleBar;
QBoxLayout* TopLayout;
DockAreaLayout* ContentsLayout;
CDockAreaTabBar* TabBar;
QPushButton* TabsMenuButton;
QPushButton* CloseButton;
CDockAreaTitleBar* TitleBar;
CDockManager* DockManager = nullptr;
bool MenuOutdated = true;
/**
* Private data constructor
@ -226,7 +222,7 @@ struct DockAreaWidgetPrivate
/**
* Creates the layout for top area with tabs and close button
*/
void createTabBar();
void createTitleBar();
/**
* Returns the dock widget with the given index
@ -244,13 +240,6 @@ struct DockAreaWidgetPrivate
return dockWidgetAt(index)->tabWidget();
}
/**
* Adds a tabs menu entry for the given dock widget
* If menu is 0, a menu entry is added to the menu of the TabsMenuButton
* member. If menu is a valid menu pointer, the entry will be added to
* the given menu
*/
void addTabsMenuEntry(CDockWidget* DockWidget, int Index = -1, QMenu* menu = 0);
/**
* Returns the tab action of the given dock widget
@ -268,22 +257,19 @@ struct DockAreaWidgetPrivate
return DockWidget->property(INDEX_PROPERTY).toInt();
}
/**
* Update the tabs menu if dock widget order changed or if dock widget has
* been removed
*/
void markTabsMenuOutdated();
/**
* Updates the tabs menu if it is outdated
*/
void updateTabsMenu();
/**
* Updates the tab bar visibility depending on the number of dock widgets
* in this area
*/
void updateTabBar();
/**
* Convenience function for tabbar access
*/
CDockAreaTabBar* tabBar() const
{
return TitleBar->tabBar();
}
};
// struct DockAreaWidgetPrivate
@ -297,43 +283,14 @@ DockAreaWidgetPrivate::DockAreaWidgetPrivate(CDockAreaWidget* _public) :
//============================================================================
void DockAreaWidgetPrivate::createTabBar()
void DockAreaWidgetPrivate::createTitleBar()
{
TitleBar = new QFrame(_this);
TitleBar->setObjectName("dockAreaTitleBar");
TopLayout = new QBoxLayout(QBoxLayout::LeftToRight);
TopLayout->setContentsMargins(0, 0, 0, 0);
TopLayout->setSpacing(0);
TitleBar->setLayout(TopLayout);
TitleBar = new CDockAreaTitleBar(_this);
Layout->addWidget(TitleBar);
TitleBar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
TabBar = new CDockAreaTabBar(_this);
TopLayout->addWidget(TabBar, 1);
_this->connect(TabBar, SIGNAL(currentChanged(int)), SLOT(setCurrentIndex(int)));
_this->connect(TabBar, SIGNAL(tabMoved(int, int)), SLOT(reorderDockWidget(int, int)));
TabsMenuButton = new QPushButton();
TabsMenuButton->setObjectName("tabsMenuButton");
TabsMenuButton->setFlat(true);
TabsMenuButton->setIcon(_this->style()->standardIcon(QStyle::SP_TitleBarUnshadeButton));
TabsMenuButton->setMaximumWidth(TabsMenuButton->iconSize().width());
QMenu* TabsMenu = new QMenu(TabsMenuButton);
_this->connect(TabsMenu, SIGNAL(aboutToShow()), SLOT(onTabsMenuAboutToShow()));
TabsMenuButton->setMenu(TabsMenu);
TopLayout->addWidget(TabsMenuButton, 0);
TabsMenuButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
_this->connect(TabsMenuButton->menu(), SIGNAL(triggered(QAction*)),
SLOT(onTabsMenuActionTriggered(QAction*)));
CloseButton = new QPushButton();
CloseButton->setObjectName("closeButton");
CloseButton->setFlat(true);
CloseButton->setIcon(_this->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
CloseButton->setToolTip(_this->tr("Close"));
CloseButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
TopLayout->addWidget(CloseButton, 0);
_this->connect(CloseButton, SIGNAL(clicked()), SLOT(onCloseButtonClicked()));
_this->connect(tabBar(), SIGNAL(tabCloseRequested(int)),
SLOT(onTabCloseRequested(int)));
_this->connect(tabBar(), SIGNAL(tabBarClicked(int)),
SLOT(setCurrentIndex(int)));
}
@ -350,57 +307,6 @@ void DockAreaWidgetPrivate::updateTabBar()
}
//============================================================================
void DockAreaWidgetPrivate::addTabsMenuEntry(CDockWidget* DockWidget,
int Index, QMenu* menu)
{
menu = menu ? menu : TabsMenuButton->menu();
QAction* Action;
if (Index >= 0 && Index < menu->actions().count())
{
Action = new QAction(DockWidget->icon(), DockWidget->windowTitle());
menu->insertAction(menu->actions().at(Index), Action);
}
else
{
Action = menu->addAction(DockWidget->icon(), DockWidget->windowTitle());
}
Action->setProperty(DOCKWIDGET_PROPERTY, QVariant::fromValue(DockWidget));
QVariant vAction = QVariant::fromValue(Action);
DockWidget->setProperty(ACTION_PROPERTY, vAction);
}
//============================================================================
void DockAreaWidgetPrivate::markTabsMenuOutdated()
{
MenuOutdated = true;
}
//============================================================================
void DockAreaWidgetPrivate::updateTabsMenu()
{
if (!MenuOutdated)
{
return;
}
QMenu* menu = TabsMenuButton->menu();
menu->clear();
for (int i = 0; i < ContentsLayout->count(); ++i)
{
if (dockWidgetAt(i)->isClosed())
{
continue;
}
addTabsMenuEntry(dockWidgetAt(i), APPEND, menu);
}
MenuOutdated = false;
}
//============================================================================
CDockAreaWidget::CDockAreaWidget(CDockManager* DockManager, CDockContainerWidget* parent) :
QFrame(parent),
@ -412,7 +318,7 @@ CDockAreaWidget::CDockAreaWidget(CDockManager* DockManager, CDockContainerWidget
d->Layout->setSpacing(0);
setLayout(d->Layout);
d->createTabBar();
d->createTitleBar();
d->ContentsLayout = new DockAreaLayout(d->Layout);
}
@ -453,10 +359,9 @@ void CDockAreaWidget::insertDockWidget(int index, CDockWidget* DockWidget,
d->ContentsLayout->insertWidget(index, DockWidget);
DockWidget->tabWidget()->setDockAreaWidget(this);
auto TabWidget = DockWidget->tabWidget();
d->TabBar->insertTab(index, TabWidget);
d->tabBar()->insertTab(index, TabWidget);
TabWidget->setVisible(!DockWidget->isClosed());
DockWidget->setProperty(INDEX_PROPERTY, index);
d->markTabsMenuOutdated();
if (Activate)
{
setCurrentIndex(index);
@ -474,11 +379,10 @@ void CDockAreaWidget::removeDockWidget(CDockWidget* DockWidget)
d->ContentsLayout->removeWidget(DockWidget);
auto TabWidget = DockWidget->tabWidget();
TabWidget->hide();
d->TabBar->removeTab(TabWidget);
d->tabBar()->removeTab(TabWidget);
if (NextOpenDockWidget)
{
setCurrentDockWidget(NextOpenDockWidget);
d->markTabsMenuOutdated();
}
else if (d->ContentsLayout->isEmpty())
{
@ -541,9 +445,10 @@ void CDockAreaWidget::hideAreaIfNoVisibleContent()
//============================================================================
void CDockAreaWidget::onCloseButtonClicked()
void CDockAreaWidget::onTabCloseRequested(int Index)
{
currentDockWidget()->toggleView(false);
qDebug() << "CDockAreaWidget::onTabCloseRequested " << Index;
dockWidget(Index)->toggleView(false);
}
@ -576,18 +481,15 @@ void CDockAreaWidget::setCurrentDockWidget(CDockWidget* DockWidget)
void CDockAreaWidget::setCurrentIndex(int index)
{
std::cout << "CDockAreaWidget::setCurrentIndex " << index << std::endl;
if (index < 0 || index > (d->TabBar->count() - 1))
auto TabBar = d->tabBar();
if (index < 0 || index > (TabBar->count() - 1))
{
qWarning() << Q_FUNC_INFO << "Invalid index" << index;
return;
}
emit currentChanging(index);
d->TabBar->setCurrentIndex(index);
CDockWidgetTab* CurrentTab = d->TabBar->currentTab();
auto Features = CurrentTab->dockWidget()->features();
d->CloseButton->setVisible(Features.testFlag(CDockWidget::DockWidgetClosable));
TabBar->setCurrentIndex(index);
d->ContentsLayout->setCurrentIndex(index);
d->ContentsLayout->currentWidget()->show();
emit currentChanged(index);
@ -602,9 +504,9 @@ int CDockAreaWidget::currentIndex() const
//============================================================================
QRect CDockAreaWidget::titleAreaGeometry() const
QRect CDockAreaWidget::titleBarGeometry() const
{
return d->TopLayout->geometry();
return d->TitleBar->geometry();
}
//============================================================================
@ -664,21 +566,6 @@ QList<CDockWidget*> CDockAreaWidget::openedDockWidgets() const
}
//============================================================================
int CDockAreaWidget::indexOfContentByTitlePos(const QPoint& p, QWidget* exclude) const
{
for (int i = 0; i < d->ContentsLayout->count(); ++i)
{
auto TabWidget = d->tabWidgetAt(i);
if (TabWidget->isVisible() && TabWidget->geometry().contains(p) && (!exclude || TabWidget != exclude))
{
return i;
}
}
return -1;
}
//============================================================================
int CDockAreaWidget::dockWidgetsCount() const
{
@ -716,16 +603,6 @@ void CDockAreaWidget::toggleDockWidgetView(CDockWidget* DockWidget, bool Open)
Q_UNUSED(DockWidget);
Q_UNUSED(Open);
updateTabBarVisibility();
d->markTabsMenuOutdated();
}
//============================================================================
void CDockAreaWidget::onTabsMenuActionTriggered(QAction* Action)
{
QVariant vDockWidget = Action->property(DOCKWIDGET_PROPERTY);
CDockWidget* DockWidget = vDockWidget.value<CDockWidget*>();
setCurrentDockWidget(DockWidget);
}
@ -777,13 +654,6 @@ CDockWidget* CDockAreaWidget::nextOpenDockWidget(CDockWidget* DockWidget) const
}
}
//============================================================================
void CDockAreaWidget::onTabsMenuAboutToShow()
{
d->updateTabsMenu();
}
} // namespace ads
//---------------------------------------------------------------------------

View File

@ -63,9 +63,7 @@ private:
friend class CDockWidget;
private slots:
void onTabsMenuActionTriggered(QAction* Action);
void onCloseButtonClicked();
void onTabsMenuAboutToShow();
void onTabCloseRequested(int Index);
/**
* Reorder the index position of DockWidget at fromIndx to toIndex
@ -94,12 +92,6 @@ protected:
*/
void removeDockWidget(CDockWidget* DockWidget);
/**
* Returns the index of contents of the title widget that is located at
* mouse position pos
*/
int indexOfContentByTitlePos(const QPoint& pos, QWidget* exclude = nullptr) const;
/**
* Called from dock widget if it is opened or closed
*/
@ -161,7 +153,7 @@ public:
/**
* Returns the rectangle of the title area
*/
QRect titleAreaGeometry() const;
QRect titleBarGeometry() const;
/**
* Returns the rectangle of the content

View File

@ -346,7 +346,7 @@ DockWidgetArea CDockOverlay::dropAreaUnderCursor() const
return Result;
}
if (DockArea->titleAreaGeometry().contains(DockArea->mapFromGlobal(QCursor::pos())))
if (DockArea->titleBarGeometry().contains(DockArea->mapFromGlobal(QCursor::pos())))
{
return CenterDockWidgetArea;
}

View File

@ -107,7 +107,7 @@ struct DockWidgetTabPrivate
*/
bool titleAreaGeometryContains(const QPoint& GlobalPos) const
{
return DockArea->titleAreaGeometry().contains(DockArea->mapFromGlobal(GlobalPos));
return DockArea->titleBarGeometry().contains(DockArea->mapFromGlobal(GlobalPos));
}
/**
@ -227,7 +227,6 @@ void CDockWidgetTab::mousePressEvent(QMouseEvent* ev)
{
if (ev->button() == Qt::LeftButton)
{
qDebug() << "CDockWidgetTab::mousePressEvent";
ev->accept();
d->DragStartMousePosition = ev->pos();
d->DragState = DraggingMousePressed;
@ -242,7 +241,6 @@ void CDockWidgetTab::mousePressEvent(QMouseEvent* ev)
//============================================================================
void CDockWidgetTab::mouseReleaseEvent(QMouseEvent* ev)
{
qDebug() << "CDockWidgetTab::mouseReleaseEvent";
// End of tab moving, emit signal
if (d->isDraggingState(DraggingTab) && d->DockArea)
{