Fixed a bug with shoing and hiding empty splitters, added some pictures to main page

This commit is contained in:
Uwe Kindler 2017-03-29 15:43:18 +02:00
parent 990d3235c5
commit 844c853768
9 changed files with 96 additions and 31 deletions

View File

@ -1,27 +1,53 @@
# Advanced Docking System for Qt # Advanced Docking System for Qt
Manages content widgets more like Visual Studio or similar programs. Qt Advanced Docking System lets you create customizable layouts using a full
I also try to get everything done with basic Qt functionality. featured window docking system similar to what is found in many popular
Basic usage of QWidgets an QLayouts and using basic styles as much as possible. integrated development environements (IDEs) such as Visual Studio.
Everything is implemented with standard Qt functionality without any
platform specific code. Basic usage of QWidgets an QLayouts and using basic
styles as much as possible.
This work is based on and inspired by the
[Advanced Docking System for Qt](https://github.com/mfreiholz/Qt-Advanced-Docking-System)
from Manuel Freiholz. I did an almost complete rewrite of his code to improve
code quality, readibility and to fix all issues from the issue tracker
of his docking system project.
## Features
### Docking everywhere - no central widget
There is no central widget like in the Qt docking system. You can dock on every
border of the main window or you can dock into each dock area - so you are
free to dock almost everywhere.
![Layout of widgets](preview.png) ![Layout of widgets](preview.png)
![Dropping widgets](preview-dragndrop.png) ![Dropping widgets](preview-dragndrop.png)
### Docking inside floating windows
There is no difference between the main window and a floating window. Docking
into floating windows is supported.
![Docking inside floating windows](floating-widget-dragndrop.png)
### Grouped dragging
When dragging the titlebar of a dock, all the tabs that are tabbed with it are
going to be dragged. So you can move complete groups of tabbed widgets into
a floating widget or from one dock area to another one.
![Grouped dragging](grouped-dragging.png)
## Tested Compatible Environments ## Tested Compatible Environments
- Windows 10 - Windows 10
## Build ## Build
Open the `build.pro` with QtCreator and start the build, that's it. Open the `ads.pro` with QtCreator and start the build, that's it.
You can run the demo project and test it yourself. You can run the demo project and test it yourself.
## Release & Development
The `master` branch is not guaranteed to be stable or does not even build, since it is the main working branch.
If you want a version that builds, you should always use a release/beta tag.
## Developers ## Developers
- Uwe Kindler, Project Maintainer - Uwe Kindler, Project Maintainer
- Manuel Freiholz - Manuel Freiholz
## License information ## License information
This project uses the [GPLv3 license] (gnu-gpl-v3.0.md) This project uses the [GPLv3 license](gnu-gpl-v3.0.md)

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

BIN
grouped-dragging.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

View File

@ -433,6 +433,7 @@ bool DockContainerWidgetPrivate::restoreDockArea(QDataStream& stream,
DockArea->addDockWidget(DockWidget); DockArea->addDockWidget(DockWidget);
DockArea->hide(); DockArea->hide();
DockWidget->setToggleViewActionChecked(!Closed);
DockWidget->setProperty("closed", Closed); DockWidget->setProperty("closed", Closed);
DockWidget->setProperty("dirty", false); DockWidget->setProperty("dirty", false);
} }
@ -762,6 +763,21 @@ int CDockContainerWidget::dockAreaCount() const
} }
//============================================================================
int CDockContainerWidget::visibleDockAreaCount() const
{
// TODO Cache or precalculate this to speed it up because it is used during
// movement of floating widget
int Result = 0;
for (auto DockArea : d->DockAreas)
{
Result += DockArea->isVisible() ? 1 : 0;
}
return Result;
}
//============================================================================ //============================================================================
void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWidget, void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWidget,
const QPoint& TargetPos) const QPoint& TargetPos)

View File

@ -134,6 +134,11 @@ public:
*/ */
int dockAreaCount() const; int dockAreaCount() const;
/**
* Returns the number of visible dock areas
*/
int visibleDockAreaCount() const;
/** /**
* This function returns true, if this container is in a floating widget * This function returns true, if this container is in a floating widget
*/ */

View File

@ -21,6 +21,22 @@ CDockSplitter::~CDockSplitter()
qDebug() << "~CDockSplitter"; qDebug() << "~CDockSplitter";
} }
//============================================================================
bool CDockSplitter::hasVisibleContent() const
{
// TODO Cache or precalculate this to speed up
for (int i = 0; i < count(); ++i)
{
if (widget(i)->isVisibleTo(this))
{
return true;
}
}
return false;
}
} // namespace ads } // namespace ads
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@ -28,6 +28,11 @@ public:
* Prints debug info * Prints debug info
*/ */
virtual ~CDockSplitter(); virtual ~CDockSplitter();
/**
* Returns true, if any of the internal widgets is visible
*/
bool hasVisibleContent() const;
}; // class CDockSplitter }; // class CDockSplitter
} // namespace ads } // namespace ads

View File

