mirror of
https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git
synced 2024-12-25 23:51:33 +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
44
README.md
44
README.md
@ -1,27 +1,53 @@
|
||||
# Advanced Docking System for Qt
|
||||
|
||||
Manages content widgets more like Visual Studio or similar programs.
|
||||
I also try to get everything done with basic Qt functionality.
|
||||
Basic usage of QWidgets an QLayouts and using basic styles as much as possible.
|
||||
Qt Advanced Docking System lets you create customizable layouts using a full
|
||||
featured window docking system similar to what is found in many popular
|
||||
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)
|
||||
|
||||
![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
|
||||
- Windows 10
|
||||
|
||||
## 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.
|
||||
|
||||
## 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
|
||||
- Uwe Kindler, Project Maintainer
|
||||
- Manuel Freiholz
|
||||
|
||||
## License information
|
||||
This project uses the [GPLv3 license] (gnu-gpl-v3.0.md)
|
||||
This project uses the [GPLv3 license](gnu-gpl-v3.0.md)
|
||||
|
||||
|
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->hide();
|
||||
DockWidget->setToggleViewActionChecked(!Closed);
|
||||
DockWidget->setProperty("closed", Closed);
|
||||
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,
|
||||
const QPoint& TargetPos)
|
||||
|
@ -134,6 +134,11 @@ public:
|
||||
*/
|
||||
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
|
||||
*/
|
||||
|
@ -21,6 +21,22 @@ CDockSplitter::~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
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -28,6 +28,11 @@ public:
|
||||
* Prints debug info
|
||||
*/
|
||||
virtual ~CDockSplitter();
|
||||
|
||||
/**
|
||||
* Returns true, if any of the internal widgets is visible
|
||||
*/
|
||||
bool hasVisibleContent() const;
|
||||
}; // class CDockSplitter
|
||||
|
||||
} // namespace ads
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "DockManager.h"
|
||||
#include "FloatingDockContainer.h"
|
||||
#include "DockStateSerialization.h"
|
||||
#include "DockSplitter.h"
|
||||
#include "ads_globals.h"
|
||||
|
||||
namespace ads
|
||||
@ -82,7 +83,7 @@ struct DockWidgetPrivate
|
||||
/**
|
||||
* 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
|
||||
@ -119,9 +120,10 @@ void DockWidgetPrivate::showDockWidget()
|
||||
DockArea->show();
|
||||
DockArea->setCurrentIndex(DockArea->tabIndex(_this));
|
||||
QSplitter* Splitter = internal::findParent<QSplitter*>(_this);
|
||||
if (Splitter)
|
||||
while (Splitter && !Splitter->isVisible())
|
||||
{
|
||||
Splitter->show();
|
||||
Splitter = internal::findParent<QSplitter*>(Splitter);
|
||||
}
|
||||
|
||||
CDockContainerWidget* Container = DockArea->dockContainer();
|
||||
@ -138,32 +140,25 @@ void DockWidgetPrivate::showDockWidget()
|
||||
//============================================================================
|
||||
void DockWidgetPrivate::hideDockWidget()
|
||||
{
|
||||
ToggleViewAction->setChecked(false);
|
||||
TitleWidget->hide();
|
||||
hideEmptyParentDockArea();
|
||||
hideEmptyParentSplitter();
|
||||
hideEmptyParentSplitters();
|
||||
hideEmptyFloatingWidget();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void DockWidgetPrivate::hideEmptyParentSplitter()
|
||||
void DockWidgetPrivate::hideEmptyParentSplitters()
|
||||
{
|
||||
QSplitter* Splitter = internal::findParent<QSplitter*>(_this);
|
||||
if (!Splitter)
|
||||
auto Splitter = internal::findParent<CDockSplitter*>(_this);
|
||||
while (Splitter && Splitter->isVisible())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < Splitter->count(); ++i)
|
||||
{
|
||||
if (Splitter->widget(i)->isVisibleTo(Splitter))
|
||||
if (!Splitter->hasVisibleContent())
|
||||
{
|
||||
return;
|
||||
Splitter->hide();
|
||||
}
|
||||
Splitter = internal::findParent<CDockSplitter*>(Splitter);
|
||||
}
|
||||
|
||||
Splitter->hide();
|
||||
}
|
||||
|
||||
|
||||
@ -346,6 +341,9 @@ void CDockWidget::toggleView(bool Open)
|
||||
d->hideDockWidget();
|
||||
}
|
||||
d->Closed = !Open;
|
||||
d->ToggleViewAction->blockSignals(true);
|
||||
d->ToggleViewAction->setChecked(Open);
|
||||
d->ToggleViewAction->blockSignals(false);
|
||||
if (!Open)
|
||||
{
|
||||
emit closed();
|
||||
|
@ -131,7 +131,6 @@ void FloatingDockContainerPrivate::updateDropOverlays(const QPoint& GlobalPos)
|
||||
}
|
||||
|
||||
DropContainer = TopContainer;
|
||||
//std::cout << "TopContainer " << TopContainer << std::endl;
|
||||
auto ContainerOverlay = DockManager->containerOverlay();
|
||||
auto DockAreaOverlay = DockManager->dockAreaOverlay();
|
||||
|
||||
@ -142,15 +141,15 @@ void FloatingDockContainerPrivate::updateDropOverlays(const QPoint& GlobalPos)
|
||||
return;
|
||||
}
|
||||
|
||||
ContainerOverlay->setAllowedAreas(TopContainer->dockAreaCount() > 1 ?
|
||||
int VisibleDockAreas = TopContainer->visibleDockAreaCount();
|
||||
ContainerOverlay->setAllowedAreas(VisibleDockAreas > 1 ?
|
||||
OuterDockAreas : AllDockAreas);
|
||||
ContainerOverlay->showOverlay(TopContainer);
|
||||
//ContainerOverlay->raise();
|
||||
|
||||
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);
|
||||
DockWidgetArea Area = DockAreaOverlay->showOverlay(DockArea);
|
||||
ContainerOverlay->enableDropPreview(InvalidDockWidgetArea == Area);
|
||||
|
Loading…
Reference in New Issue
Block a user