Skip to content

Commit c973482

Browse files
author
Uwe Kindler
committed
Properly implemented showing and hiding of TitleBarUndockButton
1 parent 1886244 commit c973482

8 files changed

+377
-47
lines changed

src/DockAreaWidget.cpp

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ static const int APPEND = -1;
6666

6767

6868
/**
69-
* New dock area layout mimics stack layout but ony inserts the current
70-
* widget
69+
* New dock area layout mimics stack layout but only inserts the current
70+
* widget into the internal QLayout object
7171
*/
7272
class CDockAreaLayout
7373
{
@@ -78,17 +78,27 @@ class CDockAreaLayout
7878
QWidget* m_CurrentWidget = nullptr;
7979

8080
public:
81+
/**
82+
* Creates an instance with the given parent layout
83+
*/
8184
CDockAreaLayout(QBoxLayout* ParentLayout)
8285
: m_ParentLayout(ParentLayout)
8386
{
8487

8588
}
8689

90+
/**
91+
* Returns the number of widgets in this layout
92+
*/
8793
int count() const
8894
{
8995
return m_Widgets.count();
9096
}
9197

98+
/**
99+
* Inserts the widget at the given index position into the internal widget
100+
* list
101+
*/
92102
void insertWidget(int index, QWidget* Widget)
93103
{
94104
Widget->setParent(0);
@@ -110,6 +120,9 @@ class CDockAreaLayout
110120
}
111121
}
112122

123+
/**
124+
* Removes the given widget from the lyout
125+
*/
113126
void removeWidget(QWidget* Widget)
114127
{
115128
if (currentWidget() == Widget)
@@ -125,11 +138,17 @@ class CDockAreaLayout
125138
m_Widgets.removeOne(Widget);
126139
}
127140

141+
/**
142+
* Returns the current selected widget
143+
*/
128144
QWidget* currentWidget() const
129145
{
130146
return m_CurrentWidget;
131147
}
132148

149+
/**
150+
* Activates the widget with the give index.
151+
*/
133152
void setCurrentIndex(int index)
134153
{
135154
QWidget *prev = currentWidget();
@@ -169,26 +188,41 @@ class CDockAreaLayout
169188
}
170189
}
171190

191+
/**
192+
* Returns the index of the current active widget
193+
*/
172194
int currentIndex() const
173195
{
174196
return m_CurrentIndex;
175197
}
176198

199+
/**
200+
* Returns true if there are no widgets in the layout
201+
*/
177202
bool isEmpty() const
178203
{
179204
return m_Widgets.empty();
180205
}
181206

207+
/**
208+
* Returns the index of the given widget
209+
*/
182210
int indexOf(QWidget* w) const
183211
{
184212
return m_Widgets.indexOf(w);
185213
}
186214

215+
/**
216+
* Returns the widget for the given index
217+
*/
187218
QWidget* widget(int index) const
188219
{
189220
return (index < m_Widgets.size()) ? m_Widgets.at(index) : nullptr;
190221
}
191222

223+
/**
224+
* Returns the geometry of the current active widget
225+
*/
192226
QRect geometry() const
193227
{
194228
return m_Widgets.empty() ? QRect() : currentWidget()->geometry();
@@ -254,12 +288,6 @@ struct DockAreaWidgetPrivate
254288
return DockWidget->property(INDEX_PROPERTY).toInt();
255289
}
256290

257-
/**
258-
* Updates the tab bar visibility depending on the number of dock widgets
259-
* in this area
260-
*/
261-
void updateTitleBarVisibility();
262-
263291
/**
264292
* Convenience function for tabbar access
265293
*/
@@ -293,19 +321,6 @@ void DockAreaWidgetPrivate::createTitleBar()
293321
}
294322

295323

296-
//============================================================================
297-
void DockAreaWidgetPrivate::updateTitleBarVisibility()
298-
{
299-
CDockContainerWidget* Container = _this->dockContainer();
300-
if (!Container)
301-
{
302-
return;
303-
}
304-
305-
TitleBar->setVisible(!Container->isFloating() || !Container->hasTopLevelDockWidget());
306-
}
307-
308-
309324
//============================================================================
310325
CDockAreaWidget::CDockAreaWidget(CDockManager* DockManager, CDockContainerWidget* parent) :
311326
QFrame(parent),
@@ -402,7 +417,7 @@ void CDockAreaWidget::removeDockWidget(CDockWidget* DockWidget)
402417
hideAreaWithNoVisibleContent();
403418
}
404419

405-
d->updateTitleBarVisibility();
420+
updateTitleBarVisibility();
406421
auto TopLevelDockWidget = dockContainer()->topLevelDockWidget();
407422
if (TopLevelDockWidget)
408423
{
@@ -440,7 +455,7 @@ void CDockAreaWidget::hideAreaWithNoVisibleContent()
440455
return;
441456
}
442457

