Skip to content

Commit 9bfb3fb

Browse files
author
Uwe Kindler
committed
Created new DockAreaTitleBar class to encapsulate all title bar functionality
1 parent 9c95e34 commit 9bfb3fb

File tree

7 files changed

+328
-82
lines changed

7 files changed

+328
-82
lines changed

src/DockAreaTabBar.cpp

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ struct DockAreaTabBarPrivate
3939
QWidget* TabsContainerWidget;
4040
QBoxLayout* TabsLayout;
4141
int CurrentIndex = -1;
42-
bool MenuOutdated = true;
43-
QMenu* TabsMenu;
4442

4543
/**
4644
* Private data constructor
@@ -266,7 +264,7 @@ void CDockAreaTabBar::insertTab(int Index, CDockWidgetTab* Tab)
266264
connect(Tab, SIGNAL(clicked()), this, SLOT(onTabClicked()));
267265
connect(Tab, SIGNAL(moved(const QPoint&)), this, SLOT(onTabWidgetMoved(const QPoint&)));
268266
Tab->installEventFilter(this);
269-
d->MenuOutdated = true;
267+
emit tabInserted(Index);
270268
if (Index <= d->CurrentIndex)
271269
{
272270
setCurrentIndex(d->CurrentIndex++);
@@ -320,10 +318,10 @@ void CDockAreaTabBar::removeTab(CDockWidgetTab* Tab)
320318
}
321319
}
322320

321+
emit removingTab(RemoveIndex);
323322
d->TabsLayout->removeWidget(Tab);
324323
Tab->disconnect(this);
325324
Tab->removeEventFilter(this);
326-
d->MenuOutdated = true;
327325
qDebug() << "NewCurrentIndex " << NewCurrentIndex;
328326
if (NewCurrentIndex != d->CurrentIndex)
329327
{
@@ -448,28 +446,55 @@ void CDockAreaTabBar::closeTab(int Index)
448446
{
449447
return;
450448
}
449+
450+
auto Tab = tab(Index);
451+
if (!Tab->isVisibleTo(this))
452+
{
453+
return;
454+
}
451455
emit tabCloseRequested(Index);
456+
Tab->hide();
452457
}
453458

454459

455460
//===========================================================================
456461
bool CDockAreaTabBar::eventFilter(QObject *watched, QEvent *event)
457462
{
458463
bool Result = Super::eventFilter(watched, event);
459-
if (event->type() != QEvent::Hide)
464+
CDockWidgetTab* Tab = qobject_cast<CDockWidgetTab*>(watched);
465+
if (!Tab)
460466
{
461467
return Result;
462468
}
463469

464-
CDockWidgetTab* Tab = qobject_cast<CDockWidgetTab*>(watched);
465-
if (!Tab)
470+
if (event->type() == QEvent::Hide)
466471
{
467472
return Result;
468473
}
469474

470-
qDebug() << "Hide event for tab " << Tab->text();
475+
int TabIndex = d->TabsLayout->indexOf(Tab);
476+
switch (event->type())
477+
{
478+
case QEvent::Hide: emit tabClosed(TabIndex); break;
479+
case QEvent::Show: emit tabOpened(TabIndex); break;
480+
default:
481+
break;
482+
}
483+
471484
return Result;
472485
}
486+
487+
488+
//===========================================================================
489+
bool CDockAreaTabBar::isTabOpen(int Index) const
490+
{
491+
if (Index < 0 || Index >= count())
492+
{
493+
return false;
494+
}
495+
496+
return tab(Index)->isVisibleTo(this);
497+
}
473498
} // namespace ads
474499

475500
//---------------------------------------------------------------------------

src/DockAreaTabBar.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,13 @@ private slots:
111111
*/
112112
virtual bool eventFilter(QObject *watched, QEvent *event) override;
113113

114+
/**
115+
* This function returns true if the tab is open, that means if it is
116+
* visible to the user. If the function returns false, the tab is
117+
* closed
118+
*/
119+
bool isTabOpen(int Index) const;
120+
114121
public slots:
115122
/**
116123
* This property sets the index of the tab bar's visible tab
@@ -147,11 +154,33 @@ public slots:
147154
*/
148155
void tabCloseRequested(int index);
149156

157+
/**
158+
* This signal is emitted if a tab has been closed
159+
*/
160+
void tabClosed(int index);
161+
162+
/**
163+
* This signal is emitted if a tab has been opened.
164+
* A tab is opened if it has been made visible
165+
*/
166+
void tabOpened(int index);
167+
150168
/**
151169
* This signal is emitted when the tab has moved the tab at index position
152170
* from to index position to.
153171
*/
154172
void tabMoved(int from, int to);
173+
174+
/**
175+
* This signal is emitted, just before the tab with the given index is
176+
* removed
177+
*/
178+
void removingTab(int index);
179+
180+
/**
181+
* This signal is emitted if a tab has been inserted
182+
*/
183+
void tabInserted(int index);
155184
}; // class CDockAreaTabBar
156185
} // namespace ads
157186
//-----------------------------------------------------------------------------

