From 889d9bff5b9d59a9c10653d8396b65e4075b7bdd Mon Sep 17 00:00:00 2001 From: Uwe Kindler Date: Fri, 20 Jan 2017 22:43:18 +0100 Subject: [PATCH] Some refactorings to cleanup code, moved ContainerWidget private data into private data class --- AdvancedDockingSystem/include/ads/API.h | 5 + .../include/ads/ContainerWidget.h | 46 +-- .../include/ads/DropOverlay.h | 6 + AdvancedDockingSystem/include/ads/Internal.h | 3 - AdvancedDockingSystem/src/ContainerWidget.cpp | 283 ++++++++---------- AdvancedDockingSystem/src/DropOverlay.cpp | 31 +- AdvancedDockingSystem/src/FloatingWidget.cpp | 12 +- AdvancedDockingSystem/src/SectionContent.cpp | 16 +- .../src/SectionTitleWidget.cpp | 6 +- AdvancedDockingSystem/src/SectionWidget.cpp | 19 +- 10 files changed, 206 insertions(+), 221 deletions(-) diff --git a/AdvancedDockingSystem/include/ads/API.h b/AdvancedDockingSystem/include/ads/API.h index e290c90..8a89a9d 100644 --- a/AdvancedDockingSystem/include/ads/API.h +++ b/AdvancedDockingSystem/include/ads/API.h @@ -60,6 +60,11 @@ enum DropArea LeftDropArea = 8, CenterDropArea = 16, + TopBorderDropArea = 32, + RightBorderDropArea = 64, + BottomBorderDropArea = 128, + LeftBorderDropArea = 256, + AllAreas = TopDropArea | RightDropArea | BottomDropArea | LeftDropArea | CenterDropArea }; Q_DECLARE_FLAGS(DropAreas, DropArea) diff --git a/AdvancedDockingSystem/include/ads/ContainerWidget.h b/AdvancedDockingSystem/include/ads/ContainerWidget.h index b68d3f0..d9b60c2 100644 --- a/AdvancedDockingSystem/include/ads/ContainerWidget.h +++ b/AdvancedDockingSystem/include/ads/ContainerWidget.h @@ -21,6 +21,30 @@ class SectionWidget; class DropOverlay; class InternalContentData; +struct ContainerWidgetPrivate +{ + // Elements inside container. + QList sections; + QList floatings; + QHash hiddenSectionContents; + + + // Helper lookup maps, restricted to this container. + QHash scLookupMapById; + QHash scLookupMapByName; + QHash swLookupMapById; + + + // Layout stuff + QGridLayout* mainLayout = nullptr;; + Qt::Orientation orientation = Qt::Horizontal; + QPointer splitter; // $mfreiholz: I'd like to remove this variable entirely, + // because it changes during user interaction anyway. + + // Drop overlay stuff. + QPointer dropOverlay; +}; + /*! * ContainerWidget is the main container to provide the docking @@ -36,6 +60,7 @@ class ADS_EXPORT_API ContainerWidget : public QFrame friend class SectionTitleWidget; friend class SectionContentWidget; friend class SectionWidgetTabsScrollArea; + friend class ContainerWidgetPrivate; public: explicit ContainerWidget(QWidget *parent = NULL); @@ -169,26 +194,7 @@ signals: void sectionContentVisibilityChanged(const SectionContent::RefPtr& sc, bool visible); private: - // Elements inside container. - QList _sections; - QList _floatings; - QHash _hiddenSectionContents; - - - // Helper lookup maps, restricted to this container. - QHash _scLookupMapById; - QHash _scLookupMapByName; - QHash _swLookupMapById; - - - // Layout stuff - QGridLayout* _mainLayout; - Qt::Orientation _orientation; - QPointer _splitter; // $mfreiholz: I'd like to remove this variable entirely, - // because it changes during user interaction anyway. - - // Drop overlay stuff. - QPointer _dropOverlay; + ContainerWidgetPrivate* d;///< private data }; ADS_NAMESPACE_END diff --git a/AdvancedDockingSystem/include/ads/DropOverlay.h b/AdvancedDockingSystem/include/ads/DropOverlay.h index 9e39644..0bb8ae5 100644 --- a/AdvancedDockingSystem/include/ads/DropOverlay.h +++ b/AdvancedDockingSystem/include/ads/DropOverlay.h @@ -36,6 +36,11 @@ public: void showDropOverlay(QWidget* target, const QRect& targetAreaRect); void hideDropOverlay(); + /** + * Creates a drop indicator widget for the given drop area + */ + static QWidget* createDropIndicatorWidget(DropArea dropArea); + protected: virtual void paintEvent(QPaintEvent *e); virtual void showEvent(QShowEvent* e); @@ -51,6 +56,7 @@ private: QPointer _target; QRect _targetRect; DropArea _lastLocation; + QWidget* m_LeftBorderDropArea; }; /*! diff --git a/AdvancedDockingSystem/include/ads/Internal.h b/AdvancedDockingSystem/include/ads/Internal.h index 7a1acf1..8dfcfda 100644 --- a/AdvancedDockingSystem/include/ads/Internal.h +++ b/AdvancedDockingSystem/include/ads/Internal.h @@ -11,9 +11,6 @@ #include "ads/SectionContent.h" #endif -#define SCLookupMapById(X) X->_scLookupMapById -#define SCLookupMapByName(X) X->_scLookupMapByName -#define SWLookupMapById(X) X->_swLookupMapById ADS_NAMESPACE_BEGIN class SectionContent; diff --git a/AdvancedDockingSystem/src/ContainerWidget.cpp b/AdvancedDockingSystem/src/ContainerWidget.cpp index df7358f..ad5bfe8 100644 --- a/AdvancedDockingSystem/src/ContainerWidget.cpp +++ b/AdvancedDockingSystem/src/ContainerWidget.cpp @@ -18,8 +18,12 @@ #include "ads/DropOverlay.h" #include "ads/Serialization.h" +#include + ADS_NAMESPACE_BEGIN + + // Static Helper ////////////////////////////////////////////////////// static QSplitter* newSplitter(Qt::Orientation orientation = Qt::Horizontal, QWidget* parent = 0) @@ -35,15 +39,13 @@ static QSplitter* newSplitter(Qt::Orientation orientation = Qt::Horizontal, QWid ContainerWidget::ContainerWidget(QWidget *parent) : QFrame(parent), - _mainLayout(NULL), - _orientation(Qt::Horizontal), - _splitter(NULL), - _dropOverlay(new DropOverlay(this)) + d(new ContainerWidgetPrivate()) { - _mainLayout = new QGridLayout(); - _mainLayout->setContentsMargins(9, 9, 9, 9); - _mainLayout->setSpacing(0); - setLayout(_mainLayout); + d->dropOverlay = new DropOverlay(this); + d->mainLayout = new QGridLayout(); + d->mainLayout->setContentsMargins(4, 4, 4, 4); + d->mainLayout->setSpacing(0); + setLayout(d->mainLayout); } ContainerWidget::~ContainerWidget() @@ -52,21 +54,23 @@ ContainerWidget::~ContainerWidget() // Remove from list, and then delete. // Because the destrcutor of objects wants to modfiy the current // iterating list as well... :-/ - while (!_sections.isEmpty()) + while (!d->sections.isEmpty()) { - SectionWidget* sw = _sections.takeLast(); + SectionWidget* sw = d->sections.takeLast(); delete sw; } - while (!_floatings.isEmpty()) + while (!d->floatings.isEmpty()) { - FloatingWidget* fw = _floatings.takeLast(); + FloatingWidget* fw = d->floatings.takeLast(); delete fw; } - _scLookupMapById.clear(); - _scLookupMapByName.clear(); - _swLookupMapById.clear(); + d->scLookupMapById.clear(); + d->scLookupMapByName.clear(); + d->swLookupMapById.clear(); + delete d; } + SectionWidget* ContainerWidget::addSectionContent(const SectionContent::RefPtr& sc, SectionWidget* sw, DropArea area) { ADS_Expects(!sc.isNull()); @@ -77,12 +81,7 @@ SectionWidget* ContainerWidget::addSectionContent(const SectionContent::RefPtr& data.titleWidget = new SectionTitleWidget(sc, NULL); data.contentWidget = new SectionContentWidget(sc, NULL); -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) - QObject::connect(data.titleWidget, &SectionTitleWidget::activeTabChanged, this, &ContainerWidget::onActiveTabChanged); -#else - QObject::connect(data.titleWidget, SIGNAL(activeTabChanged()), this, SLOT(onActiveTabChanged())); -#endif - + connect(data.titleWidget, SIGNAL(activeTabChanged()), this, SLOT(onActiveTabChanged())); return dropContent(data, sw, area, false); } @@ -100,13 +99,13 @@ bool ContainerWidget::removeSectionContent(const SectionContent::RefPtr& sc) // but only cares about SectionWidgets right now. So we need to check whether it was a FloatingWidget // and delete it. bool found = false; - for (int i = 0; i < _floatings.count(); ++i) + for (int i = 0; i < d->floatings.count(); ++i) { - FloatingWidget* fw = _floatings.at(i); + FloatingWidget* fw = d->floatings.at(i); InternalContentData data; if (!(found = fw->takeContent(data))) continue; - _floatings.removeAll(fw); + d->floatings.removeAll(fw); delete fw; delete data.titleWidget; delete data.contentWidget; @@ -114,14 +113,14 @@ bool ContainerWidget::removeSectionContent(const SectionContent::RefPtr& sc) } // End of ugly work arround. // Get from hidden contents and delete associated internal stuff. - if (!_hiddenSectionContents.contains(sc->uid())) + if (!d->hiddenSectionContents.contains(sc->uid())) { qFatal("Something went wrong... The content should have been there :-/"); return false; } // Delete internal objects. - HiddenSectionItem hsi = _hiddenSectionContents.take(sc->uid()); + HiddenSectionItem hsi = d->hiddenSectionContents.take(sc->uid()); delete hsi.data.titleWidget; delete hsi.data.contentWidget; @@ -136,9 +135,9 @@ bool ContainerWidget::showSectionContent(const SectionContent::RefPtr& sc) ADS_Expects(!sc.isNull()); // Search SC in floatings - for (int i = 0; i < _floatings.count(); ++i) + for (int i = 0; i < d->floatings.count(); ++i) { - FloatingWidget* fw = _floatings.at(i); + FloatingWidget* fw = d->floatings.at(i); const bool found = fw->content()->uid() == sc->uid(); if (!found) continue; @@ -152,19 +151,19 @@ bool ContainerWidget::showSectionContent(const SectionContent::RefPtr& sc) // Search SC in hidden sections // Try to show them in the last position, otherwise simply append // it to the first section (or create a new section?) - if (_hiddenSectionContents.contains(sc->uid())) + if (d->hiddenSectionContents.contains(sc->uid())) { - const HiddenSectionItem hsi = _hiddenSectionContents.take(sc->uid()); + const HiddenSectionItem hsi = d->hiddenSectionContents.take(sc->uid()); hsi.data.titleWidget->setVisible(true); hsi.data.contentWidget->setVisible(true); - SectionWidget* sw = NULL; - if (hsi.preferredSectionId > 0 && (sw = SWLookupMapById(this).value(hsi.preferredSectionId)) != NULL) + SectionWidget* sw = nullptr; + if (hsi.preferredSectionId > 0 && (sw = d->swLookupMapById.value(hsi.preferredSectionId)) != nullptr) { sw->addContent(hsi.data, true); emit sectionContentVisibilityChanged(sc, true); return true; } - else if (_sections.size() > 0 && (sw = _sections.first()) != NULL) + else if (d->sections.size() > 0 && (sw = d->sections.first()) != NULL) { sw->addContent(hsi.data, true); emit sectionContentVisibilityChanged(sc, true); @@ -192,12 +191,12 @@ bool ContainerWidget::hideSectionContent(const SectionContent::RefPtr& sc) // Search SC in floatings // We can simply hide floatings, nothing else required. - for (int i = 0; i < _floatings.count(); ++i) + for (int i = 0; i < d->floatings.count(); ++i) { - const bool found = _floatings.at(i)->content()->uid() == sc->uid(); + const bool found = d->floatings.at(i)->content()->uid() == sc->uid(); if (!found) continue; - _floatings.at(i)->setVisible(false); + d->floatings.at(i)->setVisible(false); emit sectionContentVisibilityChanged(sc, false); return true; } @@ -206,9 +205,9 @@ bool ContainerWidget::hideSectionContent(const SectionContent::RefPtr& sc) // It's required to remove the SC from SW completely and hold it in a // separate list as long as a "showSectionContent" gets called for the SC again. // In case that the SW does not have any other SCs, we need to delete it. - for (int i = 0; i < _sections.count(); ++i) + for (int i = 0; i < d->sections.count(); ++i) { - SectionWidget* sw = _sections.at(i); + SectionWidget* sw = d->sections.at(i); const bool found = sw->indexOfContent(sc) >= 0; if (!found) continue; @@ -221,7 +220,7 @@ bool ContainerWidget::hideSectionContent(const SectionContent::RefPtr& sc) hsi.data.titleWidget->setVisible(false); hsi.data.contentWidget->setVisible(false); - _hiddenSectionContents.insert(sc->uid(), hsi); + d->hiddenSectionContents.insert(sc->uid(), hsi); if (sw->contents().isEmpty()) { @@ -235,7 +234,7 @@ bool ContainerWidget::hideSectionContent(const SectionContent::RefPtr& sc) // Search SC in hidden elements // The content may already be hidden - if (_hiddenSectionContents.contains(sc->uid())) + if (d->hiddenSectionContents.contains(sc->uid())) return true; qFatal("Unable to hide SectionContent, don't know this one 8-/"); @@ -247,9 +246,9 @@ bool ContainerWidget::raiseSectionContent(const SectionContent::RefPtr& sc) ADS_Expects(!sc.isNull()); // Search SC in sections - for (int i = 0; i < _sections.count(); ++i) + for (int i = 0; i < d->sections.count(); ++i) { - SectionWidget* sw = _sections.at(i); + SectionWidget* sw = d->sections.at(i); int index = sw->indexOfContent(sc); if (index < 0) continue; @@ -258,9 +257,9 @@ bool ContainerWidget::raiseSectionContent(const SectionContent::RefPtr& sc) } // Search SC in floatings - for (int i = 0; i < _floatings.size(); ++i) + for (int i = 0; i < d->floatings.size(); ++i) { - FloatingWidget* fw = _floatings.at(i); + FloatingWidget* fw = d->floatings.at(i); if (fw->content()->uid() != sc->uid()) continue; fw->setVisible(true); @@ -269,7 +268,7 @@ bool ContainerWidget::raiseSectionContent(const SectionContent::RefPtr& sc) } // Search SC in hidden - if (_hiddenSectionContents.contains(sc->uid())) + if (d->hiddenSectionContents.contains(sc->uid())) return showSectionContent(sc); qFatal("Unable to hide SectionContent, don't know this one 8-/"); @@ -281,18 +280,18 @@ bool ContainerWidget::isSectionContentVisible(const SectionContent::RefPtr& sc) ADS_Expects(!sc.isNull()); // Search SC in floatings - for (int i = 0; i < _floatings.count(); ++i) + for (int i = 0; i < d->floatings.count(); ++i) { - const bool found = _floatings.at(i)->content()->uid() == sc->uid(); + const bool found = d->floatings.at(i)->content()->uid() == sc->uid(); if (!found) continue; - return _floatings.at(i)->isVisible(); + return d->floatings.at(i)->isVisible(); } // Search SC in sections - for (int i = 0; i < _sections.count(); ++i) + for (int i = 0; i < d->sections.count(); ++i) { - SectionWidget* sw = _sections.at(i); + SectionWidget* sw = d->sections.at(i); const int index = sw->indexOfContent(sc); if (index < 0) continue; @@ -300,7 +299,7 @@ bool ContainerWidget::isSectionContentVisible(const SectionContent::RefPtr& sc) } // Search SC in hidden - if (_hiddenSectionContents.contains(sc->uid())) + if (d->hiddenSectionContents.contains(sc->uid())) return false; qWarning() << "SectionContent is not a part of this ContainerWidget:" << sc->uniqueName(); @@ -313,9 +312,9 @@ QMenu* ContainerWidget::createContextMenu() const QMap actions; // Visible contents of sections - for (int i = 0; i < _sections.size(); ++i) + for (int i = 0; i < d->sections.size(); ++i) { - const SectionWidget* sw = _sections.at(i); + const SectionWidget* sw = d->sections.at(i); const QList& contents = sw->contents(); foreach (const SectionContent::RefPtr& sc, contents) { @@ -326,17 +325,13 @@ QMenu* ContainerWidget::createContextMenu() const a->setCheckable(true); a->setChecked(true); a->setEnabled(sc->flags().testFlag(SectionContent::Closeable)); -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) - QObject::connect(a, &QAction::toggled, this, &ContainerWidget::onActionToggleSectionContentVisibility); -#else - QObject::connect(a, SIGNAL(toggled(bool)), this, SLOT(onActionToggleSectionContentVisibility(bool))); -#endif + connect(a, SIGNAL(toggled(bool)), this, SLOT(onActionToggleSectionContentVisibility(bool))); actions.insert(a->text(), a); } } // Hidden contents of sections - QHashIterator hiddenIter(_hiddenSectionContents); + QHashIterator hiddenIter(d->hiddenSectionContents); while (hiddenIter.hasNext()) { hiddenIter.next(); @@ -348,18 +343,14 @@ QMenu* ContainerWidget::createContextMenu() const a->setProperty("type", "section"); a->setCheckable(true); a->setChecked(false); -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) - QObject::connect(a, &QAction::toggled, this, &ContainerWidget::onActionToggleSectionContentVisibility); -#else - QObject::connect(a, SIGNAL(toggled(bool)), this, SLOT(onActionToggleSectionContentVisibility(bool))); -#endif + connect(a, SIGNAL(toggled(bool)), this, SLOT(onActionToggleSectionContentVisibility(bool))); actions.insert(a->text(), a); } // Floating contents - for (int i = 0; i < _floatings.size(); ++i) + for (int i = 0; i < d->floatings.size(); ++i) { - const FloatingWidget* fw = _floatings.at(i); + const FloatingWidget* fw = d->floatings.at(i); const SectionContent::RefPtr sc = fw->content(); QAction* a = new QAction(QIcon(), sc->visibleTitle(), NULL); @@ -368,11 +359,7 @@ QMenu* ContainerWidget::createContextMenu() const a->setProperty("type", "floating"); a->setCheckable(true); a->setChecked(fw->isVisible()); -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) - QObject::connect(a, &QAction::toggled, this, &ContainerWidget::onActionToggleSectionContentVisibility); -#else - QObject::connect(a, SIGNAL(toggled(bool)), this, SLOT(onActionToggleSectionContentVisibility(bool))); -#endif + connect(a, SIGNAL(toggled(bool)), this, SLOT(onActionToggleSectionContentVisibility(bool))); actions.insert(a->text(), a); } @@ -453,7 +440,7 @@ QRect ContainerWidget::outerLeftDropRect() const QList ContainerWidget::contents() const { - QList wl = _scLookupMapById.values(); + QList wl = d->scLookupMapById.values(); QList sl; for (int i = 0; i < wl.count(); ++i) { @@ -466,7 +453,7 @@ QList ContainerWidget::contents() const QPointer ContainerWidget::dropOverlay() const { - return _dropOverlay; + return d->dropOverlay; } /////////////////////////////////////////////////////////////////////// @@ -476,7 +463,7 @@ QPointer ContainerWidget::dropOverlay() const SectionWidget* ContainerWidget::newSectionWidget() { SectionWidget* sw = new SectionWidget(this); - _sections.append(sw); + d->sections.append(sw); return sw; } @@ -487,7 +474,7 @@ SectionWidget* ContainerWidget::dropContent(const InternalContentData& data, Sec SectionWidget* ret = NULL; // If no sections exists yet, create a default one and always drop into it. - if (_sections.count() <= 0) + if (d->sections.count() <= 0) { targetSection = newSectionWidget(); addSection(targetSection); @@ -500,17 +487,17 @@ SectionWidget* ContainerWidget::dropContent(const InternalContentData& data, Sec switch (area) { case TopDropArea: - ret = dropContentOuterHelper(_mainLayout, data, Qt::Vertical, false); + ret = dropContentOuterHelper(d->mainLayout, data, Qt::Vertical, false); break; case RightDropArea: - ret = dropContentOuterHelper(_mainLayout, data, Qt::Horizontal, true); + ret = dropContentOuterHelper(d->mainLayout, data, Qt::Horizontal, true); break; case CenterDropArea: case BottomDropArea: - ret = dropContentOuterHelper(_mainLayout, data, Qt::Vertical, true); + ret = dropContentOuterHelper(d->mainLayout, data, Qt::Vertical, true); break; case LeftDropArea: - ret = dropContentOuterHelper(_mainLayout, data, Qt::Horizontal, false); + ret = dropContentOuterHelper(d->mainLayout, data, Qt::Horizontal, false); break; default: return NULL; @@ -620,25 +607,25 @@ void ContainerWidget::addSection(SectionWidget* section) ADS_Expects(section != NULL); // Create default splitter. - if (!_splitter) + if (!d->splitter) { - _splitter = newSplitter(_orientation); - _mainLayout->addWidget(_splitter, 0, 0); + d->splitter = newSplitter(d->orientation); + d->mainLayout->addWidget(d->splitter, 0, 0); } - if (_splitter->indexOf(section) != -1) + if (d->splitter->indexOf(section) != -1) { qWarning() << Q_FUNC_INFO << QString("Section has already been added"); return; } - _splitter->addWidget(section); + d->splitter->addWidget(section); } SectionWidget* ContainerWidget::sectionAt(const QPoint& pos) const { const QPoint gpos = mapToGlobal(pos); - for (int i = 0; i < _sections.size(); ++i) + for (int i = 0; i < d->sections.size(); ++i) { - SectionWidget* sw = _sections[i]; + SectionWidget* sw = d->sections[i]; if (sw->rect().contains(sw->mapFromGlobal(gpos))) { return sw; @@ -748,40 +735,40 @@ QByteArray ContainerWidget::saveHierarchy() const saveFloatingWidgets(out); // Save state of sections and contents - if (_mainLayout->count() <= 0 || _sections.isEmpty()) + if (d->mainLayout->count() <= 0 || d->sections.isEmpty()) { // Looks like the user has hidden all contents and no more sections // are available. We can simply write a list of all hidden contents. out << 0; // Mode - out << _hiddenSectionContents.count(); - QHashIterator iter(_hiddenSectionContents); + out << d->hiddenSectionContents.count(); + QHashIterator iter(d->hiddenSectionContents); while (iter.hasNext()) { iter.next(); out << iter.value().data.content->uniqueName(); } } - else if (_mainLayout->count() == 1) + else if (d->mainLayout->count() == 1) { out << 1; // Mode // There should only be one! - QLayoutItem* li = _mainLayout->itemAt(0); + QLayoutItem* li = d->mainLayout->itemAt(0); if (!li->widget()) - qFatal("Not a widget in _mainLayout, this shouldn't happen."); + qFatal("Not a widget in d->mainLayout, this shouldn't happen."); // Save sections beginning with the first QSplitter (li->widget()). saveSectionWidgets(out, li->widget()); // Safe state of hidden contents, which doesn't have an section association // or the section association points to a no longer existing section. - QHashIterator iter(_hiddenSectionContents); + QHashIterator iter(d->hiddenSectionContents); int cnt = 0; while (iter.hasNext()) { iter.next(); - if (iter.value().preferredSectionId <= 0 || !SWLookupMapById(this).contains(iter.value().preferredSectionId)) + if (iter.value().preferredSectionId <= 0 || !d->swLookupMapById.contains(iter.value().preferredSectionId)) cnt++; } out << cnt; @@ -789,7 +776,7 @@ QByteArray ContainerWidget::saveHierarchy() const while (iter.hasNext()) { iter.next(); - if (iter.value().preferredSectionId <= 0 || !SWLookupMapById(this).contains(iter.value().preferredSectionId)) + if (iter.value().preferredSectionId <= 0 || !d->swLookupMapById.contains(iter.value().preferredSectionId)) out << iter.value().data.content->uniqueName(); } } @@ -797,17 +784,17 @@ QByteArray ContainerWidget::saveHierarchy() const { // More? Oh oh.. something is wrong :-/ out << -1; - qWarning() << "Oh noooz.. Something went wrong. There are too many items in _mainLayout."; + qWarning() << "Oh noooz.. Something went wrong. There are too many items in d->mainLayout."; } return ba; } void ContainerWidget::saveFloatingWidgets(QDataStream& out) const { - out << _floatings.count(); - for (int i = 0; i < _floatings.count(); ++i) + out << d->floatings.count(); + for (int i = 0; i < d->floatings.count(); ++i) { - FloatingWidget* fw = _floatings.at(i); + FloatingWidget* fw = d->floatings.at(i); out << fw->content()->uniqueName(); out << fw->saveGeometry(); out << fw->isVisible(); @@ -848,7 +835,7 @@ void ContainerWidget::saveSectionWidgets(QDataStream& out, QWidget* widget) cons const QList& contents = sw->contents(); QList hiddenContents; - QHashIterator iter(_hiddenSectionContents); + QHashIterator iter(d->hiddenSectionContents); while (iter.hasNext()) { iter.next(); @@ -879,25 +866,25 @@ void ContainerWidget::saveSectionWidgets(QDataStream& out, QWidget* widget) cons bool ContainerWidget::saveSectionIndex(ADS_NS_SER::SectionIndexData& sid) const { - if (_sections.count() <= 0) + if (d->sections.count() <= 0) return false; - sid.sectionsCount = _sections.count(); + sid.sectionsCount = d->sections.count(); for (int i = 0; i < sid.sectionsCount; ++i) { ADS_NS_SER::SectionEntity se; - se.x = mapFromGlobal(_sections[i]->parentWidget()->mapToGlobal(_sections[i]->pos())).x(); - se.y = mapFromGlobal(_sections[i]->parentWidget()->mapToGlobal(_sections[i]->pos())).y(); - se.width = _sections[i]->geometry().width(); - se.height = _sections[i]->geometry().height(); - se.currentIndex = _sections[i]->currentIndex(); - se.sectionContentsCount = _sections[i]->contents().count(); - foreach (const SectionContent::RefPtr& sc, _sections[i]->contents()) + se.x = mapFromGlobal(d->sections[i]->parentWidget()->mapToGlobal(d->sections[i]->pos())).x(); + se.y = mapFromGlobal(d->sections[i]->parentWidget()->mapToGlobal(d->sections[i]->pos())).y(); + se.width = d->sections[i]->geometry().width(); + se.height = d->sections[i]->geometry().height(); + se.currentIndex = d->sections[i]->currentIndex(); + se.sectionContentsCount = d->sections[i]->contents().count(); + foreach (const SectionContent::RefPtr& sc, d->sections[i]->contents()) { ADS_NS_SER::SectionContentEntity sce; sce.uniqueName = sc->uniqueName(); sce.visible = true; - sce.preferredIndex = _sections[i]->indexOfContent(sc); + sce.preferredIndex = d->sections[i]->indexOfContent(sc); se.sectionContents.append(sce); // std::move()? } sid.sections.append(se); // std::move()? @@ -920,8 +907,8 @@ bool ContainerWidget::restoreHierarchy(const QByteArray& data) if (version != 1) return false; - QList oldFloatings = _floatings; - QList oldSections = _sections; + QList oldFloatings = d->floatings; + QList oldSections = d->sections; // Restore floating widgets QList floatings; @@ -954,7 +941,7 @@ bool ContainerWidget::restoreHierarchy(const QByteArray& data) QString uname; in >> uname; - const SectionContent::RefPtr sc = SCLookupMapByName(this).value(uname); + const SectionContent::RefPtr sc = d->scLookupMapByName.value(uname); if (!sc) continue; @@ -980,7 +967,7 @@ bool ContainerWidget::restoreHierarchy(const QByteArray& data) { QString uname; in >> uname; - const SectionContent::RefPtr sc = SCLookupMapByName(this).value(uname); + const SectionContent::RefPtr sc = d->scLookupMapByName.value(uname); if (!sc) continue; @@ -1019,7 +1006,7 @@ bool ContainerWidget::restoreHierarchy(const QByteArray& data) contents.append(contentsToHide.at(i)); // Compare restored contents with available contents - const QList allContents = SCLookupMapById(this).values(); + const QList allContents = d->scLookupMapById.values(); for (int i = 0; i < allContents.count(); ++i) { const SectionContent::RefPtr sc = allContents.at(i).toStrongRef(); @@ -1055,12 +1042,12 @@ bool ContainerWidget::restoreHierarchy(const QByteArray& data) } } - _floatings = floatings; - _sections = sections; + d->floatings = floatings; + d->sections = sections; // Delete old objects - QLayoutItem* old = _mainLayout->takeAt(0); - _mainLayout->addWidget(_splitter); + QLayoutItem* old = d->mainLayout->takeAt(0); + d->mainLayout->addWidget(d->splitter); delete old; qDeleteAll(oldFloatings); qDeleteAll(oldSections); @@ -1091,7 +1078,7 @@ bool ContainerWidget::restoreFloatingWidgets(QDataStream& in, int version, QList bool visible = false; in >> visible; - const SectionContent::RefPtr sc = SCLookupMapByName(this).value(uname).toStrongRef(); + const SectionContent::RefPtr sc = d->scLookupMapByName.value(uname).toStrongRef(); if (!sc) { qWarning() << "Can not find SectionContent:" << uname; @@ -1147,7 +1134,7 @@ bool ContainerWidget::restoreSectionWidgets(QDataStream& in, int version, QSplit sp->setSizes(sizes); if (!currentSplitter) - _splitter = sp; + d->splitter = sp; else currentSplitter->addWidget(sp); } @@ -1174,7 +1161,7 @@ bool ContainerWidget::restoreSectionWidgets(QDataStream& in, int version, QSplit int preferredIndex = -1; in >> preferredIndex; - const SectionContent::RefPtr sc = SCLookupMapByName(this).value(uname).toStrongRef(); + const SectionContent::RefPtr sc = d->scLookupMapByName.value(uname).toStrongRef(); if (!sc) { qWarning() << "Can not find SectionContent:" << uname; @@ -1220,23 +1207,23 @@ bool ContainerWidget::takeContent(const SectionContent::RefPtr& sc, InternalCont // Search in sections bool found = false; - for (int i = 0; i < _sections.count() && !found; ++i) + for (int i = 0; i < d->sections.count() && !found; ++i) { - found = _sections.at(i)->takeContent(sc->uid(), data); + found = d->sections.at(i)->takeContent(sc->uid(), data); } // Search in floating widgets - for (int i = 0; i < _floatings.count() && !found; ++i) + for (int i = 0; i < d->floatings.count() && !found; ++i) { - found = _floatings.at(i)->content()->uid() == sc->uid(); + found = d->floatings.at(i)->content()->uid() == sc->uid(); if (found) - _floatings.at(i)->takeContent(data); + d->floatings.at(i)->takeContent(data); } // Search in hidden items - if (!found && _hiddenSectionContents.contains(sc->uid())) + if (!found && d->hiddenSectionContents.contains(sc->uid())) { - const HiddenSectionItem hsi = _hiddenSectionContents.take(sc->uid()); + const HiddenSectionItem hsi = d->hiddenSectionContents.take(sc->uid()); data = hsi.data; found = true; } @@ -1259,7 +1246,7 @@ void ContainerWidget::onActionToggleSectionContentVisibility(bool visible) if (!a) return; const int uid = a->property("uid").toInt(); - const SectionContent::RefPtr sc = SCLookupMapById(this).value(uid).toStrongRef(); + const SectionContent::RefPtr sc = d->scLookupMapById.value(uid).toStrongRef(); if (sc.isNull()) { qCritical() << "Can not find content by ID" << uid; @@ -1276,37 +1263,21 @@ void ContainerWidget::moveFloatingWidget(const QPoint& TargetPos) { // Mouse is over a SectionWidget SectionWidget* sectionwidget = sectionAt(mapFromGlobal(QCursor::pos())); + if (rect().contains(mapFromGlobal(QCursor::pos()))) + { + std::cout << "over Container" << std::endl; + } + + if (sectionwidget) { qInfo() << "over sectionWidget"; - _dropOverlay->setAllowedAreas(ADS_NS::AllAreas); - _dropOverlay->showDropOverlay(sectionwidget); - } - // Mouse is at the edge of the ContainerWidget - // Top, Right, Bottom, Left - else if (outerTopDropRect().contains(mapFromGlobal(QCursor::pos()))) - { - _dropOverlay->setAllowedAreas(ADS_NS::TopDropArea); - _dropOverlay->showDropOverlay(this, outerTopDropRect()); - } - else if (outerRightDropRect().contains(mapFromGlobal(QCursor::pos()))) - { - _dropOverlay->setAllowedAreas(ADS_NS::RightDropArea); - _dropOverlay->showDropOverlay(this, outerRightDropRect()); - } - else if (outerBottomDropRect().contains(mapFromGlobal(QCursor::pos()))) - { - _dropOverlay->setAllowedAreas(ADS_NS::BottomDropArea); - _dropOverlay->showDropOverlay(this, outerBottomDropRect()); - } - else if (outerLeftDropRect().contains(mapFromGlobal(QCursor::pos()))) - { - _dropOverlay->setAllowedAreas(ADS_NS::LeftDropArea); - _dropOverlay->showDropOverlay(this, outerLeftDropRect()); + d->dropOverlay->setAllowedAreas(ADS_NS::AllAreas); + d->dropOverlay->showDropOverlay(sectionwidget); } else { - _dropOverlay->hideDropOverlay(); + d->dropOverlay->hideDropOverlay(); } } @@ -1323,7 +1294,7 @@ FloatingWidget* ContainerWidget::startFloating(SectionWidget* sectionwidget, int FloatingWidget* fw = new FloatingWidget(this, data.content, data.titleWidget, data.contentWidget, this); fw->resize(sectionwidget->size()); - _floatings.append(fw); + d->floatings.append(fw); fw->move(TargetPos); fw->show(); diff --git a/AdvancedDockingSystem/src/DropOverlay.cpp b/AdvancedDockingSystem/src/DropOverlay.cpp index 8fb7905..0222f9c 100644 --- a/AdvancedDockingSystem/src/DropOverlay.cpp +++ b/AdvancedDockingSystem/src/DropOverlay.cpp @@ -12,6 +12,8 @@ #include #include +#include + ADS_NAMESPACE_BEGIN // Helper ///////////////////////////////////////////////////////////// @@ -42,42 +44,40 @@ static QPixmap createDropIndicatorPixmap(const QPalette& pal, const QSizeF& size switch (dropArea) { case TopDropArea: + case TopBorderDropArea: areaRect = QRectF(baseRect.x(), baseRect.y(), baseRect.width(), baseRect.height() * .5f); areaLine = QLineF(areaRect.bottomLeft(), areaRect.bottomRight()); gradient.setStart(areaRect.topLeft()); gradient.setFinalStop(areaRect.bottomLeft()); - gradient.setColorAt(0.f, areaBackgroundColor); - gradient.setColorAt(1.f, areaBackgroundColor.lighter(120)); break; case RightDropArea: + case RightBorderDropArea: areaRect = QRectF(baseRect.width() * .5f, baseRect.y(), baseRect.width() * .5f, baseRect.height()); areaLine = QLineF(areaRect.topLeft(), areaRect.bottomLeft()); gradient.setStart(areaRect.topLeft()); gradient.setFinalStop(areaRect.topRight()); - gradient.setColorAt(0.f, areaBackgroundColor.lighter(120)); - gradient.setColorAt(1.f, areaBackgroundColor); break; case BottomDropArea: + case BottomBorderDropArea: areaRect = QRectF(baseRect.x(), baseRect.height() * .5f, baseRect.width(), baseRect.height() * .5f); areaLine = QLineF(areaRect.topLeft(), areaRect.topRight()); gradient.setStart(areaRect.topLeft()); gradient.setFinalStop(areaRect.bottomLeft()); - gradient.setColorAt(0.f, areaBackgroundColor.lighter(120)); - gradient.setColorAt(1.f, areaBackgroundColor); break; case LeftDropArea: + case LeftBorderDropArea: areaRect = QRectF(baseRect.x(), baseRect.y(), baseRect.width() * .5f, baseRect.height()); areaLine = QLineF(areaRect.topRight(), areaRect.bottomRight()); gradient.setStart(areaRect.topLeft()); gradient.setFinalStop(areaRect.topRight()); - gradient.setColorAt(0.f, areaBackgroundColor); - gradient.setColorAt(1.f, areaBackgroundColor.lighter(120)); break; default: break; } if (areaRect.isValid()) { + gradient.setColorAt(0.f, areaBackgroundColor); + gradient.setColorAt(1.f, areaBackgroundColor.lighter(120)); p.fillRect(areaRect, gradient); pen = p.pen(); @@ -104,7 +104,7 @@ static QPixmap createDropIndicatorPixmap(const QPalette& pal, const QSizeF& size return pm; } -static QWidget* createDropIndicatorWidget(DropArea dropArea) +QWidget* DropOverlay::createDropIndicatorWidget(DropArea dropArea) { QLabel* l = new QLabel(); l->setObjectName("DropAreaLabel"); @@ -113,6 +113,8 @@ static QWidget* createDropIndicatorWidget(DropArea dropArea) const QSizeF size(metric, metric); l->setPixmap(createDropIndicatorPixmap(l->palette(), size, dropArea)); + l->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint); + l->setAttribute(Qt::WA_TranslucentBackground); return l; } @@ -142,6 +144,10 @@ DropOverlay::DropOverlay(QWidget* parent) : areaWidgets.insert(ADS_NS::LeftDropArea, createDropIndicatorWidget(LeftDropArea));//createDropWidget(":/img/split-left.png")); areaWidgets.insert(ADS_NS::CenterDropArea, createDropIndicatorWidget(CenterDropArea));//createDropWidget(":/img/dock-center.png")); + m_LeftBorderDropArea = createDropIndicatorWidget(LeftDropArea); + m_LeftBorderDropArea->setVisible(false); + m_LeftBorderDropArea->setWindowTitle("DropOverlayCross"); + _cross->setAreaWidgets(areaWidgets); _cross->setVisible(false); setVisible(false); @@ -253,6 +259,7 @@ void DropOverlay::paintEvent(QPaintEvent*) // Draw rect based on location QRect r = rect(); const DropArea da = cursorLocation(); + std::cout << "CursorLocation: " << cursorLocation() << std::endl; switch (da) { case ADS_NS::TopDropArea: @@ -293,11 +300,17 @@ void DropOverlay::paintEvent(QPaintEvent*) void DropOverlay::showEvent(QShowEvent*) { _cross->show(); + QRect ContainerWidgetRect = parentWidget()->rect(); + QPoint Pos(ContainerWidgetRect.left(), ContainerWidgetRect.center().y()); + m_LeftBorderDropArea->move(parentWidget()->mapToGlobal(Pos)); + m_LeftBorderDropArea->show(); + } void DropOverlay::hideEvent(QHideEvent*) { _cross->hide(); + m_LeftBorderDropArea->hide(); } void DropOverlay::resizeEvent(QResizeEvent* e) diff --git a/AdvancedDockingSystem/src/FloatingWidget.cpp b/AdvancedDockingSystem/src/FloatingWidget.cpp index c0188bc..324cb88 100644 --- a/AdvancedDockingSystem/src/FloatingWidget.cpp +++ b/AdvancedDockingSystem/src/FloatingWidget.cpp @@ -41,18 +41,10 @@ FloatingWidget::FloatingWidget(ContainerWidget* container, SectionContent::RefPt closeButton->setToolTip(tr("Close")); closeButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); _titleLayout->addWidget(closeButton); -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) - QObject::connect(closeButton, &QPushButton::clicked, this, &FloatingWidget::onCloseButtonClicked); -#else - QObject::connect(closeButton, SIGNAL(clicked(bool)), this, SLOT(onCloseButtonClicked())); -#endif + connect(closeButton, SIGNAL(clicked(bool)), this, SLOT(onCloseButtonClicked())); } - - // Content l->addWidget(contentWidget, 1); contentWidget->show(); - -// _container->_floatingWidgets.append(this); } @@ -69,7 +61,7 @@ FloatingWidget::FloatingWidget(SectionWidget* sectionWidget) FloatingWidget::~FloatingWidget() { - _container->_floatings.removeAll(this); // Note: I don't like this here, but we have to remove it from list... + _container->d->floatings.removeAll(this); // Note: I don't like this here, but we have to remove it from list... } bool FloatingWidget::takeContent(InternalContentData& data) diff --git a/AdvancedDockingSystem/src/SectionContent.cpp b/AdvancedDockingSystem/src/SectionContent.cpp index d7efb12..95024aa 100644 --- a/AdvancedDockingSystem/src/SectionContent.cpp +++ b/AdvancedDockingSystem/src/SectionContent.cpp @@ -16,12 +16,15 @@ SectionContent::SectionContent() : SectionContent::RefPtr SectionContent::newSectionContent(const QString& uniqueName, ContainerWidget* container, QWidget* title, QWidget* content) { + auto SectionContentNameMap = container->d->scLookupMapByName; + auto SectionContentIdMap = container->d->scLookupMapById; + if (uniqueName.isEmpty()) { qFatal("Can not create SectionContent with empty uniqueName"); return RefPtr(); } - else if (SCLookupMapByName(container).contains(uniqueName)) + else if (SectionContentNameMap.contains(uniqueName)) { qFatal("Can not create SectionContent with already used uniqueName"); return RefPtr(); @@ -38,17 +41,20 @@ SectionContent::RefPtr SectionContent::newSectionContent(const QString& uniqueNa sc->_titleWidget = title; sc->_contentWidget = content; - SCLookupMapById(container).insert(sc->uid(), sc); - SCLookupMapByName(container).insert(sc->uniqueName(), sc); + SectionContentIdMap.insert(sc->uid(), sc); + SectionContentNameMap.insert(sc->uniqueName(), sc); return sc; } SectionContent::~SectionContent() { + auto SectionContentNameMap = _containerWidget->d->scLookupMapByName; + auto SectionContentIdMap = _containerWidget->d->scLookupMapById; + if (_containerWidget) { - SCLookupMapById(_containerWidget).remove(_uid); - SCLookupMapByName(_containerWidget).remove(_uniqueName); + SectionContentIdMap.remove(_uid); + SectionContentNameMap.remove(_uniqueName); } delete _titleWidget; delete _contentWidget; diff --git a/AdvancedDockingSystem/src/SectionTitleWidget.cpp b/AdvancedDockingSystem/src/SectionTitleWidget.cpp index 8ccf6d6..025cb96 100644 --- a/AdvancedDockingSystem/src/SectionTitleWidget.cpp +++ b/AdvancedDockingSystem/src/SectionTitleWidget.cpp @@ -83,8 +83,8 @@ void SectionTitleWidget::mouseReleaseEvent(QMouseEvent* ev) SectionWidget* sw = cw->sectionAt(cw->mapFromGlobal(ev->globalPos())); if (sw) { - cw->_dropOverlay->setAllowedAreas(ADS_NS::AllAreas); - DropArea loc = cw->_dropOverlay->showDropOverlay(sw); + cw->d->dropOverlay->setAllowedAreas(ADS_NS::AllAreas); + DropArea loc = cw->d->dropOverlay->showDropOverlay(sw); if (loc != InvalidDropArea) { InternalContentData data; @@ -140,7 +140,7 @@ void SectionTitleWidget::mouseReleaseEvent(QMouseEvent* ev) // Reset m_DragStartPosition = QPoint(); m_TabMoving = false; - cw->_dropOverlay->hideDropOverlay(); + cw->d->dropOverlay->hideDropOverlay(); QFrame::mouseReleaseEvent(ev); } diff --git a/AdvancedDockingSystem/src/SectionWidget.cpp b/AdvancedDockingSystem/src/SectionWidget.cpp index 161f53b..a7dd643 100644 --- a/AdvancedDockingSystem/src/SectionWidget.cpp +++ b/AdvancedDockingSystem/src/SectionWidget.cpp @@ -82,11 +82,7 @@ SectionWidget::SectionWidget(ContainerWidget* parent) : _closeButton->setToolTip(tr("Close")); _closeButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); _topLayout->addWidget(_closeButton, 0); -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) - QObject::connect(_closeButton, &QPushButton::clicked, this, &SectionWidget::onCloseButtonClicked); -#else - QObject::connect(_closeButton, SIGNAL(clicked(bool)), this, SLOT(onCloseButtonClicked())); -#endif + connect(_closeButton, SIGNAL(clicked(bool)), this, SLOT(onCloseButtonClicked())); _tabsLayoutInitCount = _tabsLayout->count(); @@ -97,22 +93,15 @@ SectionWidget::SectionWidget(ContainerWidget* parent) : _contentsLayout->setSpacing(0); l->addLayout(_contentsLayout, 1); -#if defined(ADS_ANIMATIONS_ENABLED) - QGraphicsDropShadowEffect* shadow = new QGraphicsDropShadowEffect(this); - shadow->setOffset(0, 0); - shadow->setBlurRadius(8); - setGraphicsEffect(shadow); -#endif - - SWLookupMapById(_container).insert(_uid, this); + _container->d->swLookupMapById.insert(_uid, this); } SectionWidget::~SectionWidget() { if (_container) { - SWLookupMapById(_container).remove(_uid); - _container->_sections.removeAll(this); // Note: I don't like this here, but we have to remove it from list... + _container->d->swLookupMapById.remove(_uid); + _container->d->sections.removeAll(this); // Note: I don't like this here, but we have to remove it from list... } // Delete empty QSplitter.