1
0
mirror of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git synced 2025-04-01 02:42:39 +08:00

- Fixes empty QSplitter bug

- Removes obsolete code
This commit is contained in:
mfreiholz 2016-02-03 08:01:26 +01:00
parent cb5781cfdc
commit 4f394ddf5e
9 changed files with 64 additions and 89 deletions

View File

@ -10,7 +10,15 @@ CONFIG += staticlib
INCLUDEPATH += $$PWD/src INCLUDEPATH += $$PWD/src
INCLUDEPATH += $$PWD/include INCLUDEPATH += $$PWD/include
QMAKE_CXXFLAGS += -std=c++11 windows {
# MinGW
*-g++* {
QMAKE_CXXFLAGS += -std=c++11
}
# MSVC
*-msvc* {
}
}
SOURCES += \ SOURCES += \
src/API.cpp \ src/API.cpp \

View File

@ -1,5 +1,5 @@
#ifndef ADS_H #ifndef ADS_API_H
#define ADS_H #define ADS_API_H
#include <QByteArray> #include <QByteArray>
#include <QDataStream> #include <QDataStream>
@ -22,39 +22,6 @@ class QSplitter;
//#define ADS_ANIMATIONS_ENABLED 1 //#define ADS_ANIMATIONS_ENABLED 1
//#define ADS_ANIMATION_DURATION 150 //#define ADS_ANIMATION_DURATION 150
// DragData contains information about dragged contents (SectionContent).
// e.g. from where is has been dragged.
class DragData
{
public:
static const QString MIMETYPE;
QByteArray serialize() const
{
QByteArray ba;
QDataStream out(&ba, QIODevice::WriteOnly);
out << contentUid;
out << sectionUid;
return ba;
}
void deserialize(const QByteArray& bytes)
{
QDataStream in(bytes);
in >> contentUid;
in >> sectionUid;
}
QString toString() const
{
return QString("content-uid=%1; section-uid=%2").arg(contentUid).arg(sectionUid);
}
public:
int contentUid;
int sectionUid;
};
ADS_NAMESPACE_BEGIN ADS_NAMESPACE_BEGIN
enum DropArea enum DropArea
@ -76,11 +43,11 @@ public:
class SectionContentWidget* contentWidget; class SectionContentWidget* contentWidget;
}; };
void deleteEmptySplitter(class ContainerWidget* container);
class ContainerWidget* findParentContainerWidget(class QWidget* w); class ContainerWidget* findParentContainerWidget(class QWidget* w);
class SectionWidget* findParentSectionWidget(class QWidget* w); class SectionWidget* findParentSectionWidget(class QWidget* w);
QSplitter* findParentSplitter(class QWidget* w); QSplitter* findParentSplitter(class QWidget* w);
QSplitter* findImmediateSplitter(class QWidget* w); QSplitter* findImmediateSplitter(class QWidget* w);
ADS_NAMESPACE_END ADS_NAMESPACE_END
#endif
#endif // ADC_H

View File

@ -1,6 +1,7 @@
#ifndef ADS_CONTAINERWIDGET_H #ifndef ADS_CONTAINERWIDGET_H
#define ADS_CONTAINERWIDGET_H #define ADS_CONTAINERWIDGET_H
#include <QPointer>
#include <QFrame> #include <QFrame>
#include <QGridLayout> #include <QGridLayout>
#include <QPoint> #include <QPoint>
@ -49,9 +50,6 @@ public:
QMenu* createContextMenu() const; QMenu* createContextMenu() const;
private: // Make private!
signals: signals:
void orientationChanged(); void orientationChanged();
@ -66,7 +64,7 @@ public:
// Layout stuff // Layout stuff
QGridLayout* _mainLayout; QGridLayout* _mainLayout;
Qt::Orientation _orientation; ///< Default orientation of new sections. Qt::Orientation _orientation; ///< Default orientation of new sections.
QSplitter* _splitter; ///< Default/main splitter. QPointer<QSplitter> _splitter; ///< Default/main splitter.
}; };
ADS_NAMESPACE_END ADS_NAMESPACE_END

View File