443-
d->updateTitleBarVisibility();
458+
updateTitleBarVisibility();
444459
auto TopLevelWidget = Container->topLevelDockWidget();
445460
auto FloatingWidget = Container->floatingWidget();
446461
if (TopLevelWidget)
@@ -626,14 +641,20 @@ void CDockAreaWidget::toggleDockWidgetView(CDockWidget* DockWidget, bool Open)
626641
{
627642
Q_UNUSED(DockWidget);
628643
Q_UNUSED(Open);
629-
updateTabBarVisibility();
644+
updateTitleBarVisibility();
630645
}
631646

632647

633648
//============================================================================
634-
void CDockAreaWidget::updateTabBarVisibility()
649+
void CDockAreaWidget::updateTitleBarVisibility()
635650
{
636-
d->updateTitleBarVisibility();
651+
CDockContainerWidget* Container = dockContainer();
652+
if (!Container)
653+
{
654+
return;
655+
}
656+
657+
d->TitleBar->setVisible(!Container->isFloating() || !Container->hasTopLevelDockWidget());
637658
}
638659

639660

src/DockAreaWidget.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ private slots:
121121
/**
122122
* Updates the dock area layout and components visibility
123123
*/
124-
void updateTabBarVisibility();
124+
void updateTitleBarVisibility();
125125

126126
/**
127127
* This is the internal private function for setting the current widget.

src/DockContainerWidget.cpp

Lines changed: 79 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <QVariant>
3838
#include <QDebug>
3939
#include <QXmlStreamWriter>
40+
#include <QAbstractButton>
4041

4142
#include "DockManager.h"
4243
#include "DockAreaWidget.h"
@@ -105,6 +106,7 @@ class DockContainerWidgetPrivate
105106
bool isFloating = false;
106107
CDockAreaWidget* LastAddedAreaCache[5]{0, 0, 0, 0, 0};
107108
int VisibleDockAreaCount = -1;
109+
CDockAreaWidget* TopLevelDockArea = nullptr;
108110

109111
/**
110112
* Private data constructor
@@ -144,6 +146,12 @@ class DockContainerWidgetPrivate
144146
*/
145147
void addDockAreasToList(const QList<CDockAreaWidget*> NewDockAreas);
146148

149+
/**
150+
* Wrapper function for DockAreas append, that ensures that dock area signals
151+
* are properly connected to dock container slots
152+
*/
153+
void appendDockAreas(const QList<CDockAreaWidget*> NewDockAreas);
154+
147155
/**
148156
* Save state of child nodes
149157
*/
@@ -208,11 +216,31 @@ class DockContainerWidgetPrivate
208216
return VisibleDockAreaCount;
209217
}
210218

219+
/**
220+
* The visible dock area count changes, if dock areas are remove, added or
221+
* when its view is toggled
222+
*/
223+
void onVisibleDockAreaCountChanged();
224+
225+
void emitDockAreasRemoved()
226+
{
227+
onVisibleDockAreaCountChanged();
228+
emit _this->dockAreasRemoved();
229+
}
230+
231+
void emitDockAreasAdded()
232+
{
233+
onVisibleDockAreaCountChanged();
234+
emit _this->dockAreasAdded();
235+
}
236+
211237
// private slots: ------------------------------------------------------------
212238
void onDockAreaViewToggled(bool Visible)
213239
{
214-
std::cout << "onDockAreaViewToggled " << Visible << std::endl;
240+
CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(_this->sender());
215241
VisibleDockAreaCount += Visible ? 1 : -1;
242+
onVisibleDockAreaCountChanged();
243+
emit _this->dockAreaViewToggled(DockArea, Visible);
216244
}
217245
}; // struct DockContainerWidgetPrivate
218246

@@ -225,6 +253,24 @@ DockContainerWidgetPrivate::DockContainerWidgetPrivate(CDockContainerWidget* _pu
225253
}
226254

227255

256+
//============================================================================
257+
void DockContainerWidgetPrivate::onVisibleDockAreaCountChanged()
258+
{
259+
auto TopLevelDockArea = _this->topLevelDockArea();
260+
261+
if (TopLevelDockArea)
262+
{
263+
this->TopLevelDockArea = TopLevelDockArea;
264+
TopLevelDockArea->titleBarButton(TitleBarButtonUndock)->setVisible(false || !_this->isFloating());
265+
}
266+
else if (this->TopLevelDockArea)
267+
{
268+
this->TopLevelDockArea->titleBarButton(TitleBarButtonUndock)->setVisible(true);
269+
this->TopLevelDockArea = nullptr;
270+
}
271+
}
272+
273+
228274
//============================================================================
229275
void DockContainerWidgetPrivate::dropIntoContainer(CFloatingDockContainer* FloatingWidget,
230276
DockWidgetArea area)
@@ -299,7 +345,7 @@ void DockContainerWidgetPrivate::dropIntoSection(CFloatingDockContainer* Floatin
299345
}
300346
TargetArea->setCurrentIndex(0); // make the topmost widget active
301347
FloatingWidget->deleteLater();
302-
TargetArea->updateTabBarVisibility();
348+
TargetArea->updateTitleBarVisibility();
303349
return;
304350
}
305351

