Compare commits

...

55 Commits
3.2.5 ... 3.3.5

Author SHA1 Message Date
Uwe Kindler
985d164cd1 Merge branch 'master' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System 2020-05-04 15:14:50 +02:00
Uwe Kindler
0c9a1ee3f2 Fixed a bug in FloatingDragPreview that prevents dock widget from floating when dragging over another dock widget 2020-05-04 15:14:35 +02:00
githubuser0xFFFF
0bd20883df Update user-guide.md 2020-04-30 19:51:35 +02:00
githubuser0xFFFF
1d8a1e9bb8 Update user-guide.md 2020-04-29 07:15:06 +02:00
Uwe Kindler
3adabaec81 Merge branch 'master' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System 2020-04-29 07:13:57 +02:00
Uwe Kindler
5695d0d305 Added documentation for HideSingleCentralWidgetTitleBar configuration flag 2020-04-29 07:13:42 +02:00
farmovit
f1792820e1 Fix memory leak (#152) 2020-04-28 15:17:02 +02:00
Uwe Kindler
e091be0b76 Restored default demo application settings 2020-04-28 07:19:06 +02:00
Uwe Kindler
e4c5eac146 Added FloatingContainerHasWidgetIcon documentation to user-guide.md 2020-04-28 06:51:34 +02:00
Uwe Kindler
cbd2fcb0d3 Fixed CDockWidget::setWidget function to test for QAbstractScrollArea instead of QScrollArea
Now setWidget properly supports ItemViews like QTreeView or QTableView
2020-04-27 16:51:46 +02:00
Uwe Kindler
47029190dc Fixed wrong display of center drop area when dragging over invisible dock area title bar 2020-04-27 15:27:34 +02:00
Uwe Kindler
80aee638c9 Fixed bug that drop overlay sometimes was not visible when moving the drag preview over a floating window
This bug was caused by accidentally using hide() instead of hideOverlay()
2020-04-27 15:20:27 +02:00
Uwe Kindler
cdc863e962 Fixed dropping of FloatingDragPreview into center of dock container with only one single visible dock area
If this happens the dropped dock widget needs to get tabified
2020-04-27 14:00:37 +02:00
Uwe Kindler
ef855e3843 Added documentation for FloatingContainerHasWidgetTitle flag 2020-04-27 08:58:50 +02:00
Uwe Kindler
842d417e8d Fixed crash when trying to make a CDockWidget floating in non-opaque mode if the CDockWidget is not floatable 2020-04-27 07:54:43 +02:00
Uwe Kindler
52a64350e6 Fixed DockWidgetTab to provide the right size when starting floating 2020-04-27 07:48:15 +02:00
Uwe Kindler
79831d482b Added QtCreator IDE to showcases 2020-04-24 10:08:18 +02:00
Uwe Kindler
a4fbaf413b Fixed source documentation of DockAreaDynamicTabsMenuButtonVisibility flag 2020-04-24 09:31:13 +02:00
Uwe Kindler
b982947cf4 Added documentation for DockAreaDynamicTabsMenuButtonVisibility to user-guide.md 2020-04-24 09:30:06 +02:00
Uwe Kindler
bc2ac48eab Fixed default elide mode in DockWidgetTab.cpp 2020-04-24 09:29:33 +02:00
Uwe Kindler
ddbdb83821 Added documentation for DockAreaHideDisabledButtons flag 2020-04-22 12:03:58 +02:00
Uwe Kindler
85626c9a21 Added Q_INIT_RESOURCE(ads) for static builds 2020-04-22 06:25:01 +02:00
Uwe Kindler
8bf8309949 Added configuration flags DockAreaHasTabsMenuButton and DockAreaHasUndockButton to user-guide.md 2020-04-20 16:25:30 +02:00
Uwe Kindler
528f48e6d1 Added documentation for AlwaysShowTabs configuration flag 2020-04-19 12:08:01 +02:00
Uwe Kindler
28dfcc2a62 Updated user-guide images 2020-04-17 10:43:28 +02:00
Uwe Kindler
0bfa2eb88e Updated documentation picture cfg_flag_DragPreviewHasWindowFrame_true.png 2020-04-17 10:28:46 +02:00
Uwe Kindler
27bbe9f7f5 Added additional configuration flags to user-guide.md 2020-04-17 10:25:32 +02:00
Uwe Kindler
92dbcec7c0 Added missing image to user-guide.md 2020-04-15 20:19:54 +02:00
Uwe Kindler
2be2f2bc6f Added DragPreviewIsDynamic section to user-guide.md 2020-04-15 20:18:20 +02:00
Uwe Kindler
a083d778bd Merge branch 'master' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System 2020-04-15 13:13:39 +02:00
Uwe Kindler
d4770a7d41 Continued writing of user-guide.md - added further configuration flags documentation 2020-04-15 13:10:03 +02:00
githubuser0xFFFF
37365caf8e Update user-guide.md 2020-04-14 22:55:47 +02:00
Uwe Kindler
3f5bfc3139 Added new sections to user-guide.md 2020-04-14 20:00:59 +02:00
Uwe Kindler
4ac7291831 Merge branch 'documentation' 2020-04-14 17:24:44 +02:00
Uwe Kindler
b5e9096387 Fixed cmake build 2020-04-14 17:24:34 +02:00
Uwe Kindler
19c8e9ffcc Started creation of user-guide.md 2020-04-14 17:23:01 +02:00
Uwe Kindler
6a815a836c Implemented status dialog in demo application to test several CDockWidget functions 2020-04-14 16:07:00 +02:00
Uwe Kindler
277d3fffe4 Removed unused slot 2020-04-13 22:40:14 +02:00
Uwe Kindler
9502e7bf6c Added new features to sip/DockManager.sip and DockWidget.sip for Python integration 2020-04-13 22:35:35 +02:00
Uwe Kindler
8aae6bf70b Added DockWidget functions setAsCurrentTab, raise, isCurrentTab, isTabbed 2020-04-13 22:16:47 +02:00
Uwe Kindler
a668fe2f73 Added new config flag HideSingleCentralWidgetTitleBar to enble a central single dock widget in the main dock container (dock manager) without titlebar
Added a test case for the new flag to MainWindow.cpp
2020-04-12 01:05:20 +02:00
Uwe Kindler
12bb7b73e9 Fixed CDockContainerWidget::hasTopLevelDockWidget() and CDockContainerWidget::topLevelDockArea() to work properly also for the main non floating dock container 2020-04-12 00:56:41 +02:00
Uwe Kindler
dbf90a4233 Fixed ElidingLabel to properly support Qt::ElideNone
added setElideMode function to CDockWidgetTab
2020-04-10 21:06:43 +02:00
Uwe Kindler
19331ebe2b Added comment to showFullScreen that this only works for Windows 2020-04-10 12:54:37 +02:00
Uwe Kindler
16a149b436 Fixed wrong call to base class function in DockWidget::showNormal 2020-04-10 12:35:47 +02:00
Uwe Kindler
1f995299f0 Added setFullScreen(), setNormal() and isFullScreen() function to CDockWidget to be more compatible to QDockWidget 2020-04-09 23:16:50 +02:00
Uwe Kindler
7a17aba42d Fixed takeWidget() function and fixed setWidget() function to handle case if there is already a content widget 2020-04-09 21:44:21 +02:00
Uwe Kindler
9fe1dd6a88 Updated README.md toc 2020-04-09 21:16:04 +02:00
Uwe Kindler
7c2d1891a2 Added showcase section to README.md 2020-04-01 12:31:37 +02:00
Uwe Kindler
998fe9fa11 Added Q_OS_WIN around the installation of the eventFilter in FloatingDockContainer because it is only required for Windows 2020-04-01 08:36:33 +02:00
Uwe Kindler
28dc374fc2 Added support for proper handling on non client escape key presses on Windows 2020-04-01 08:12:45 +02:00
Uwe Kindler
1b6e449b4a Merge branch 'dev' 2020-03-28 19:32:59 +01:00
Uwe Kindler
0e88467f94 DockAreaWidget now properly considers minimumSizeHint() of contained DockWidgets
Added setMinimumSizeHintMode() test in demo MainWindow
2020-03-28 19:32:07 +01:00
Uwe Kindler
d0f4ce3248 Added support to adhere the minimumSizeHint() of the content widget of a dock widget 2020-03-26 07:09:01 +01:00
Uwe Kindler
542618fd4e Removed unneeded includes from DockManager.h and fixed includes to use "" instead of <> to prvent conflicts with external libraries 2020-03-26 06:53:13 +01:00
60 changed files with 1192 additions and 148 deletions

View File

@@ -4,6 +4,9 @@
[![Build status](https://ci.appveyor.com/api/projects/status/qcfb3cy932jw9mpy/branch/master?svg=true)](https://ci.appveyor.com/project/githubuser0xFFFF/qt-advanced-docking-system/branch/master) [![Build status](https://ci.appveyor.com/api/projects/status/qcfb3cy932jw9mpy/branch/master?svg=true)](https://ci.appveyor.com/project/githubuser0xFFFF/qt-advanced-docking-system/branch/master)
[![License: LGPL v2.1](https://img.shields.io/badge/License-LGPL%20v2.1-blue.svg)](gnu-lgpl-v2.1.md) [![License: LGPL v2.1](https://img.shields.io/badge/License-LGPL%20v2.1-blue.svg)](gnu-lgpl-v2.1.md)
[What's new](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/releases/latest) •
[Documentation](doc/user-guide.md)
Qt Advanced Docking System lets you create customizable layouts using a full Qt Advanced Docking System lets you create customizable layouts using a full
featured window docking system similar to what is found in many popular featured window docking system similar to what is found in many popular
integrated development environments (IDEs) such as Visual Studio. integrated development environments (IDEs) such as Visual Studio.
@@ -24,30 +27,33 @@ of his docking system project.
### Overview ### Overview
- [Advanced Docking System for Qt](#advanced-docking-system-for-qt) - [Features](#features)
- [Features](#features) - [Overview](#overview)
- [Overview](#overview) - [Docking everywhere - no central widget](#docking-everywhere---no-central-widget)
- [Docking everywhere - no central widget](#docking-everywhere---no-central-widget) - [Docking inside floating windows](#docking-inside-floating-windows)
- [Docking inside floating windows](#docking-inside-floating-windows) - [Grouped dragging](#grouped-dragging)
- [Grouped dragging](#grouped-dragging) - [Perspectives for fast switching of the complete main window layout](#perspectives-for-fast-switching-of-the-complete-main-window-layout)
- [Perspectives for fast switching of the complete main window layout](#perspectives-for-fast-switching-of-the-complete-main-window-layout) - [Opaque and non-opaque splitter resizing](#opaque-and-non-opaque-splitter-resizing)
- [Opaque and non-opaque splitter resizing](#opaque-and-non-opaque-splitter-resizing) - [Opaque and non-opaque undocking](#opaque-and-non-opaque-undocking)
- [Opaque and non-opaque undocking](#opaque-and-non-opaque-undocking) - [Tab-menu for easy handling of many tabbed dock widgets](#tab-menu-for-easy-handling-of-many-tabbed-dock-widgets)
- [Tab-menu for easy handling of many tabbed dock widgets](#tab-menu-for-easy-handling-of-many-tabbed-dock-widgets) - [Many different ways to detach dock widgets](#many-different-ways-to-detach-dock-widgets)
- [Many different ways to detach dock widgets](#many-different-ways-to-detach-dock-widgets) - [Supports deletion of dynamically created dock widgets](#supports-deletion-of-dynamically-created-dock-widgets)
- [Supports deletion of dynamically created dock widgets](#supports-deletion-of-dynamically-created-dock-widgets) - [Tested Compatible Environments](#tested-compatible-environments)
- [Tested Compatible Environments](#tested-compatible-environments) - [Windows](#windows)
- [Windows](#windows) - [macOS](#macos)
- [macOS](#macos) - [Linux](#linux)
- [Linux](#linux) - [Build](#build)
- [Build](#build) - [Getting started / Example](#getting-started--example)
- [Getting started / Example](#getting-started--example) - [Developers](#developers)
- [Developers](#developers) - [License information](#license-information)
- [License information](#license-information) - [Alternative Docking System Implementations](#alternative-docking-system-implementations)
- [Alternative Docking System Implementations](#alternative-docking-system-implementations) - [KDDockWidgets](#kddockwidgets)
- [KDDockWidgets](#kddockwidgets) - [QtitanDocking](#qtitandocking)
- [QtitanDocking](#qtitandocking) - [Donation](#donation)
- [Donation](#donation) - [Showcase](#showcase)
- [Qt Creator IDE](#qt-creator-ide)
- [Qt Design Studio](#qt-design-studio)
- [QmixElements](#qmixelements)
### Docking everywhere - no central widget ### Docking everywhere - no central widget
@@ -273,3 +279,28 @@ If this project help you reduce time to develop or if you just like it, you can
<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=85R64TMMSY9T6"> <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=85R64TMMSY9T6">
<img src="doc/donate.png" alt="Donate with PayPal" width="160"/> <img src="doc/donate.png" alt="Donate with PayPal" width="160"/>
</a> </a>
## Showcase
### [Qt Creator IDE](https://www.qt.io/development-tools)
From version 4.12 on, Qt Creator uses the Advanced Docking Framework for its
Qt Quick Designer. This improves the usability when using multiple screens.
![Qt Creator](doc/qtcreator.png)
### [Qt Design Studio](https://www.qt.io/ui-design-tools)
Taken from the [Qt Blog](https://www.qt.io/blog/qt-design-studio-1.5-beta-released):
> The most obvious change in [Qt Design Studio 1.5](https://www.qt.io/blog/qt-design-studio-1.5-beta-released) is the integration of dock widgets using the Qt Advanced Docking System. This allows the user to fully customize the workspace and also to undock any view into its own top level window. This especially improves the usability when using multiple screens.
![Qt Design Studio](doc/qt_design_studio.png)
### [QmixElements](https://www.cetoni.com/products/qmixelements/)
The QmixElements software from [CETONI](https://www.cetoni.com) is a comprehensive,
plugin-based and modular laboratory automation software for controlling CETONI devices using a joint graphical user interface. The software features a powerful script system to automate processes. This [blog post](https://www.cetoni.com/blog/qmixelements-advanced-docking-system/) gives a nice overview about the use of the Qt
Advanced Docking System in the QmixElements sofware.
![QmixElements](doc/qmix_elements.png)

View File

@@ -30,6 +30,8 @@ set(ads_demo_SRCS
main.cpp main.cpp
MainWindow.cpp MainWindow.cpp
mainwindow.ui mainwindow.ui
StatusDialog.cpp
StatusDialog.ui
demo.qrc demo.qrc
) )
add_executable(AdvancedDockingSystemDemo WIN32 ${ads_demo_SRCS}) add_executable(AdvancedDockingSystemDemo WIN32 ${ads_demo_SRCS})

View File

@@ -74,6 +74,7 @@
#include "DockAreaTabBar.h" #include "DockAreaTabBar.h"
#include "FloatingDockContainer.h" #include "FloatingDockContainer.h"
#include "DockComponentsFactory.h" #include "DockComponentsFactory.h"
#include "StatusDialog.h"
@@ -169,7 +170,12 @@ static ads::CDockWidget* createCalendarDockWidget(QMenu* ViewMenu)
static int CalendarCount = 0; static int CalendarCount = 0;
QCalendarWidget* w = new QCalendarWidget(); QCalendarWidget* w = new QCalendarWidget();
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Calendar %1").arg(CalendarCount++)); ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Calendar %1").arg(CalendarCount++));
// The following lines are for testing the setWidget() and takeWidget()
// functionality
DockWidget->setWidget(w); DockWidget->setWidget(w);
DockWidget->setWidget(w); // what happens if we set a widget if a widget is already set
DockWidget->takeWidget(); // we remove the widget
DockWidget->setWidget(w); // and set the widget again - there should be no error
DockWidget->setToggleViewActionMode(ads::CDockWidget::ActionModeShow); DockWidget->setToggleViewActionMode(ads::CDockWidget::ActionModeShow);
DockWidget->setIcon(svgIcon(":/adsdemo/images/date_range.svg")); DockWidget->setIcon(svgIcon(":/adsdemo/images/date_range.svg"));
ViewMenu->addAction(DockWidget->toggleViewAction()); ViewMenu->addAction(DockWidget->toggleViewAction());
@@ -224,11 +230,27 @@ static ads::CDockWidget* createEditorWidget(QMenu* ViewMenu)
} }
//===========================================================================
/**
* Custom QTableWidget with a minimum size hint to test CDockWidget
* setMinimumSizeHintMode() function of CDockWidget
*/
class CMinSizeTableWidget : public QTableWidget
{
public:
using QTableWidget::QTableWidget;
virtual QSize minimumSizeHint() const override
{
return QSize(300, 100);
}
};
//============================================================================ //============================================================================
static ads::CDockWidget* createTableWidget(QMenu* ViewMenu) static ads::CDockWidget* createTableWidget(QMenu* ViewMenu)
{ {
static int TableCount = 0; static int TableCount = 0;
QTableWidget* w = new QTableWidget(); auto w = new CMinSizeTableWidget();
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Table %1").arg(TableCount++)); ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Table %1").arg(TableCount++));
static int colCount = 5; static int colCount = 5;
static int rowCount = 30; static int rowCount = 30;
@@ -244,6 +266,20 @@ static ads::CDockWidget* createTableWidget(QMenu* ViewMenu)
} }
DockWidget->setWidget(w); DockWidget->setWidget(w);
DockWidget->setIcon(svgIcon(":/adsdemo/images/grid_on.svg")); DockWidget->setIcon(svgIcon(":/adsdemo/images/grid_on.svg"));
DockWidget->setMinimumSizeHintMode(ads::CDockWidget::MinimumSizeHintFromContent);
auto ToolBar = DockWidget->createDefaultToolBar();
auto Action = ToolBar->addAction(svgIcon(":/adsdemo/images/fullscreen.svg"), "Toggle Fullscreen");
QObject::connect(Action, &QAction::triggered, [=]()
{
if (DockWidget->isFullScreen())
{
DockWidget->showNormal();
}
else
{
DockWidget->showFullScreen();
}
});
ViewMenu->addAction(DockWidget->toggleViewAction()); ViewMenu->addAction(DockWidget->toggleViewAction());
return DockWidget; return DockWidget;
} }
@@ -316,8 +352,6 @@ void MainWindowPrivate::createContent()
QMenu* ViewMenu = ui.menuView; QMenu* ViewMenu = ui.menuView;
auto DockWidget = createCalendarDockWidget(ViewMenu); auto DockWidget = createCalendarDockWidget(ViewMenu);
DockWidget->setFeature(ads::CDockWidget::DockWidgetClosable, false); DockWidget->setFeature(ads::CDockWidget::DockWidgetClosable, false);
DockWidget->setFeature(ads::CDockWidget::DockWidgetMovable, false);
DockWidget->setFeature(ads::CDockWidget::DockWidgetFloatable, false);
auto SpecialDockArea = DockManager->addDockWidget(ads::LeftDockWidgetArea, DockWidget); auto SpecialDockArea = DockManager->addDockWidget(ads::LeftDockWidgetArea, DockWidget);
// For this Special Dock Area we want to avoid dropping on the center of it (i.e. we don't want this widget to be ever tabbified): // For this Special Dock Area we want to avoid dropping on the center of it (i.e. we don't want this widget to be ever tabbified):
@@ -351,9 +385,6 @@ void MainWindowPrivate::createContent()
// We create a calendar widget and clear all flags to prevent the dock area // We create a calendar widget and clear all flags to prevent the dock area
// from closing // from closing
DockWidget = createCalendarDockWidget(ViewMenu); DockWidget = createCalendarDockWidget(ViewMenu);
DockWidget->setFeature(ads::CDockWidget::DockWidgetClosable, false);
DockWidget->setFeature(ads::CDockWidget::DockWidgetMovable, false);
DockWidget->setFeature(ads::CDockWidget::DockWidgetFloatable, false);
DockWidget->setTabToolTip(QString("Tab ToolTip\nHodie est dies magna")); DockWidget->setTabToolTip(QString("Tab ToolTip\nHodie est dies magna"));
auto DockArea = DockManager->addDockWidget(ads::CenterDockWidgetArea, DockWidget, TopDockArea); auto DockArea = DockManager->addDockWidget(ads::CenterDockWidgetArea, DockWidget, TopDockArea);
@@ -363,6 +394,7 @@ void MainWindowPrivate::createContent()
CustomButton->setToolTip(QObject::tr("Create Editor")); CustomButton->setToolTip(QObject::tr("Create Editor"));
CustomButton->setIcon(svgIcon(":/adsdemo/images/plus.svg")); CustomButton->setIcon(svgIcon(":/adsdemo/images/plus.svg"));
CustomButton->setAutoRaise(true); CustomButton->setAutoRaise(true);
auto TitleBar = DockArea->titleBar(); auto TitleBar = DockArea->titleBar();
int Index = TitleBar->indexOf(TitleBar->tabBar()); int Index = TitleBar->indexOf(TitleBar->tabBar());
TitleBar->insertWidget(Index + 1, CustomButton); TitleBar->insertWidget(Index + 1, CustomButton);
@@ -381,8 +413,12 @@ void MainWindowPrivate::createContent()
DockManager->addDockWidget(ads::CenterDockWidgetArea, createLongTextLabelDockWidget(ViewMenu), RighDockArea); DockManager->addDockWidget(ads::CenterDockWidgetArea, createLongTextLabelDockWidget(ViewMenu), RighDockArea);
DockManager->addDockWidget(ads::CenterDockWidgetArea, createLongTextLabelDockWidget(ViewMenu), BottomDockArea); DockManager->addDockWidget(ads::CenterDockWidgetArea, createLongTextLabelDockWidget(ViewMenu), BottomDockArea);
auto Action = ui.menuView->addAction(QString("Set %1 floating").arg(DockWidget->windowTitle())); auto Action = ui.menuTests->addAction(QString("Set %1 Floating").arg(DockWidget->windowTitle()));
DockWidget->connect(Action, SIGNAL(triggered()), SLOT(setFloating())); DockWidget->connect(Action, SIGNAL(triggered()), SLOT(setFloating()));
Action = ui.menuTests->addAction(QString("Set %1 As Current Tab").arg(DockWidget->windowTitle()));
DockWidget->connect(Action, SIGNAL(triggered()), SLOT(setAsCurrentTab()));
Action = ui.menuTests->addAction(QString("Raise %1").arg(DockWidget->windowTitle()));
DockWidget->connect(Action, SIGNAL(triggered()), SLOT(raise()));
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
if (!DockManager->configFlags().testFlag(ads::CDockManager::OpaqueUndocking)) if (!DockManager->configFlags().testFlag(ads::CDockManager::OpaqueUndocking))
@@ -424,11 +460,18 @@ void MainWindowPrivate::createActions()
a->setToolTip("Creates floating dynamic dockable editor windows that are deleted on close"); a->setToolTip("Creates floating dynamic dockable editor windows that are deleted on close");
a->setIcon(svgIcon(":/adsdemo/images/note_add.svg")); a->setIcon(svgIcon(":/adsdemo/images/note_add.svg"));
_this->connect(a, SIGNAL(triggered()), SLOT(createEditor())); _this->connect(a, SIGNAL(triggered()), SLOT(createEditor()));
ui.menuTests->addAction(a);
a = ui.toolBar->addAction("Create Table"); a = ui.toolBar->addAction("Create Table");
a->setToolTip("Creates floating dynamic dockable table with millions of entries"); a->setToolTip("Creates floating dynamic dockable table with millions of entries");
a->setIcon(svgIcon(":/adsdemo/images/grid_on.svg")); a->setIcon(svgIcon(":/adsdemo/images/grid_on.svg"));
_this->connect(a, SIGNAL(triggered()), SLOT(createTable())); _this->connect(a, SIGNAL(triggered()), SLOT(createTable()));
ui.menuTests->addAction(a);
ui.menuTests->addSeparator();
a = ui.menuTests->addAction("Show Status Dialog");
_this->connect(a, SIGNAL(triggered()), SLOT(showStatusDialog()));
ui.menuTests->addSeparator();
} }
@@ -479,7 +522,7 @@ CMainWindow::CMainWindow(QWidget *parent) :
{ {
using namespace ads; using namespace ads;
d->ui.setupUi(this); d->ui.setupUi(this);
setWindowTitle(QApplication::instance()->applicationName());
d->createActions(); d->createActions();
// uncomment the following line if the tab close button should be // uncomment the following line if the tab close button should be
@@ -488,7 +531,7 @@ CMainWindow::CMainWindow(QWidget *parent) :
// uncomment the following line if you want to use opaque undocking and // uncomment the following line if you want to use opaque undocking and
// opaque splitter resizing // opaque splitter resizing
//CDockManager::setConfigFlags(CDockManager::DefaultOpaqueConfig); // CDockManager::setConfigFlags(CDockManager::DefaultOpaqueConfig);
// uncomment the following line if you want a fixed tab width that does // uncomment the following line if you want a fixed tab width that does
// not change if the visibility of the close button changes // not change if the visibility of the close button changes
@@ -515,13 +558,14 @@ CMainWindow::CMainWindow(QWidget *parent) :
// uncomment the following line if you want floating container to show active dock widget's icon instead of always showing application icon // uncomment the following line if you want floating container to show active dock widget's icon instead of always showing application icon
//CDockManager::setConfigFlag(CDockManager::FloatingContainerHasWidgetIcon, true); //CDockManager::setConfigFlag(CDockManager::FloatingContainerHasWidgetIcon, true);
// uncomment the following line if you want a central widget in the main dock container (the dock manager) without a titlebar
// If you enable this code, you can test it in the demo with the Calendar 0
// dock widget.
// CDockManager::setConfigFlag(CDockManager::HideSingleCentralWidgetTitleBar, true);
// Now create the dock manager and its content // Now create the dock manager and its content
d->DockManager = new CDockManager(this); d->DockManager = new CDockManager(this);
// uncomment the following line to have the old style where the dock
// area close button closes the active tab
// CDockManager::setConfigFlags({CDockManager::DockAreaHasCloseButton
// | CDockManager::DockAreaCloseButtonClosesTab});
connect(d->PerspectiveComboBox, SIGNAL(activated(const QString&)), connect(d->PerspectiveComboBox, SIGNAL(activated(const QString&)),
d->DockManager, SLOT(openPerspective(const QString&))); d->DockManager, SLOT(openPerspective(const QString&)));
@@ -648,3 +692,11 @@ void CMainWindow::createTable()
FloatingWidget->move(QPoint(40, 40)); FloatingWidget->move(QPoint(40, 40));
} }
//============================================================================
void CMainWindow::showStatusDialog()
{
CStatusDialog Dialog(d->DockManager);
Dialog.exec();
}

View File

@@ -63,6 +63,7 @@ private slots:
void createEditor(); void createEditor();
void createTable(); void createTable();
void onEditorCloseRequested(); void onEditorCloseRequested();
void showStatusDialog();
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H

88
demo/StatusDialog.cpp Normal file
View File

@@ -0,0 +1,88 @@
//============================================================================
/// \file StatusDialog.cpp
/// \author Uwe Kindler
/// \date 13.04.2020
/// \brief Implementation of CStatusDialog class
//============================================================================
//============================================================================
// INCLUDES
//============================================================================
#include "StatusDialog.h"
#include <iostream>
#include "DockManager.h"
#include "DockWidget.h"
#include "ui_StatusDialog.h"
/**
* Private data class of CStatusDialog class (pimpl)
*/
struct StatusDialogPrivate
{
CStatusDialog *_this;
Ui::CStatusDialogClass ui;
ads::CDockManager* DockManager;
QMap<QString, ads::CDockWidget*> DockWidgets;
/**
* Private data constructor
*/
StatusDialogPrivate(CStatusDialog *_public);
};
// struct StatusDialogPrivate
//============================================================================
StatusDialogPrivate::StatusDialogPrivate(CStatusDialog *_public) :
_this(_public)
{
}
//============================================================================
CStatusDialog::CStatusDialog(ads::CDockManager* DockManager) :
QDialog(DockManager),
d(new StatusDialogPrivate(this))
{
d->ui.setupUi(this);
d->DockManager = DockManager;
d->DockWidgets = DockManager->dockWidgetsMap();
for (auto it = d->DockWidgets.begin(); it != d->DockWidgets.end(); ++it)
{
QVariant vDockWidget = QVariant::fromValue(it.value());
d->ui.dockWidgetsComboBox->addItem(it.key(), vDockWidget);
}
}
//============================================================================
CStatusDialog::~CStatusDialog()
{
delete d;
}
//============================================================================
void CStatusDialog::on_dockWidgetsComboBox_currentIndexChanged(int index)
{
if (index < 0)
{
return;
}
auto vDockWidget = d->ui.dockWidgetsComboBox->currentData();
auto DockWidget = vDockWidget.value<ads::CDockWidget*>();
d->ui.isClosedCheckBox->setChecked(DockWidget->isClosed());
d->ui.isFloatingCheckBox->setChecked(DockWidget->isFloating());
d->ui.tabbedCheckBox->setChecked(DockWidget->isTabbed());
d->ui.isCurrentTabCheckBox->setChecked(DockWidget->isCurrentTab());
d->ui.closableCheckBox->setChecked(DockWidget->features().testFlag(ads::CDockWidget::DockWidgetClosable));
d->ui.movableCheckBox->setChecked(DockWidget->features().testFlag(ads::CDockWidget::DockWidgetMovable));
d->ui.floatableCheckBox->setChecked(DockWidget->features().testFlag(ads::CDockWidget::DockWidgetFloatable));
d->ui.deleteOnCloseCheckBox->setChecked(DockWidget->features().testFlag(ads::CDockWidget::DockWidgetDeleteOnClose));
d->ui.customCloseHandlingCheckBox->setChecked(DockWidget->features().testFlag(ads::CDockWidget::CustomCloseHandling));
}
//---------------------------------------------------------------------------
// EOF StatusDialog.cpp

47
demo/StatusDialog.h Normal file
View File

@@ -0,0 +1,47 @@
#ifndef StatusDialogH
#define StatusDialogH
//============================================================================
/// \file StatusDialog.h
/// \author Uwe Kindler
/// \date 13.04.2020
/// \brief Declaration of CStatusDialog class
//============================================================================
//============================================================================
// INCLUDES
//============================================================================
#include <QDialog>
namespace ads {class CDockManager;}
struct StatusDialogPrivate;
/**
* Displays status info about dock widgets
*/
class CStatusDialog : public QDialog
{
Q_OBJECT
private:
StatusDialogPrivate* d; ///< private data (pimpl)
friend class StatusDialogPrivate;
private slots:
void on_dockWidgetsComboBox_currentIndexChanged(int index);
protected:
public:
using Super = QDialog;
/**
* Default Constructor
*/
CStatusDialog(ads::CDockManager* parent);
/**
* Virtual Destructor
*/
virtual ~CStatusDialog();
}; // class StatusDialog
// namespace namespace_name
//-----------------------------------------------------------------------------
#endif // StatusDialogH

146
demo/StatusDialog.ui Normal file
View File

@@ -0,0 +1,146 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CStatusDialogClass</class>
<widget class="QDialog" name="CStatusDialogClass">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>357</width>
<height>331</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Dock Widget Status</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="sizeConstraint">
<enum>QLayout::SetFixedSize</enum>
</property>
<item>
<widget class="QLabel" name="dockWidgetLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Dock Widget:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="dockWidgetsComboBox">
<property name="minimumSize">
<size>
<width>300</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="statusGroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Status</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="isClosedCheckBox">
<property name="text">
<string>closed</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="isFloatingCheckBox">
<property name="text">
<string>floating</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="tabbedCheckBox">
<property name="text">
<string>tabbed</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="isCurrentTabCheckBox">
<property name="text">
<string>is current tab</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="flagsGroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Feature Flags</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QCheckBox" name="closableCheckBox">
<property name="text">
<string>DockWidgetClosable</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="movableCheckBox">
<property name="text">
<string>DockWidgetMovable</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="floatableCheckBox">
<property name="text">
<string>DockWidgetFloatable</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="deleteOnCloseCheckBox">
<property name="text">
<string>DockWidgetDeleteOnClose</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="customCloseHandlingCheckBox">
<property name="text">
<string>CustomCloseHandling</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -18,13 +18,16 @@ adsBuildStatic {
SOURCES += \ SOURCES += \
main.cpp \ main.cpp \
MainWindow.cpp MainWindow.cpp \
StatusDialog.cpp
HEADERS += \ HEADERS += \
MainWindow.h MainWindow.h \
StatusDialog.h
FORMS += \ FORMS += \
mainwindow.ui mainwindow.ui \
StatusDialog.ui
RESOURCES += demo.qrc RESOURCES += demo.qrc

View File

@@ -13,5 +13,6 @@
<file>app.css</file> <file>app.css</file>
<file>images/plus.svg</file> <file>images/plus.svg</file>
<file>images/help_outline.svg</file> <file>images/help_outline.svg</file>
<file>images/fullscreen.svg</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@@ -0,0 +1,6 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,1024,1024">
<desc>settings_overscan icon - Licensed under Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0) - Created with Iconfu.com - Derivative work of Material icons (Copyright Google Inc.)</desc>
<g fill="#03b8e5" fill-rule="nonzero" style="mix-blend-mode: normal">
<path d="M981.33,213.33v597.34c0,46.93 -38.4,85.33 -85.33,85.33h-768c-46.93,0 -85.33,-38.4 -85.33,-85.33v-597.34c0,-46.93 38.4,-85.33 85.33,-85.33h768c46.93,0 85.33,38.4 85.33,85.33zM896,212.91h-768v598.18h768zM256,597.33l-106.67,-84.9l106.67,-85.76zM597.33,341.33h-170.66l85.76,-106.66zM874.67,512.43l-106.67,84.9v-170.66zM512.43,789.33l-85.76,-106.66h170.66z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 776 B

View File

@@ -41,6 +41,7 @@ int main(int argc, char *argv[])
#endif #endif
std::shared_ptr<int> b; std::shared_ptr<int> b;
QApplication a(argc, argv); QApplication a(argc, argv);
a.setApplicationName("Advanced Docking System Demo");
a.setQuitOnLastWindowClosed(true); a.setQuitOnLastWindowClosed(true);
QFile StyleSheetFile(":/adsdemo/app.css"); QFile StyleSheetFile(":/adsdemo/app.css");

View File

@@ -31,7 +31,6 @@
<property name="title"> <property name="title">
<string>File</string> <string>File</string>
</property> </property>
<addaction name="actionExit"/>
<addaction name="actionSaveState"/> <addaction name="actionSaveState"/>
<addaction name="actionRestoreState"/> <addaction name="actionRestoreState"/>
</widget> </widget>
@@ -45,8 +44,14 @@
<string>About</string> <string>About</string>
</property> </property>
</widget> </widget>
<widget class="QMenu" name="menuTests">
<property name="title">
<string>Tests</string>
</property>
</widget>
<addaction name="menuFile"/> <addaction name="menuFile"/>
<addaction name="menuView"/> <addaction name="menuView"/>
<addaction name="menuTests"/>
<addaction name="menuAbout"/> <addaction name="menuAbout"/>
</widget> </widget>
<widget class="QToolBar" name="toolBar"> <widget class="QToolBar" name="toolBar">

View File

@@ -14,18 +14,17 @@ styles as much as possible.
### Overview ### Overview
- [Advanced Docking System for Qt](#advanced-docking-system-for-qt) - [Features](#features)
- [Features](#features) - [Overview](#overview)
- [Overview](#overview) - [Docking everywhere - no central widget](#docking-everywhere---no-central-widget)
- [Docking everywhere - no central widget](#docking-everywhere---no-central-widget) - [Docking inside floating windows](#docking-inside-floating-windows)
- [Docking inside floating windows](#docking-inside-floating-windows) - [Grouped dragging](#grouped-dragging)
- [Grouped dragging](#grouped-dragging) - [Perspectives for fast switching of the complete main window layout](#perspectives-for-fast-switching-of-the-complete-main-window-layout)
- [Perspectives for fast switching of the complete main window layout](#perspectives-for-fast-switching-of-the-complete-main-window-layout) - [Opaque and non-opaque splitter resizing](#opaque-and-non-opaque-splitter-resizing)
- [Opaque and non-opaque splitter resizing](#opaque-and-non-opaque-splitter-resizing) - [Opaque and non-opaque undocking](#opaque-and-non-opaque-undocking)
- [Opaque and non-opaque undocking](#opaque-and-non-opaque-undocking) - [Tab-menu for easy handling of many tabbed dock widgets](#tab-menu-for-easy-handling-of-many-tabbed-dock-widgets)
- [Tab-menu for easy handling of many tabbed dock widgets](#tab-menu-for-easy-handling-of-many-tabbed-dock-widgets) - [Many different ways to detach dock widgets](#many-different-ways-to-detach-dock-widgets)
- [Many different ways to detach dock widgets](#many-different-ways-to-detach-dock-widgets) - [Supports deletion of dynamically created dock widgets](#supports-deletion-of-dynamically-created-dock-widgets)
- [Supports deletion of dynamically created dock widgets](#supports-deletion-of-dynamically-created-dock-widgets)
### Docking everywhere - no central widget ### Docking everywhere - no central widget
@@ -33,8 +32,8 @@ There is no central widget like in the Qt docking system. You can dock on every
border of the main window or you can dock into each dock area - so you are border of the main window or you can dock into each dock area - so you are
free to dock almost everywhere. free to dock almost everywhere.
![Dropping widgets](https://raw.githubusercontent.com/githubuser0xFFFF/Qt-Advanced-Docking-System/master/doc/preview-dragndrop.png)\ ![Dropping widgets](https://raw.githubusercontent.com/githubuser0xFFFF/Qt-Advanced-Docking-System/master/doc/preview-dragndrop.png)
\
![Dropping widgets](https://raw.githubusercontent.com/githubuser0xFFFF/Qt-Advanced-Docking-System/master/doc/preview-dragndrop_dark.png) ![Dropping widgets](https://raw.githubusercontent.com/githubuser0xFFFF/Qt-Advanced-Docking-System/master/doc/preview-dragndrop_dark.png)
### Docking inside floating windows ### Docking inside floating windows
@@ -42,8 +41,8 @@ free to dock almost everywhere.
There is no difference between the main window and a floating window. Docking There is no difference between the main window and a floating window. Docking
into floating windows is supported. into floating windows is supported.
![Docking inside floating windows](https://raw.githubusercontent.com/githubuser0xFFFF/Qt-Advanced-Docking-System/master/doc/floating-widget-dragndrop.png)\ ![Docking inside floating windows](https://raw.githubusercontent.com/githubuser0xFFFF/Qt-Advanced-Docking-System/master/doc/floating-widget-dragndrop.png)
\
![Docking inside floating windows](https://raw.githubusercontent.com/githubuser0xFFFF/Qt-Advanced-Docking-System/master/doc/floating-widget-dragndrop_dark.png) ![Docking inside floating windows](https://raw.githubusercontent.com/githubuser0xFFFF/Qt-Advanced-Docking-System/master/doc/floating-widget-dragndrop_dark.png)
### Grouped dragging ### Grouped dragging
@@ -52,8 +51,8 @@ When dragging the titlebar of a dock, all the tabs that are tabbed with it are
going to be dragged. So you can move complete groups of tabbed widgets into going to be dragged. So you can move complete groups of tabbed widgets into
a floating widget or from one dock area to another one. a floating widget or from one dock area to another one.
![Grouped dragging](https://raw.githubusercontent.com/githubuser0xFFFF/Qt-Advanced-Docking-System/master/doc/grouped-dragging.gif)\ ![Grouped dragging](https://raw.githubusercontent.com/githubuser0xFFFF/Qt-Advanced-Docking-System/master/doc/grouped-dragging.gif)
\
![Grouped dragging](https://raw.githubusercontent.com/githubuser0xFFFF/Qt-Advanced-Docking-System/master/doc/grouped-dragging_dark.png) ![Grouped dragging](https://raw.githubusercontent.com/githubuser0xFFFF/Qt-Advanced-Docking-System/master/doc/grouped-dragging_dark.png)
### Perspectives for fast switching of the complete main window layout ### Perspectives for fast switching of the complete main window layout
@@ -64,8 +63,8 @@ perspective to make your own custom perspective. Later you can simply
select a perspective from the perspective list to quickly switch the complete select a perspective from the perspective list to quickly switch the complete
main window layout. main window layout.
![Perspective](https://raw.githubusercontent.com/githubuser0xFFFF/Qt-Advanced-Docking-System/master/doc/perspectives.gif)\ ![Perspective](https://raw.githubusercontent.com/githubuser0xFFFF/Qt-Advanced-Docking-System/master/doc/perspectives.gif)
\
![Perspective](https://raw.githubusercontent.com/githubuser0xFFFF/Qt-Advanced-Docking-System/master/doc/perspectives_dark.png) ![Perspective](https://raw.githubusercontent.com/githubuser0xFFFF/Qt-Advanced-Docking-System/master/doc/perspectives_dark.png)
### Opaque and non-opaque splitter resizing ### Opaque and non-opaque splitter resizing

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 763 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 KiB

BIN
doc/opaque_undocking.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 503 KiB

BIN
doc/qmix_elements.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 539 KiB

BIN
doc/qt_design_studio.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

BIN
doc/qtcreator.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

299
doc/user-guide.md Normal file
View File

@@ -0,0 +1,299 @@
# User Guide
- [Configuration Flags](#configuration-flags)
- [Setting Configuration Flags](#setting-configuration-flags)
- [`ActiveTabHasCloseButton`](#activetabhasclosebutton)
- [`DockAreaHasCloseButton`](#dockareahasclosebutton)
- [`DockAreaCloseButtonClosesTab`](#dockareaclosebuttonclosestab)
- [`OpaqueSplitterResize`](#opaquesplitterresize)
- [`XmlAutoFormattingEnabled`](#xmlautoformattingenabled)
- [`XmlCompressionEnabled`](#xmlcompressionenabled)
- [`TabCloseButtonIsToolButton`](#tabclosebuttonistoolbutton)
- [`AllTabsHaveCloseButton`](#alltabshaveclosebutton)
- [`RetainTabSizeWhenCloseButtonHidden`](#retaintabsizewhenclosebuttonhidden)
- [`OpaqueUndocking`](#opaqueundocking)
- [`DragPreviewIsDynamic`](#dragpreviewisdynamic)
- [`DragPreviewShowsContentPixmap`](#dragpreviewshowscontentpixmap)
- [`DragPreviewHasWindowFrame`](#dragpreviewhaswindowframe)
- [`AlwaysShowTabs`](#alwaysshowtabs)
- [`DockAreaHasUndockButton`](#dockareahasundockbutton)
- [`DockAreaHasTabsMenuButton`](#dockareahastabsmenubutton)
- [`DockAreaHideDisabledButtons`](#dockareahidedisabledbuttons)
- [`DockAreaDynamicTabsMenuButtonVisibility`](#dockareadynamictabsmenubuttonvisibility)
- [`FloatingContainerHasWidgetTitle`](#floatingcontainerhaswidgettitle)
- [`FloatingContainerHasWidgetIcon`](#floatingcontainerhaswidgeticon)
- [`HideSingleCentralWidgetTitleBar`](#hidesinglecentralwidgettitlebar)
## Configuration Flags
The Advanced Docking System has a number of global configuration options to
configure the design and the functionality of the docking system. Each
configuration will be explained in detail in the following sections.
### Setting Configuration Flags
You should set the configuration flags before you create the dock manager
instance. That means, setting the configurations flags is the first thing
you do, if you use the library.
```c++
CDockManager::setConfigFlags(CDockManager::DefaultOpaqueConfig);
CDockManager::setConfigFlag(CDockManager::RetainTabSizeWhenCloseButtonHidden, true);
...
d->DockManager = new CDockManager(this);
```
If you set the configurations flags, you can set individual flags using the
function `CDockManager::setConfigFlag` or you can set all flags using
the function `CDockManager::setConfigFlags`. Instead of settings all
flags individualy, it is better to pick a predefined set of configuration
flags and then modify individual flags. The following predefined
configurations are avilable
- `DefaultNonOpaqueConfig` - uses non opaque splitter resizing and non opaque docking
- `DefaultOpaqueConfig` - uses opaque splitter resizing and opaque docking
Pick one of those predefined configurations and then modify the following
configurations flags to adjust the docking system to your needs.
### `ActiveTabHasCloseButton`
If this flag is set (default configuration), the active tab in a tab area has
a close button.
![ActiveTabHasCloseButton true](cfg_flag_ActiveTabHasCloseButton_true.png)
If this flag is cleared, the active tab has no close button. You can combine
this with the flag `DockAreaCloseButtonClosesTab` to use the close button
of the dock are to close the single tabs.
![ActiveTabHasCloseButton true](cfg_flag_ActiveTabHasCloseButton_false.png)
### `DockAreaHasCloseButton`
If the flag is set (default configuration) each dock area has a close button.
![DockAreaHasCloseButton true](cfg_flag_DockAreaHasCloseButton_true.png)
If this flag is cleared, dock areas do not have a close button.
![DockAreaHasCloseButton true](cfg_flag_DockAreaHasCloseButton_false.png)
### `DockAreaCloseButtonClosesTab`
If the flag is set, the dock area close button closes the active tab,
if not set, it closes the complete dock area (default).
### `OpaqueSplitterResize`
The advanced docking system uses standard `QSplitters` as resize separators and thus supports opaque and non-opaque resizing functionality of `QSplitter`. In some rare cases, for very complex widgets or on slow machines resizing via separator on the fly may cause flicking and glaring of rendered content inside a widget. This global dock manager flag configures the resizing behaviour of the splitters. If this flag is set, then widgets are resized dynamically (opaquely) while interactively moving the splitters. If you select the predefined configuration `DefaultOpaqueConfig`, then this is the configured behaviour.
![Opaque resizing](opaque_resizing.gif)
If this flag is cleared, the widget resizing is deferred until the mouse button is released - this is some kind of lazy resizing separator. If you select the predefined
configuration `DefaultNonOpaqueConfig`, then this is the configured behaviour.
![Non-opaque resizing](non_opaque_resizing.gif)
### `XmlAutoFormattingEnabled`
If enabled, the XML writer automatically adds line-breaks and indentation to
empty sections between elements (ignorable whitespace). This is used, when
the current state or perspective is saved. It is disabled by default.
### `XmlCompressionEnabled`
If enabled, the XML output will be compressed and is not human readable anymore.
This ie enabled by default to minimize the size of the saved data.
### `TabCloseButtonIsToolButton`
If enabled the tab close buttons will be `QToolButtons` instead of `QPushButtons` -
disabled by default. Normally the default configuration should be ok but if your
application requires `QToolButtons` instead of `QPushButtons` for styling reasons
or for any other reasons, then you can enable this flag.
### `AllTabsHaveCloseButton`
If this flag is set, then all tabs that are closable show a close button. The
advantage of this setting is that the size of the tabs does not change and the
user can immediately close each tab. The disadvantage is that all tabs take up
more space.
![AllTabsHaveCloseButton true](cfg_flag_AllTabsHaveCloseButton_true.png)
If this flas is cleared, then only the active tab has a close button (default)
and therefore the tabs need less space.
![AllTabsHaveCloseButton false](cfg_flag_ActiveTabHasCloseButton_true.png)
### `RetainTabSizeWhenCloseButtonHidden`
If this flag is set, the space for the close button is reserved even if the
close button is not visible. This flag is disabled by default. If this flag
is disabled, the tab size dynamically changes if the close button is
visible / hidden in a tab. If this flag is enabled, the tab size always remains
constant, that means, if enabled, the tabs need more space.
![AllTabsHaveCloseButton false](cfg_flag_RetainTabSizeWhenCloseButtonHidden_true.png)
### `OpaqueUndocking`
If this flag is set, opaque undocking is active. That means, as soon as you drag a dock widget or a dock area with a number of dock widgets it will be undocked and moved into a floating widget and then the floating widget will be dragged around. That means undocking will take place immediatelly. You can compare this with opaque splitter resizing.
![OpaqueUndocking true](opaque_undocking.gif)
If you would like to test opaque undocking, you should set the pedefined config
flags `CDockManager::DefaultOpaqueConfig`.
```c++
CDockManager::setConfigFlags(CDockManager::DefaultOpaqueConfig);
```
If this flag is cleared (default), then non-opaque undocking is active. In this mode, undocking is more like a standard drag and drop operation. That means, the dragged dock widget or dock area is not undocked immediatelly. Instead, a drag preview widget is created and dragged around to indicate the future position of the dock widget or dock area. The actual dock operation is only executed when the mouse button is released. That makes it possible, to cancel an active drag operation with the escape key.
![OpaqueUndocking true](non_opaque_undocking.gif)
The drag preview widget can be configured by a number of global dock manager flags:
- `DragPreviewIsDynamic`
- `DragPreviewShowsContentPixmap`
- `DragPreviewHasWindowFrame`
Non-opaque undocking is enabled by default. If you would like to enable it
explicitely, you can do this by setting the predefined configuration flags
`CDockManager::DefaultNonOpaqueConfig`.
```c++
CDockManager::setConfigFlags(CDockManager::DefaultNonOpaqueConfig);
```
### `DragPreviewIsDynamic`
If non-opaque undocking is enabled, this flag defines the behavior of the drag
preview window. If this flag is enabled, then it will give the user the
impression, that the floating drag preview is dynamically adjusted to the drop
area. In order to give the perfect impression, you should disable the flags
`DragPreviewShowsContentPixmap` and `DragPreviewHasWindowFrame`.
```c++
CDockManager::setConfigFlag(CDockManager::DragPreviewIsDynamic, true);
CDockManager::setConfigFlag(CDockManager::DragPreviewShowsContentPixmap, false);
CDockManager::setConfigFlag(CDockManager::DragPreviewHasWindowFrame, false);
```
![DragPreviewIsDynamic true](dynamic_drag_preview.gif)
### `DragPreviewShowsContentPixmap`
If non-opaque undocking is enabled, the created drag preview window shows a
copy of the content of the dock widget / dock are that is dragged, if this
flag is enabled (default).
![DragPreviewShowsContentPixmap true](cfg_flag_DragPreviewShowsContentPixmap_true.png)
If this flag is disabled, the drag preview is only a transparent `QRubberBand`
like window without any content.
![DragPreviewShowsContentPixmap true](cfg_flag_DragPreviewShowsContentPixmap_false.png)
### `DragPreviewHasWindowFrame`
If non-opaque undocking is enabled, then this flag configures if the drag
preview is frameless (default) or looks like a real window. If it is enabled,
then the drag preview is a transparent window with a system window frame.
![DragPreviewHasWindowFrame true](cfg_flag_DragPreviewHasWindowFrame_true.png)
### `AlwaysShowTabs`
If this option is enabled, the tab of a dock widget is always displayed - even
if it is the only visible dock widget in a floating widget. In the image below
on the left side, the flag is disabled (default) and on the right side it is
enabled.
![AlwaysShowTabs false true](cfg_flag_AlwaysShowTabs_false_true.png)
### `DockAreaHasUndockButton`
If the flag is set (default) each dock area has an undock button (right
image). If the flag is cleared, a dock area has no undock button (left image)
![DockAreaHasUndockButton false true](cfg_flag_DockAreaHasUndockButton_false_true.png)
### `DockAreaHasTabsMenuButton`
Tabs are a good way to quickly switch between dockwidgets in a dockarea.
However, if the number of dockwidgets in a dockarea is too large, this may affect
the usability of the tab bar. To keep track in this situation, you can use the
tab menu. The menu allows you to quickly select the dockwidget you want to
activate from a drop down menu. This flag shows / hides the tabs menu button
in the dock area title bar. On the left side, the tabs menu button flag
is cleared.
![DockAreaHasTabsMenuButton false true](cfg_flag_DockAreaHasTabsMenuButton_false_true.png)
### `DockAreaHideDisabledButtons`
If certain flags of a dock widget are disabled, like `DockWidgetClosable` or
`DockWidgetFloatable`, then the corresponding dock area buttons like close
button or detach button are disabled (greyed out). This is the default
setting.
![DockAreaHideDisabledButtons false](cfg_flag_DockAreaHideDisabledButtons_false.png)
If the flag is set, disabled dock area buttons will not appear on the toolbar at
all - they are hidden.
![DockAreaHideDisabledButtons true](cfg_flag_DockAreaHideDisabledButtons_true.png)
### `DockAreaDynamicTabsMenuButtonVisibility`
If this flag is cleared, the the tabs menu button is always visible. This is
the default setting. If the flag is set, the tabs menu button will be shown
only when it is required - that means, if the tabs are elided.
![DockAreaDynamicTabsMenuButtonVisibility false](cfg_flag_DockAreaDynamicTabsMenuButtonVisibility_true_visible.png)
If the tabs are not elided, the tabs menu button is hidden.
![DockAreaDynamicTabsMenuButtonVisibility false](cfg_flag_DockAreaDynamicTabsMenuButtonVisibility_true_hidden.png)
### `FloatingContainerHasWidgetTitle`
If set (default), the floating widget window title reflects the title of the
current dock widget.
![FloatingContainerHasWidgetTitle true](cfg_flag_FloatingContainerHasWidgetTitle_true.png)
otherwise it displays application name as window title.
![FloatingContainerHasWidgetTitle false](cfg_flag_FloatingContainerHasWidgetTitle_false.png)
### `FloatingContainerHasWidgetIcon`
If set, the floating widget icon reflects the icon of the current dock widget
![FloatingContainerHasWidgetIcon true](cfg_flag_FloatingContainerHasWidgetIcon_true.png)
otherwise (default setting) it displays application icon.
![FloatingContainerHasWidgetIcon false](cfg_flag_FloatingContainerHasWidgetIcon_false.png)
### `HideSingleCentralWidgetTitleBar`
If there is only one single visible dock widget in the main dock container (the dock manager) and if this flag is set, then the titlebar of this dock widget will be hidden.
This only makes sense for non draggable and non floatable dock widgets and enables
the creation of some kind of "central" static widget. Because the titlebar is
hidden, it is not possible to drag out the central widget to make it floating
or to close it via the close button.
![HideSingleCentralWidgetTitleBar true](cfg_flag_HideSingleCentralWidgetTitleBar_true.png)
The Advanced Docking System is meant for applications without a static central
widget and normally does not know anything about a central static widget.
Therefore this flag is disabled by default and a central single dock widget
still has a titlebar to drag it out of the main window.
![HideSingleCentralWidgetTitleBar false](cfg_flag_HideSingleCentralWidgetTitleBar_false.png)

View File

@@ -170,6 +170,7 @@ public:
DefaultOpaqueConfig, DefaultOpaqueConfig,
DefaultNonOpaqueConfig, DefaultNonOpaqueConfig,
NonOpaqueWithWindowFrame, NonOpaqueWithWindowFrame,
HideSingleCentralWidgetTitleBar,
}; };
typedef QFlags<ads::CDockManager::eConfigFlag> ConfigFlags; typedef QFlags<ads::CDockManager::eConfigFlag> ConfigFlags;

View File

@@ -50,6 +50,12 @@ public:
ForceScrollArea, ForceScrollArea,
ForceNoScrollArea ForceNoScrollArea
}; };
enum eMinimumSizeHintMode
{
MinimumSizeHintFromDockWidget,
MinimumSizeHintFromContent
};
enum eToggleViewActionMode enum eToggleViewActionMode
{ {
@@ -76,6 +82,7 @@ public:
bool isClosed() const; bool isClosed() const;
QAction* toggleViewAction() const; QAction* toggleViewAction() const;
void setToggleViewActionMode(ads::CDockWidget::eToggleViewActionMode Mode); void setToggleViewActionMode(ads::CDockWidget::eToggleViewActionMode Mode);
void setMinimumSizeHintMode(ads::CDockWidget::eMinimumSizeHintMode Mode);
void setIcon(const QIcon& Icon); void setIcon(const QIcon& Icon);
QIcon icon() const; QIcon icon() const;
QToolBar* toolBar() const; QToolBar* toolBar() const;
@@ -89,15 +96,22 @@ public:
virtual QList<QAction*> titleBarActions() const; virtual QList<QAction*> titleBarActions() const;
void setTabToolTip(const QString &text); void setTabToolTip(const QString &text);
bool isFullScreen() const;
bool isTabbed() const;
bool isCurrentTab() const;
public: public:
virtual bool event(QEvent *e); virtual bool event(QEvent *e);
public slots: public slots:
void toggleView(bool Open = true); void toggleView(bool Open = true);
void setAsCurrentTab();
void raise();
void setFloating(); void setFloating();
void deleteDockWidget(); void deleteDockWidget();
void closeDockWidget(); void closeDockWidget();
void showFullScreen();
void showNormal();
signals: signals:
void viewToggled(bool Open); void viewToggled(bool Open);

View File

@@ -247,6 +247,7 @@ struct DockAreaWidgetPrivate
CDockManager* DockManager = nullptr; CDockManager* DockManager = nullptr;
bool UpdateTitleBarButtons = false; bool UpdateTitleBarButtons = false;
DockWidgetAreas AllowedAreas = AllDockAreas; DockWidgetAreas AllowedAreas = AllDockAreas;
QSize MinSizeHint;
/** /**
* Private data constructor * Private data constructor
@@ -303,6 +304,20 @@ struct DockAreaWidgetPrivate
* Udpates the enable state of the close and detach button * Udpates the enable state of the close and detach button
*/ */
void updateTitleBarButtonStates(); void updateTitleBarButtonStates();
/**
* Scans all contained dock widgets for the max. minimum size hint
*/
void updateMinimumSizeHint()
{
MinSizeHint = QSize();
for (int i = 0; i < ContentsLayout->count(); ++i)
{
auto Widget = ContentsLayout->widget(i);
MinSizeHint.setHeight(qMax(MinSizeHint.height(), Widget->minimumSizeHint().height()));
MinSizeHint.setWidth(qMax(MinSizeHint.width(), Widget->minimumSizeHint().width()));
}
}
}; };
// struct DockAreaWidgetPrivate // struct DockAreaWidgetPrivate
@@ -407,6 +422,8 @@ void CDockAreaWidget::insertDockWidget(int index, CDockWidget* DockWidget,
d->tabBar()->blockSignals(false); d->tabBar()->blockSignals(false);
TabWidget->setVisible(!DockWidget->isClosed()); TabWidget->setVisible(!DockWidget->isClosed());
DockWidget->setProperty(INDEX_PROPERTY, index); DockWidget->setProperty(INDEX_PROPERTY, index);
d->MinSizeHint.setHeight(qMax(d->MinSizeHint.height(), DockWidget->minimumSizeHint().height()));
d->MinSizeHint.setWidth(qMax(d->MinSizeHint.width(), DockWidget->minimumSizeHint().width()));
if (Activate) if (Activate)
{ {
setCurrentIndex(index); setCurrentIndex(index);
@@ -447,6 +464,7 @@ void CDockAreaWidget::removeDockWidget(CDockWidget* DockWidget)
d->updateTitleBarButtonStates(); d->updateTitleBarButtonStates();
updateTitleBarVisibility(); updateTitleBarVisibility();
d->updateMinimumSizeHint();
auto TopLevelDockWidget = DockContainer->topLevelDockWidget(); auto TopLevelDockWidget = DockContainer->topLevelDockWidget();
if (TopLevelDockWidget) if (TopLevelDockWidget)
{ {
@@ -470,7 +488,7 @@ void CDockAreaWidget::hideAreaWithNoVisibleContent()
//Hide empty floating widget //Hide empty floating widget
CDockContainerWidget* Container = this->dockContainer(); CDockContainerWidget* Container = this->dockContainer();
if (!Container->isFloating()) if (!Container->isFloating() && !CDockManager::testConfigFlag(CDockManager::HideSingleCentralWidgetTitleBar))
{ {
return; return;
} }
@@ -480,10 +498,13 @@ void CDockAreaWidget::hideAreaWithNoVisibleContent()
auto FloatingWidget = Container->floatingWidget(); auto FloatingWidget = Container->floatingWidget();
if (TopLevelWidget) if (TopLevelWidget)
{ {
FloatingWidget->updateWindowTitle(); if (FloatingWidget)
{
FloatingWidget->updateWindowTitle();
}
CDockWidget::emitTopLevelEventForWidget(TopLevelWidget, true); CDockWidget::emitTopLevelEventForWidget(TopLevelWidget, true);
} }
else if (Container->openedDockAreas().isEmpty()) else if (Container->openedDockAreas().isEmpty() && FloatingWidget)
{ {
FloatingWidget->hide(); FloatingWidget->hide();
} }
@@ -711,7 +732,9 @@ void CDockAreaWidget::updateTitleBarVisibility()
if (d->TitleBar) if (d->TitleBar)
{ {
d->TitleBar->setVisible(!Container->isFloating() || !Container->hasTopLevelDockWidget()); bool Hidden = Container->hasTopLevelDockWidget() && (Container->isFloating()
|| CDockManager::configFlags().testFlag(CDockManager::HideSingleCentralWidgetTitleBar));
d->TitleBar->setVisible(!Hidden);
} }
} }
@@ -863,6 +886,13 @@ CDockAreaTitleBar* CDockAreaWidget::titleBar() const
{ {
return d->TitleBar; return d->TitleBar;
} }
//============================================================================
QSize CDockAreaWidget::minimumSizeHint() const
{
return d->MinSizeHint.isValid() ? d->MinSizeHint : Super::minimumSizeHint();
}
} // namespace ads } // namespace ads
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@@ -164,6 +164,13 @@ public:
*/ */
CDockContainerWidget* dockContainer() const; CDockContainerWidget* dockContainer() const;
/**
* Returns the largest minimumSizeHint() of the dock widgets in this
* area.
* The minimum size hint is updated if a dock widget is removed or added.
*/
virtual QSize minimumSizeHint() const override;
/** /**
* Returns the rectangle of the title area * Returns the rectangle of the title area
*/ */

View File

@@ -1614,11 +1614,6 @@ CDockAreaWidget* CDockContainerWidget::lastAddedDockAreaWidget(DockWidgetArea ar
//============================================================================ //============================================================================
bool CDockContainerWidget::hasTopLevelDockWidget() const bool CDockContainerWidget::hasTopLevelDockWidget() const
{ {
if (!isFloating())
{
return false;
}
auto DockAreas = openedDockAreas(); auto DockAreas = openedDockAreas();
if (DockAreas.count() != 1) if (DockAreas.count() != 1)
{ {
@@ -1652,11 +1647,6 @@ CDockWidget* CDockContainerWidget::topLevelDockWidget() const
//============================================================================ //============================================================================
CDockAreaWidget* CDockContainerWidget::topLevelDockArea() const CDockAreaWidget* CDockContainerWidget::topLevelDockArea() const
{ {
if (!isFloating())
{
return nullptr;
}
auto DockAreas = openedDockAreas(); auto DockAreas = openedDockAreas();
if (DockAreas.count() != 1) if (DockAreas.count() != 1)
{ {

View File

@@ -55,8 +55,8 @@ class CDockingStateReader;
* Container that manages a number of dock areas with single dock widgets * Container that manages a number of dock areas with single dock widgets
* or tabyfied dock widgets in each area. * or tabyfied dock widgets in each area.
* Each window that support docking has a DockContainerWidget. That means * Each window that support docking has a DockContainerWidget. That means
* the main application window and all floating windows are ore contain * the main application window and all floating windows contain a
* an DockContainerWidget. * DockContainerWidget instance.
*/ */
class ADS_EXPORT CDockContainerWidget : public QFrame class ADS_EXPORT CDockContainerWidget : public QFrame
{ {

View File

@@ -55,6 +55,20 @@
#include "DockingStateReader.h" #include "DockingStateReader.h"
/**
* Initializes the resources specified by the .qrc file with the specified base
* name. Normally, when resources are built as part of the application, the
* resources are loaded automatically at startup. The Q_INIT_RESOURCE() macro
* is necessary on some platforms for resources stored in a static library.
* Because GCC caues a linker error if we put Q_INIT_RESOURCE into the
* loadStyleSheet() function, we place it into a function outside of the ads
* namespace
*/
static void initResource()
{
Q_INIT_RESOURCE(ads);
}
namespace ads namespace ads
{ {
@@ -148,6 +162,7 @@ DockManagerPrivate::DockManagerPrivate(CDockManager* _public) :
//============================================================================ //============================================================================
void DockManagerPrivate::loadStylesheet() void DockManagerPrivate::loadStylesheet()
{ {
initResource();
QString Result; QString Result;
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
QFile StyleSheetFile(":ads/stylesheets/default_linux.css"); QFile StyleSheetFile(":ads/stylesheets/default_linux.css");

View File

@@ -30,18 +30,11 @@
//============================================================================ //============================================================================
// INCLUDES // INCLUDES
//============================================================================ //============================================================================
#include <ads_globals.h> #include "ads_globals.h"
#include <DockContainerWidget.h> #include "DockContainerWidget.h"
#include <DockWidget.h> #include "DockWidget.h"
#include <FloatingDockContainer.h> #include "FloatingDockContainer.h"
#include <qbytearray.h>
#include <qflags.h>
#include <qlist.h>
#include <qmap.h>
#include <qobjectdefs.h>
#include <qstring.h>
#include <qstringlist.h>
#include <QtGui/qicon.h>
class QSettings; class QSettings;
class QMenu; class QMenu;
@@ -162,10 +155,12 @@ public:
AlwaysShowTabs = 0x2000,///< If this option is enabled, the tab of a dock widget is always displayed - even if it is the only visible dock widget in a floating widget. AlwaysShowTabs = 0x2000,///< If this option is enabled, the tab of a dock widget is always displayed - even if it is the only visible dock widget in a floating widget.
DockAreaHasUndockButton = 0x4000, //!< If the flag is set each dock area has an undock button DockAreaHasUndockButton = 0x4000, //!< If the flag is set each dock area has an undock button
DockAreaHasTabsMenuButton = 0x8000, //!< If the flag is set each dock area has a tabs menu button DockAreaHasTabsMenuButton = 0x8000, //!< If the flag is set each dock area has a tabs menu button
DockAreaHideDisabledButtons = 0x10000, //!< If the flag is set disabled dock area buttons will not appear on the tollbar at all (enabling them will bring them back) DockAreaHideDisabledButtons = 0x10000, //!< If the flag is set disabled dock area buttons will not appear on the toolbar at all (enabling them will bring them back)
DockAreaDynamicTabsMenuButtonVisibility = 0x20000, //!< If the flag is set dock area will disable a tabs menu button when there is only one tab in the area DockAreaDynamicTabsMenuButtonVisibility = 0x20000, //!< If the flag is set, the tabs menu button will be shown only when it is required - that means, if the tabs are elided. If the tabs are not elided, it is hidden
FloatingContainerHasWidgetTitle = 0x40000, FloatingContainerHasWidgetTitle = 0x40000, //!< If set, the Floating Widget window title reflects the title of the current dock widget otherwise it displays application name as window title
FloatingContainerHasWidgetIcon = 0x80000, FloatingContainerHasWidgetIcon = 0x80000, //!< If set, the Floating Widget icon reflects the icon of the current dock widget otherwise it displays application icon
HideSingleCentralWidgetTitleBar = 0x100000, //!< If there is only one single visible dock widget in the main dock container (the dock manager) and if this flag is set, then the titlebar of this dock widget will be hidden
//!< this only makes sense for non draggable and non floatable widgets and enables the creation of some kind of "central" widget
DefaultDockAreaButtons = DockAreaHasCloseButton DefaultDockAreaButtons = DockAreaHasCloseButton

View File

@@ -37,6 +37,7 @@
#include <QWindow> #include <QWindow>
#include "DockAreaWidget.h" #include "DockAreaWidget.h"
#include "DockAreaTitleBar.h"
#include <iostream> #include <iostream>
@@ -387,6 +388,7 @@ DockWidgetArea CDockOverlay::dropAreaUnderCursor() const
} }
if (DockArea->allowedAreas().testFlag(CenterDockWidgetArea) if (DockArea->allowedAreas().testFlag(CenterDockWidgetArea)
&& !DockArea->titleBar()->isHidden()
&& DockArea->titleBarGeometry().contains(DockArea->mapFromGlobal(QCursor::pos()))) && DockArea->titleBarGeometry().contains(DockArea->mapFromGlobal(QCursor::pos())))
{ {
return CenterDockWidgetArea; return CenterDockWidgetArea;

View File

@@ -44,6 +44,7 @@
#include <QDebug> #include <QDebug>
#include <QToolBar> #include <QToolBar>
#include <QXmlStreamWriter> #include <QXmlStreamWriter>
#include <QWindow>
#include <QGuiApplication> #include <QGuiApplication>
#include <QScreen> #include <QScreen>
@@ -82,6 +83,7 @@ struct DockWidgetPrivate
QSize ToolBarIconSizeFloating = QSize(24, 24); QSize ToolBarIconSizeFloating = QSize(24, 24);
bool IsFloatingTopLevel = false; bool IsFloatingTopLevel = false;
QList<QAction*> TitleBarActions; QList<QAction*> TitleBarActions;
CDockWidget::eMinimumSizeHintMode MinimumSizeHintMode = CDockWidget::MinimumSizeHintFromDockWidget;
/** /**
* Private data constructor * Private data constructor
@@ -256,7 +258,12 @@ void CDockWidget::setToggleViewActionChecked(bool Checked)
//============================================================================ //============================================================================
void CDockWidget::setWidget(QWidget* widget, eInsertMode InsertMode) void CDockWidget::setWidget(QWidget* widget, eInsertMode InsertMode)
{ {
QScrollArea* ScrollAreaWidget = qobject_cast<QScrollArea*>(widget); if (d->Widget)
{
takeWidget();
}
auto ScrollAreaWidget = qobject_cast<QAbstractScrollArea*>(widget);
if (ScrollAreaWidget || ForceNoScrollArea == InsertMode) if (ScrollAreaWidget || ForceNoScrollArea == InsertMode)
{ {
d->Layout->addWidget(widget); d->Layout->addWidget(widget);
@@ -279,10 +286,26 @@ void CDockWidget::setWidget(QWidget* widget, eInsertMode InsertMode)
//============================================================================ //============================================================================
QWidget* CDockWidget::takeWidget() QWidget* CDockWidget::takeWidget()
{ {
d->ScrollArea->takeWidget(); QWidget* w = nullptr;
d->Layout->removeWidget(d->Widget); if (d->ScrollArea)
d->Widget->setParent(nullptr); {
return d->Widget; d->Layout->removeWidget(d->ScrollArea);
w = d->ScrollArea->takeWidget();
delete d->ScrollArea;
d->ScrollArea = nullptr;
}
else if (d->Widget)
{
d->Layout->removeWidget(d->Widget);
w = d->Widget;
d->Widget = nullptr;
}
if (w)
{
w->setParent(nullptr);
}
return w;
} }
@@ -424,6 +447,13 @@ void CDockWidget::setToggleViewActionMode(eToggleViewActionMode Mode)
} }
//============================================================================
void CDockWidget::setMinimumSizeHintMode(eMinimumSizeHintMode Mode)
{
d->MinimumSizeHintMode = Mode;
}
//============================================================================ //============================================================================
void CDockWidget::toggleView(bool Open) void CDockWidget::toggleView(bool Open)
{ {
@@ -753,7 +783,14 @@ void CDockWidget::setClosedState(bool Closed)
//============================================================================ //============================================================================
QSize CDockWidget::minimumSizeHint() const QSize CDockWidget::minimumSizeHint() const
{ {
return QSize(60, 40); if (d->MinimumSizeHintMode == CDockWidget::MinimumSizeHintFromDockWidget || !d->Widget)
{
return QSize(60, 40);
}
else
{
return d->Widget->minimumSizeHint();
}
} }
@@ -840,6 +877,91 @@ QList<QAction*> CDockWidget::titleBarActions() const
} }
//============================================================================
void CDockWidget::showFullScreen()
{
if (isFloating())
{
dockContainer()->floatingWidget()->showFullScreen();
}
else
{
Super::showFullScreen();
}
}
//============================================================================
void CDockWidget::showNormal()
{
if (isFloating())
{
dockContainer()->floatingWidget()->showNormal();
}
else
{
Super::showNormal();
}
}
//============================================================================
bool CDockWidget::isFullScreen() const
{
if (isFloating())
{
return dockContainer()->floatingWidget()->isFullScreen();
}
else
{
return Super::isFullScreen();
}
}
//============================================================================
void CDockWidget::setAsCurrentTab()
{
if (d->DockArea && !isClosed())
{
d->DockArea->setCurrentDockWidget(this);
}
}
//============================================================================
bool CDockWidget::isTabbed() const
{
return d->DockArea && (d->DockArea->openDockWidgetsCount() > 1);
}
//============================================================================
bool CDockWidget::isCurrentTab() const
{
return d->DockArea && (d->DockArea->currentDockWidget() == this);
}
//============================================================================
void CDockWidget::raise()
{
if (isClosed())
{
return;
}
setAsCurrentTab();
if (isInFloatingContainer())
{
auto FloatingWindow = window();
FloatingWindow->raise();
FloatingWindow->activateWindow();
}
}
} // namespace ads } // namespace ads
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@@ -147,8 +147,8 @@ public:
enum DockWidgetFeature enum DockWidgetFeature
{ {
DockWidgetClosable = 0x01, DockWidgetClosable = 0x01,///< dock widget has a close button
DockWidgetMovable = 0x02,///< this feature is not properly implemented yet and is ignored DockWidgetMovable = 0x02,///< dock widget is movable and can be moved to a new position in the current dock container
DockWidgetFloatable = 0x04, DockWidgetFloatable = 0x04,
DockWidgetDeleteOnClose = 0x08, ///< deletes the dock widget when it is closed DockWidgetDeleteOnClose = 0x08, ///< deletes the dock widget when it is closed
CustomCloseHandling = 0x10, CustomCloseHandling = 0x10,
@@ -189,6 +189,23 @@ public:
ForceNoScrollArea ForceNoScrollArea
}; };
/**
* The mode of the minimumSizeHint() that is returned by the DockWidget
* minimumSizeHint() function.
* To ensure, that a dock widget does not block resizing, the dock widget
* reimplements minimumSizeHint() function to return a very small minimum
* size hint. If you would like to adhere the minimumSizeHint() from the
* content widget, the set the minimumSizeHintMode() to
* MinimumSizeHintFromContent.
*/
enum eMinimumSizeHintMode
{
MinimumSizeHintFromDockWidget,
MinimumSizeHintFromContent
};
/** /**
* This mode configures the behavior of the toggle view action. * This mode configures the behavior of the toggle view action.
* If the mode if ActionModeToggle, then the toggle view action is * If the mode if ActionModeToggle, then the toggle view action is
@@ -225,7 +242,8 @@ public:
virtual ~CDockWidget(); virtual ~CDockWidget();
/** /**
* We return a fixed minimum size hint for all dock widgets * We return a fixed minimum size hint or the size hint of the content
* widget if minimum size hint mode is MinimumSizeHintFromContent
*/ */
virtual QSize minimumSizeHint() const override; virtual QSize minimumSizeHint() const override;
@@ -334,6 +352,13 @@ public:
*/ */
void setToggleViewActionMode(eToggleViewActionMode Mode); void setToggleViewActionMode(eToggleViewActionMode Mode);
/**
* Configures the minimum size hint that is returned by the
* minimumSizeHint() function.
* \see eMinimumSizeHintMode for a detailed description
*/
void setMinimumSizeHintMode(eMinimumSizeHintMode Mode);
/** /**
* Sets the dock widget icon that is shown in tabs and in toggle view * Sets the dock widget icon that is shown in tabs and in toggle view
* actions * actions
@@ -424,6 +449,26 @@ public:
void setTabToolTip(const QString &text); void setTabToolTip(const QString &text);
#endif #endif
/**
* Returns true if the dock widget is floating and if the floating dock
* container is full screen
*/
bool isFullScreen() const;
/**
* Returns true if this dock widget is in a dock area, that contains at
* least 2 opened dock widgets
*/
bool isTabbed() const;
/**
* Returns true if this dock widget is the current one in the dock
* area widget that contains it.
* If the dock widget is the only opened dock widget in a dock area,
* the true is returned
*/
bool isCurrentTab() const;
public: // reimplements QFrame ----------------------------------------------- public: // reimplements QFrame -----------------------------------------------
/** /**
* Emits titleChanged signal if title change event occurs * Emits titleChanged signal if title change event occurs
@@ -437,6 +482,23 @@ public slots:
*/ */
void toggleView(bool Open = true); void toggleView(bool Open = true);
/**
* Makes this dock widget the current tab in its dock area.
* The function only has an effect, if the dock widget is open. A call
* to this function will not toggle the view, so if it is closed,
* nothing will happen
*/
void setAsCurrentTab();
/**
* Brings the dock widget to the front
* This means:
* - If the dock widget is tabbed with other dock widgets but its tab is not current, it's made current.
* - If the dock widget is floating, QWindow::raise() is called.
* This only applies if the dock widget is already open. If closed, does nothing.
*/
void raise();
/** /**
* This function will make a docked widget floating * This function will make a docked widget floating
*/ */
@@ -453,6 +515,26 @@ public slots:
*/ */
void closeDockWidget(); void closeDockWidget();
/**
* Shows the widget in full-screen mode.
* Normally this function only affects windows. To make the interface
* compatible to QDockWidget, this function also maximizes a floating
* dock widget.
*
* \note Full-screen mode works fine under Windows, but has certain
* problems (doe not work) under X (Linux). These problems are due to
* limitations of the ICCCM protocol that specifies the communication
* between X11 clients and the window manager. ICCCM simply does not
* understand the concept of non-decorated full-screen windows.
*/
void showFullScreen();
/**
* This function complements showFullScreen() to restore the widget
* after it has been in full screen mode.
*/
void showNormal();
signals: signals:
/** /**

View File

@@ -241,7 +241,6 @@ bool DockWidgetTabPrivate::startFloating(eDragState DraggingState)
ADS_PRINT("startFloating"); ADS_PRINT("startFloating");
DragState = DraggingState; DragState = DraggingState;
QSize Size = DockArea->size();
IFloatingWidget* FloatingWidget = nullptr; IFloatingWidget* FloatingWidget = nullptr;
bool OpaqueUndocking = CDockManager::configFlags().testFlag(CDockManager::OpaqueUndocking) || bool OpaqueUndocking = CDockManager::configFlags().testFlag(CDockManager::OpaqueUndocking) ||
(DraggingFloatingWidget != DraggingState); (DraggingFloatingWidget != DraggingState);
@@ -249,13 +248,16 @@ bool DockWidgetTabPrivate::startFloating(eDragState DraggingState)
// If section widget has multiple tabs, we take only one tab // If section widget has multiple tabs, we take only one tab
// If it has only one single tab, we can move the complete // If it has only one single tab, we can move the complete
// dock area into floating widget // dock area into floating widget
QSize Size;
if (DockArea->dockWidgetsCount() > 1) if (DockArea->dockWidgetsCount() > 1)
{ {
FloatingWidget = createFloatingWidget(DockWidget, OpaqueUndocking); FloatingWidget = createFloatingWidget(DockWidget, OpaqueUndocking);
Size = DockWidget->size();
} }
else else
{ {
FloatingWidget = createFloatingWidget(DockArea, OpaqueUndocking); FloatingWidget = createFloatingWidget(DockArea, OpaqueUndocking);
Size = DockArea->size();
} }
if (DraggingFloatingWidget == DraggingState) if (DraggingFloatingWidget == DraggingState)
@@ -578,6 +580,8 @@ void CDockWidgetTab::setText(const QString& title)
d->TitleLabel->setText(title); d->TitleLabel->setText(title);
} }
//============================================================================
bool CDockWidgetTab::isTitleElided() const bool CDockWidgetTab::isTitleElided() const
{ {
return d->TitleLabel->isElided(); return d->TitleLabel->isElided();
@@ -630,6 +634,13 @@ void CDockWidgetTab::onDockWidgetFeaturesChanged()
} }
//============================================================================
void CDockWidgetTab::setElideMode(Qt::TextElideMode mode)
{
d->TitleLabel->setElideMode(mode);
}
} // namespace ads } // namespace ads

View File

@@ -147,6 +147,11 @@ public:
*/ */
virtual bool event(QEvent *e) override; virtual bool event(QEvent *e) override;
/**
* Sets the text elide mode
*/
void setElideMode(Qt::TextElideMode mode);
public slots: public slots:
virtual void setVisible(bool visible) override; virtual void setVisible(bool visible) override;

View File

@@ -197,13 +197,13 @@ QSize CElidingLabel::sizeHint() const
//============================================================================ //============================================================================
void CElidingLabel::setText(const QString &text) void CElidingLabel::setText(const QString &text)
{ {
d->Text = text;
if (d->isModeElideNone()) if (d->isModeElideNone())
{ {
Super::setText(text); Super::setText(text);
} }
else else
{ {
d->Text = text;
internal::setToolTip(this, text); internal::setToolTip(this, text);
d->elideText(this->size().width()); d->elideText(this->size().width());
} }

View File

@@ -38,6 +38,7 @@
#include <QDebug> #include <QDebug>
#include <QAbstractButton> #include <QAbstractButton>
#include <QElapsedTimer> #include <QElapsedTimer>
#include <QTime>
#include "DockContainerWidget.h" #include "DockContainerWidget.h"
#include "DockAreaWidget.h" #include "DockAreaWidget.h"
@@ -66,6 +67,7 @@ struct FloatingDockContainerPrivate
QPoint DragStartMousePosition; QPoint DragStartMousePosition;
CDockContainerWidget *DropContainer = nullptr; CDockContainerWidget *DropContainer = nullptr;
CDockAreaWidget *SingleDockArea = nullptr; CDockAreaWidget *SingleDockArea = nullptr;
QPoint DragStartPos;
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
QWidget* MouseEventHandler = nullptr; QWidget* MouseEventHandler = nullptr;
CFloatingWidgetTitleBar* TitleBar = nullptr; CFloatingWidgetTitleBar* TitleBar = nullptr;
@@ -109,6 +111,10 @@ struct FloatingDockContainerPrivate
#endif #endif
} }
/**
* Reflect the current dock widget title in the floating widget windowTitle()
* depending on the CDockManager::FloatingContainerHasWidgetTitle flag
*/
void reflectCurrentWidget(CDockWidget* CurrentWidget) void reflectCurrentWidget(CDockWidget* CurrentWidget)
{ {
// reflect CurrentWidget's title if configured to do so, otherwise display application name as window title // reflect CurrentWidget's title if configured to do so, otherwise display application name as window title
@@ -133,6 +139,11 @@ struct FloatingDockContainerPrivate
_this->setWindowIcon(QApplication::windowIcon()); _this->setWindowIcon(QApplication::windowIcon());
} }
} }
/**
* Handles escape key press when dragging around the floating widget
*/
void handleEscapeKey();
}; };
// struct FloatingDockContainerPrivate // struct FloatingDockContainerPrivate
@@ -158,14 +169,14 @@ void FloatingDockContainerPrivate::titleMouseReleaseEvent()
|| DockManager->containerOverlay()->dropAreaUnderCursor() || DockManager->containerOverlay()->dropAreaUnderCursor()
!= InvalidDockWidgetArea) != InvalidDockWidgetArea)
{ {
// Resize the floating widget to the size of the highlighted drop area
// rectangle
CDockOverlay *Overlay = DockManager->containerOverlay(); CDockOverlay *Overlay = DockManager->containerOverlay();
if (!Overlay->dropOverlayRect().isValid()) if (!Overlay->dropOverlayRect().isValid())
{ {
Overlay = DockManager->dockAreaOverlay(); Overlay = DockManager->dockAreaOverlay();
} }
// Resize the floating widget to the size of the highlighted drop area
// rectangle
QRect Rect = Overlay->dropOverlayRect(); QRect Rect = Overlay->dropOverlayRect();
int FrameWidth = (_this->frameSize().width() - _this->rect().width()) int FrameWidth = (_this->frameSize().width() - _this->rect().width())
/ 2; / 2;
@@ -264,6 +275,17 @@ void FloatingDockContainerPrivate::updateDropOverlays(const QPoint &GlobalPos)
} }
} }
//============================================================================
void FloatingDockContainerPrivate::handleEscapeKey()
{
ADS_PRINT("FloatingDockContainerPrivate::handleEscapeKey()");
setState(DraggingInactive);
DockManager->containerOverlay()->hideOverlay();
DockManager->dockAreaOverlay()->hideOverlay();
}
//============================================================================ //============================================================================
CFloatingDockContainer::CFloatingDockContainer(CDockManager *DockManager) : CFloatingDockContainer::CFloatingDockContainer(CDockManager *DockManager) :
tFloatingWidgetBase(DockManager), tFloatingWidgetBase(DockManager),
@@ -363,6 +385,9 @@ void CFloatingDockContainer::moveEvent(QMoveEvent *event)
switch (d->DraggingState) switch (d->DraggingState)
{ {
case DraggingMousePressed: case DraggingMousePressed:
#ifdef Q_OS_WIN
qApp->installEventFilter(this);
#endif
d->setState(DraggingFloatingWidget); d->setState(DraggingFloatingWidget);
d->updateDropOverlays(QCursor::pos()); d->updateDropOverlays(QCursor::pos());
break; break;
@@ -380,6 +405,8 @@ void CFloatingDockContainer::moveEvent(QMoveEvent *event)
default: default:
break; break;
} }
} }
//============================================================================ //============================================================================
@@ -443,6 +470,7 @@ void CFloatingDockContainer::showEvent(QShowEvent *event)
Super::showEvent(event); Super::showEvent(event);
} }
//============================================================================ //============================================================================
bool CFloatingDockContainer::event(QEvent *e) bool CFloatingDockContainer::event(QEvent *e)
{ {
@@ -458,21 +486,17 @@ bool CFloatingDockContainer::event(QEvent *e)
// It is really great to work around the whole NonClientMouseArea // It is really great to work around the whole NonClientMouseArea
// bugs // bugs
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 2)) #if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 2))
if (e->type() if (e->type() == QEvent::NonClientAreaMouseButtonPress /*&& QGuiApplication::mouseButtons().testFlag(Qt::LeftButton)*/)
== QEvent::NonClientAreaMouseButtonPress /*&& QGuiApplication::mouseButtons().testFlag(Qt::LeftButton)*/)
{
ADS_PRINT("FloatingWidget::event Event::NonClientAreaMouseButtonPress" << e->type());
d->setState(DraggingMousePressed);
}
#else #else
if (e->type() == QEvent::NonClientAreaMouseButtonPress && QGuiApplication::mouseButtons().testFlag(Qt::LeftButton)) if (e->type() == QEvent::NonClientAreaMouseButtonPress && QGuiApplication::mouseButtons().testFlag(Qt::LeftButton))
#endif
{ {
ADS_PRINT("FloatingWidget::event Event::NonClientAreaMouseButtonPress" << e->type()); ADS_PRINT("FloatingWidget::event Event::NonClientAreaMouseButtonPress" << e->type());
d->DragStartPos = pos();
d->setState(DraggingMousePressed); d->setState(DraggingMousePressed);
} }
#endif
} }
break; break;
case DraggingMousePressed: case DraggingMousePressed:
switch (e->type()) switch (e->type())
@@ -515,12 +539,49 @@ bool CFloatingDockContainer::event(QEvent *e)
} }
#if (ADS_DEBUG_LEVEL > 0) #if (ADS_DEBUG_LEVEL > 0)
qDebug() << "CFloatingDockContainer::event " << e->type(); qDebug() << QTime::currentTime() << "CFloatingDockContainer::event " << e->type();
#endif #endif
return QWidget::event(e); return QWidget::event(e);
} }
//============================================================================
bool CFloatingDockContainer::eventFilter(QObject *watched, QEvent *e)
{
Q_UNUSED(watched);
// I have not found a way to detect non client area key press events to
// handle escape key presses. On Windows, if the escape key is pressed while
// dragging around a widget, the widget position is reset to its start position
// which in turn generates a QEvent::NonClientAreaMouseButtonRelease event
// if the mouse is outside of the widget after the move to its initial position
// or a QEvent::MouseButtonRelease event, if the mouse is inside of teh widget
// after the position has been reset.
// So we can install an event filter on the application to get these events
// here to properly cancel dragging and hide the overlays.
// If we are in DraggingFloatingWidget state, it means the widget
// has been dragged already but if the position is the same like
// the start position, then this is an indication that the escape
// key has been pressed.
if (e->type() == QEvent::MouseButtonRelease || e->type() == QEvent::NonClientAreaMouseButtonRelease)
{
ADS_PRINT("CFloatingDockContainer::eventFilter QEvent::MouseButtonRelease or"
"QEvent::NonClientAreaMouseButtonRelease" << "d->DragggingState " << d->DraggingState);
qApp->removeEventFilter(this);
if (d->DragStartPos == pos())
{
d->handleEscapeKey();
return true;
}
return false;
}
#if (ADS_DEBUG_LEVEL > 0)
qDebug() << QTime::currentTime() << "CFloatingDockContainer::eventFilter " << e->type();
#endif
return false;
}
//============================================================================ //============================================================================
void CFloatingDockContainer::startFloating(const QPoint &DragStartMousePos, void CFloatingDockContainer::startFloating(const QPoint &DragStartMousePos,
const QSize &Size, eDragState DragState, QWidget *MouseEventHandler) const QSize &Size, eDragState DragState, QWidget *MouseEventHandler)

View File

@@ -68,6 +68,8 @@ class CDockingStateReader;
class IFloatingWidget class IFloatingWidget
{ {
public: public:
virtual ~IFloatingWidget() = default;
/** /**
* Starts floating. * Starts floating.
* This function should get called typically from a mouse press event * This function should get called typically from a mouse press event
@@ -180,6 +182,7 @@ protected: // reimplements QWidget
virtual void closeEvent(QCloseEvent *event) override; virtual void closeEvent(QCloseEvent *event) override;
virtual void hideEvent(QHideEvent *event) override; virtual void hideEvent(QHideEvent *event) override;
virtual void showEvent(QShowEvent *event) override; virtual void showEvent(QShowEvent *event) override;
virtual bool eventFilter(QObject *watched, QEvent *event) override;
public: public:
using Super = QWidget; using Super = QWidget;

View File

@@ -66,6 +66,12 @@ struct FloatingDragPreviewPrivate
DockManager->dockAreaOverlay()->hideOverlay(); DockManager->dockAreaOverlay()->hideOverlay();
_this->close(); _this->close();
} }
/**
* Creates the real floating widget in case the mouse is released outside
* outside of any drop area
*/
void createFloatingWidget();
}; };
// struct LedArrayPanelPrivate // struct LedArrayPanelPrivate
@@ -150,7 +156,7 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &GlobalPos)
// would be removed and inserted at the same position // would be removed and inserted at the same position
if (VisibleDockAreas <= 1) if (VisibleDockAreas <= 1)
{ {
ContainerOverlay->hide(); ContainerOverlay->hideOverlay();
} }
if (DockArea == ContentSourceArea && InvalidDockWidgetArea == ContainerDropArea) if (DockArea == ContentSourceArea && InvalidDockWidgetArea == ContainerDropArea)
@@ -173,6 +179,40 @@ FloatingDragPreviewPrivate::FloatingDragPreviewPrivate(CFloatingDragPreview *_pu
} }
//============================================================================
void FloatingDragPreviewPrivate::createFloatingWidget()
{
CDockWidget* DockWidget = qobject_cast<CDockWidget*>(Content);
CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(Content);
CFloatingDockContainer* FloatingWidget = nullptr;
if (DockWidget && DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable))
{
FloatingWidget = new CFloatingDockContainer(DockWidget);
}
else if (DockArea && DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
{
FloatingWidget = new CFloatingDockContainer(DockArea);
}
if (FloatingWidget)
{
FloatingWidget->setGeometry(_this->geometry());
FloatingWidget->show();
if (!CDockManager::configFlags().testFlag(CDockManager::DragPreviewHasWindowFrame))
{
QApplication::processEvents();
int FrameHeight = FloatingWidget->frameGeometry().height() - FloatingWidget->geometry().height();
QRect FixedGeometry = _this->geometry();
FixedGeometry.adjust(0, FrameHeight, 0, 0);
FloatingWidget->setGeometry(FixedGeometry);
}
}
}
//============================================================================ //============================================================================
CFloatingDragPreview::CFloatingDragPreview(QWidget* Content, QWidget* parent) : CFloatingDragPreview::CFloatingDragPreview(QWidget* Content, QWidget* parent) :
QWidget(parent), QWidget(parent),
@@ -288,46 +328,31 @@ void CFloatingDragPreview::finishDragging()
ADS_PRINT("CFloatingDragPreview::finishDragging"); ADS_PRINT("CFloatingDragPreview::finishDragging");
auto DockDropArea = d->DockManager->dockAreaOverlay()->visibleDropAreaUnderCursor(); auto DockDropArea = d->DockManager->dockAreaOverlay()->visibleDropAreaUnderCursor();
auto ContainerDropArea = d->DockManager->containerOverlay()->visibleDropAreaUnderCursor(); auto ContainerDropArea = d->DockManager->containerOverlay()->visibleDropAreaUnderCursor();
if (d->DropContainer && (DockDropArea != InvalidDockWidgetArea)) if (!d->DropContainer)
{
d->createFloatingWidget();
}
else if (DockDropArea != InvalidDockWidgetArea)
{ {
d->DropContainer->dropWidget(d->Content, DockDropArea, d->DropContainer->dockAreaAt(QCursor::pos())); d->DropContainer->dropWidget(d->Content, DockDropArea, d->DropContainer->dockAreaAt(QCursor::pos()));
} }
else if (d->DropContainer && (ContainerDropArea != InvalidDockWidgetArea)) else if (ContainerDropArea != InvalidDockWidgetArea)
{ {
d->DropContainer->dropWidget(d->Content, ContainerDropArea, nullptr); // If there is only one single dock area, and we drop into the center
} // then we tabify the dropped widget into the only visible dock area
else if (d->DropContainer->visibleDockAreaCount() <= 1 && CenterDockWidgetArea == ContainerDropArea)
{
CDockWidget* DockWidget = qobject_cast<CDockWidget*>(d->Content);
CFloatingDockContainer* FloatingWidget = nullptr;
if (DockWidget && DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable))
{ {
FloatingWidget = new CFloatingDockContainer(DockWidget); d->DropContainer->dropWidget(d->Content, ContainerDropArea, d->DropContainer->dockAreaAt(QCursor::pos()));
} }
else else
{ {
CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(d->Content); d->DropContainer->dropWidget(d->Content, ContainerDropArea, nullptr);
if (DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
{
FloatingWidget = new CFloatingDockContainer(DockArea);
}
}
if (FloatingWidget)
{
FloatingWidget->setGeometry(this->geometry());
FloatingWidget->show();
if (!CDockManager::configFlags().testFlag(CDockManager::DragPreviewHasWindowFrame))
{
QApplication::processEvents();
int FrameHeight = FloatingWidget->frameGeometry().height() - FloatingWidget->geometry().height();
QRect FixedGeometry = this->geometry();
FixedGeometry.adjust(0, FrameHeight, 0, 0);
FloatingWidget->setGeometry(FixedGeometry);
}
} }
} }
else
{
d->createFloatingWidget();
}
this->close(); this->close();
d->DockManager->containerOverlay()->hideOverlay(); d->DockManager->containerOverlay()->hideOverlay();

View File

@@ -66,7 +66,7 @@ namespace ads
{ {
enum eStateFileVersion enum eStateFileVersion
{ {
InitialVerison = 0, InitialVersion = 0,
Version1 = 1, Version1 = 1,
CurrentVersion = Version1 CurrentVersion = Version1
}; };