src/DockAreaTitleBar.cpp

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
//============================================================================
2+
/// \file DockAreaTitleBar.cpp
3+
/// \author Uwe Kindler
4+
/// \date 12.10.2018
5+
/// \brief Implementation of CDockAreaTitleBar class
6+
//============================================================================
7+
8+
//============================================================================
9+
// INCLUDES
10+
//============================================================================
11+
#include "DockAreaTitleBar.h"
12+
13+
#include <QPushButton>
14+
#include <QBoxLayout>
15+
#include <QStyle>
16+
#include <QMenu>
17+
#include <QScrollArea>
18+
#include <QMouseEvent>
19+
#include <QDebug>
20+
21+
#include "FloatingDockContainer.h"
22+
#include "DockAreaWidget.h"
23+
#include "DockOverlay.h"
24+
#include "DockManager.h"
25+
#include "DockWidget.h"
26+
#include "DockWidgetTab.h"
27+
#include "DockAreaTabBar.h"
28+
29+
#include <iostream>
30+
31+
namespace ads
32+
{
33+
/**
34+
* Private data class of CDockAreaTitleBar class (pimpl)
35+
*/
36+
struct DockAreaTitleBarPrivate
37+
{
38+
CDockAreaTitleBar* _this;
39+
QPushButton* TabsMenuButton;
40+
QPushButton* CloseButton;
41+
QBoxLayout* TopLayout;
42+
CDockAreaWidget* DockArea;
43+
CDockAreaTabBar* TabBar;
44+
bool MenuOutdated = true;
45+
QMenu* TabsMenu;
46+
47+
/**
48+
* Private data constructor
49+
*/
50+
DockAreaTitleBarPrivate(CDockAreaTitleBar* _public);
51+
52+
/**
53+
* Creates the title bar close and menu buttons
54+
*/
55+
void createButtons();
56+
57+
/**
58+
* Creates the internal TabBar
59+
*/
60+
void createTabBar();
61+
};// struct DockAreaTitleBarPrivate
62+
63+
64+
65+
//============================================================================
66+
DockAreaTitleBarPrivate::DockAreaTitleBarPrivate(CDockAreaTitleBar* _public) :
67+
_this(_public)
68+
{
69+
70+
}
71+
72+
73+
//============================================================================
74+
void DockAreaTitleBarPrivate::createButtons()
75+
{
76+
TabsMenuButton = new QPushButton();
77+
TabsMenuButton->setObjectName("tabsMenuButton");
78+
TabsMenuButton->setFlat(true);
79+
TabsMenuButton->setIcon(_this->style()->standardIcon(QStyle::SP_TitleBarUnshadeButton));
80+
TabsMenuButton->setMaximumWidth(TabsMenuButton->iconSize().width());
81+
82+
QMenu* TabsMenu = new QMenu(TabsMenuButton);
83+
_this->connect(TabsMenu, SIGNAL(aboutToShow()), SLOT(onTabsMenuAboutToShow()));
84+
TabsMenuButton->setMenu(TabsMenu);
85+
TopLayout->addWidget(TabsMenuButton, 0);
86+
TabsMenuButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
87+
_this->connect(TabsMenuButton->menu(), SIGNAL(triggered(QAction*)),
88+
SLOT(onTabsMenuActionTriggered(QAction*)));
89+
90+
CloseButton = new QPushButton();
91+
CloseButton->setObjectName("closeButton");
92+
CloseButton->setFlat(true);
93+
CloseButton->setIcon(_this->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
94+
CloseButton->setToolTip(QObject::tr("Close"));
95+
CloseButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
96+
TopLayout->addWidget(CloseButton, 0);
97+
_this->connect(CloseButton, SIGNAL(clicked()), SLOT(onCloseButtonClicked()));
98+
}
99+
100+
101+
//============================================================================
102+
void DockAreaTitleBarPrivate::createTabBar()
103+
{
104+
TabBar = new CDockAreaTabBar(DockArea);
105+
TopLayout->addWidget(TabBar);
106+
_this->connect(TabBar, SIGNAL(tabClosed()), SLOT(markTabsMenuOutdated()));
107+
_this->connect(TabBar, SIGNAL(tabOpened()), SLOT(markTabsMenuOutdated()));
108+
_this->connect(TabBar, SIGNAL(tabInserted()), SLOT(markTabsMenuOutdated()));
109+
_this->connect(TabBar, SIGNAL(tabRemoved()), SLOT(markTabsMenuOutdated()));
110+
}
111+
112+
113+
//============================================================================
114+
CDockAreaTitleBar::CDockAreaTitleBar(CDockAreaWidget* parent) :
115+
QFrame(parent),
116+
d(new DockAreaTitleBarPrivate(this))
117+
{
118+
d->DockArea = parent;
119+
120+
setObjectName("dockAreaTitleBar");
121+
d->TopLayout = new QBoxLayout(QBoxLayout::LeftToRight);
122+
d->TopLayout->setContentsMargins(0, 0, 0, 0);
123+
d->TopLayout->setSpacing(0);
124+
setLayout(d->TopLayout);
125+
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
126+
127+
d->createTabBar();
128+
d->createButtons();
129+
130+
}
131+
132+
133+
//============================================================================
134+
CDockAreaTitleBar::~CDockAreaTitleBar()
135+
{
136+
delete d;
137+
}
138+
139+
140+
//============================================================================
141+
CDockAreaTabBar* CDockAreaTitleBar::tabBar() const
142+
{
143+
return d->TabBar;
144+
}
145+
146+
147+
//============================================================================
148+
void CDockAreaTitleBar::markTabsMenuOutdated()
149+
{
150+
qDebug() << "CDockAreaTitleBar::markTabsMenuOutdated()";
151+
d->MenuOutdated = true;
152+
}
153+
154+
155+
//============================================================================
156+
void CDockAreaTitleBar::onTabsMenuAboutToShow()
157+
{
158+
if (!d->MenuOutdated)
159+
{
160+
return;
161+
}
162+
163+
QMenu* menu = d->TabsMenuButton->menu();
164+
menu->clear();
165+
for (int i = 0; i < d->TabBar->count(); ++i)
166+
{
167+
if (!d->TabBar->isTabOpen(i))
168+
{
169+
continue;
170+
}
171+
auto Tab = d->TabBar->tab(i);
172+
QAction* Action = menu->addAction(Tab->icon(), Tab->text());
173+
Action->setData(i);
174+
}
175+
176+
d->MenuOutdated = false;
177+
}
178+
179+
180+
//============================================================================
181+
void CDockAreaTitleBar::onCloseButtonClicked()
182+
{
183+
qDebug() << "CDockAreaTitleBar::onCloseButtonClicked";
184+
d->TabBar->closeTab(d->TabBar->currentIndex());
185+
}
186+
187+
188+
//============================================================================
189+
void CDockAreaTitleBar::onTabsMenuActionTriggered(QAction* Action)
190+
{
191+
int Index = Action->data().toInt();
192+
d->TabBar->setCurrentIndex(Index);
193+
}
194+
195+
196+
} // namespace ads
197+
198+
//---------------------------------------------------------------------------
199+
// EOF DockAreaTitleBar.cpp

src/DockAreaTitleBar.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#ifndef DockAreaTitleBarH
2+
#define DockAreaTitleBarH
3+
//============================================================================
4+
/// \file DockAreaTitleBar.h
5+
/// \author Uwe Kindler
6+
/// \date 12.10.2018
7+
/// \brief Declaration of CDockAreaTitleBar class
8+
//============================================================================
9+
10+
//============================================================================
11+
// INCLUDES
12+
//============================================================================
13+
#include <QFrame>
14+
15+
namespace ads
16+
{
17+
class CDockAreaTabBar;
18+
class CDockAreaWidget;
19+
struct DockAreaTitleBarPrivate;
20+
21+
/**
22+
* Title bar of a dock area
23+
*/
24+
class CDockAreaTitleBar : public QFrame
25+
{
26+
Q_OBJECT
27+
private:
28+
DockAreaTitleBarPrivate* d; ///< private data (pimpl)
29+
friend class DockAreaTitleBarPrivate;
30+
31+
private slots:
32+
void markTabsMenuOutdated();
33+
void onTabsMenuAboutToShow();
34+
void onCloseButtonClicked();
35+
void onTabsMenuActionTriggered(QAction* Action);
36+
37+
public:
38+
using Super = QFrame;
39+
/**
40+
* Default Constructor
41+
*/
42+
CDockAreaTitleBar(CDockAreaWidget* parent);
43+
44+
/**
45+
* Virtual Destructor
46+
*/
47+
virtual ~CDockAreaTitleBar();
48+
49+
/**
50+
* Returns the pointer to the tabBar()
51+
*/
52+
CDockAreaTabBar* tabBar() const;
53+
}; // class name
54+
}
55+
// namespace ads
56+
//-----------------------------------------------------------------------------
57+
#endif // DockAreaTitleBarH

0 commit comments

Comments
 (0)