@@ -364,21 +410,39 @@ void DockContainerWidgetPrivate::addDockAreasToList(const QList<CDockAreaWidget*
364410
{
365411
int CountBefore = DockAreas.count();
366412
int NewAreaCount = NewDockAreas.count();
367-
DockAreas.append(NewDockAreas);
413+
appendDockAreas(NewDockAreas);
414+
// If the user dropped a floating widget that contains only one single
415+
// visible dock area, then its title bar button TitleBarButtonUndock is
416+
// likely hidden. We need to ensure, that it is visible
417+
for (auto DockArea : NewDockAreas)
418+
{
419+
DockArea->titleBarButton(TitleBarButtonUndock)->setVisible(true);
420+
}
368421

369422
// We need to ensure, that the dock area title bar is visible. The title bar
370423
// is invisible, if the dock are is a single dock area in a floating widget.
371424
if (1 == CountBefore)
372425
{
373-
DockAreas.at(0)->updateTabBarVisibility();
426+
DockAreas.at(0)->updateTitleBarVisibility();
374427
}
375428

376429
if (1 == NewAreaCount)
377430
{
378-
DockAreas.last()->updateTabBarVisibility();
431+
DockAreas.last()->updateTitleBarVisibility();
379432
}
380433

381-
emit _this->dockAreasAdded();
434+
emitDockAreasAdded();
435+
}
436+
437+
438+
//============================================================================
439+
void DockContainerWidgetPrivate::appendDockAreas(const QList<CDockAreaWidget*> NewDockAreas)
440+
{
441+
DockAreas.append(NewDockAreas);
442+
for (auto DockArea : NewDockAreas)
443+
{
444+
_this->connect(DockArea, SIGNAL(viewToggled(bool)), SLOT(onDockAreaViewToggled(bool)));
445+
}
382446
}
383447

384448

@@ -588,7 +652,7 @@ bool DockContainerWidgetPrivate::restoreDockArea(QXmlStreamReader& s,
588652
else
589653
{
590654
DockArea->setProperty("currentDockWidget", CurrentDockWidget);
591-
DockAreas.append(DockArea);
655+
appendDockAreas({DockArea});
592656
}
593657

594658
CreatedWidget = DockArea;
@@ -631,7 +695,7 @@ CDockAreaWidget* DockContainerWidgetPrivate::dockWidgetIntoContainer(DockWidgetA
631695
CDockAreaWidget* NewDockArea = new CDockAreaWidget(DockManager, _this);
632696
NewDockArea->addDockWidget(Dockwidget);
633697
addDockArea(NewDockArea, area);
634-
NewDockArea->updateTabBarVisibility();
698+
NewDockArea->updateTitleBarVisibility();
635699
LastAddedAreaCache[areaIdToIndex(area)] = NewDockArea;
636700
return NewDockArea;
637701
}
@@ -673,9 +737,9 @@ void DockContainerWidgetPrivate::addDockArea(CDockAreaWidget* NewDockArea, DockW
673737
RootSplitter = NewSplitter;
674738
}
675739

676-
DockAreas.append(NewDockArea);
677-
NewDockArea->updateTabBarVisibility();
678-
emit _this->dockAreasAdded();
740+
appendDockAreas({NewDockArea});
741+
NewDockArea->updateTitleBarVisibility();
742+
emitDockAreasAdded();
679743
}
680744

681745

@@ -744,8 +808,8 @@ CDockAreaWidget* DockContainerWidgetPrivate::dockWidgetIntoDockArea(DockWidgetAr
744808
TargetAreaSplitter->insertWidget(index, NewSplitter);
745809
}
746810

747-
DockAreas.append(NewDockArea);
748-
emit _this->dockAreasAdded();
811+
appendDockAreas({NewDockArea});
812+
emitDockAreasAdded();
749813
return NewDockArea;
750814
}
751815

@@ -853,6 +917,7 @@ void CDockContainerWidget::addDockArea(CDockAreaWidget* DockAreaWidget,
853917
void CDockContainerWidget::removeDockArea(CDockAreaWidget* area)
854918
{
855919
qDebug() << "CDockContainerWidget::removeDockArea";
920+
area->disconnect(this);
856921
d->DockAreas.removeAll(area);
857922
CDockSplitter* Splitter = internal::findParent<CDockSplitter*>(area);
858923

@@ -913,7 +978,7 @@ void CDockContainerWidget::removeDockArea(CDockAreaWidget* area)
913978
// one single visible dock widget
914979
CDockWidget::emitTopLevelEventForWidget(TopLevelWidget, true);
915980
dumpLayout();
916-
emit dockAreasRemoved();
981+
d->emitDockAreasRemoved();
917982
}
918983

919984

0 commit comments

Comments
 (0)