@ -5,10 +5,21 @@
#include "ads/ContainerWidget.h" #include "ads/ContainerWidget.h"
const QString DragData::MIMETYPE = QString("qt/ads-dragdata"); //const QString DragData::MIMETYPE = QString("qt/ads-dragdata");
ADS_NAMESPACE_BEGIN ADS_NAMESPACE_BEGIN
void deleteEmptySplitter(ContainerWidget* container)
{
auto splitters = container->findChildren<QSplitter*>();
for (auto i = 0; i < splitters.count(); ++i)
{
auto sp = splitters.at(i);
if (sp->count() == 0)
delete splitters[i];
}
}
ContainerWidget* findParentContainerWidget(QWidget* w) ContainerWidget* findParentContainerWidget(QWidget* w)
{ {
ContainerWidget* cw = 0; ContainerWidget* cw = 0;

View File

@ -10,12 +10,11 @@ ADS_NAMESPACE_BEGIN
// Static Helper ////////////////////////////////////////////////////// // Static Helper //////////////////////////////////////////////////////
static QSplitter* newSplitter(Qt::Orientation orientation = Qt::Horizontal) static QSplitter* newSplitter(Qt::Orientation orientation = Qt::Horizontal, QWidget* parent = 0)
{ {
QSplitter* s = new QSplitter(); QSplitter* s = new QSplitter(orientation, parent);
s->setChildrenCollapsible(false); s->setChildrenCollapsible(false);
s->setOpaqueResize(false); s->setOpaqueResize(false);
s->setOrientation(orientation);
return s; return s;
} }
@ -105,24 +104,24 @@ void ContainerWidget::dropContent(const InternalContentData& data, SectionWidget
return; return;
} }
auto targetSectionSplitter = findParentSplitter(targetSection); QSplitter* targetSectionSplitter = findParentSplitter(targetSection);
// Drop logic based on area. // Drop logic based on area.
switch (area) switch (area)
{ {
case TopDropArea: case TopDropArea:
{ {
auto sw = new SectionWidget(this); SectionWidget* sw = new SectionWidget(this);
sw->addContent(data, true); sw->addContent(data, true);
if (targetSectionSplitter->orientation() == Qt::Vertical) if (targetSectionSplitter->orientation() == Qt::Vertical)
{ {
auto index = targetSectionSplitter->indexOf(targetSection); const int index = targetSectionSplitter->indexOf(targetSection);
targetSectionSplitter->insertWidget(index, sw); targetSectionSplitter->insertWidget(index, sw);
} }
else else
{ {
auto index = targetSectionSplitter->indexOf(targetSection); const int index = targetSectionSplitter->indexOf(targetSection);
auto s = newSplitter(Qt::Vertical); QSplitter* s = newSplitter(Qt::Vertical);
s->addWidget(sw); s->addWidget(sw);
s->addWidget(targetSection); s->addWidget(targetSection);
targetSectionSplitter->insertWidget(index, s); targetSectionSplitter->insertWidget(index, s);
@ -131,17 +130,17 @@ void ContainerWidget::dropContent(const InternalContentData& data, SectionWidget
} }
case RightDropArea: case RightDropArea:
{ {
auto sw = new SectionWidget(this); SectionWidget* sw = new SectionWidget(this);
sw->addContent(data, true); sw->addContent(data, true);
if (targetSectionSplitter->orientation() == Qt::Horizontal) if (targetSectionSplitter->orientation() == Qt::Horizontal)
{ {
auto index = targetSectionSplitter->indexOf(targetSection); const int index = targetSectionSplitter->indexOf(targetSection);
targetSectionSplitter->insertWidget(index + 1, sw); targetSectionSplitter->insertWidget(index + 1, sw);
} }
else else
{ {
auto index = targetSectionSplitter->indexOf(targetSection); const int index = targetSectionSplitter->indexOf(targetSection);
auto s = newSplitter(Qt::Horizontal); QSplitter* s = newSplitter(Qt::Horizontal);
s->addWidget(targetSection); s->addWidget(targetSection);
s->addWidget(sw); s->addWidget(sw);
targetSectionSplitter->insertWidget(index, s); targetSectionSplitter->insertWidget(index, s);
@ -199,9 +198,7 @@ void ContainerWidget::addSection(SectionWidget* section)
// Create default splitter. // Create default splitter.
if (!_splitter) if (!_splitter)
{ {
_splitter = new QSplitter(_orientation); _splitter = newSplitter(_orientation);
_splitter->setChildrenCollapsible(false);
_splitter->setOpaqueResize(false);
_mainLayout->addWidget(_splitter, 0, 0); _mainLayout->addWidget(_splitter, 0, 0);
} }
if (_splitter->indexOf(section) != -1) if (_splitter->indexOf(section) != -1)
@ -221,9 +218,7 @@ void ContainerWidget::splitSections(SectionWidget* s1, SectionWidget* s2, Qt::Or
if (currentSplitter) if (currentSplitter)
{ {
const int index = currentSplitter->indexOf(s1); const int index = currentSplitter->indexOf(s1);
auto splitter = new QSplitter(orientation, this); QSplitter* splitter = newSplitter(orientation, this);
splitter->setChildrenCollapsible(false);
splitter->setOpaqueResize(false);
splitter->addWidget(s1); splitter->addWidget(s1);
splitter->addWidget(s2); splitter->addWidget(s2);
currentSplitter->insertWidget(index, splitter); currentSplitter->insertWidget(index, splitter);
@ -317,7 +312,9 @@ QMenu* ContainerWidget::createContextMenu() const
{ {
FloatingWidget* fw = _floatingWidgets.at(i); FloatingWidget* fw = _floatingWidgets.at(i);
SectionContent::RefPtr c = fw->content(); SectionContent::RefPtr c = fw->content();
m->addAction(QIcon(), QString("Floating %1").arg(c->uid())); QAction* a = m->addAction(QIcon(), QString("Floating %1").arg(c->uid()));
a->setCheckable(true);
a->setChecked(fw->isVisible());
} }
} }

View File

@ -1,3 +1,4 @@
#include "ads/FloatingWidget.h" #include "ads/FloatingWidget.h"
#include <QDebug> #include <QDebug>
@ -20,21 +21,22 @@ FloatingWidget::FloatingWidget(ContainerWidget* container, SectionContent::RefPt
_titleWidget(titleWidget), _titleWidget(titleWidget),
_contentWidget(contentWidget) _contentWidget(contentWidget)
{ {
auto l = new QBoxLayout(QBoxLayout::TopToBottom); auto l = new QBoxLayout(QBoxLayout::TopToBottom, this);
l->setContentsMargins(0, 0, 0, 0); l->setContentsMargins(0, 0, 0, 0);
l->setSpacing(0); l->setSpacing(0);
setLayout(l); setLayout(l);
// Title + Controls // Title + Controls
_titleLayout = new QBoxLayout(QBoxLayout::LeftToRight); _titleLayout = new QBoxLayout(QBoxLayout::LeftToRight, this);
_titleLayout->addWidget(titleWidget, 1); _titleLayout->addWidget(titleWidget, 1);
l->addLayout(_titleLayout, 0);
auto maximizeButton = new QPushButton(); // auto maximizeButton = new QPushButton();
maximizeButton->setObjectName("maximizeButton"); // maximizeButton->setObjectName("maximizeButton");
maximizeButton->setIcon(style()->standardIcon(QStyle::SP_TitleBarMaxButton)); // maximizeButton->setIcon(style()->standardIcon(QStyle::SP_TitleBarMaxButton));
maximizeButton->setToolTip(tr("Maximize")); // maximizeButton->setToolTip(tr("Maximize"));
maximizeButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // maximizeButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
_titleLayout->addWidget(maximizeButton); // _titleLayout->addWidget(maximizeButton);
auto closeButton = new QPushButton(); auto closeButton = new QPushButton();
closeButton->setObjectName("closeButton"); closeButton->setObjectName("closeButton");
@ -44,8 +46,6 @@ FloatingWidget::FloatingWidget(ContainerWidget* container, SectionContent::RefPt
_titleLayout->addWidget(closeButton); _titleLayout->addWidget(closeButton);
QObject::connect(closeButton, &QPushButton::clicked, this, &FloatingWidget::close); QObject::connect(closeButton, &QPushButton::clicked, this, &FloatingWidget::close);
l->addLayout(_titleLayout, 0);
// Content // Content
l->addWidget(contentWidget, 1); l->addWidget(contentWidget, 1);
contentWidget->show(); contentWidget->show();

View File

@ -24,21 +24,6 @@
ADS_NAMESPACE_BEGIN ADS_NAMESPACE_BEGIN
static void deleteEmptySplitter(ContainerWidget* container)
{
auto splitters = container->findChildren<QSplitter*>();
for (auto i = 0; i < splitters.count(); ++i)
{
if (splitters[i]->count() == 0 /*&& container->_splitter != splitters[i]*/)
{
if (splitters[i] == container->_splitter)
continue;
qDebug() << "Delete empty QSplitter";
delete splitters[i];//splitters[i]->deleteLater();
}
}
}
SectionTitleWidget::SectionTitleWidget(SectionContent::RefPtr content, QWidget* parent) : SectionTitleWidget::SectionTitleWidget(SectionContent::RefPtr content, QWidget* parent) :
QFrame(parent), QFrame(parent),
_content(content), _content(content),

View File

@ -7,7 +7,15 @@ TEMPLATE = app
INCLUDEPATH += $$PWD/src INCLUDEPATH += $$PWD/src
QMAKE_CXXFLAGS += -std=c++11 windows {
# MinGW
*-g++* {
QMAKE_CXXFLAGS += -std=c++11
}
# MSVC
*-msvc* {
}
}
SOURCES += \ SOURCES += \
src/main.cpp \ src/main.cpp \

View File

@ -21,6 +21,7 @@ Open the `build.pro` with QtCreator and start the build, that's it.
## TODOs ## TODOs
Sorted by priority Sorted by priority
- Improve FloatingWidget (Remove maximize button, only support close-button which hides the widget)
- Serialize state/size/positions of dockings - Serialize state/size/positions of dockings
- Deserialize state/size/positions of dockings - Deserialize state/size/positions of dockings
- Make compatible with Qt 4.5 (\*ROFL!\*) - Make compatible with Qt 4.5 (\*ROFL!\*)
@ -28,7 +29,7 @@ Sorted by priority
- Pin contents: Pins a content and its title widget to the edge and opens on click/hover as long as it has focus - Pin contents: Pins a content and its title widget to the edge and opens on click/hover as long as it has focus
## Bugs ## Bugs
- Working with outer-edge-drops sometimes leaves empty splitters - **[DONE]** Working with outer-edge-drops sometimes leaves empty splitters
- **[DONE]** Clean up of unused e.g. count()<=1 QSplitters doesn't work well - **[DONE]** Clean up of unused e.g. count()<=1 QSplitters doesn't work well
## Credits ## Credits