Skip to content

Commit b6ee26a

Browse files
author
Uwe Kindler
committed
Improved hide / show functionality of dock widgets
1 parent 0d6f469 commit b6ee26a

File tree

8 files changed

+158
-94
lines changed

8 files changed

+158
-94
lines changed

demo/mainwindow.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,17 @@ static ads::CDockWidget* createLongTextLabelDockWidget(QMenu* ViewMenu)
2626
QLabel* l = new QLabel();
2727
l->setWordWrap(true);
2828
l->setAlignment(Qt::AlignTop | Qt::AlignLeft);
29-
l->setText(QString("Lorem Ipsum ist ein einfacher Demo-Text für die Print- "
29+
l->setText(QString("Label %1 %2 - Lorem Ipsum ist ein einfacher Demo-Text für die Print- "
3030
"und Schriftindustrie. Lorem Ipsum ist in der Industrie bereits der "
3131
"Standard Demo-Text seit 1500, als ein unbekannter Schriftsteller eine "
3232
"Hand voll Wörter nahm und diese durcheinander warf um ein Musterbuch zu "
3333
"erstellen. Es hat nicht nur 5 Jahrhunderte überlebt, sondern auch in "
3434
"Spruch in die elektronische Schriftbearbeitung geschafft (bemerke, nahezu "
3535
"unverändert). Bekannt wurde es 1960, mit dem erscheinen von Letrase, "
3636
"welches Passagen von Lorem Ipsum enhielt, so wie Desktop Software wie "
37-
"Aldus PageMaker - ebenfalls mit Lorem Ipsum."));
37+
"Aldus PageMaker - ebenfalls mit Lorem Ipsum.")
38+
.arg(LabelCount)
39+
.arg(QTime::currentTime().toString("hh:mm:ss:zzz")));
3840

3941
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Label %1").arg(LabelCount++));
4042
DockWidget->setWidget(l);

src/DockAreaWidget.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,18 @@ CDockWidget* CDockAreaWidget::currentDockWidget() const
504504
}
505505

506506

507+
//============================================================================
508+
void CDockAreaWidget::setCurrentDockWidget(CDockWidget* DockWidget)
509+
{
510+
int Index = tabIndex(DockWidget);
511+
if (Index < 0)
512+
{
513+
return;
514+
}
515+
setCurrentIndex(Index);
516+
}
517+
518+
507519
//============================================================================
508520
void CDockAreaWidget::setCurrentIndex(int index)
509521
{
@@ -530,6 +542,7 @@ void CDockAreaWidget::setCurrentIndex(int index)
530542

531543
if (i == index)
532544
{
545+
TitleWidget->show();
533546
TitleWidget->setActiveTab(true);
534547
d->TabsScrollArea->ensureWidgetVisible(TitleWidget);
535548
auto Features = TitleWidget->dockWidget()->features();
@@ -542,6 +555,7 @@ void CDockAreaWidget::setCurrentIndex(int index)
542555
}
543556

544557
d->ContentsLayout->setCurrentIndex(index);
558+
d->ContentsLayout->currentWidget()->show();
545559
emit currentChanged(index);
546560
}
547561

@@ -585,6 +599,22 @@ QList<CDockWidget*> CDockAreaWidget::dockWidgets() const
585599
}
586600

587601

602+
//============================================================================
603+
QList<CDockWidget*> CDockAreaWidget::openDockWidgets() const
604+
{
605+
QList<CDockWidget*> DockWidgetList;
606+
for (int i = 0; i < d->ContentsLayout->count(); ++i)
607+
{
608+
CDockWidget* DockWidget = dockWidget(i);
609+
if (!DockWidget->isClosed())
610+
{
611+
DockWidgetList.append(dockWidget(i));
612+
}
613+
}
614+
return DockWidgetList;
615+
}
616+
617+
588618
//============================================================================
589619
int CDockAreaWidget::indexOfContentByTitlePos(const QPoint& p, QWidget* exclude) const
590620
{
@@ -665,6 +695,22 @@ void CDockAreaWidget::updateDockArea()
665695
d->updateTabBar();
666696
}
667697

698+
699+
//============================================================================
700+
void CDockAreaWidget::hideEvent(QHideEvent* event)
701+
{
702+
QFrame::hideEvent(event);
703+
emit visibilityChanged(isVisible());
704+
}
705+
706+
707+
//============================================================================
708+
void CDockAreaWidget::showEvent(QShowEvent* event)
709+
{
710+
QFrame::showEvent(event);
711+
emit visibilityChanged(isVisible());
712+
}
713+
668714
} // namespace ads
669715

670716
//---------------------------------------------------------------------------

src/DockAreaWidget.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ private slots:
5656
void onTabsMenuActionTriggered(QAction* Action);
5757
void onCloseButtonClicked();
5858