@ -45,6 +45,7 @@
#include "DockManager.h" #include "DockManager.h"
#include "FloatingDockContainer.h" #include "FloatingDockContainer.h"
#include "DockStateSerialization.h" #include "DockStateSerialization.h"
#include "DockSplitter.h"
#include "ads_globals.h" #include "ads_globals.h"
namespace ads namespace ads
@ -82,7 +83,7 @@ struct DockWidgetPrivate
/** /**
* Hides a parent splitter if all dock widgets in the splitter are closed * Hides a parent splitter if all dock widgets in the splitter are closed
*/ */
void hideEmptyParentSplitter(); void hideEmptyParentSplitters();
/** /**
* Hides a dock area if all dock widgets in the area are closed * Hides a dock area if all dock widgets in the area are closed
@ -119,9 +120,10 @@ void DockWidgetPrivate::showDockWidget()
DockArea->show(); DockArea->show();
DockArea->setCurrentIndex(DockArea->tabIndex(_this)); DockArea->setCurrentIndex(DockArea->tabIndex(_this));
QSplitter* Splitter = internal::findParent<QSplitter*>(_this); QSplitter* Splitter = internal::findParent<QSplitter*>(_this);
if (Splitter) while (Splitter && !Splitter->isVisible())
{ {
Splitter->show(); Splitter->show();
Splitter = internal::findParent<QSplitter*>(Splitter);
} }
CDockContainerWidget* Container = DockArea->dockContainer(); CDockContainerWidget* Container = DockArea->dockContainer();
@ -138,32 +140,25 @@ void DockWidgetPrivate::showDockWidget()
//============================================================================ //============================================================================
void DockWidgetPrivate::hideDockWidget() void DockWidgetPrivate::hideDockWidget()
{ {
ToggleViewAction->setChecked(false);
TitleWidget->hide(); TitleWidget->hide();
hideEmptyParentDockArea(); hideEmptyParentDockArea();
hideEmptyParentSplitter(); hideEmptyParentSplitters();
hideEmptyFloatingWidget(); hideEmptyFloatingWidget();
} }
//============================================================================ //============================================================================
void DockWidgetPrivate::hideEmptyParentSplitter() void DockWidgetPrivate::hideEmptyParentSplitters()
{ {
QSplitter* Splitter = internal::findParent<QSplitter*>(_this); auto Splitter = internal::findParent<CDockSplitter*>(_this);
if (!Splitter) while (Splitter && Splitter->isVisible())
{ {
return; if (!Splitter->hasVisibleContent())
}
for (int i = 0; i < Splitter->count(); ++i)
{ {
if (Splitter->widget(i)->isVisibleTo(Splitter))
{
return;
}
}
Splitter->hide(); Splitter->hide();
}
Splitter = internal::findParent<CDockSplitter*>(Splitter);
}
} }
@ -346,6 +341,9 @@ void CDockWidget::toggleView(bool Open)
d->hideDockWidget(); d->hideDockWidget();
} }
d->Closed = !Open; d->Closed = !Open;
d->ToggleViewAction->blockSignals(true);
d->ToggleViewAction->setChecked(Open);
d->ToggleViewAction->blockSignals(false);
if (!Open) if (!Open)
{ {
emit closed(); emit closed();

View File

@ -131,7 +131,6 @@ void FloatingDockContainerPrivate::updateDropOverlays(const QPoint& GlobalPos)
} }
DropContainer = TopContainer; DropContainer = TopContainer;
//std::cout << "TopContainer " << TopContainer << std::endl;
auto ContainerOverlay = DockManager->containerOverlay(); auto ContainerOverlay = DockManager->containerOverlay();
auto DockAreaOverlay = DockManager->dockAreaOverlay(); auto DockAreaOverlay = DockManager->dockAreaOverlay();
@ -142,15 +141,15 @@ void FloatingDockContainerPrivate::updateDropOverlays(const QPoint& GlobalPos)
return; return;
} }
ContainerOverlay->setAllowedAreas(TopContainer->dockAreaCount() > 1 ? int VisibleDockAreas = TopContainer->visibleDockAreaCount();
ContainerOverlay->setAllowedAreas(VisibleDockAreas > 1 ?
OuterDockAreas : AllDockAreas); OuterDockAreas : AllDockAreas);
ContainerOverlay->showOverlay(TopContainer); ContainerOverlay->showOverlay(TopContainer);
//ContainerOverlay->raise();
auto DockArea = TopContainer->dockAreaAt(GlobalPos); auto DockArea = TopContainer->dockAreaAt(GlobalPos);
if (DockArea && TopContainer->dockAreaCount() > 0) if (DockArea && DockArea->isVisible() && VisibleDockAreas > 0)
{ {
DockAreaOverlay->setAllowedAreas((TopContainer->dockAreaCount() == 1) ? DockAreaOverlay->setAllowedAreas((VisibleDockAreas == 1) ?
NoDockWidgetArea : AllDockAreas); NoDockWidgetArea : AllDockAreas);
DockWidgetArea Area = DockAreaOverlay->showOverlay(DockArea); DockWidgetArea Area = DockAreaOverlay->showOverlay(DockArea);
ContainerOverlay->enableDropPreview(InvalidDockWidgetArea == Area); ContainerOverlay->enableDropPreview(InvalidDockWidgetArea == Area);