diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index a7ff41e..5ae02d6 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required(VERSION 3.5) project(QtADSExamples LANGUAGES CXX VERSION ${VERSION_SHORT}) add_subdirectory(simple) +add_subdirectory(hideshow) add_subdirectory(sidebar) add_subdirectory(deleteonclose) add_subdirectory(centralwidget) diff --git a/examples/examples.pro b/examples/examples.pro index e8680f9..3569f37 100644 --- a/examples/examples.pro +++ b/examples/examples.pro @@ -3,6 +3,7 @@ TEMPLATE = subdirs SUBDIRS = \ centralwidget \ simple \ + hideshow \ sidebar \ deleteonclose \ emptydockarea \ diff --git a/examples/hideshow/CMakeLists.txt b/examples/hideshow/CMakeLists.txt new file mode 100644 index 0000000..71f22f2 --- /dev/null +++ b/examples/hideshow/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.5) +project(ads_example_hideshow VERSION ${VERSION_SHORT}) +find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED) +set(CMAKE_INCLUDE_CURRENT_DIR ON) +add_executable(HideShowExample WIN32 + main.cpp + MainWindow.cpp + MainWindow.ui +) +target_include_directories(HideShowExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src") +target_link_libraries(HideShowExample PRIVATE qtadvanceddocking) +target_link_libraries(HideShowExample PUBLIC Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Widgets) +set_target_properties(HideShowExample 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 Hide,Show 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/hideshow/MainWindow.cpp b/examples/hideshow/MainWindow.cpp new file mode 100644 index 0000000..e4d7449 --- /dev/null +++ b/examples/hideshow/MainWindow.cpp @@ -0,0 +1,78 @@ +#include "../../examples/hideshow/MainWindow.h" + +#include "ui_MainWindow.h" + +#include +#include + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainWindow) +{ + ui->setupUi(this); + + ui->centralWidget->setLayout( m_layout = new QStackedLayout() ); + + m_welcomeWidget = new QWidget(this); + auto welcomeLayout = new QVBoxLayout(m_welcomeWidget); + welcomeLayout->addStretch(); + QPushButton* openButton = new QPushButton("Open project"); + welcomeLayout->addWidget( openButton ); + welcomeLayout->addStretch(); + + connect( openButton, SIGNAL(clicked()), this, SLOT(openProject()) ); + + m_DockManager = new ads::CDockManager(ui->centralWidget); + + // Create example content label - this can be any application specific + // widget + QLabel* l = new QLabel(); + l->setWordWrap(true); + l->setAlignment(Qt::AlignTop | Qt::AlignLeft); + l->setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. "); + + // Create a dock widget with the title Label 1 and set the created label + // as the dock widget content + ads::CDockWidget* DockWidget = new ads::CDockWidget("Label 1"); + DockWidget->setWidget(l); + + // Add the toggleViewAction of the dock widget to the menu to give + // the user the possibility to show the dock widget if it has been closed + ui->menuView->addAction(DockWidget->toggleViewAction()); + + connect( ui->actionOpen, SIGNAL(triggered()), this, SLOT(openProject()) ); + connect( ui->actionClose, SIGNAL(triggered()), this, SLOT(closeProject()) ); + + // Add the dock widget to the top dock widget area + m_DockManager->addDockWidget(ads::TopDockWidgetArea, DockWidget); + + ui->centralWidget->layout()->addWidget( m_welcomeWidget ); + ui->centralWidget->layout()->addWidget( m_DockManager ); + + closeProject(); +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +void MainWindow::openProject() +{ + ui->actionOpen->setEnabled(false); + ui->actionClose->setEnabled(true); + ui->menuView->setEnabled(true); + + m_layout->setCurrentWidget( m_DockManager ); +} + +void MainWindow::closeProject() +{ + ui->actionOpen->setEnabled(true); + ui->actionClose->setEnabled(false); + ui->menuView->setEnabled(false); + + m_DockManager->hideManagerAndFloatingWidgets(); + m_layout->setCurrentWidget( m_welcomeWidget ); +} + diff --git a/examples/hideshow/MainWindow.h b/examples/hideshow/MainWindow.h new file mode 100644 index 0000000..6668387 --- /dev/null +++ b/examples/hideshow/MainWindow.h @@ -0,0 +1,33 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include "DockManager.h" + +QT_BEGIN_NAMESPACE +namespace Ui { +class MainWindow; +} +QT_END_NAMESPACE + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = 0); + ~MainWindow(); + +private slots: + void openProject(); + void closeProject(); + +private: + Ui::MainWindow *ui; + QWidget* m_welcomeWidget; + ads::CDockManager* m_DockManager; + QStackedLayout* m_layout; +}; + +#endif // MAINWINDOW_H diff --git a/examples/hideshow/MainWindow.ui b/examples/hideshow/MainWindow.ui new file mode 100644 index 0000000..260b1f4 --- /dev/null +++ b/examples/hideshow/MainWindow.ui @@ -0,0 +1,56 @@ + + + MainWindow + + + + 0 + 0 + 400 + 300 + + + + MainWindow + + + + + + 0 + 0 + 400 + 26 + + + + + View + + + + + File + + + + + + + + + + + Open project + + + + + Close project + + + + + + + diff --git a/examples/hideshow/hideshow.pro b/examples/hideshow/hideshow.pro new file mode 100644 index 0000000..86782d9 --- /dev/null +++ b/examples/hideshow/hideshow.pro @@ -0,0 +1,31 @@ +ADS_OUT_ROOT = $${OUT_PWD}/../.. + +QT += core gui widgets + +TARGET = HideShowExample +DESTDIR = $${ADS_OUT_ROOT}/lib +TEMPLATE = app +CONFIG += c++14 +CONFIG += debug_and_release +adsBuildStatic { + DEFINES += ADS_STATIC +} + +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/hideshow/main.cpp b/examples/hideshow/main.cpp new file mode 100644 index 0000000..e62035c --- /dev/null +++ b/examples/hideshow/main.cpp @@ -0,0 +1,11 @@ +#include +#include "../../examples/hideshow/MainWindow.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + + return a.exec(); +} diff --git a/src/DockManager.cpp b/src/DockManager.cpp index d56e930..e658ce9 100644 --- a/src/DockManager.cpp +++ b/src/DockManager.cpp @@ -98,6 +98,7 @@ struct DockManagerPrivate { CDockManager* _this; QList FloatingWidgets; + QList HiddenFloatingWidgets; QList Containers; CDockOverlay* ContainerOverlay; CDockOverlay* DockAreaOverlay; @@ -755,6 +756,10 @@ CFloatingDockContainer* CDockManager::addDockWidgetFloating(CDockWidget* Dockwid void CDockManager::showEvent(QShowEvent *event) { Super::showEvent(event); + + // Fix Issue #380 + restoreHiddenFloatingWidgets(); + if (d->UninitializedFloatingWidgets.empty()) { return; @@ -772,6 +777,32 @@ void CDockManager::showEvent(QShowEvent *event) d->UninitializedFloatingWidgets.clear(); } +void CDockManager::restoreHiddenFloatingWidgets() +{ + // Restore floating widgets that were hidden upon hideManagerAndFloatingWidgets + for (auto FloatingWidget : d->HiddenFloatingWidgets) + { + bool hasDockWidgetVisible = false; + + // Needed to prevent CFloatingDockContainer being shown empty + // Could make sense to move this to CFloatingDockContainer::showEvent(QShowEvent *event) + // if experiencing CFloatingDockContainer being shown empty in other situations, but let's keep + // it here for now to make sure changes to fix Issue #380 does not impact existing behaviours + for ( auto dockWidget : FloatingWidget->dockWidgets() ) + { + if ( dockWidget->toggleViewAction()->isChecked() ) + { + dockWidget->toggleView(true); + hasDockWidgetVisible = true; + } + } + + if ( hasDockWidgetVisible ) + FloatingWidget->show(); + } + + d->HiddenFloatingWidgets.clear(); +} //============================================================================ CDockAreaWidget* CDockManager::addDockWidget(DockWidgetArea area, @@ -1102,6 +1133,38 @@ void CDockManager::setDockWidgetFocused(CDockWidget* DockWidget) } } +//=========================================================================== +void CDockManager::hideManagerAndFloatingWidgets() +{ + hide(); + + d->HiddenFloatingWidgets.clear(); + // Hide updates of floating widgets from user + for (auto FloatingWidget : d->FloatingWidgets) + { + if ( FloatingWidget->isVisible() ) + { + QList VisibleWidgets; + for ( auto dockWidget : FloatingWidget->dockWidgets() ) + { + if ( dockWidget->toggleViewAction()->isChecked() ) + VisibleWidgets.push_back( dockWidget ); + } + + // save as floating widget to be shown when CDockManager will be shown back + d->HiddenFloatingWidgets.push_back( FloatingWidget ); + FloatingWidget->hide(); + + // hidding floating widget automatically marked contained CDockWidgets as hidden + // but they must remain marked as visible as we want them to be restored visible + // when CDockManager will be shown back + for ( auto dockWidget : VisibleWidgets ) + { + dockWidget->toggleViewAction()->setChecked(true); + } + } + } +} //=========================================================================== CDockWidget* CDockManager::focusedDockWidget() const diff --git a/src/DockManager.h b/src/DockManager.h index 9ebf8a2..46bcb14 100644 --- a/src/DockManager.h +++ b/src/DockManager.h @@ -147,6 +147,11 @@ protected: */ CDockFocusController* dockFocusController() const; + /** + * Restore floating widgets hidden by an earlier call to hideManagerAndFloatingWidgets. + */ + void restoreHiddenFloatingWidgets(); + public: using Super = CDockContainerWidget; @@ -527,6 +532,12 @@ public Q_SLOTS: */ void setDockWidgetFocused(CDockWidget* DockWidget); + /** + * hide CDockManager and all floating widgets (See Issue #380). Calling regular QWidget::hide() + * hides the CDockManager but not the floating widgets; + */ + void hideManagerAndFloatingWidgets(); + Q_SIGNALS: /** * This signal is emitted if the list of perspectives changed.