59+
protected:
60+
virtual void hideEvent(QHideEvent *) override;
61+
virtual void showEvent(QShowEvent *) override;
62+
5963
public:
6064
/**
6165
* Default Constructor
@@ -120,10 +124,16 @@ private slots:
120124
int indexOfContentByTitlePos(const QPoint& pos, QWidget* exclude = nullptr) const;
121125

122126
/**
123-
* Returns a list of all dock widgets in this dock area
127+
* Returns a list of all dock widgets in this dock area.
128+
* This list contains open and closed dock widgets.
124129
*/
125130
QList<CDockWidget*> dockWidgets() const;
126131

132+
/**
133+
* Returns a list of dock widgets that are not closed
134+
*/
135+
QList<CDockWidget*> openDockWidgets() const;
136+
127137
/**
128138
* Returns the number of dock widgets in this area
129139
*/
@@ -149,6 +159,11 @@ private slots:
149159
*/
150160
CDockWidget* currentDockWidget() const;
151161

162+
/**
163+
* Shows the tab with tghe given dock widget
164+
*/
165+
void setCurrentDockWidget(CDockWidget* DockWidget);
166+
152167
public slots:
153168
/**
154169
* This sets the index position of the current tab page.
@@ -172,6 +187,14 @@ public slots:
172187
* @param index
173188
*/
174189
void currentChanged(int index);
190+
191+
/**
192+
* This signal is emitted if a dock areas visibility changed.
193+
* The visibility changes, if the last dock widget in a dock area is closed
194+
* or if one dock widget in a dock area with only closed dock widgets
195+
* becomes visible
196+
*/
197+
void visibilityChanged(bool Visible);
175198
}; // class DockAreaWidget
176199
}
177200
// namespace ads

src/DockContainerWidget.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,7 @@ void CDockContainerWidget::removeDockArea(CDockAreaWidget* area)
497497
area->setParent(0);
498498
if (!(Splitter && Splitter->count() == 1))
499499
{
500+
emit dockAreasRemoved();
500501
return;
501502
}
502503

@@ -586,6 +587,7 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
586587
}
587588
}
588589

590+
589591
} // namespace ads
590592

591593
//---------------------------------------------------------------------------

src/DockContainerWidget.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class CDockContainerWidget : public QFrame
5252
private:
5353
DockContainerWidgetPrivate* d; ///< private data (pimpl)
5454
friend class DockContainerWidgetPrivate;
55+
5556
protected:
5657
/**
5758
* Handles activation events to update zOrderIndex

src/DockWidget.cpp

Lines changed: 65 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ struct DockWidgetPrivate
6262
CDockManager* DockManager = nullptr;
6363
CDockAreaWidget* DockArea = nullptr;
6464
QAction* ToggleViewAction;
65+
bool Closed = false;
6566
struct CapturedState
6667
{
6768
QString DockTreePosition;
@@ -83,6 +84,16 @@ struct DockWidgetPrivate
8384
* Show dock widget
8485
*/
8586
void showDockWidget();
87+
88+
/**
89+
* Hides a parent splitter if all dock widgets in the splitter are closed
90+
*/
91+
void hideEmptyParentSplitter();
92+
93+
/**
94+
* Hides a dock area if all dock widgets in the area are closed
95+
*/
96+
void hideEmptyParentDockArea();
8697
};
8798
// struct DockWidgetPrivate
8899

@@ -131,36 +142,59 @@ void DockWidgetPrivate::capturedState()
131142
//============================================================================
132143
void DockWidgetPrivate::showDockWidget()
133144
{
134-
/*if (!CapturedState.DockContainer)
145+
DockArea->show();
146+
DockArea->setCurrentIndex(DockArea->tabIndex(_this));
147+
QSplitter* Splitter = internal::findParent<QSplitter*>(_this);
148+
if (Splitter)
135149
{
136-
auto FloatingWidget = new CFloatingDockContainer(_this);
137-
FloatingWidget->setGeometry(CapturedState.GlobalGeometry);
138-
FloatingWidget->show();
139-
return;
150+
Splitter->show();
140151
}
152+
}
141153

142-
CDockContainerWidget* DockContainer = CapturedState.DockContainer.data();
143-
QStringList DockTree = this->CapturedState.DockTreePosition.split(' ');
144-
QSplitter* splitter = DockContainer->findChild<QSplitter*>(QString(), Qt::FindDirectChildrenOnly);
145154

146-
while (splitter)
155+
//============================================================================
156+
void DockWidgetPrivate::hideEmptyParentSplitter()
157+
{
158+
QSplitter* Splitter = internal::findParent<QSplitter*>(_this);
159+
if (!Splitter)
147160
{
148-
161+
return;
149162
}
150163

151-
for (const auto& TreeItem : DockTree)
164+
for (int i = 0; i < Splitter->count(); ++i)
152165
{
166+
if (Splitter->widget(i)->isVisible())
167+
{
168+
return;
169+
}
170+
}
153171

154-
}*/
172+
Splitter->hide();
173+
}
155174

