From a614e3cc3d06d6b34426c21267f25083c9f81cdf Mon Sep 17 00:00:00 2001 From: Uwe Kindler Date: Mon, 11 Jan 2021 11:07:03 +0100 Subject: [PATCH] Fixed CDockAreaWidget::nextOpenDockWidget() function to properly return a DockWidget with tab if this is possible Added new emptydockarea example --- examples/CMakeLists.txt | 3 +- examples/centralwidget/mainwindow.cpp | 36 +++--- examples/emptydockarea/CMakeLists.txt | 25 +++++ examples/emptydockarea/emptydockarea.pro | 34 ++++++ examples/emptydockarea/main.cpp | 10 ++ examples/emptydockarea/mainwindow.cpp | 134 +++++++++++++++++++++++ examples/emptydockarea/mainwindow.h | 43 ++++++++ examples/emptydockarea/mainwindow.ui | 47 ++++++++ examples/examples.pro | 3 +- src/DockAreaWidget.cpp | 43 +++++++- 10 files changed, 351 insertions(+), 27 deletions(-) create mode 100644 examples/emptydockarea/CMakeLists.txt create mode 100644 examples/emptydockarea/emptydockarea.pro create mode 100644 examples/emptydockarea/main.cpp create mode 100644 examples/emptydockarea/mainwindow.cpp create mode 100644 examples/emptydockarea/mainwindow.h create mode 100644 examples/emptydockarea/mainwindow.ui diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 32ca8c4..bc17f01 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -3,4 +3,5 @@ project(QtADSExamples LANGUAGES CXX VERSION ${VERSION_SHORT}) add_subdirectory(simple) add_subdirectory(sidebar) add_subdirectory(deleteonclose) -add_subdirectory(centralwidget) \ No newline at end of file +add_subdirectory(centralwidget) +add_subdirectory(emptydockarea) \ No newline at end of file diff --git a/examples/centralwidget/mainwindow.cpp b/examples/centralwidget/mainwindow.cpp index b4d5635..fe1b347 100644 --- a/examples/centralwidget/mainwindow.cpp +++ b/examples/centralwidget/mainwindow.cpp @@ -38,36 +38,34 @@ CMainWindow::CMainWindow(QWidget *parent) DockManager = new CDockManager(this); // Set central widget - //QPlainTextEdit* w = new QPlainTextEdit(); - //w->setPlaceholderText("This is the central editor. Enter your text here."); + QPlainTextEdit* w = new QPlainTextEdit(); + w->setPlaceholderText("This is the central editor. Enter your text here."); CDockWidget* CentralDockWidget = new CDockWidget("CentralWidget"); - //CentralDockWidget->setWidget(w); + CentralDockWidget->setWidget(w); auto* CentralDockArea = DockManager->setCentralWidget(CentralDockWidget); - CentralDockWidget->setFeature(ads::CDockWidget::NoTab, true); - //CentralDockArea->setAllowedAreas(DockWidgetArea::OuterDockAreas); + CentralDockArea->setAllowedAreas(DockWidgetArea::OuterDockAreas); // create other dock widgets - QTreeView* fileTree = new QTreeView(); - fileTree->setFrameShape(QFrame::NoFrame); - QFileSystemModel* fileModel = new QFileSystemModel(fileTree); - fileModel->setRootPath(QDir::currentPath()); - fileTree->setModel(fileModel); - CDockWidget* DataDockWidget = new CDockWidget("File system"); - DataDockWidget->setWidget(fileTree); - DataDockWidget->resize(150, 250); - DataDockWidget->setMinimumSize(100, 250); - auto* fileArea = DockManager->addDockWidget(DockWidgetArea::LeftDockWidgetArea, DataDockWidget, CentralDockArea); - ui->menuView->addAction(DataDockWidget->toggleViewAction()); - QTableWidget* table = new QTableWidget(); table->setColumnCount(3); table->setRowCount(10); - CDockWidget* TableDockWidget = new CDockWidget("Table"); + CDockWidget* TableDockWidget = new CDockWidget("Table 1"); TableDockWidget->setWidget(table); TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget); TableDockWidget->resize(250, 150); TableDockWidget->setMinimumSize(200,150); - DockManager->addDockWidget(DockWidgetArea::BottomDockWidgetArea, TableDockWidget, fileArea); + auto TableArea = DockManager->addDockWidget(DockWidgetArea::LeftDockWidgetArea, TableDockWidget); + ui->menuView->addAction(TableDockWidget->toggleViewAction()); + + table = new QTableWidget(); + table->setColumnCount(5); + table->setRowCount(1020); + TableDockWidget = new CDockWidget("Table 2"); + TableDockWidget->setWidget(table); + TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget); + TableDockWidget->resize(250, 150); + TableDockWidget->setMinimumSize(200,150); + DockManager->addDockWidget(DockWidgetArea::BottomDockWidgetArea, TableDockWidget, TableArea); ui->menuView->addAction(TableDockWidget->toggleViewAction()); QTableWidget* propertiesTable = new QTableWidget(); diff --git a/examples/emptydockarea/CMakeLists.txt b/examples/emptydockarea/CMakeLists.txt new file mode 100644 index 0000000..94e851d --- /dev/null +++ b/examples/emptydockarea/CMakeLists.txt @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 3.5) +project(ads_example_centralwidget VERSION ${VERSION_SHORT}) +find_package(Qt5 5.5 COMPONENTS Core Gui Widgets REQUIRED) +set(CMAKE_INCLUDE_CURRENT_DIR ON) +add_executable(EmptyDockAreaExample WIN32 + main.cpp + mainwindow.cpp + mainwindow.ui +) +target_include_directories(EmptyDockAreaExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src") +target_link_libraries(EmptyDockAreaExample PRIVATE qtadvanceddocking) +target_link_libraries(EmptyDockAreaExample PUBLIC Qt5::Core Qt5::Gui Qt5::Widgets) +set_target_properties(EmptyDockAreaExample PROPERTIES + AUTOMOC ON + AUTORCC ON + AUTOUIC ON + CXX_STANDARD 14 + CXX_STANDARD_REQUIRED ON + CXX_EXTENSIONS OFF + VERSION ${VERSION_SHORT} + EXPORT_NAME "Qt Advanced Docking System Empty Dock Area Example" + ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib" + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib" + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/bin" +) diff --git a/examples/emptydockarea/emptydockarea.pro b/examples/emptydockarea/emptydockarea.pro new file mode 100644 index 0000000..b45979b --- /dev/null +++ b/examples/emptydockarea/emptydockarea.pro @@ -0,0 +1,34 @@ +ADS_OUT_ROOT = $${OUT_PWD}/../.. + +QT += core gui widgets + +TARGET = EmptyDockareaExample +DESTDIR = $${ADS_OUT_ROOT}/lib +TEMPLATE = app +CONFIG += c++14 +CONFIG += debug_and_release +adsBuildStatic { + DEFINES += ADS_STATIC +} + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +SOURCES += \ + main.cpp \ + mainwindow.cpp + +HEADERS += \ + mainwindow.h + +FORMS += \ + mainwindow.ui + +LIBS += -L$${ADS_OUT_ROOT}/lib +include(../../ads.pri) +INCLUDEPATH += ../../src +DEPENDPATH += ../../src + diff --git a/examples/emptydockarea/main.cpp b/examples/emptydockarea/main.cpp new file mode 100644 index 0000000..fa4c4fd --- /dev/null +++ b/examples/emptydockarea/main.cpp @@ -0,0 +1,10 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + CMainWindow w; + w.show(); + return a.exec(); +} diff --git a/examples/emptydockarea/mainwindow.cpp b/examples/emptydockarea/mainwindow.cpp new file mode 100644 index 0000000..4fbecc7 --- /dev/null +++ b/examples/emptydockarea/mainwindow.cpp @@ -0,0 +1,134 @@ +#include "mainwindow.h" + +#include "ui_mainwindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "DockAreaWidget.h" +#include "DockAreaTitleBar.h" +#include "DockAreaTabBar.h" +#include "FloatingDockContainer.h" +#include "DockComponentsFactory.h" + +using namespace ads; + + +CMainWindow::CMainWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::CMainWindow) +{ + ui->setupUi(this); + CDockManager::setConfigFlag(CDockManager::OpaqueSplitterResize, true); + CDockManager::setConfigFlag(CDockManager::XmlCompressionEnabled, false); + CDockManager::setConfigFlag(CDockManager::FocusHighlighting, true); + DockManager = new CDockManager(this); + + // Set central widget + QLabel* label = new QLabel(); + label->setText("This is a DockArea which is always visible, even if it does not contain any DockWidgets."); + label->setAlignment(Qt::AlignCenter); + CDockWidget* CentralDockWidget = new CDockWidget("CentralWidget"); + CentralDockWidget->setWidget(label); + auto* CentralDockArea = DockManager->setCentralWidget(CentralDockWidget); + CentralDockWidget->setFeature(ads::CDockWidget::NoTab, true); + + // create other dock widgets + QTableWidget* table = new QTableWidget(); + table->setColumnCount(3); + table->setRowCount(10); + CDockWidget* TableDockWidget = new CDockWidget("Table 1"); + TableDockWidget->setWidget(table); + TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget); + TableDockWidget->resize(250, 150); + TableDockWidget->setMinimumSize(200,150); + auto TableArea = DockManager->addDockWidget(DockWidgetArea::LeftDockWidgetArea, TableDockWidget); + ui->menuView->addAction(TableDockWidget->toggleViewAction()); + + table = new QTableWidget(); + table->setColumnCount(5); + table->setRowCount(1020); + TableDockWidget = new CDockWidget("Table 2"); + TableDockWidget->setWidget(table); + TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget); + TableDockWidget->resize(250, 150); + TableDockWidget->setMinimumSize(200,150); + DockManager->addDockWidget(DockWidgetArea::BottomDockWidgetArea, TableDockWidget, TableArea); + ui->menuView->addAction(TableDockWidget->toggleViewAction()); + + QTableWidget* propertiesTable = new QTableWidget(); + propertiesTable->setColumnCount(3); + propertiesTable->setRowCount(10); + CDockWidget* PropertiesDockWidget = new CDockWidget("Properties"); + PropertiesDockWidget->setWidget(propertiesTable); + PropertiesDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget); + PropertiesDockWidget->resize(250, 150); + PropertiesDockWidget->setMinimumSize(200,150); + DockManager->addDockWidget(DockWidgetArea::RightDockWidgetArea, PropertiesDockWidget, CentralDockArea); + ui->menuView->addAction(PropertiesDockWidget->toggleViewAction()); + + createPerspectiveUi(); +} + +CMainWindow::~CMainWindow() +{ + delete ui; +} + + +void CMainWindow::createPerspectiveUi() +{ + SavePerspectiveAction = new QAction("Create Perspective", this); + connect(SavePerspectiveAction, SIGNAL(triggered()), SLOT(savePerspective())); + PerspectiveListAction = new QWidgetAction(this); + PerspectiveComboBox = new QComboBox(this); + PerspectiveComboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents); + PerspectiveComboBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + connect(PerspectiveComboBox, SIGNAL(activated(const QString&)), + DockManager, SLOT(openPerspective(const QString&))); + PerspectiveListAction->setDefaultWidget(PerspectiveComboBox); + ui->toolBar->addSeparator(); + ui->toolBar->addAction(PerspectiveListAction); + ui->toolBar->addAction(SavePerspectiveAction); +} + + +void CMainWindow::savePerspective() +{ + QString PerspectiveName = QInputDialog::getText(this, "Save Perspective", "Enter unique name:"); + if (PerspectiveName.isEmpty()) + { + return; + } + + DockManager->addPerspective(PerspectiveName); + QSignalBlocker Blocker(PerspectiveComboBox); + PerspectiveComboBox->clear(); + PerspectiveComboBox->addItems(DockManager->perspectiveNames()); + PerspectiveComboBox->setCurrentText(PerspectiveName); +} + + +//============================================================================ +void CMainWindow::closeEvent(QCloseEvent* event) +{ + // Delete dock manager here to delete all floating widgets. This ensures + // that all top level windows of the dock manager are properly closed + DockManager->deleteLater(); + QMainWindow::closeEvent(event); +} + + diff --git a/examples/emptydockarea/mainwindow.h b/examples/emptydockarea/mainwindow.h new file mode 100644 index 0000000..75869da --- /dev/null +++ b/examples/emptydockarea/mainwindow.h @@ -0,0 +1,43 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include + +#include "DockManager.h" +#include "DockAreaWidget.h" +#include "DockWidget.h" + +QT_BEGIN_NAMESPACE +namespace Ui { class CMainWindow; } +QT_END_NAMESPACE + +class CMainWindow : public QMainWindow +{ + Q_OBJECT + +public: + CMainWindow(QWidget *parent = nullptr); + ~CMainWindow(); + +protected: + virtual void closeEvent(QCloseEvent* event) override; + +private: + QAction* SavePerspectiveAction = nullptr; + QWidgetAction* PerspectiveListAction = nullptr; + QComboBox* PerspectiveComboBox = nullptr; + + Ui::CMainWindow *ui; + + ads::CDockManager* DockManager; + ads::CDockAreaWidget* StatusDockArea; + ads::CDockWidget* TimelineDockWidget; + + void createPerspectiveUi(); + +private slots: + void savePerspective(); +}; +#endif // MAINWINDOW_H diff --git a/examples/emptydockarea/mainwindow.ui b/examples/emptydockarea/mainwindow.ui new file mode 100644 index 0000000..f7d3b09 --- /dev/null +++ b/examples/emptydockarea/mainwindow.ui @@ -0,0 +1,47 @@ + + + CMainWindow + + + + 0 + 0 + 1284 + 757 + + + + MainWindow + + + + + + 0 + 0 + 1284 + 21 + + + + + View + + + + + + + toolBar + + + TopToolBarArea + + + false + + + + + + diff --git a/examples/examples.pro b/examples/examples.pro index de8cf7f..86ac5b0 100644 --- a/examples/examples.pro +++ b/examples/examples.pro @@ -4,4 +4,5 @@ SUBDIRS = \ centralwidget \ simple \ sidebar \ - deleteonclose + deleteonclose \ + emptydockarea diff --git a/src/DockAreaWidget.cpp b/src/DockAreaWidget.cpp index 882ae6d..2f32cdb 100644 --- a/src/DockAreaWidget.cpp +++ b/src/DockAreaWidget.cpp @@ -808,18 +808,49 @@ CDockWidget* CDockAreaWidget::nextOpenDockWidget(CDockWidget* DockWidget) const auto OpenDockWidgets = openedDockWidgets(); if (OpenDockWidgets.count() > 1 || (OpenDockWidgets.count() == 1 && OpenDockWidgets[0] != DockWidget)) { - CDockWidget* NextDockWidget; if (OpenDockWidgets.last() == DockWidget) { - NextDockWidget = OpenDockWidgets[OpenDockWidgets.count() - 2]; + CDockWidget* NextDockWidget = OpenDockWidgets[OpenDockWidgets.count() - 2]; + // search backwards for widget with tab + for (int i = OpenDockWidgets.count() - 2; i >= 0; --i) + { + auto dw = OpenDockWidgets[i]; + if (!dw->features().testFlag(CDockWidget::NoTab)) + { + return dw; + } + } + + // return widget without tab + return NextDockWidget; } else { - int NextIndex = OpenDockWidgets.indexOf(DockWidget) + 1; - NextDockWidget = OpenDockWidgets[NextIndex]; - } + int IndexOfDockWidget = OpenDockWidgets.indexOf(DockWidget); + CDockWidget* NextDockWidget = OpenDockWidgets[IndexOfDockWidget + 1]; + // search forwards for widget with tab + for (int i = IndexOfDockWidget + 1; i < OpenDockWidgets.count(); ++i) + { + auto dw = OpenDockWidgets[i]; + if (!dw->features().testFlag(CDockWidget::NoTab)) + { + return dw; + } + } - return NextDockWidget; + // search backwards for widget with tab + for (int i = IndexOfDockWidget - 1; i >= 0; --i) + { + auto dw = OpenDockWidgets[i]; + if (!dw->features().testFlag(CDockWidget::NoTab)) + { + return dw; + } + } + + // return widget without tab + return NextDockWidget; + } } else {