Fix issue #380 and add example

This commit is contained in:
Jean Porcherot 2021-12-09 10:11:05 +01:00
parent 4b27af959b
commit 6b3027401d
10 changed files with 313 additions and 0 deletions

View File

@ -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)

View File

@ -3,6 +3,7 @@ TEMPLATE = subdirs
SUBDIRS = \
centralwidget \
simple \
hideshow \
sidebar \
deleteonclose \
emptydockarea \

View File

@ -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"
)

View File

@ -0,0 +1,78 @@
#include "../../examples/hideshow/MainWindow.h"
#include "ui_MainWindow.h"
#include <QLabel>
#include <QPushButton>
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 );
}

View File

@ -0,0 +1,33 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QStackedLayout>
#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

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget"/>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>26</height>
</rect>
</property>
<widget class="QMenu" name="menuView">
<property name="title">
<string>View</string>
</property>
</widget>
<widget class="QMenu" name="menuFile">
<property name="title">
<string>File</string>
</property>
<addaction name="actionOpen"/>
<addaction name="actionClose"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuView"/>
</widget>
<widget class="QStatusBar" name="statusBar"/>
<action name="actionOpen">
<property name="text">
<string>Open project</string>
</property>
</action>
<action name="actionClose">
<property name="text">
<string>Close project</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>

View File

@ -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

View File

@ -0,0 +1,11 @@
#include <QApplication>
#include "../../examples/hideshow/MainWindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

View File

@ -98,6 +98,7 @@ struct DockManagerPrivate
{
CDockManager* _this;
QList<CFloatingDockContainer*> FloatingWidgets;
QList<CFloatingDockContainer*> HiddenFloatingWidgets;
QList<CDockContainerWidget*> 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;
@ -767,6 +772,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,
@ -1097,6 +1128,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<CDockWidget*> 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

View File

@ -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.