Created new DockAreaTitleBar class to encapsulate all title bar functionality

This commit is contained in:
Uwe Kindler 2018-10-12 13:37:37 +02:00
parent 9c95e34df5
commit 9bfb3fbea1
7 changed files with 330 additions and 84 deletions

View File

@ -39,8 +39,6 @@ struct DockAreaTabBarPrivate
QWidget* TabsContainerWidget;
QBoxLayout* TabsLayout;
int CurrentIndex = -1;
bool MenuOutdated = true;
QMenu* TabsMenu;
/**
* Private data constructor
@ -266,7 +264,7 @@ void CDockAreaTabBar::insertTab(int Index, CDockWidgetTab* Tab)
connect(Tab, SIGNAL(clicked()), this, SLOT(onTabClicked()));
connect(Tab, SIGNAL(moved(const QPoint&)), this, SLOT(onTabWidgetMoved(const QPoint&)));
Tab->installEventFilter(this);
d->MenuOutdated = true;
emit tabInserted(Index);
if (Index <= d->CurrentIndex)
{
setCurrentIndex(d->CurrentIndex++);
@ -320,10 +318,10 @@ void CDockAreaTabBar::removeTab(CDockWidgetTab* Tab)
}
}
emit removingTab(RemoveIndex);
d->TabsLayout->removeWidget(Tab);
Tab->disconnect(this);
Tab->removeEventFilter(this);
d->MenuOutdated = true;
qDebug() << "NewCurrentIndex " << NewCurrentIndex;
if (NewCurrentIndex != d->CurrentIndex)
{
@ -448,7 +446,14 @@ void CDockAreaTabBar::closeTab(int Index)
{
return;
}
auto Tab = tab(Index);
if (!Tab->isVisibleTo(this))
{
return;
}
emit tabCloseRequested(Index);
Tab->hide();
}
@ -456,20 +461,40 @@ void CDockAreaTabBar::closeTab(int Index)
bool CDockAreaTabBar::eventFilter(QObject *watched, QEvent *event)
{
bool Result = Super::eventFilter(watched, event);
if (event->type() != QEvent::Hide)
{
return Result;
}
CDockWidgetTab* Tab = qobject_cast<CDockWidgetTab*>(watched);
if (!Tab)
{
return Result;
}
qDebug() << "Hide event for tab " << Tab->text();
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;
default:
break;
}
return Result;
}
//===========================================================================
bool CDockAreaTabBar::isTabOpen(int Index) const
{
if (Index < 0 || Index >= count())
{
return false;
}
return tab(Index)->isVisibleTo(this);
}
} // namespace ads
//---------------------------------------------------------------------------

View File

@ -111,6 +111,13 @@ public:
*/
virtual bool eventFilter(QObject *watched, QEvent *event) override;
/**
* This function returns true if the tab is open, that means if it is
* visible to the user. If the function returns false, the tab is
* closed
*/
bool isTabOpen(int Index) const;
public slots:
/**
* This property sets the index of the tab bar's visible tab
@ -147,11 +154,33 @@ signals:
*/
void tabCloseRequested(int index);
/**
* This signal is emitted if a tab has been closed
*/
void tabClosed(int index);
/**
* This signal is emitted if a tab has been opened.
* A tab is opened if it has been made visible
*/
void tabOpened(int index);
/**
* This signal is emitted when the tab has moved the tab at index position
* from to index position to.
*/
void tabMoved(int from, int to);
/**
* This signal is emitted, just before the tab with the given index is
* removed
*/
void removingTab(int index);
/**
* This signal is emitted if a tab has been inserted
*/
void tabInserted(int index);
}; // class CDockAreaTabBar
} // namespace ads
//-----------------------------------------------------------------------------

199
src/DockAreaTitleBar.cpp Normal file
View File

