Skip to content

Commit 844c853

Browse files
author
Uwe Kindler
committed
Fixed a bug with shoing and hiding empty splitters, added some pictures to main page
1 parent 990d323 commit 844c853

9 files changed

+96
-31
lines changed

README.md

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,53 @@
11
# Advanced Docking System for Qt
22

3-
Manages content widgets more like Visual Studio or similar programs.
4-
I also try to get everything done with basic Qt functionality.
5-
Basic usage of QWidgets an QLayouts and using basic styles as much as possible.
3+
Qt Advanced Docking System lets you create customizable layouts using a full
4+
featured window docking system similar to what is found in many popular
5+
integrated development environements (IDEs) such as Visual Studio.
6+
Everything is implemented with standard Qt functionality without any
7+
platform specific code. Basic usage of QWidgets an QLayouts and using basic
8+
styles as much as possible.
9+
10+
This work is based on and inspired by the
11+
[Advanced Docking System for Qt](https://github.com/mfreiholz/Qt-Advanced-Docking-System)
12+
from Manuel Freiholz. I did an almost complete rewrite of his code to improve
13+
code quality, readibility and to fix all issues from the issue tracker
14+
of his docking system project.
15+
16+
## Features
17+
### Docking everywhere - no central widget
18+
There is no central widget like in the Qt docking system. You can dock on every
19+
border of the main window or you can dock into each dock area - so you are
20+
free to dock almost everywhere.
21+
22+
![Layout of widgets](preview.png)
623

7-
![Layout of widgets](preview.png)
824
![Dropping widgets](preview-dragndrop.png)
925

26+
### Docking inside floating windows
27+
There is no difference between the main window and a floating window. Docking
28+
into floating windows is supported.
29+
30+
![Docking inside floating windows](floating-widget-dragndrop.png)
31+
32+
### Grouped dragging
33+
When dragging the titlebar of a dock, all the tabs that are tabbed with it are
34+
going to be dragged. So you can move complete groups of tabbed widgets into
35+
a floating widget or from one dock area to another one.
36+
37+
![Grouped dragging](grouped-dragging.png)
38+
39+
1040
## Tested Compatible Environments
1141
- Windows 10
1242

1343
## Build
14-
Open the `build.pro` with QtCreator and start the build, that's it.
44+
Open the `ads.pro` with QtCreator and start the build, that's it.
1545
You can run the demo project and test it yourself.
1646

17-
## Release & Development
18-
The `master` branch is not guaranteed to be stable or does not even build, since it is the main working branch.
19-
If you want a version that builds, you should always use a release/beta tag.
20-
2147
## Developers
2248
- Uwe Kindler, Project Maintainer
2349
- Manuel Freiholz
2450

2551
## License information
26-
This project uses the [GPLv3 license] (gnu-gpl-v3.0.md)
52+
This project uses the [GPLv3 license](gnu-gpl-v3.0.md)
2753

floating-widget-dragndrop.png

222 KB
Loading

grouped-dragging.png

41.4 KB
Loading

src/DockContainerWidget.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,7 @@ bool DockContainerWidgetPrivate::restoreDockArea(QDataStream& stream,
433433
DockArea->addDockWidget(DockWidget);
434434

435435
DockArea->hide();
436+
DockWidget->setToggleViewActionChecked(!Closed);
436437
DockWidget->setProperty("closed", Closed);
437438
DockWidget->setProperty("dirty", false);
438439
}
@@ -762,6 +763,21 @@ int CDockContainerWidget::dockAreaCount() const
762763
}
763764

764765

766+
//============================================================================
767+
int CDockContainerWidget::visibleDockAreaCount() const
768+
{
769+
// TODO Cache or precalculate this to speed it up because it is used during
770+
// movement of floating widget
771+
int Result = 0;
772+
for (auto DockArea : d->DockAreas)
773+
{
774+
Result += DockArea->isVisible() ? 1 : 0;
775+
}
776+
777+
return Result;
778+
}
779+
780+
765781
//============================================================================
766782
void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWidget,
767783
const QPoint& TargetPos)

src/DockContainerWidget.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ class CDockContainerWidget : public QFrame
134134
*/
135135
int dockAreaCount() const;
136136

137+
/**
138+
* Returns the number of visible dock areas
139+
*/
140+
int visibleDockAreaCount() const;
141+
137142
/**
138143
* This function returns true, if this container is in a floating widget
139144
*/

src/DockSplitter.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,22 @@ CDockSplitter::~CDockSplitter()
2121
qDebug() << "~CDockSplitter";
2222
}
2323

24+
25+
//============================================================================
26+
bool CDockSplitter::hasVisibleContent() const
27+
{
28+
// TODO Cache or precalculate this to speed up
29+
for (int i = 0; i < count(); ++i)
30+
{
31+
if (widget(i)->isVisibleTo(this))
32+
{
33+
return true;
34+
}
35+
}
36+
37+
return false;
38+
}
39+
2440
} // namespace ads
2541

2642
//---------------------------------------------------------------------------

