From b31c5f1f3d432ac5ca54d784845c5738af173319 Mon Sep 17 00:00:00 2001 From: Uwe Kindler Date: Tue, 28 Feb 2017 22:41:34 +0100 Subject: [PATCH] Added initial support for docking into dock areas --- .../src/v2/DockContainerWidget.cpp | 45 ++++++++++++++----- AdvancedDockingSystem/src/v2/ads_globals.cpp | 21 ++++++++- AdvancedDockingSystem/src/v2/ads_globals.h | 21 ++++++++- .../src/mainwindow.cpp | 12 ++++- 4 files changed, 82 insertions(+), 17 deletions(-) diff --git a/AdvancedDockingSystem/src/v2/DockContainerWidget.cpp b/AdvancedDockingSystem/src/v2/DockContainerWidget.cpp index e4434aa..e8bc112 100644 --- a/AdvancedDockingSystem/src/v2/DockContainerWidget.cpp +++ b/AdvancedDockingSystem/src/v2/DockContainerWidget.cpp @@ -39,6 +39,8 @@ #include "DockAreaWidget.h" #include "ads_globals.h" +#include + namespace ads { static unsigned int zOrderCounter = 0; @@ -46,7 +48,7 @@ static unsigned int zOrderCounter = 0; /** * Helper function to ease insertion of dock area into splitter */ -static void inserDockAreaIntoSplitter(QSplitter* Splitter, QWidget* widget, bool Append) +static void insertDockAreaIntoSplitter(QSplitter* Splitter, QWidget* widget, bool Append) { if (Append) { @@ -94,7 +96,7 @@ struct DockContainerWidgetPrivate * Adds dock widget to a existing DockWidgetArea */ CDockAreaWidget* dockWidgetIntoDockArea(DockWidgetArea area, CDockWidget* Dockwidget, - CDockAreaWidget* DockAreaWidget); + CDockAreaWidget* TargetDockArea); }; // struct DockContainerWidgetPrivate @@ -120,23 +122,23 @@ CDockAreaWidget* DockContainerWidgetPrivate::dockWidgetIntoContainer(DockWidgetA } else if (DockAreas.count() == 1) { - QSplitter* Splitter = internal::newSplitter(InsertParam.first); + QSplitter* Splitter = internal::newSplitter(InsertParam.orientation()); auto DockArea = dynamic_cast(Layout->itemAtPosition(0, 0)->widget()); Layout->replaceWidget(DockArea, Splitter); Splitter->addWidget(DockArea); - inserDockAreaIntoSplitter(Splitter, NewDockArea, InsertParam.second); + insertDockAreaIntoSplitter(Splitter, NewDockArea, InsertParam.append()); } else { QSplitter* Splitter = _this->findChild(QString(), Qt::FindDirectChildrenOnly); - if (Splitter->orientation() == InsertParam.first) + if (Splitter->orientation() == InsertParam.orientation()) { - inserDockAreaIntoSplitter(Splitter, NewDockArea, InsertParam.second); + insertDockAreaIntoSplitter(Splitter, NewDockArea, InsertParam.append()); } else { - QSplitter* NewSplitter = internal::newSplitter(InsertParam.first); - if (InsertParam.second) + QSplitter* NewSplitter = internal::newSplitter(InsertParam.orientation()); + if (InsertParam.append()) { QLayoutItem* li = Layout->replaceWidget(Splitter, NewSplitter); NewSplitter->addWidget(Splitter); @@ -160,16 +162,35 @@ CDockAreaWidget* DockContainerWidgetPrivate::dockWidgetIntoContainer(DockWidgetA //============================================================================ CDockAreaWidget* DockContainerWidgetPrivate::dockWidgetIntoDockArea(DockWidgetArea area, - CDockWidget* Dockwidget, CDockAreaWidget* DockAreaWidget) + CDockWidget* Dockwidget, CDockAreaWidget* TargetDockArea) { if (CenterDockWidgetArea == area) { - DockAreaWidget->addDockWidget(Dockwidget); - return DockAreaWidget; + TargetDockArea->addDockWidget(Dockwidget); + return TargetDockArea; } + CDockAreaWidget* NewDockArea = new CDockAreaWidget(DockManager, _this); + NewDockArea->addDockWidget(Dockwidget); auto InsertParam = internal::dockAreaInsertParameters(area); - return 0; + QSplitter* TargetAreaSplitter = internal::findParentSplitter(TargetDockArea); + int index = TargetAreaSplitter ->indexOf(TargetDockArea); + if (TargetAreaSplitter->orientation() == InsertParam.orientation()) + { + std::cout << "TargetAreaSplitter->orientation() == InsertParam.orientation()" << std::endl; + TargetAreaSplitter->insertWidget(index + InsertParam.insertOffset(), NewDockArea); + } + else + { + std::cout << "TargetAreaSplitter->orientation() != InsertParam.orientation()" << std::endl; + QSplitter* NewSplitter = internal::newSplitter(InsertParam.orientation()); + NewSplitter->addWidget(TargetDockArea); + insertDockAreaIntoSplitter(NewSplitter, NewDockArea, InsertParam.append()); + TargetAreaSplitter->insertWidget(index, NewSplitter); + } + + DockAreas.append(NewDockArea); + return NewDockArea; } diff --git a/AdvancedDockingSystem/src/v2/ads_globals.cpp b/AdvancedDockingSystem/src/v2/ads_globals.cpp index eccbe23..aeb77d7 100644 --- a/AdvancedDockingSystem/src/v2/ads_globals.cpp +++ b/AdvancedDockingSystem/src/v2/ads_globals.cpp @@ -49,7 +49,7 @@ QSplitter* newSplitter(Qt::Orientation orientation, QWidget* parent) } //============================================================================ -QPair dockAreaInsertParameters(DockWidgetArea Area) +CDockInsertParam dockAreaInsertParameters(DockWidgetArea Area) { switch (Area) { @@ -61,10 +61,27 @@ QPair dockAreaInsertParameters(DockWidgetArea Area) default: QPair(Qt::Vertical, false); } // switch (Area) - return QPair(Qt::Vertical, false); + return CDockInsertParam(Qt::Vertical, false); } +//============================================================================ +QSplitter* findParentSplitter(QWidget* w) +{ + QWidget* parentWidget = w; + do + { + QSplitter* splitter = dynamic_cast(parentWidget); + if (splitter) + { + return splitter; + } + parentWidget = parentWidget->parentWidget(); + } + while (parentWidget); + return 0; +} + } // namespace internal } // namespace ads diff --git a/AdvancedDockingSystem/src/v2/ads_globals.h b/AdvancedDockingSystem/src/v2/ads_globals.h index d0ad5e1..8bffee2 100644 --- a/AdvancedDockingSystem/src/v2/ads_globals.h +++ b/AdvancedDockingSystem/src/v2/ads_globals.h @@ -57,10 +57,29 @@ namespace internal */ QSplitter* newSplitter(Qt::Orientation orientation, QWidget* parent = 0); +/** + * Convenience class for QPair to provide better naming than first and + * second + */ +class CDockInsertParam : public QPair +{ +public: + using QPair::QPair; + Qt::Orientation orientation() const {return this->first;} + bool append() const {return this->second;} + int insertOffset() const {return append() ? 1 : 0;} +}; + /** * Returns the insertion parameters for the given dock area */ -QPair dockAreaInsertParameters(DockWidgetArea Area); +CDockInsertParam dockAreaInsertParameters(DockWidgetArea Area); + +/** + * Returns the parent splitter of the given widget or 0 if the widget is not + * child of any splitter + */ +QSplitter* findParentSplitter(QWidget* w); } // namespace internal } // namespace ads diff --git a/AdvancedDockingSystemDemo_v2/src/mainwindow.cpp b/AdvancedDockingSystemDemo_v2/src/mainwindow.cpp index c35ea9b..a79ad0b 100644 --- a/AdvancedDockingSystemDemo_v2/src/mainwindow.cpp +++ b/AdvancedDockingSystemDemo_v2/src/mainwindow.cpp @@ -86,15 +86,23 @@ MainWindow::~MainWindow() void MainWindow::createContent() { + // Test container docking auto DockWidget = createCalendarDockWidget(m_DockManager); DockWidget->setFeatures(DockWidget->features().setFlag(ads::CDockWidget::DockWidgetClosable, false)); m_DockManager->addDockWidget(ads::LeftDockWidgetArea, DockWidget); m_DockManager->addDockWidget(ads::LeftDockWidgetArea, createLongTextLabelDockWidget(m_DockManager)); m_DockManager->addDockWidget(ads::BottomDockWidgetArea, createFileSystemTreeDockWidget(m_DockManager)); - auto DockArea = m_DockManager->addDockWidget(ads::TopDockWidgetArea, createFileSystemTreeDockWidget(m_DockManager)); + auto TopDockArea = m_DockManager->addDockWidget(ads::TopDockWidgetArea, createFileSystemTreeDockWidget(m_DockManager)); DockWidget = createCalendarDockWidget(m_DockManager); DockWidget->setFeatures(DockWidget->features().setFlag(ads::CDockWidget::DockWidgetClosable, false)); - m_DockManager->addDockWidget(ads::CenterDockWidgetArea, DockWidget, DockArea); + m_DockManager->addDockWidget(ads::CenterDockWidgetArea, DockWidget, TopDockArea); + + // Test dock area docking + auto RighDockArea = m_DockManager->addDockWidget(ads::RightDockWidgetArea, createLongTextLabelDockWidget(m_DockManager), TopDockArea); + m_DockManager->addDockWidget(ads::TopDockWidgetArea, createLongTextLabelDockWidget(m_DockManager), RighDockArea); + auto BottomDockArea = m_DockManager->addDockWidget(ads::BottomDockWidgetArea, createLongTextLabelDockWidget(m_DockManager), RighDockArea); + m_DockManager->addDockWidget(ads::RightDockWidgetArea, createLongTextLabelDockWidget(m_DockManager), RighDockArea); + m_DockManager->addDockWidget(ads::CenterDockWidgetArea, createLongTextLabelDockWidget(m_DockManager), BottomDockArea); }