@ -0,0 +1,199 @@
//============================================================================
/// \file DockAreaTitleBar.cpp
/// \author Uwe Kindler
/// \date 12.10.2018
/// \brief Implementation of CDockAreaTitleBar class
//============================================================================
//============================================================================
// INCLUDES
//============================================================================
#include "DockAreaTitleBar.h"
#include <QPushButton>
#include <QBoxLayout>
#include <QStyle>
#include <QMenu>
#include <QScrollArea>
#include <QMouseEvent>
#include <QDebug>
#include "FloatingDockContainer.h"
#include "DockAreaWidget.h"
#include "DockOverlay.h"
#include "DockManager.h"
#include "DockWidget.h"
#include "DockWidgetTab.h"
#include "DockAreaTabBar.h"
#include <iostream>
namespace ads
{
/**
* Private data class of CDockAreaTitleBar class (pimpl)
*/
struct DockAreaTitleBarPrivate
{
CDockAreaTitleBar* _this;
QPushButton* TabsMenuButton;
QPushButton* CloseButton;
QBoxLayout* TopLayout;
CDockAreaWidget* DockArea;
CDockAreaTabBar* TabBar;
bool MenuOutdated = true;
QMenu* TabsMenu;
/**
* Private data constructor
*/
DockAreaTitleBarPrivate(CDockAreaTitleBar* _public);
/**
* Creates the title bar close and menu buttons
*/
void createButtons();
/**
* Creates the internal TabBar
*/
void createTabBar();
};// struct DockAreaTitleBarPrivate
//============================================================================
DockAreaTitleBarPrivate::DockAreaTitleBarPrivate(CDockAreaTitleBar* _public) :
_this(_public)
{
}
//============================================================================
void DockAreaTitleBarPrivate::createButtons()
{
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(QObject::tr("Close"));
CloseButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
TopLayout->addWidget(CloseButton, 0);
_this->connect(CloseButton, SIGNAL(clicked()), SLOT(onCloseButtonClicked()));
}
//============================================================================
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()));
}
//============================================================================
CDockAreaTitleBar::CDockAreaTitleBar(CDockAreaWidget* parent) :
QFrame(parent),
d(new DockAreaTitleBarPrivate(this))
{
d->DockArea = parent;
setObjectName("dockAreaTitleBar");
d->TopLayout = new QBoxLayout(QBoxLayout::LeftToRight);
d->TopLayout->setContentsMargins(0, 0, 0, 0);
d->TopLayout->setSpacing(0);
setLayout(d->TopLayout);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
d->createTabBar();
d->createButtons();
}
//============================================================================
CDockAreaTitleBar::~CDockAreaTitleBar()
{
delete d;
}
//============================================================================
CDockAreaTabBar* CDockAreaTitleBar::tabBar() const
{
return d->TabBar;
}
//============================================================================
void CDockAreaTitleBar::markTabsMenuOutdated()
{
qDebug() << "CDockAreaTitleBar::markTabsMenuOutdated()";
d->MenuOutdated = true;
}
//============================================================================
void CDockAreaTitleBar::onTabsMenuAboutToShow()
{
if (!d->MenuOutdated)
{
return;
}
QMenu* menu = d->TabsMenuButton->menu();
menu->clear();
for (int i = 0; i < d->TabBar->count(); ++i)
{
if (!d->TabBar->isTabOpen(i))
{
continue;
}
auto Tab = d->TabBar->tab(i);
QAction* Action = menu->addAction(Tab->icon(), Tab->text());
Action->setData(i);
}
d->MenuOutdated = false;
}
//============================================================================
void CDockAreaTitleBar::onCloseButtonClicked()
{
qDebug() << "CDockAreaTitleBar::onCloseButtonClicked";
d->TabBar->closeTab(d->TabBar->currentIndex());
}
//============================================================================
void CDockAreaTitleBar::onTabsMenuActionTriggered(QAction* Action)
{
int Index = Action->data().toInt();
d->TabBar->setCurrentIndex(Index);
}
} // namespace ads
//---------------------------------------------------------------------------
// EOF DockAreaTitleBar.cpp

57
src/DockAreaTitleBar.h Normal file
View File