src/DockSplitter.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ class CDockSplitter : public QSplitter
2828
* Prints debug info
2929
*/
3030
virtual ~CDockSplitter();
31+
32+
/**
33+
* Returns true, if any of the internal widgets is visible
34+
*/
35+
bool hasVisibleContent() const;
3136
}; // class CDockSplitter
3237

3338
} // namespace ads

src/DockWidget.cpp

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include "DockManager.h"
4646
#include "FloatingDockContainer.h"
4747
#include "DockStateSerialization.h"
48+
#include "DockSplitter.h"
4849
#include "ads_globals.h"
4950

5051
namespace ads
@@ -82,7 +83,7 @@ struct DockWidgetPrivate
8283
/**
8384
* Hides a parent splitter if all dock widgets in the splitter are closed
8485
*/
85-
void hideEmptyParentSplitter();
86+
void hideEmptyParentSplitters();
8687

8788
/**
8889
* Hides a dock area if all dock widgets in the area are closed
@@ -119,9 +120,10 @@ void DockWidgetPrivate::showDockWidget()
119120
DockArea->show();
120121
DockArea->setCurrentIndex(DockArea->tabIndex(_this));
121122
QSplitter* Splitter = internal::findParent<QSplitter*>(_this);
122-
if (Splitter)
123+
while (Splitter && !Splitter->isVisible())
123124
{
124125
Splitter->show();
126+
Splitter = internal::findParent<QSplitter*>(Splitter);
125127
}
126128

127129
CDockContainerWidget* Container = DockArea->dockContainer();
@@ -138,32 +140,25 @@ void DockWidgetPrivate::showDockWidget()
138140
//============================================================================
139141
void DockWidgetPrivate::hideDockWidget()
140142
{
141-
ToggleViewAction->setChecked(false);
142143
TitleWidget->hide();
143144
hideEmptyParentDockArea();
144-
hideEmptyParentSplitter();
145+
hideEmptyParentSplitters();
145146
hideEmptyFloatingWidget();
146147
}
147148

148149

149150
//============================================================================
150-
void DockWidgetPrivate::hideEmptyParentSplitter()
151+
void DockWidgetPrivate::hideEmptyParentSplitters()
151152
{
152-
QSplitter* Splitter = internal::findParent<QSplitter*>(_this);
153-
if (!Splitter)
153+
auto Splitter = internal::findParent<CDockSplitter*>(_this);
154+
while (Splitter && Splitter->isVisible())
154155
{
155-
return;
156-
}
157-
158-
for (int i = 0; i < Splitter->count(); ++i)
159-
{
160-
if (Splitter->widget(i)->isVisibleTo(Splitter))
156+
if (!Splitter->hasVisibleContent())
161157
{
162-
return;
158+
Splitter->hide();
163159
}
160+
Splitter = internal::findParent<CDockSplitter*>(Splitter);
164161
}
165-
166-
Splitter->hide();
167162
}
168163

169164

@@ -346,6 +341,9 @@ void CDockWidget::toggleView(bool Open)
346341
d->hideDockWidget();
347342
}
348343
d->Closed = !Open;
344+
d->ToggleViewAction->blockSignals(true);
345+
d->ToggleViewAction->setChecked(Open);
346+
d->ToggleViewAction->blockSignals(false);
349347
if (!Open)
350348
{
351349
emit closed();

src/FloatingDockContainer.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,6 @@ void FloatingDockContainerPrivate::updateDropOverlays(const QPoint& GlobalPos)
131131
}
132132

133133
DropContainer = TopContainer;
134-
//std::cout << "TopContainer " << TopContainer << std::endl;
135134
auto ContainerOverlay = DockManager->containerOverlay();
136135
auto DockAreaOverlay = DockManager->dockAreaOverlay();
137136

@@ -142,15 +141,15 @@ void FloatingDockContainerPrivate::updateDropOverlays(const QPoint& GlobalPos)
142141
return;
143142
}
144143

145-
ContainerOverlay->setAllowedAreas(TopContainer->dockAreaCount() > 1 ?
144+
int VisibleDockAreas = TopContainer->visibleDockAreaCount();
145+
ContainerOverlay->setAllowedAreas(VisibleDockAreas > 1 ?
146146
OuterDockAreas : AllDockAreas);
147147
ContainerOverlay->showOverlay(TopContainer);
148-
//ContainerOverlay->raise();
149148

150149
auto DockArea = TopContainer->dockAreaAt(GlobalPos);
151-
if (DockArea && TopContainer->dockAreaCount() > 0)
150+
if (DockArea && DockArea->isVisible() && VisibleDockAreas > 0)
152151
{
153-
DockAreaOverlay->setAllowedAreas((TopContainer->dockAreaCount() == 1) ?
152+
DockAreaOverlay->setAllowedAreas((VisibleDockAreas == 1) ?
154153
NoDockWidgetArea : AllDockAreas);
155154
DockWidgetArea Area = DockAreaOverlay->showOverlay(DockArea);
156155
ContainerOverlay->enableDropPreview(InvalidDockWidgetArea == Area);

0 commit comments

Comments
 (0)