mirror of
https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git
synced 2024-12-26 08:01:32 +08:00
Fixed a bug with shoing and hiding empty splitters, added some pictures to main page
This commit is contained in:
parent
990d3235c5
commit
844c853768
42
README.md
42
README.md
@ -1,23 +1,49 @@
|
|||||||
# 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
|
||||||
|
BIN
floating-widget-dragndrop.png
Normal file
BIN
floating-widget-dragndrop.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 222 KiB |
BIN
grouped-dragging.png
Normal file
BIN
grouped-dragging.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
@ -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)
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -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
|
||||||
|
@ -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,33 +140,26 @@ 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();
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user