@ -0,0 +1,57 @@
#ifndef DockAreaTitleBarH
#define DockAreaTitleBarH
//============================================================================
/// \file DockAreaTitleBar.h
/// \author Uwe Kindler
/// \date 12.10.2018
/// \brief Declaration of CDockAreaTitleBar class
//============================================================================
//============================================================================
// INCLUDES
//============================================================================
#include <QFrame>
namespace ads
{
class CDockAreaTabBar;
class CDockAreaWidget;
struct DockAreaTitleBarPrivate;
/**
* Title bar of a dock area
*/
class CDockAreaTitleBar : public QFrame
{
Q_OBJECT
private:
DockAreaTitleBarPrivate* d; ///< private data (pimpl)
friend class DockAreaTitleBarPrivate;
private slots:
void markTabsMenuOutdated();
void onTabsMenuAboutToShow();
void onCloseButtonClicked();
void onTabsMenuActionTriggered(QAction* Action);
public:
using Super = QFrame;
/**
* Default Constructor
*/
CDockAreaTitleBar(CDockAreaWidget* parent);
/**
* Virtual Destructor
*/
virtual ~CDockAreaTitleBar();
/**
* Returns the pointer to the tabBar()
*/
CDockAreaTabBar* tabBar() const;
}; // class name
}
// namespace ads
//-----------------------------------------------------------------------------
#endif // DockAreaTitleBarH

View File

@ -65,77 +65,8 @@ static const int APPEND = -1;
/**
* Default stack area layout
*/
class CStackedDockAreaLayout
{
private:
QStackedLayout* Layout;
public:
CStackedDockAreaLayout(QBoxLayout* ParentLayout)
{
Layout = new QStackedLayout();
Layout->setContentsMargins(0, 0, 0, 0);
Layout->setSpacing(0);
Layout->setSizeConstraint(QLayout::SetNoConstraint);
ParentLayout->addLayout(Layout, 1);
}
int count() const
{
return Layout->count();
}
void insertWidget(int index, QWidget* Widget)
{
Layout->insertWidget(index, Widget);
}
void removeWidget(QWidget* Widget)
{
Layout->removeWidget(Widget);
}
void setCurrentIndex(int Index)
{
Layout->setCurrentIndex(Index);
}
int currentIndex() const
{
return Layout->currentIndex();
}
QWidget* currentWidget() const
{
return Layout->currentWidget();
}
bool isEmpty() const
{
return Layout->isEmpty();
}
int indexOf(QWidget* w) const
{
return Layout->indexOf(w);
}
QWidget* widget(int index) const
{
return Layout->widget(index);
}
QRect geometry() const
{
return Layout->geometry();
}
};
/**
* New dock area layout
* New dock area layout mimics stack layout but ony inserts the current
* widget
*/
class CDockAreaLayout
{
@ -284,7 +215,6 @@ struct DockAreaWidgetPrivate
CDockAreaTabBar* TabBar;
QPushButton* TabsMenuButton;
QPushButton* CloseButton;
//int TabsLayoutInitCount;
CDockManager* DockManager = nullptr;
bool MenuOutdated = true;

View File

@ -47,6 +47,8 @@ class CDockManager;
class CDockAreaTabBar;
class CDockWidgetTab;
struct DockWidgetTabPrivate;
class CDockAreaTitleBar;
struct DockAreaTitleBarPrivate;
/**
* This implements a floating widget that is a dock container that accepts
@ -64,6 +66,8 @@ private:
friend class CDockAreaTabBar;
friend struct DockWidgetTabPrivate;
friend class CDockWidgetTab;
friend class CDockAreaTitleBar;
friend struct DockAreaTitleBarPrivate;
private slots:
void onDockAreasAddedOrRemoved();

View File

@ -40,7 +40,8 @@ HEADERS += \
DockWidgetTab.h \
FloatingDockContainer.h \
DockOverlay.h \
DockSplitter.h
DockSplitter.h \
DockAreaTitleBar.h
@ -54,4 +55,5 @@ SOURCES += \
DockWidgetTab.cpp \
FloatingDockContainer.cpp \
DockOverlay.cpp \
DockSplitter.cpp
DockSplitter.cpp \
DockAreaTitleBar.cpp