156-
std::cout << "DockWidgetPrivate::showDockWidget()" << std::endl;
157-
_this->show();
158-
DockArea->show();
159175

160-
QSplitter* Splitter = internal::findParent<QSplitter*>(_this);
161-
if (Splitter)
176+
//============================================================================
177+
void DockWidgetPrivate::hideEmptyParentDockArea()
178+
{
179+
auto OpenDockWidgets = DockArea->openDockWidgets();
180+
if (OpenDockWidgets.count() > 1)
162181
{
163-
Splitter->show();
182+
CDockWidget* NextDockWidget;
183+
if (OpenDockWidgets.last() == _this)
184+
{
185+
NextDockWidget = OpenDockWidgets[OpenDockWidgets.count() - 2];
186+
}
187+
else
188+
{
189+
int NextIndex = OpenDockWidgets.indexOf(_this) + 1;
190+
NextDockWidget = OpenDockWidgets[NextIndex];
191+
}
192+
193+
DockArea->setCurrentDockWidget(NextDockWidget);
194+
}
195+
else
196+
{
197+
DockArea->hide();
164198
}
165199
}
166200

@@ -270,6 +304,13 @@ bool CDockWidget::isFloating() const
270304
}
271305

272306

307+
//============================================================================
308+
bool CDockWidget::isClosed() const
309+
{
310+
return d->Closed;
311+
}
312+
313+
273314
//============================================================================
274315
QAction* CDockWidget::toggleViewAction() const
275316
{
@@ -280,28 +321,15 @@ QAction* CDockWidget::toggleViewAction() const
280321
//============================================================================
281322
void CDockWidget::toggleView(bool Open)
282323
{
283-
/*if ((d->DockArea != nullptr) == Open)
284-
{
285-
return;
286-
}
287-
288-
if (!Open && d->DockArea)
289-
{
290-
hideDockWidget(true);
291-
}
292-
else if (Open && !d->DockArea)
293-
{
294-
d->showDockWidget();
295-
}*/
296-
297324
if (Open)
298325
{
299326
d->showDockWidget();
300327
}
301328
else
302329
{
303-
hideDockWidget(true);
330+
hideDockWidget();
304331
}
332+
d->Closed = !Open;
305333
}
306334

307335

@@ -315,59 +343,13 @@ void CDockWidget::setDockArea(CDockAreaWidget* DockArea)
315343

316344

317345
//============================================================================
318-
void CDockWidget::hideDockWidget(bool RemoveFromDockArea)
346+
void CDockWidget::hideDockWidget()
319347
{
320-
/*d->capturedState();
321-
if (d->DockArea && RemoveFromDockArea)
322-
{
323-
d->DockArea->removeDockWidget(this);
324-
}
325-
this->setParent(d->DockManager);
326-
this->setDockArea(nullptr);
327-
// Remove title from dock area widget to prevent its deletion if dock
328-
// area is deleted
329-
d->TitleWidget->setParent(this);*/
330-
331-
std::cout << "CDockWidget::hideDockWidget" << std::endl;
332-
this->hide();
348+
CDockAreaWidget* DockArea = d->DockArea;
333349
d->ToggleViewAction->setChecked(false);
334350
d->TitleWidget->hide();
335-
CDockAreaWidget* DockArea = d->DockArea;
336-
for (int i = 0; i < DockArea->count(); ++i)
337-
{
338-
if (DockArea->dockWidget(i)->isVisible())
339-
{
340-
return;
341-
}
342-
}
343-
344-
if (DockArea->count() > 1)
345-
{
346-
if (DockArea->currentIndex() == (DockArea->count() - 1))
347-
{
348-
DockArea->setCurrentIndex(DockArea->currentIndex() - 1);
349-
}
350-
else
351-
{
352-
DockArea->setCurrentIndex(DockArea->currentIndex() + 1);
353-
}
354-
}
355-
QSplitter* Splitter = internal::findParent<QSplitter*>(this);
356-
if (!Splitter)
357-
{
358-
return;
359-
}
360-
361-
std::cout << "DockWidgets " << Splitter->count() << std::endl;
362-
for (int i = 0; i < Splitter->count(); ++i)
363-
{
364-
if (Splitter->widget(i)->isVisible())
365-
{
366-
return;
367-
}
368-
}
369-
370-
Splitter->hide();
351+
d->hideEmptyParentDockArea();
352+
d->hideEmptyParentSplitter();
371353
}
372354

373355
} // namespace ads

0 commit comments

Comments
 (0)