Compare commits

..

49 Commits

Author SHA1 Message Date
Uwe Kindler
e857421fdf Added all build* subfolders to .gitignore 2024-10-28 15:41:46 +01:00
Uwe Kindler
8dcdc8fad2 Improved autohidedragndrop example to check, if it also works when dragging with multiple auto hide tabs 2024-10-28 15:40:32 +01:00
Uwe Kindler
f964ce2c68 Refactored, fixed and improved drag hover functionality 2024-10-28 15:39:29 +01:00
Uwe Kindler
eb9b439d11 Added support for setting config parameters to CDockManager 2024-10-28 15:30:29 +01:00
TheBoje
a13ed7e4d6 Add AutoHideDragNDrop example 2024-10-22 22:36:53 +02:00
TheBoje
8cfa5c8e0e Fix formatting#2 (#663) 2024-10-04 22:27:15 +02:00
TheBoje
2878559ee6 Fix formatting (#663) 2024-10-04 22:23:40 +02:00
TheBoje
6ff39bccf8 Add open auto-hide dock on hover from drag and drop (#663) 2024-10-04 22:17:42 +02:00
gavininfinity
952131a1e9 Make startDragging public (#658) 2024-08-19 07:37:51 +02:00
Uwe Kindler
5edbcc1970 Fixed issue #654 - Wheel event on DockAreaTabBar 2024-07-25 08:42:30 +02:00
Uwe Kindler
04f6d9168e Fixed #642 - The floating window can not back to normal size after maximizing it 2024-07-08 14:32:33 +02:00
Uwe Kindler
cea1327dac Fixed #653 - DisablingTabTextEliding not letting DockAreaDynamicTabsMenuButtonVisibility to function and program crashes 2024-07-08 12:15:00 +02:00
Uwe Kindler
1c41cbff82 Fixed issue #641 - Unexpected behaviour with tab drag on scrollable tab bar 2024-07-08 10:43:02 +02:00
invisibleGG
06e8451fc0 Update DockAreaTabBar.cpp (#640)
This fix seems to have introduced a regression when _this is deleted before the lambda slot occurred, for example deleting the DockManager (and consequently _this) immediately after the execution of updateTabs function (we encountered this problem in linux)
2024-06-03 08:29:59 +02:00
Uwe Kindler
3ff6918b1f Added configflags example to test use of CDockManager config flags 2024-05-21 08:37:35 +02:00
Uwe Kindler
ac3af4c6cd Merge branch 'master' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System 2024-05-08 14:44:44 +02:00
Uwe Kindler
41bb861417 Fixed problem in AutoHideSideBar that prevented the dock container, that contained a vertical sidebar with many tabs, from shrinking vertically 2024-05-08 14:43:53 +02:00
Stefan Gerlach
6e63418798 Fix "extra ;" warning (#624) 2024-04-08 11:40:06 +02:00
Nicolas Elie
65781b7cac Include GNUInstallDirs for CMAKE_INSTALL_* vars to be defined (#621) 2024-04-03 23:49:37 +02:00
Nicolas Elie
d7e6c613c6 Update PyQt bindings to 4.3.0 (#622) 2024-04-03 23:49:08 +02:00
UnlimitedStack
8da0713bf0 Ensure that TabWidget was not deleted by using it as context object (#612)
Co-authored-by: Marcus Venturi <marcus.venturi@visu-it.de>
2024-03-16 01:23:42 +01:00
NeroBurner
08da925fde readme: small wording improvements (#610)
Removes an extra `the` in the Readme about the tested Linux versions
2024-02-28 20:45:32 +01:00
Dominik Nussbaumer
fb58c435ef Fix ODR violations when using CMake unity builds. (#609) 2024-02-28 13:25:20 +01:00
Dominik Nussbaumer
6bf593ef4b fix forward declarations of QXmlStreamWriter (#608) 2024-02-27 17:34:42 +01:00
Uwe Kindler
6b3b7750cb Fixed #604 - AutoHide widgets disapears when last open DockWidget is closed 2024-02-12 08:18:33 +01:00
Uwe Kindler
541db8e214 Fixed wrong hiding/showing of dock area title bar buttons when DockAreaHideDisabledButtons flag is enabled 2024-02-12 08:11:56 +01:00
Uwe Kindler
644c828f00 Fixed crash caused by changes related to issue #594 - deletion of CFloatingWidget caused crash when loading a state from XML 2024-01-26 16:31:04 +01:00
Uwe Kindler
ed6636ae26 Added CDockManager::lockDockWidgetFeaturesGlobally functionality to globally "freeze" the current docking layout 2024-01-23 13:29:41 +01:00
Stefan Gerlach
1a543e946d Fix 'zero as null pointer constant' warning (#598) 2024-01-16 14:05:42 +01:00
Uwe Kindler
9bdefd6055 Fixed issue #597 - Crashes when the floating widget moves to the dock manager and then tries to drag it back 2024-01-16 14:03:53 +01:00
Uwe Kindler
8fd691968c Merge branch 'master' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System 2024-01-04 08:31:57 +01:00
Uwe Kindler
7abc698d09 Fixed #594 - Destruction of CDockWidget inside a CFloatingDockContainer 2024-01-04 08:31:18 +01:00
Uwe Kindler
5b23248fb8 Fixed debug output issues and improved debug output for CDockWidget destructor 2024-01-04 08:30:17 +01:00
Uwe Kindler
46a5cee9c9 Added .clang-format file 2024-01-02 09:11:36 +01:00
Benjamin Buch
6c2c9888be respect customized CMake install locations (#593) 2023-12-12 13:54:51 +01:00
Uwe Kindler
44ff9e9956 Fixed some compiler warnings on Ubuntu 22.04 2023-12-08 07:58:36 +01:00
tmartsum
f848df74c3 Improve safety in code (#588)
Delete areas later so that that they can be accessed by
(inherited) dock widgets in dtor. Add some QPointer to
prevent crashes.

Hence allow users to do more while dock widgets etc
are being destroyed.
2023-12-08 06:47:02 +01:00
tmartsum
6c98c29855 Update documentation regarding central widget (#589) 2023-12-07 10:00:30 +01:00
tmartsum
c34d479d5c Avoid dock manager double delete (crashes) (#587)
If a dockwidget has been manually deleted, the dockmanager
would delete it again when deleting the area in its dtor.
The 'optimal' solution would likely have been changing
CDockWidget::~CDockWidget to add
if (d->DockArea) d->DockArea->removeDockWidget(this);
(before delete d).
However, it is not trivial (for me) to conclude that such
a change would be safe on program shutdown.

Co-authored-by: Thorbjørn Lund Martsum <thorbjorn@luxion.com>
2023-12-06 15:12:48 +01:00
jporcher
a7a97e6978 Fix https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/585 (#586) 2023-12-05 14:44:31 +01:00
Uwe Kindler
ec018a4c70 Added documentation for new "ShowTabTextOnlyForActiveTab" config flag 2023-12-04 09:24:59 +01:00
Uwe Kindler
0fabebb0fe Merge branch 'master' of https://github.com/nitramr/Qt-Advanced-Docking-System into nitramr-master 2023-12-04 09:10:34 +01:00
Uwe Kindler
521e1fbe39 Updated default AutoHide config to use Minimize button 2023-12-04 09:10:02 +01:00
Uwe Kindler
5f2aeaef00 Updated gitignore 2023-12-04 09:09:37 +01:00
nitramr
818e568f4a new configuration of icon only tabs 2023-12-02 14:48:43 +01:00
tmartsum
5d6831d179 Fix DockWidget crach when area is a nullptr. (#582)
When requesting hide on a dockwidget that has been added
to a dockmanager, but isn't yet visible, there was a creash.
The crash has been fixed by moving the code to the existing
guard check for the area.

Co-authored-by: Thorbjørn Lund Martsum <thorbjorn@luxion.com>
2023-12-01 15:13:45 +01:00
Uwe Kindler
a2c94c16b5 Fixed bug in focus_highlighting.css stylesheet 2023-11-27 22:04:45 +01:00
Uwe Kindler
68f1084bf0 Added parentSplitter() fucntion to DockArea and removed dead code from DockContainerWidget 2023-11-27 21:48:14 +01:00
Uwe Kindler
761bfc50d6 Fixed #581 - FocusHighlighting is broken after detaching a dock widget 2023-11-24 13:54:19 +01:00
70 changed files with 1611 additions and 247 deletions

146
.clang-format Normal file
View File

@@ -0,0 +1,146 @@
---
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: None
AlignConsecutiveAssignments: None
AlignConsecutiveDeclarations: None
AlignEscapedNewlines: Right
AlignOperands: Align
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: InlineOnly
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: Inline
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: true
AfterClass: true
AfterControlStatement: Always
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
BeforeCatch: true
BeforeElse: true
BeforeLambdaBody: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: false
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: AfterColon
BreakStringLiterals: true
ColumnLimit: 82
CommentPragmas: '^(!.*|@c)'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
FixNamespaceComments: true
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^<windows(\.h)?>' # windows headers
Priority: -1
- Regex: '^<labbcan[[:alnum:]._/]+' # labbcan headers
Priority: 1
- Regex: '^<diag[[:alnum:]._/]+' # usl headers
Priority: 1
- Regex: '^<usl[[:alnum:]._/]+' # usl headers
Priority: 1
- Regex: '^<qt5compat[[:alnum:]._/]+' # qtlabb headers
Priority: 2
- Regex: '^<qtcoreaddons[[:alnum:]._/]+' # qtlabb headers
Priority: 2
- Regex: '^<qtlabb[[:alnum:]._/]+' # qtlabb headers
Priority: 2
- Regex: '<Q[[:alnum:].]+>' # Qt headers
Priority: 3
- Regex: '^<sila_cpp[[:alnum:]._/]+' # sila_cpp headers
Priority: 4
- Regex: '<[[:alnum:]._/]+\.h>' # other headers
Priority: 5
- Regex: '<[[:alnum:]._/]+>' # system headers
Priority: 6
- Regex: '.*'
Priority: 7
IncludeIsMainRegex: '(_p)?$'
IndentCaseBlocks: false
IndentCaseLabels: false
IndentPPDirectives: AfterHash
IndentWidth: 4
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
PenaltyBreakAssignment: 20
PenaltyBreakBeforeFirstCallParameter: 15
PenaltyBreakComment: 10
PenaltyBreakFirstLessLess: 5
# PenaltyBreakOpenParenthesis: 30
PenaltyBreakString: 150
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 100
PenaltyIndentedWhitespace: 0
PenaltyReturnTypeOnItsOwnLine: 150
PointerAlignment: Left
ReflowComments: true
SortIncludes: CaseSensitive
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: Never
SpacesInCStyleCastParentheses: false
SpacesInConditionalStatement: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: c++17
StatementMacros: [ 'Q_UNUSED', 'PIMPL_D', 'PIMPL_Q', 'OD_ENTRY', 'OD_ENTRY_PROCIMG' ]
TabWidth: 4
UseTab: Never

5
.gitignore vendored
View File

@@ -1,4 +1,4 @@
*.pro.user
*.pro.user*
/build
*.o
*.dylib
@@ -7,6 +7,9 @@ qrc_*
moc_*
ui_*
Makefile
*.dll
*.a
build*
# IDEs
.idea

View File

@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.5)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
if (POLICY CMP0091)
cmake_policy(SET CMP0091 NEW)
endif (POLICY CMP0091)

View File

@@ -368,7 +368,7 @@ The application can be compiled for macOS. A user reported, that the library wor
[![Build Status](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System.svg?branch=master)](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System)
[![Build status](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/workflows/linux-builds/badge.svg)](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/actions?query=workflow%3Alinux-builds)
Unfortunately, there is no such thing as a Linux operating system. Linux is a heterogeneous environment with a variety of different distributions. So it is not possible to support "Linux" like this is possible for Windows. It is only possible to support and test a small subset of Linux distributions. The library can be compiled for and has been developed and tested with the some Linux distributions. Depending on the used window manager or compositor, dock widgets
Unfortunately, there is no such thing as a Linux operating system. Linux is a heterogeneous environment with a variety of different distributions. So it is not possible to support "Linux" like it is possible for Windows. It is only possible to support and test a small subset of Linux distributions. The library can be compiled for and has been developed and tested with some Linux distributions. Depending on the used window manager or compositor, dock widgets
with native title bars are supported or not. If native title bars are not supported,
the library switches to `QWidget` based title bars.

View File

@@ -592,19 +592,29 @@ void MainWindowPrivate::createActions()
ui.toolBar->addAction(ui.actionRestoreState);
ui.actionRestoreState->setIcon(svgIcon(":/adsdemo/images/restore.svg"));
SavePerspectiveAction = new QAction("Create Perspective", _this);
SavePerspectiveAction->setIcon(svgIcon(":/adsdemo/images/picture_in_picture.svg"));
_this->connect(SavePerspectiveAction, SIGNAL(triggered()), SLOT(savePerspective()));
ui.toolBar->addSeparator();
QAction* a = ui.toolBar->addAction("Lock Workspace");
a->setIcon(svgIcon(":/adsdemo/images/lock_outline.svg"));
a->setCheckable(true);
a->setChecked(false);
QObject::connect(a, &QAction::triggered, _this, &CMainWindow::lockWorkspace);
PerspectiveListAction = new QWidgetAction(_this);
PerspectiveComboBox = new QComboBox(_this);
PerspectiveComboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
PerspectiveComboBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
PerspectiveComboBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
PerspectiveListAction->setDefaultWidget(PerspectiveComboBox);
ui.toolBar->addSeparator();
ui.toolBar->addAction(PerspectiveListAction);
a = SavePerspectiveAction = ui.toolBar->addAction("Create Perspective");
a->setIcon(svgIcon(":/adsdemo/images/picture_in_picture.svg"));
QObject::connect(a, &QAction::triggered, _this, &CMainWindow::savePerspective);
ui.toolBar->addAction(SavePerspectiveAction);
QAction* a = ui.toolBar->addAction("Create Floating Editor");
ui.toolBar->addSeparator();
a = ui.toolBar->addAction("Create Floating Editor");
a->setProperty("Floating", true);
a->setToolTip("Creates floating dynamic dockable editor windows that are deleted on close");
a->setIcon(svgIcon(":/adsdemo/images/note_add.svg"));
@@ -626,6 +636,7 @@ void MainWindowPrivate::createActions()
_this->connect(a, SIGNAL(triggered()), SLOT(createEditor()));
ui.menuTests->addAction(a);
ui.toolBar->addSeparator();
a = ui.toolBar->addAction("Create Floating Table");
a->setToolTip("Creates floating dynamic dockable table with millions of entries");
a->setIcon(svgIcon(":/adsdemo/images/grid_on.svg"));
@@ -1030,3 +1041,17 @@ void CMainWindow::createImageViewer()
}
}
//============================================================================
void CMainWindow::lockWorkspace(bool Value)
{
if (Value)
{
d->DockManager->lockDockWidgetFeaturesGlobally();
}
else
{
d->DockManager->lockDockWidgetFeaturesGlobally(ads::CDockWidget::NoDockWidgetFeatures);
}
}

View File

@@ -68,6 +68,7 @@ private slots:
void toggleDockWidgetWindowTitle();
void applyVsStyle();
void createImageViewer();
void lockWorkspace(bool Value);
};
#endif // MAINWINDOW_H

View File

@@ -36,5 +36,8 @@
<file>images/panorama.svg</file>
<file>images/ads_icon2.svg</file>
<file>images/font_download.svg</file>
<file>images/lock_outline.svg</file>
<file>images/lock.svg</file>
<file>images/lock_open.svg</file>
</qresource>
</RCC>

6
demo/images/lock.svg Normal file
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>lock 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="M853.33,426.67v426.66c0,46.93 -38.4,85.34 -85.33,85.34h-512c-46.93,0 -85.33,-38.41 -85.33,-85.34v-426.66c0,-46.93 38.4,-85.34 85.33,-85.34h42.67v-85.33c0,-117.76 95.57,-213.33 213.33,-213.33c117.76,0 213.33,95.57 213.33,213.33v85.33h42.67c46.93,0 85.33,38.41 85.33,85.34zM644.27,256c0,-72.96 -59.31,-132.27 -132.27,-132.27c-72.96,0 -132.27,59.31 -132.27,132.27v85.33h264.54zM597.33,640c0,-46.93 -38.4,-85.33 -85.33,-85.33c-46.93,0 -85.33,38.4 -85.33,85.33c0,46.93 38.4,85.33 85.33,85.33c46.93,0 85.33,-38.4 85.33,-85.33z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 932 B

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>lock_open 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="M853.33,426.67v426.66c0,46.93 -38.4,85.34 -85.33,85.34h-512c-46.93,0 -85.33,-38.41 -85.33,-85.34v-426.66c0,-46.93 38.4,-85.34 85.33,-85.34h388.27v-85.33c0,-72.96 -59.31,-132.27 -132.27,-132.27c-72.96,0 -132.27,59.31 -132.27,132.27h-81.06c0,-117.76 95.57,-213.33 213.33,-213.33c117.76,0 213.33,95.57 213.33,213.33v85.33h42.67c46.93,0 85.33,38.41 85.33,85.34zM768,426.67h-512v426.66h512zM426.67,640c0,-46.93 38.4,-85.33 85.33,-85.33c46.93,0 85.33,38.4 85.33,85.33c0,46.93 -38.4,85.33 -85.33,85.33c-46.93,0 -85.33,-38.4 -85.33,-85.33z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 948 B

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>lock_outline 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="M853.33,426.67v426.66c0,46.93 -38.4,85.34 -85.33,85.34h-512c-46.93,0 -85.33,-38.41 -85.33,-85.34v-426.66c0,-46.93 38.4,-85.34 85.33,-85.34h42.67v-85.33c0,-117.76 95.57,-213.33 213.33,-213.33c117.76,0 213.33,95.57 213.33,213.33v85.33h42.67c46.93,0 85.33,38.41 85.33,85.34zM768,426.67h-512v426.66h512zM379.73,341.33h264.54v-85.33c0,-72.96 -59.31,-132.27 -132.27,-132.27c-72.96,0 -132.27,59.31 -132.27,132.27zM426.67,640c0,-46.93 38.4,-85.33 85.33,-85.33c46.93,0 85.33,38.4 85.33,85.33c0,46.93 -38.4,85.33 -85.33,85.33c-46.93,0 -85.33,-38.4 -85.33,-85.33z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 972 B

View File

@@ -12,10 +12,10 @@ styles as much as possible.
## Features
### Docking everywhere - no central widget
### Docking everywhere - with or without a central widget
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
The Advanced Docking System works with or without a central widget.
You can dock on every border of the main window or you can dock into each dock area - so you are
free to dock almost everywhere.
![Dropping widgets](https://raw.githubusercontent.com/githubuser0xFFFF/Qt-Advanced-Docking-System/master/doc/preview-dragndrop.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -28,6 +28,7 @@
- [`FloatingContainerForceQWidgetTitleBar` (Linux only)](#floatingcontainerforceqwidgettitlebar-linux-only)
- [`MiddleMouseButtonClosesTab`](#middlemousebuttonclosestab)
- [`DisableTabTextEliding`](#disabletabtexteliding)
- [`ShowTabTextOnlyForActiveTab`](#showtabtextonlyforactivetab)
- [Auto-Hide Configuration Flags](#auto-hide-configuration-flags)
- [Auto Hide Dock Widgets](#auto-hide-dock-widgets)
- [Pinning Auto-Hide Widgets to a certain border](#pinning-auto-hide-widgets-to-a-certain-border)
@@ -48,6 +49,7 @@
- [`AutoHideCloseButtonCollapsesDock`](#autohideclosebuttoncollapsesdock)
- [`AutoHideHasCloseButton`](#autohidehasclosebutton)
- [`AutoHideHasMinimizeButton`](#autohidehasminimizebutton)
- [`AutoHideOpenOnDragHover`](#autohideopenondraghover)
- [DockWidget Feature Flags](#dockwidget-feature-flags)
- [`DockWidgetClosable`](#dockwidgetclosable)
- [`DockWidgetMovable`](#dockwidgetmovable)
@@ -149,7 +151,7 @@ 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` -
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.
@@ -180,7 +182,7 @@ constant, that means, if enabled, the tabs need more space.
### `DragPreviewIsDynamic`
If non-opaque undocking is enabled, this flag defines the behavior of the drag
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
@@ -196,7 +198,7 @@ CDockManager::setConfigFlag(CDockManager::DragPreviewHasWindowFrame, false);
### `DragPreviewShowsContentPixmap`
If non-opaque undocking is enabled, the created drag preview window shows a
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).
@@ -209,7 +211,7 @@ like window without any content.
### `DragPreviewHasWindowFrame`
If non-opaque undocking is enabled, then this flag configures if the drag
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.
@@ -302,8 +304,9 @@ 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.
Unless a central widget explicitly has been set with setCentralWidget, the
Advanced Docking System is without a static central widget and it wouldn't know
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.
@@ -376,7 +379,7 @@ ads--CDockAreaWidget[focused="true"] ads--CDockAreaTitleBar
If you have a content widget that does not support focussing for some reason
(like `QVTKOpenGLStereoWidget` from the [VTK library](https://github.com/Kitware/VTK)),
then you can manually switch the focus by reacting on mouse events. The
then you can manually switch the focus by reacting on mouse events. The
following code shows, how to install en event filter on the `QVTKOpenGLStereoWidget`
to properly switch the focus on `QEvent::MouseButtonPress`:
@@ -420,7 +423,7 @@ bool CMainWindow::eventFilter(QObject *watched, QEvent *event)
### `EqualSplitOnInsertion`
This flag configures how the space is distributed if a new dock widget is
inserted into an existing dock area. The flag is disabled by default. If 3
inserted into an existing dock area. The flag is disabled by default. If 3
dock widgets are inserted with the following code
```c++
@@ -431,7 +434,7 @@ then this is the result, if the flag is disabled:
![EqualSplitOnInsertion false](cfg_flag_EqualSplitOnInsertion_false.png)
If the flag is enabled, then the space is equally distributed to all widgets
If the flag is enabled, then the space is equally distributed to all widgets
in a splitter:
![EqualSplitOnInsertion true](cfg_flag_EqualSplitOnInsertion_true.png)
@@ -486,13 +489,20 @@ many tabs as possible even if there is not much space:
![DisableTabTextEliding false](cfg_flag_DisableTabTextEliding_false.png)
### `ShowTabTextOnlyForActiveTab`
Set this flag (default = false) to show label texts in dock area tabs only
for active tabs. Inactive tabs only show their icon:
![MShowTabTextOnlyForActiveTab true](cfg_flag_ShowTabTextOnlyForActiveTab_true.png)
## Auto-Hide Configuration Flags
### Auto Hide Dock Widgets
The Advanced Docking System supports "Auto-Hide" functionality for **all**
dock containers. The "Auto Hide" feature allows to display more information
using less screen space by hiding or showing windows pinned to one of the
using less screen space by hiding or showing windows pinned to one of the
four dock container borders.
Enabling this feature adds a button with a pin icon to each dock area.
@@ -554,7 +564,7 @@ That means, you can drag them to a different border or sidebar:
### Auto-Hide Tab Sorting
You can drag Auto-Hide tabs to a new position in the current sidebar
You can drag Auto-Hide tabs to a new position in the current sidebar
to sort them:
![Auo-Hide sort tabs](AutoHide_Sort_Tabs.gif)
@@ -623,7 +633,7 @@ the other Auto-Hide flags will be evaluated.
### `DockAreaHasAutoHideButton`
If this flag is set (default), then each dock area has a pin button in the title
If this flag is set (default), then each dock area has a pin button in the title
bar to toggle Auto-Hide state.
![DockAreaHasAutoHideButton true](cfg_flag_DockAreaHasAutoHideButton.png)
@@ -667,7 +677,7 @@ works if this feature is enabled.
Some users don't understand the distinction between closing an auto hide dock and
collapsing an auto hide dock. This may lead to situations where they press the
close button (losing the side tab widget) instead of simply clicking outside
the auto hide dock (collapsing the dock).
the auto hide dock (collapsing the dock).
![AutoHideCloseButtonCollapsesDock false](cfg_flag_AutoHideCloseButtonCollapsesDock_false.gif)
@@ -695,6 +705,15 @@ If this flag is set (disabled by default), then each auto hide widget has a mini
![AutoHideHasMinimizeButton](cfg_flag_AutoHideHasMinimizeButton.png)
### `AutoHideOpenOnDragHover`
If this flag is set (disabled by default), then holding a dragging cursor hover an auto-hide collapsed dock's tab will open said dock:
![AutoHideOpenOnDragHover](cfg_flag_AutoHideOpenOnDragHover.gif)
Said dock must be set to accept drops to hide when cursor leaves its scope. See `AutoHideDragNDropExample` for more details.
## DockWidget Feature Flags
### `DockWidgetClosable`

View File

@@ -6,5 +6,6 @@ add_subdirectory(sidebar)
add_subdirectory(deleteonclose)
add_subdirectory(centralwidget)
add_subdirectory(autohide)
add_subdirectory(autohidedragndrop)
add_subdirectory(emptydockarea)
add_subdirectory(dockindock)
add_subdirectory(dockindock)

View File

@@ -0,0 +1,29 @@
cmake_minimum_required(VERSION 3.5)
project(ads_example_autohide_dragndrop VERSION ${VERSION_SHORT})
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(AutoHideDragNDropExample WIN32
main.cpp
mainwindow.cpp
mainwindow.ui
droppableitem.cpp
)
target_include_directories(AutoHideDragNDropExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
target_link_libraries(AutoHideDragNDropExample PRIVATE qt${QT_VERSION_MAJOR}advanceddocking)
target_link_libraries(AutoHideDragNDropExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)
set_target_properties(AutoHideDragNDropExample PROPERTIES
AUTOMOC ON
AUTORCC ON
AUTOUIC ON
CXX_STANDARD 14
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS OFF
VERSION ${VERSION_SHORT}
EXPORT_NAME "Qt Advanced Docking System Auto Hide With Drag N Drop Example"
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/bin"
)

View File

@@ -0,0 +1,36 @@
ADS_OUT_ROOT = $${OUT_PWD}/../..
QT += core gui widgets
TARGET = AutoHideDragNDropExample
DESTDIR = $${ADS_OUT_ROOT}/lib
TEMPLATE = app
CONFIG += c++14
CONFIG += debug_and_release
adsBuildStatic {
DEFINES += ADS_STATIC
}
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \
main.cpp \
mainwindow.cpp \
droppableitem.cpp
HEADERS += \
mainwindow.h \
droppableitem.h
FORMS += \
mainwindow.ui
LIBS += -L$${ADS_OUT_ROOT}/lib
include(../../ads.pri)
INCLUDEPATH += ../../src
DEPENDPATH += ../../src

View File

@@ -0,0 +1,38 @@
#include "droppableitem.h"
#include <QDragEnterEvent>
#include <QDragLeaveEvent>
#include <QDropEvent>
#include <QMimeData>
#include <qsizepolicy.h>
DroppableItem::DroppableItem(const QString& text, QWidget* parent)
: QPushButton(text, parent)
{
setAcceptDrops(true);
setSizePolicy(QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Expanding);
}
void DroppableItem::dragEnterEvent(QDragEnterEvent* event)
{
if (event->mimeData()->hasText())
{
event->acceptProposedAction();
setCursor(Qt::DragMoveCursor);
}
}
void DroppableItem::dragLeaveEvent(QDragLeaveEvent* event)
{
Q_UNUSED(event);
unsetCursor();
}
void DroppableItem::dropEvent(QDropEvent* event)
{
if (event->mimeData()->hasText())
{
event->acceptProposedAction();
setText(event->mimeData()->text());
}
}

View File

@@ -0,0 +1,19 @@
#include <QObject>
#include <QPushButton>
class QDragEnterEvent;
class QDragLeaveEvent;
class QDropEvent;
class DroppableItem : public QPushButton
{
Q_OBJECT;
public:
DroppableItem(const QString& text = QString(), QWidget* parent = nullptr);
protected:
void dragEnterEvent(QDragEnterEvent* event) override;
void dragLeaveEvent(QDragLeaveEvent* event) override;
void dropEvent(QDropEvent* event) override;
};

View File

@@ -0,0 +1,10 @@
#include <mainwindow.h>
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
CMainWindow w;
w.show();
return a.exec();
}

View File

@@ -0,0 +1,84 @@
import os
import sys
from PyQt5 import uic
from PyQt5.QtCore import Qt, QTimer, QDir, QSignalBlocker
from PyQt5.QtGui import QCloseEvent, QIcon
from PyQt5.QtWidgets import (QApplication, QLabel, QCalendarWidget, QFrame, QTreeView,
QTableWidget, QFileSystemModel, QPlainTextEdit, QToolBar,
QWidgetAction, QComboBox, QAction, QSizePolicy, QInputDialog)
import PyQtAds as QtAds
UI_FILE = os.path.join(os.path.dirname(__file__), 'mainwindow.ui')
MainWindowUI, MainWindowBase = uic.loadUiType(UI_FILE)
class MainWindow(MainWindowUI, MainWindowBase):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.OpaqueSplitterResize, True)
QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.XmlCompressionEnabled, False)
QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.FocusHighlighting, True)
QtAds.CDockManager.setAutoHideConfigFlag(QtAds.CDockManager.AutoHideOpenOnDragHover, True);
self.dock_manager = QtAds.CDockManager(self)
# Set central widget
text_edit = QPlainTextEdit()
text_edit.setPlaceholderText("This is the central editor. Enter your text here.")
central_dock_widget = QtAds.CDockWidget("CentralWidget")
central_dock_widget.setWidget(text_edit)
central_dock_area = self.dock_manager.setCentralWidget(central_dock_widget)
central_dock_area.setAllowedAreas(QtAds.DockWidgetArea.OuterDockAreas)
droppable_item = DroppableItem("Drop text here.")
drop_dock_widget = QtAds.CDockWidget("Tab")
drop_dock_widget.setWidget(droppable_item)
drop_dock_widget.setMinimumSizeHintMode(QtAds.CDockWidget.MinimumSizeHintFromDockWidget)
drop_dock_widget.setMinimumSize(200, 150)
drop_dock_widget.setAcceptDrops(True)
drop_area = self.dock_manager.addDockWidget(QtAds.DockWidgetArea.LeftDockWidgetArea, drop_dock_widget)
drop_area.setAcceptDrops(True)
self.menuView.addAction(drop_dock_widget.toggleViewAction())
self.create_perspective_ui()
def create_perspective_ui(self):
save_perspective_action = QAction("Create Perspective", self)
save_perspective_action.triggered.connect(self.save_perspective)
perspective_list_action = QWidgetAction(self)
self.perspective_combobox = QComboBox(self)
self.perspective_combobox.setSizeAdjustPolicy(QComboBox.AdjustToContents)
self.perspective_combobox.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
self.perspective_combobox.activated[str].connect(self.dock_manager.openPerspective)
perspective_list_action.setDefaultWidget(self.perspective_combobox)
self.toolBar.addSeparator()
self.toolBar.addAction(perspective_list_action)
self.toolBar.addAction(save_perspective_action)
def save_perspective(self):
perspective_name, ok = QInputDialog.getText(self, "Save Perspective", "Enter Unique name:")
if not ok or not perspective_name:
return
self.dock_manager.addPerspective(perspective_name)
blocker = QSignalBlocker(self.perspective_combobox)
self.perspective_combobox.clear()
self.perspective_combobox.addItems(self.dock_manager.perspectiveNames())
self.perspective_combobox.setCurrentText(perspective_name)
def closeEvent(self, event: QCloseEvent):
self.dock_manager.deleteLater()
super().closeEvent(event)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MainWindow()
w.show()
app.exec_()

View File

@@ -0,0 +1,131 @@
#include "mainwindow.h"
#include "droppableitem.h"
#include "ui_mainwindow.h"
#include <QWidgetAction>
#include <QFileSystemModel>
#include <QTableWidget>
#include <QHBoxLayout>
#include <QInputDialog>
#include <QFileDialog>
#include <QSettings>
#include <QPlainTextEdit>
#include <QToolBar>
#include "AutoHideDockContainer.h"
#include "DockAreaWidget.h"
#include "DockAreaTitleBar.h"
using namespace ads;
CMainWindow::CMainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::CMainWindow)
{
ui->setupUi(this);
CDockManager::setConfigFlag(CDockManager::OpaqueSplitterResize, true);
CDockManager::setConfigFlag(CDockManager::XmlCompressionEnabled, false);
CDockManager::setConfigFlag(CDockManager::FocusHighlighting, true);
CDockManager::setAutoHideConfigFlags(CDockManager::DefaultAutoHideConfig);
CDockManager::setAutoHideConfigFlag(CDockManager::AutoHideOpenOnDragHover, true);
CDockManager::setConfigParam(CDockManager::AutoHideOpenOnDragHoverDelay_ms, 500);
DockManager = new CDockManager(this);
// Set central widget
QPlainTextEdit* w = new QPlainTextEdit();
w->setPlaceholderText("This is the central editor. Enter your text here.");
CDockWidget* CentralDockWidget = new CDockWidget("CentralWidget");
CentralDockWidget->setWidget(w);
auto* CentralDockArea = DockManager->setCentralWidget(CentralDockWidget);
CentralDockArea->setAllowedAreas(DockWidgetArea::OuterDockAreas);
{
DroppableItem* droppableItem = new DroppableItem("Drop text here.");
CDockWidget* dropDockWidget = new CDockWidget("Tab 1");
dropDockWidget->setWidget(droppableItem);
dropDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
dropDockWidget->setMinimumSize(200,150);
dropDockWidget->setAcceptDrops(true);
const auto autoHideContainer = DockManager->addAutoHideDockWidget(SideBarLocation::SideBarLeft, dropDockWidget);
autoHideContainer->setSize(480);
autoHideContainer->setAcceptDrops(true);
ui->menuView->addAction(dropDockWidget->toggleViewAction());
}
{
DroppableItem* droppableItem = new DroppableItem("Drop text here.");
CDockWidget* dropDockWidget = new CDockWidget("Tab 2");
dropDockWidget->setWidget(droppableItem);
dropDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
dropDockWidget->setMinimumSize(200,150);
dropDockWidget->setAcceptDrops(true);
const auto autoHideContainer = DockManager->addAutoHideDockWidget(SideBarLocation::SideBarRight, dropDockWidget);
autoHideContainer->setSize(480);
autoHideContainer->setAcceptDrops(true);
ui->menuView->addAction(dropDockWidget->toggleViewAction());
}
QTableWidget* propertiesTable = new QTableWidget();
propertiesTable->setColumnCount(3);
propertiesTable->setRowCount(10);
CDockWidget* PropertiesDockWidget = new CDockWidget("Properties");
PropertiesDockWidget->setWidget(propertiesTable);
PropertiesDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
PropertiesDockWidget->resize(250, 150);
PropertiesDockWidget->setMinimumSize(200,150);
DockManager->addDockWidget(DockWidgetArea::RightDockWidgetArea, PropertiesDockWidget, CentralDockArea);
ui->menuView->addAction(PropertiesDockWidget->toggleViewAction());
createPerspectiveUi();
}
CMainWindow::~CMainWindow()
{
delete ui;
}
void CMainWindow::createPerspectiveUi()
{
SavePerspectiveAction = new QAction("Create Perspective", this);
connect(SavePerspectiveAction, SIGNAL(triggered()), SLOT(savePerspective()));
PerspectiveListAction = new QWidgetAction(this);
PerspectiveComboBox = new QComboBox(this);
PerspectiveComboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
PerspectiveComboBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
connect(PerspectiveComboBox, SIGNAL(currentTextChanged(const QString&)),
DockManager, SLOT(openPerspective(const QString&)));
PerspectiveListAction->setDefaultWidget(PerspectiveComboBox);
ui->toolBar->addSeparator();
ui->toolBar->addAction(PerspectiveListAction);
ui->toolBar->addAction(SavePerspectiveAction);
}
void CMainWindow::savePerspective()
{
QString PerspectiveName = QInputDialog::getText(this, "Save Perspective", "Enter unique name:");
if (PerspectiveName.isEmpty())
{
return;
}
DockManager->addPerspective(PerspectiveName);
QSignalBlocker Blocker(PerspectiveComboBox);
PerspectiveComboBox->clear();
PerspectiveComboBox->addItems(DockManager->perspectiveNames());
PerspectiveComboBox->setCurrentText(PerspectiveName);
}
//============================================================================
void CMainWindow::closeEvent(QCloseEvent* event)
{
// Delete dock manager here to delete all floating widgets. This ensures
// that all top level windows of the dock manager are properly closed
DockManager->deleteLater();
QMainWindow::closeEvent(event);
}

View File

@@ -0,0 +1,43 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QComboBox>
#include <QWidgetAction>
#include "DockManager.h"
#include "DockAreaWidget.h"
#include "DockWidget.h"
QT_BEGIN_NAMESPACE
namespace Ui { class CMainWindow; }
QT_END_NAMESPACE
class CMainWindow : public QMainWindow
{
Q_OBJECT
public:
CMainWindow(QWidget *parent = nullptr);
~CMainWindow();
protected:
virtual void closeEvent(QCloseEvent* event) override;
private:
QAction* SavePerspectiveAction = nullptr;
QWidgetAction* PerspectiveListAction = nullptr;
QComboBox* PerspectiveComboBox = nullptr;
Ui::CMainWindow *ui;
ads::CDockManager* DockManager;
ads::CDockAreaWidget* StatusDockArea;
ads::CDockWidget* TimelineDockWidget;
void createPerspectiveUi();
private slots:
void savePerspective();
};
#endif // MAINWINDOW_H

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CMainWindow</class>
<widget class="QMainWindow" name="CMainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1284</width>
<height>757</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget"/>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1284</width>
<height>21</height>
</rect>
</property>
<widget class="QMenu" name="menuView">
<property name="title">
<string>View</string>
</property>
</widget>
<addaction name="menuView"/>
</widget>
<widget class="QToolBar" name="toolBar">
<property name="windowTitle">
<string>toolBar</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,28 @@
cmake_minimum_required(VERSION 3.5)
project(ads_example_centralwidget VERSION ${VERSION_SHORT})
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(configFlagsExample WIN32
main.cpp
mainwindow.cpp
mainwindow.ui
)
target_include_directories(CentralWidgetExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
target_link_libraries(CentralWidgetExample PRIVATE qt${QT_VERSION_MAJOR}advanceddocking)
target_link_libraries(CentralWidgetExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)
set_target_properties(CentralWidgetExample PROPERTIES
AUTOMOC ON
AUTORCC ON
AUTOUIC ON
CXX_STANDARD 14
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS OFF
VERSION ${VERSION_SHORT}
EXPORT_NAME "Qt Advanced Docking System Central Widget Example"
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/bin"
)

View File

@@ -0,0 +1,34 @@
ADS_OUT_ROOT = $${OUT_PWD}/../..
QT += core gui widgets
TARGET = ConfigFlagsExample
DESTDIR = $${ADS_OUT_ROOT}/lib
TEMPLATE = app
CONFIG += c++14
CONFIG += debug_and_release
adsBuildStatic {
DEFINES += ADS_STATIC
}
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
LIBS += -L$${ADS_OUT_ROOT}/lib
include(../../ads.pri)
INCLUDEPATH += ../../src
DEPENDPATH += ../../src

View File

@@ -0,0 +1,10 @@
#include <mainwindow.h>
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
CMainWindow w;
w.show();
return a.exec();
}

View File

@@ -0,0 +1,65 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLabel>
#include <QToolBar>
#include "DockAreaWidget.h"
#include "DockAreaTitleBar.h"
using namespace ads;
CMainWindow::CMainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::CMainWindow)
{
ui->setupUi(this);
// Add the toolbar
auto toolbar_ = addToolBar("Top Toolbar");
// Create the dock manager
ads::CDockManager::setConfigFlags(ads::CDockManager::DefaultOpaqueConfig);
ads::CDockManager::setConfigFlag(ads::CDockManager::DockAreaHasCloseButton,
false);
ads::CDockManager::setConfigFlag(ads::CDockManager::DockAreaHasUndockButton,
false);
ads::CDockManager::setConfigFlag(
ads::CDockManager::DockAreaHasTabsMenuButton, false);
auto DockManager = new ads::CDockManager(this);
// Create a dockable widget
QLabel *l1 = new QLabel();
l1->setWordWrap(true);
l1->setAlignment(Qt::AlignTop | Qt::AlignLeft);
l1->setText("Docking widget 1");
ads::CDockWidget *dockWidget1 = new ads::CDockWidget("Dock 1");
dockWidget1->setWidget(l1);
DockManager->addDockWidget(ads::LeftDockWidgetArea, dockWidget1);
QLabel *l2 = new QLabel();
l2->setWordWrap(true);
l2->setAlignment(Qt::AlignTop | Qt::AlignLeft);
l2->setText("Docking widget 2");
ads::CDockWidget *dockWidget2 = new ads::CDockWidget("Dock 2");
dockWidget2->setWidget(l2);
DockManager->addDockWidget(ads::RightDockWidgetArea, dockWidget2);
// Add menu actions
ui->menuView->addAction(dockWidget1->toggleViewAction());
ui->menuView->addAction(dockWidget2->toggleViewAction());
toolbar_->addAction(dockWidget1->toggleViewAction());
toolbar_->addAction(dockWidget2->toggleViewAction());
}
CMainWindow::~CMainWindow()
{
delete ui;
}

View File

@@ -0,0 +1,27 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QComboBox>
#include <QWidgetAction>
#include "DockManager.h"
#include "DockAreaWidget.h"
#include "DockWidget.h"
QT_BEGIN_NAMESPACE
namespace Ui { class CMainWindow; }
QT_END_NAMESPACE
class CMainWindow : public QMainWindow
{
Q_OBJECT
public:
CMainWindow(QWidget *parent = nullptr);
~CMainWindow();
private:
Ui::CMainWindow *ui;
};
#endif // MAINWINDOW_H

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CMainWindow</class>
<widget class="QMainWindow" name="CMainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1284</width>
<height>757</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget"/>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1284</width>
<height>21</height>
</rect>
</property>
<widget class="QMenu" name="menuView">
<property name="title">
<string>View</string>
</property>
</widget>
<addaction name="menuView"/>
</widget>
<widget class="QToolBar" name="toolBar">
<property name="windowTitle">
<string>toolBar</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -1,5 +1,5 @@
#include <QApplication>
#include "../../examples/simple/MainWindow.h"
#include "mainframe.h"
int main(int argc, char *argv[])
{

View File

@@ -2,10 +2,12 @@ TEMPLATE = subdirs
SUBDIRS = \
autohide \
autohidedragndrop \
centralwidget \
simple \
hideshow \
sidebar \
deleteonclose \
emptydockarea \
dockindock
dockindock \
configflags

View File

@@ -12,10 +12,14 @@ class CTitleBarButton : QToolButton
%End
public:
CTitleBarButton(bool visible = true, QWidget* parent /TransferThis/ = Q_NULLPTR );
CTitleBarButton(bool ShowInTitleBar, bool HideWhenDisabled, TitleBarButton ButtonId,
QWidget* /TransferThis/ = Q_NULLPTR );
virtual void setVisible(bool);
void setShowInTitleBar(bool);
TitleBarButton buttonId() const;
ads::CDockAreaTitleBar* titleBar() const;
bool isInAutoHideArea() const;
protected:
bool event(QEvent *ev);
@@ -44,13 +48,15 @@ public:
ads::CDockAreaTabBar* tabBar() const;
ads::CTitleBarButton* button(ads::TitleBarButton which) const;
ads::CElidingLabel* autoHideTitleLabel() const;
ads::CDockAreaWidget* dockAreaWidget() const;
void updateDockWidgetActionsButtons();
virtual void setVisible(bool Visible);
void insertWidget(int index, QWidget *widget /Transfer/ );
int indexOf(QWidget *widget) const;
QString titleBarButtonToolTip(ads::TitleBarButton Button) const;
void setAreaFloating();
void showAutoHideControls(bool Show);
bool isAutoHide() const;
signals:
void tabBarClicked(int index);

View File

@@ -41,6 +41,7 @@ public:
ads::CDockManager* dockManager() const;
ads::CDockContainerWidget* dockContainer() const;
ads::CAutoHideDockContainer* autoHideDockContainer() const;
ads::CDockSplitter* parentSplitter() const;
bool isAutoHide() const;
void setAutoHideDockContainer(CAutoHideDockContainer*);
virtual QSize minimumSizeHint() const;

View File

@@ -20,13 +20,14 @@ class CDockContainerWidget : QFrame
protected:
virtual bool event(QEvent *e);
QSplitter* rootSplitter() const;
ads::CDockSplitter* rootSplitter() const;
ads::CAutoHideDockContainer* createAndSetupAutoHideContainer(ads::SideBarLocation area, ads::CDockWidget* DockWidget /Transfer/, int TabIndex = -1);
void createRootSplitter();
void dropFloatingWidget(ads::CFloatingDockContainer* FloatingWidget, const QPoint& TargetPos);
void dropWidget(QWidget* Widget, DockWidgetArea DropArea, CDockAreaWidget* TargetAreaWidget, int TabIndex = -1);
void addDockArea(ads::CDockAreaWidget* DockAreaWidget /Transfer/, ads::DockWidgetArea area = ads::CenterDockWidgetArea);
void removeDockArea(ads::CDockAreaWidget* area /TransferBack/);
/*QList<QPointer<ads::CDockAreaWidget>> removeAllDockAreas();*/
void saveState(QXmlStreamWriter& Stream) const;
bool restoreState(CDockingStateReader& Stream, bool Testing);
ads::CDockAreaWidget* lastAddedDockAreaWidget(ads::DockWidgetArea area) const;

View File

@@ -172,6 +172,8 @@ public:
FloatingContainerForceNativeTitleBar,
FloatingContainerForceQWidgetTitleBar,
MiddleMouseButtonClosesTab,
DisableTabTextEliding,
ShowTabTextOnlyForActiveTab,
DefaultDockAreaButtons,
DefaultBaseConfig,
DefaultOpaqueConfig,
@@ -188,6 +190,8 @@ public:
AutoHideSideBarsIconOnly,
AutoHideShowOnMouseOver,
AutoHideCloseButtonCollapsesDock,
AutoHideHasCloseButton,
AutoHideHasMinimizeButton,
DefaultAutoHideConfig,
};
typedef QFlags<ads::CDockManager::eAutoHideFlag> AutoHideFlags;
@@ -245,6 +249,12 @@ public:
void setSplitterSizes(ads::CDockAreaWidget *ContainedArea, const QList<int>& sizes);
static void setFloatingContainersTitle(const QString& Title);
static QString floatingContainersTitle();
void setDockWidgetToolBarStyle(Qt::ToolButtonStyle Style, ads::CDockWidget::eState State);
Qt::ToolButtonStyle dockWidgetToolBarStyle(ads::CDockWidget::eState State) const;
void setDockWidgetToolBarIconSize(const QSize& IconSize, ads::CDockWidget::eState State);
QSize dockWidgetToolBarIconSize(ads::CDockWidget::eState State) const;
ads::CDockWidget::DockWidgetFeatures globallyLockedDockWidgetFeatures() const;
void lockDockWidgetFeaturesGlobally(ads::CDockWidget::DockWidgetFeatures Features = ads::CDockWidget::GloballyLockableFeatures);
public slots:
void endLeavingMinimizedState();

View File

@@ -39,6 +39,7 @@ public:
DefaultDockWidgetFeatures,
AllDockWidgetFeatures,
DockWidgetAlwaysCloseAndDelete,
GloballyLockableFeatures,
NoDockWidgetFeatures
};
typedef QFlags<ads::CDockWidget::DockWidgetFeature> DockWidgetFeatures;
@@ -49,6 +50,12 @@ public:
StateDocked,
StateFloating
};
enum eToolBarStyleSource
{
ToolBarStyleFromDockManager,
ToolBarStyleFromDockWidget
};
enum eInsertMode
{
@@ -72,7 +79,7 @@ public:
};
CDockWidget(const QString &title, QWidget* parent /TransferThis/ = 0);
CDockWidget(const QString &title, QWidget* parent /TransferThis/ = Q_NULLPTR);
virtual ~CDockWidget();
virtual QSize minimumSizeHint() const;
void setWidget(QWidget* widget /Transfer/, ads::CDockWidget::eInsertMode InsertMode = AutoScrollArea);
@@ -82,6 +89,7 @@ public:
void setFeatures(ads::CDockWidget::DockWidgetFeatures features);
void setFeature(ads::CDockWidget::DockWidgetFeature flag, bool on);
ads::CDockWidget::DockWidgetFeatures features() const;
void notifyFeaturesChanged();
ads::CDockManager* dockManager() const;
ads::CDockContainerWidget* dockContainer() const;
ads::CFloatingDockContainer* floatingDockContainer() const;
@@ -95,6 +103,7 @@ public:
bool isInFloatingContainer() const;
bool isClosed() const;
QAction* toggleViewAction() const;
void setToggleViewAction(QAction* action);
void setToggleViewActionMode(ads::CDockWidget::eToggleViewActionMode Mode);
void setMinimumSizeHintMode(ads::CDockWidget::eMinimumSizeHintMode Mode);
ads::CDockWidget::eMinimumSizeHintMode minimumSizeHintMode() const;
@@ -104,6 +113,8 @@ public:
QToolBar* toolBar() const;
QToolBar* createDefaultToolBar();
void setToolBar(QToolBar* ToolBar /Transfer/ );
void setToolBarStyleSource(ads::CDockWidget::eToolBarStyleSource Source);
ads::CDockWidget::eToolBarStyleSource toolBarStyleSource() const;
void setToolBarStyle(Qt::ToolButtonStyle Style, ads::CDockWidget::eState State);
Qt::ToolButtonStyle toolBarStyle(ads::CDockWidget::eState State) const;
void setToolBarIconSize(const QSize& IconSize, ads::CDockWidget::eState State);

View File

@@ -17,8 +17,8 @@ protected:
virtual void mouseDoubleClickEvent( QMouseEvent *ev );
public:
CElidingLabel(QWidget* parent /TransferThis/ = 0, Qt::WindowFlags f = 0);
CElidingLabel(const QString& text, QWidget* parent /TransferThis/ = 0, Qt::WindowFlags f = 0);
CElidingLabel(QWidget* parent /TransferThis/ = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags ());
CElidingLabel(const QString& text, QWidget* parent /TransferThis/ = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags ());
virtual ~CElidingLabel();
Qt::TextElideMode elideMode() const;
void setElideMode(Qt::TextElideMode mode);

View File

@@ -44,6 +44,7 @@ protected:
void startDragging(const QPoint& DragStartMousePos, const QSize& Size,
QWidget* MouseEventHandler);
virtual void finishDragging();
void deleteContent();
void initFloatingGeometry(const QPoint& DragStartMousePos, const QSize& Size);
void moveFloating();
bool restoreState(ads::CDockingStateReader& Stream, bool Testing);
@@ -82,6 +83,7 @@ public:
bool hasTopLevelDockWidget() const;
ads::CDockWidget* topLevelDockWidget() const;
QList<ads::CDockWidget*> dockWidgets() const;
void finishDropOperation();
%If (WS_X11)
void onMaximizeRequest();

View File

@@ -73,7 +73,8 @@ namespace ads
TitleBarButtonTabsMenu,
TitleBarButtonUndock,
TitleBarButtonClose,
TitleBarButtonAutoHide
TitleBarButtonAutoHide,
TitleBarButtonMinimize
};
enum eDragState

View File

@@ -657,6 +657,14 @@ bool CAutoHideDockContainer::event(QEvent* event)
return Super::event(event);
}
//============================================================================
void CAutoHideDockContainer::dragLeaveEvent(QDragLeaveEvent*)
{
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideOpenOnDragHover))
{
collapseView(true);
}
}
//============================================================================
Qt::Orientation CAutoHideDockContainer::orientation() const
@@ -709,4 +717,3 @@ int CAutoHideDockContainer::tabIndex() const
}
}

View File

@@ -34,7 +34,7 @@
#include <QSplitter>
#include "AutoHideTab.h"
class QXmlStreamWriter;
QT_FORWARD_DECLARE_CLASS(QXmlStreamWriter)
namespace ads
{
@@ -65,6 +65,7 @@ protected:
virtual void resizeEvent(QResizeEvent* event) override;
virtual void leaveEvent(QEvent *event) override;
virtual bool event(QEvent* event) override;
virtual void dragLeaveEvent(QDragLeaveEvent* ev) override;
/**
* Updates the size considering the size limits and the resize margins
@@ -139,7 +140,7 @@ public:
/**
* Moves the contents to the parent container widget
* Used before removing this Auto Hide dock container
* Used before removing this Auto Hide dock container
*/
void moveContentsToParent();

View File

@@ -414,7 +414,14 @@ void CAutoHideSideBar::saveState(QXmlStreamWriter& s) const
QSize CAutoHideSideBar::minimumSizeHint() const
{
QSize Size = sizeHint();
Size.setWidth(10);
if (d->isHorizontal())
{
Size.setWidth(0);
}
else
{
Size.setHeight(0);
}
return Size;
}

View File

@@ -33,7 +33,7 @@
#include "ads_globals.h"
#include "AutoHideTab.h"
class QXmlStreamWriter;
QT_FORWARD_DECLARE_CLASS(QXmlStreamWriter)
namespace ads
{

View File

@@ -33,6 +33,8 @@
#include <QApplication>
#include <QElapsedTimer>
#include <QMenu>
#include <QEvent>
#include <QTimer>
#include "AutoHideDockContainer.h"
#include "AutoHideSideBar.h"
@@ -41,10 +43,10 @@
#include "DockWidget.h"
#include "FloatingDragPreview.h"
#include "DockOverlay.h"
#include "ads_globals.h"
namespace ads
{
static const char* const LocationProperty = "Location";
/**
* Private data class of CDockWidgetTab class (pimpl)
@@ -56,6 +58,7 @@ struct AutoHideTabPrivate
CAutoHideSideBar* SideBar = nullptr;
Qt::Orientation Orientation{Qt::Vertical};
QElapsedTimer TimeSinceHoverMousePress;
QTimer DragOverTimer;
bool MousePressed = false;
eDragState DragState = DraggingInactive;
QPoint GlobalDragStartMousePosition;
@@ -102,7 +105,7 @@ struct AutoHideTabPrivate
QMenu* Menu)
{
auto Action = Menu->addAction(Title);
Action->setProperty("Location", Location);
Action->setProperty(internal::LocationProperty, Location);
QObject::connect(Action, &QAction::triggered, _this, &CAutoHideTab::onAutoHideToActionClicked);
Action->setEnabled(Location != _this->sideBarLocation());
return Action;
@@ -174,7 +177,7 @@ void AutoHideTabPrivate::updateOrientation()
bool AutoHideTabPrivate::startFloating(eDragState DraggingState)
{
auto DockArea = DockWidget->dockAreaWidget();
ADS_PRINT("isFloating " << dockContainer->isFloating());
ADS_PRINT("isFloating " << dockContainer()->isFloating());
ADS_PRINT("startFloating");
DragState = DraggingState;
@@ -253,6 +256,14 @@ CAutoHideTab::CAutoHideTab(QWidget* parent) :
{
setAttribute(Qt::WA_NoMousePropagation);
setFocusPolicy(Qt::NoFocus);
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideOpenOnDragHover)) {
setAcceptDrops(true);
}
d->DragOverTimer.setInterval(CDockManager::configParam(
CDockManager::AutoHideOpenOnDragHoverDelay_ms, 500).toInt());
d->DragOverTimer.setSingleShot(true);
connect(&d->DragOverTimer, &QTimer::timeout, this, &CAutoHideTab::onDragHoverDelayExpired);
}
@@ -356,7 +367,6 @@ bool CAutoHideTab::event(QEvent* event)
case QEvent::Leave:
d->forwardEventToDockContainer(event);
break;
default:
break;
}
@@ -419,7 +429,7 @@ void CAutoHideTab::unpinDockWidget()
//===========================================================================
void CAutoHideTab::onAutoHideToActionClicked()
{
int Location = sender()->property(LocationProperty).toInt();
int Location = sender()->property(internal::LocationProperty).toInt();
d->DockWidget->setAutoHide(true, (SideBarLocation)Location);
}
@@ -494,48 +504,74 @@ void CAutoHideTab::mouseReleaseEvent(QMouseEvent* ev)
//============================================================================
void CAutoHideTab::mouseMoveEvent(QMouseEvent* ev)
void CAutoHideTab::mouseMoveEvent(QMouseEvent *ev)
{
if (!(ev->buttons() & Qt::LeftButton) || d->isDraggingState(DraggingInactive))
{
d->DragState = DraggingInactive;
Super::mouseMoveEvent(ev);
return;
}
// move floating window
if (d->isDraggingState(DraggingFloatingWidget))
{
d->FloatingWidget->moveFloating();
Super::mouseMoveEvent(ev);
return;
}
// move tab
if (d->isDraggingState(DraggingTab))
{
// Moving the tab is always allowed because it does not mean moving the
// dock widget around
//d->moveTab(ev);
}
auto MappedPos = mapToParent(ev->pos());
bool MouseOutsideBar = (MappedPos.x() < 0) || (MappedPos.x() > parentWidget()->rect().right());
// Maybe a fixed drag distance is better here ?
int DragDistanceY = qAbs(d->GlobalDragStartMousePosition.y() - internal::globalPositionOf(ev).y());
if (DragDistanceY >= CDockManager::startDragDistance() || MouseOutsideBar)
if (!(ev->buttons() & Qt::LeftButton)
|| d->isDraggingState(DraggingInactive))
{
// Floating is only allowed for widgets that are floatable
// We can create the drag preview if the widget is movable.
auto Features = d->DockWidget->features();
if (Features.testFlag(CDockWidget::DockWidgetFloatable) || (Features.testFlag(CDockWidget::DockWidgetMovable)))
{
d->startFloating();
}
return;
d->DragState = DraggingInactive;
Super::mouseMoveEvent(ev);
return;
}
Super::mouseMoveEvent(ev);
// move floating window
if (d->isDraggingState(DraggingFloatingWidget))
{
d->FloatingWidget->moveFloating();
Super::mouseMoveEvent(ev);
return;
}
// move tab
if (d->isDraggingState(DraggingTab))
{
// Moving the tab is always allowed because it does not mean moving the
// dock widget around
//d->moveTab(ev);
}
auto MappedPos = mapToParent(ev->pos());
bool MouseOutsideBar = (MappedPos.x() < 0)
|| (MappedPos.x() > parentWidget()->rect().right());
// Maybe a fixed drag distance is better here ?
int DragDistanceY = qAbs(
d->GlobalDragStartMousePosition.y()
- internal::globalPositionOf(ev).y());
if (DragDistanceY >= CDockManager::startDragDistance() || MouseOutsideBar)
{
// Floating is only allowed for widgets that are floatable
// We can create the drag preview if the widget is movable.
auto Features = d->DockWidget->features();
if (Features.testFlag(CDockWidget::DockWidgetFloatable)
|| (Features.testFlag(CDockWidget::DockWidgetMovable)))
{
d->startFloating();
}
return;
}
Super::mouseMoveEvent(ev);
}
//============================================================================
void CAutoHideTab::dragEnterEvent(QDragEnterEvent *ev)
{
Q_UNUSED(ev);
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideOpenOnDragHover))
{
d->DragOverTimer.start();
ev->accept();
}
}
//============================================================================
void CAutoHideTab::dragLeaveEvent(QDragLeaveEvent *ev)
{
Q_UNUSED(ev);
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideOpenOnDragHover))
{
d->DragOverTimer.stop();
}
}
@@ -545,7 +581,6 @@ void CAutoHideTab::requestCloseDockWidget()
d->DockWidget->requestCloseDockWidget();
}
//============================================================================
int CAutoHideTab::tabIndex() const
{
@@ -558,4 +593,28 @@ int CAutoHideTab::tabIndex() const
}
//============================================================================
void CAutoHideTab::onDragHoverDelayExpired()
{
static const char* const PropertyId = "ActiveDragOverAutoHideContainer";
// First we check if there is an active auto hide container that is visible
// In this case, we collapse it before we open the new one
auto v = d->DockWidget->dockManager()->property(PropertyId);
if (v.isValid())
{
auto ActiveAutoHideContainer = v.value<QPointer<CAutoHideDockContainer>>();
if (ActiveAutoHideContainer)
{
ActiveAutoHideContainer->collapseView(true);
}
}
auto AutoHideContainer = d->DockWidget->autoHideDockContainer();
AutoHideContainer->collapseView(false);
d->DockWidget->dockManager()->setProperty(PropertyId,
QVariant::fromValue(QPointer(AutoHideContainer)));
}
}

View File

@@ -55,7 +55,7 @@ class ADS_EXPORT CAutoHideTab : public CPushButton
Q_PROPERTY(bool activeTab READ isActiveTab)
Q_PROPERTY(bool iconOnly READ iconOnly)
private:
private:
AutoHideTabPrivate* d; ///< private data (pimpl)
friend struct AutoHideTabPrivate;
friend class CDockWidget;
@@ -67,6 +67,7 @@ private:
private Q_SLOTS:
void onAutoHideToActionClicked();
void onDragHoverDelayExpired();
protected:
void setSideBar(CAutoHideSideBar *SideTabBar);
@@ -76,6 +77,8 @@ protected:
virtual void mousePressEvent(QMouseEvent* ev) override;
virtual void mouseReleaseEvent(QMouseEvent* ev) override;
virtual void mouseMoveEvent(QMouseEvent* ev) override;
virtual void dragEnterEvent(QDragEnterEvent* ev) override;
virtual void dragLeaveEvent(QDragLeaveEvent* ev) override;
public:
using Super = CPushButton;

View File

@@ -1,5 +1,6 @@
cmake_minimum_required(VERSION 3.5)
project(QtAdvancedDockingSystem LANGUAGES CXX VERSION ${VERSION_SHORT})
include(GNUInstallDirs)
if (${QT_VERSION_MAJOR})
message(STATUS "Forced to use Qt version ${QT_VERSION_MAJOR}")
find_package(QT NAMES Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)
@@ -36,7 +37,7 @@ set(ads_SRCS
AutoHideTab.cpp
AutoHideDockContainer.cpp
PushButton.cpp
ResizeHandle.cpp
ResizeHandle.cpp
ads.qrc
)
set(ads_HEADERS
@@ -62,7 +63,7 @@ set(ads_HEADERS
AutoHideTab.h
AutoHideDockContainer.h
PushButton.h
ResizeHandle.h
ResizeHandle.h
)
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
if (UNIX AND NOT APPLE)
@@ -120,7 +121,7 @@ write_basic_package_version_file(
COMPATIBILITY SameMajorVersion
)
install(FILES ${ads_HEADERS}
DESTINATION include/${library_name}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${library_name}
COMPONENT headers
)
install(FILES
@@ -131,25 +132,25 @@ install(FILES
)
install(TARGETS ${library_name}
EXPORT adsTargets
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
INCLUDES DESTINATION include/${library_name}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${library_name}
)
install(EXPORT adsTargets
FILE adsTargets.cmake
NAMESPACE ads::
DESTINATION lib/cmake/${library_name}
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${library_name}
)
install(FILES qtadvanceddockingConfig.cmake RENAME ${library_name}Config.cmake
DESTINATION lib/cmake/${library_name}
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${library_name}
)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${library_name}ConfigVersion.cmake"
DESTINATION lib/cmake/${library_name}
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${library_name}
)
target_include_directories(${library_name} PUBLIC
$<INSTALL_INTERFACE:include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
)

View File

@@ -111,8 +111,9 @@ void DockAreaTabBarPrivate::updateTabs()
// Sometimes the synchronous calculation of the rectangular area fails
// Therefore we use QTimer::singleShot here to execute the call
// within the event loop - see #520
QTimer::singleShot(0, [&, TabWidget]{
_this->ensureWidgetVisible(TabWidget);
QTimer::singleShot(0, _this, [&, TabWidget]
{
_this->ensureWidgetVisible(TabWidget);
});
}
else
@@ -389,15 +390,18 @@ void CDockAreaTabBar::onTabWidgetMoved(const QPoint& GlobalPos)
int fromIndex = d->TabsLayout->indexOf(MovingTab);
auto MousePos = mapFromGlobal(GlobalPos);
MousePos.rx() = qMax(d->firstTab()->geometry().left(), MousePos.x());
MousePos.rx() = qMin(d->lastTab()->geometry().right(), MousePos.x());
MousePos.rx() = qMax(0, MousePos.x());
MousePos.rx() = qMin(width(), MousePos.x());
int toIndex = -1;
// Find tab under mouse
for (int i = 0; i < count(); ++i)
{
CDockWidgetTab* DropTab = tab(i);
auto TabGeometry = DropTab->geometry();
TabGeometry.setTopLeft(d->TabsContainerWidget->mapToParent(TabGeometry.topLeft()));
TabGeometry.setBottomRight(d->TabsContainerWidget->mapToParent(TabGeometry.bottomRight()));
if (DropTab == MovingTab || !DropTab->isVisibleTo(this)
|| !DropTab->geometry().contains(MousePos))
|| !TabGeometry.contains(MousePos))
{
continue;
}
@@ -469,6 +473,15 @@ bool CDockAreaTabBar::eventFilter(QObject *watched, QEvent *event)
updateGeometry();
break;
// Manage wheel event
case QEvent::Wheel:
// Ignore wheel events if tab is currently dragged
if (Tab->dragState() == DraggingInactive)
{
wheelEvent((QWheelEvent* )event);
}
break;
default:
break;
}
@@ -544,6 +557,13 @@ int CDockAreaTabBar::tabInsertIndexAt(const QPoint& Pos) const
}
}
//===========================================================================
bool CDockAreaTabBar::areTabsOverflowing() const
{
return d->TabsContainerWidget->width() > width();
}
} // namespace ads

View File

@@ -153,6 +153,12 @@ public:
*/
virtual QSize sizeHint() const override;
/**
* This function returns true, if the tabs need more space than the size
* of the tab bar.
*/
bool areTabsOverflowing() const;
public Q_SLOTS:
/**
* This property sets the index of the tab bar's visible tab

View File

@@ -60,7 +60,6 @@
namespace ads
{
static const char* const LocationProperty = "Location";
/**
* Private data class of CDockAreaTitleBar class (pimpl)
@@ -159,7 +158,7 @@ struct DockAreaTitleBarPrivate
QMenu* Menu)
{
auto Action = Menu->addAction(Title);
Action->setProperty("Location", Location);
Action->setProperty(internal::LocationProperty, Location);
QObject::connect(Action, &QAction::triggered, _this, &CDockAreaTitleBar::onAutoHideToActionClicked);
return Action;
}
@@ -179,7 +178,8 @@ void DockAreaTitleBarPrivate::createButtons()
QSizePolicy ButtonSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
// Tabs menu button
TabsMenuButton = new CTitleBarButton(testConfigFlag(CDockManager::DockAreaHasTabsMenuButton));
TabsMenuButton = new CTitleBarButton(testConfigFlag(CDockManager::DockAreaHasTabsMenuButton),
false, TitleBarButtonTabsMenu);
TabsMenuButton->setObjectName("tabsMenuButton");
TabsMenuButton->setAutoRaise(true);
TabsMenuButton->setPopupMode(QToolButton::InstantPopup);
@@ -197,7 +197,8 @@ void DockAreaTitleBarPrivate::createButtons()
SLOT(onTabsMenuActionTriggered(QAction*)));
// Undock button
UndockButton = new CTitleBarButton(testConfigFlag(CDockManager::DockAreaHasUndockButton));
UndockButton = new CTitleBarButton(testConfigFlag(CDockManager::DockAreaHasUndockButton),
true, TitleBarButtonUndock);
UndockButton->setObjectName("detachGroupButton");
UndockButton->setAutoRaise(true);
internal::setToolTip(UndockButton, QObject::tr("Detach Group"));
@@ -208,7 +209,8 @@ void DockAreaTitleBarPrivate::createButtons()
// AutoHide Button
const auto autoHideEnabled = testAutoHideConfigFlag(CDockManager::AutoHideFeatureEnabled);
AutoHideButton = new CTitleBarButton(testAutoHideConfigFlag(CDockManager::DockAreaHasAutoHideButton) && autoHideEnabled);
AutoHideButton = new CTitleBarButton(testAutoHideConfigFlag(CDockManager::DockAreaHasAutoHideButton) && autoHideEnabled,
true, TitleBarButtonAutoHide);
AutoHideButton->setObjectName("dockAreaAutoHideButton");
AutoHideButton->setAutoRaise(true);
internal::setToolTip(AutoHideButton, _this->titleBarButtonToolTip(TitleBarButtonAutoHide));
@@ -220,7 +222,8 @@ void DockAreaTitleBarPrivate::createButtons()
_this->connect(AutoHideButton, SIGNAL(clicked()), SLOT(onAutoHideButtonClicked()));
// Minimize button
MinimizeButton = new CTitleBarButton(testAutoHideConfigFlag(CDockManager::AutoHideHasMinimizeButton));
MinimizeButton = new CTitleBarButton(testAutoHideConfigFlag(CDockManager::AutoHideHasMinimizeButton),
false, TitleBarButtonMinimize);
MinimizeButton->setObjectName("dockAreaMinimizeButton");
MinimizeButton->setAutoRaise(true);
MinimizeButton->setVisible(false);
@@ -231,7 +234,8 @@ void DockAreaTitleBarPrivate::createButtons()
_this->connect(MinimizeButton, SIGNAL(clicked()), SLOT(minimizeAutoHideContainer()));
// Close button
CloseButton = new CTitleBarButton(testConfigFlag(CDockManager::DockAreaHasCloseButton));
CloseButton = new CTitleBarButton(testConfigFlag(CDockManager::DockAreaHasCloseButton),
true, TitleBarButtonClose);
CloseButton->setObjectName("dockAreaCloseButton");
CloseButton->setAutoRaise(true);
internal::setButtonIcon(CloseButton, QStyle::SP_TitleBarCloseButton, ads::DockAreaCloseIcon);
@@ -373,27 +377,48 @@ CDockAreaTabBar* CDockAreaTitleBar::tabBar() const
return d->TabBar;
}
//============================================================================
void CDockAreaTitleBar::resizeEvent(QResizeEvent *event)
{
Super::resizeEvent(event);
if (CDockManager::testConfigFlag(CDockManager::DockAreaDynamicTabsMenuButtonVisibility)
&& CDockManager::testConfigFlag(CDockManager::DisableTabTextEliding))
{
markTabsMenuOutdated();
}
}
//============================================================================
void CDockAreaTitleBar::markTabsMenuOutdated()
{
if(DockAreaTitleBarPrivate::testConfigFlag(CDockManager::DockAreaDynamicTabsMenuButtonVisibility))
if (CDockManager::testConfigFlag(CDockManager::DockAreaDynamicTabsMenuButtonVisibility))
{
bool hasElidedTabTitle = false;
for (int i = 0; i < d->TabBar->count(); ++i)
bool TabsMenuButtonVisible = false;
if (CDockManager::testConfigFlag(CDockManager::DisableTabTextEliding))
{
if (!d->TabBar->isTabOpen(i))
{
continue;
}
CDockWidgetTab* Tab = d->TabBar->tab(i);
if(Tab->isTitleElided())
{
hasElidedTabTitle = true;
break;
}
TabsMenuButtonVisible = d->TabBar->areTabsOverflowing();
}
bool visible = (hasElidedTabTitle && (d->TabBar->count() > 1));
QMetaObject::invokeMethod(d->TabsMenuButton, "setVisible", Qt::QueuedConnection, Q_ARG(bool, visible));
else
{
bool hasElidedTabTitle = false;
for (int i = 0; i < d->TabBar->count(); ++i)
{
if (!d->TabBar->isTabOpen(i))
{
continue;
}
CDockWidgetTab* Tab = d->TabBar->tab(i);
if(Tab->isTitleElided())
{
hasElidedTabTitle = true;
break;
}
}
TabsMenuButtonVisible = (hasElidedTabTitle && (d->TabBar->count() > 1));
}
QMetaObject::invokeMethod(d->TabsMenuButton, "setVisible", Qt::QueuedConnection, Q_ARG(bool, TabsMenuButtonVisible));
}
d->MenuOutdated = true;
}
@@ -510,7 +535,7 @@ void CDockAreaTitleBar::updateDockWidgetActionsButtons()
int InsertIndex = indexOf(d->TabsMenuButton);
for (auto Action : Actions)
{
auto Button = new CTitleBarButton(true, this);
auto Button = new CTitleBarButton(true, false, TitleBarButtonTabsMenu, this);
Button->setDefaultAction(Action);
Button->setAutoRaise(true);
Button->setPopupMode(QToolButton::InstantPopup);
@@ -564,7 +589,7 @@ void CDockAreaTitleBar::onAutoHideDockAreaActionClicked()
//============================================================================
void CDockAreaTitleBar::onAutoHideToActionClicked()
{
int Location = sender()->property(LocationProperty).toInt();
int Location = sender()->property(internal::LocationProperty).toInt();
d->DockArea->toggleAutoHide((SideBarLocation)Location);
}
@@ -856,10 +881,25 @@ void CDockAreaTitleBar::showAutoHideControls(bool Show)
//============================================================================
CTitleBarButton::CTitleBarButton(bool showInTitleBar, QWidget* parent)
bool CDockAreaTitleBar::isAutoHide() const
{
return d->DockArea && d->DockArea->isAutoHide();
}
//============================================================================
CDockAreaWidget* CDockAreaTitleBar::dockAreaWidget() const
{
return d->DockArea;
}
//============================================================================
CTitleBarButton::CTitleBarButton(bool showInTitleBar, bool hideWhenDisabled, TitleBarButton ButtonId, QWidget* parent)
: tTitleBarButton(parent),
ShowInTitleBar(showInTitleBar),
HideWhenDisabled(CDockManager::testConfigFlag(CDockManager::DockAreaHideDisabledButtons))
HideWhenDisabled(CDockManager::testConfigFlag(CDockManager::DockAreaHideDisabledButtons) && hideWhenDisabled),
TitleBarButtonId(ButtonId)
{
setFocusPolicy(Qt::NoFocus);
}
@@ -894,16 +934,47 @@ void CTitleBarButton::setShowInTitleBar(bool Show)
//============================================================================
bool CTitleBarButton::event(QEvent *ev)
{
if (QEvent::EnabledChange == ev->type() && HideWhenDisabled)
if (QEvent::EnabledChange != ev->type() || !HideWhenDisabled || !ShowInTitleBar)
{
// force setVisible() call
// Calling setVisible() directly here doesn't work well when button is expected to be shown first time
QMetaObject::invokeMethod(this, "setVisible", Qt::QueuedConnection, Q_ARG(bool, isEnabled()));
return Super::event(ev);
}
bool Show = true;
if (isInAutoHideArea())
{
switch (TitleBarButtonId)
{
case TitleBarButtonClose: Show = CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideHasCloseButton); break;
case TitleBarButtonUndock: Show = false; break;
default:
break;
}
}
// force setVisible() call - Calling setVisible() directly here doesn't
// work well when button is expected to be shown first time
QMetaObject::invokeMethod(this, "setVisible", Qt::QueuedConnection,
Q_ARG(bool, isEnabledTo(this->parentWidget()) & Show));
return Super::event(ev);
}
//============================================================================
CDockAreaTitleBar* CTitleBarButton::titleBar() const
{
return qobject_cast<CDockAreaTitleBar*>(parentWidget());
}
//============================================================================
bool CTitleBarButton::isInAutoHideArea() const
{
auto TitleBar = titleBar();
return TitleBar && TitleBar->isAutoHide();
}
//============================================================================
CSpacerWidget::CSpacerWidget(QWidget* Parent /*= 0*/) : Super(Parent)
{

View File

@@ -43,6 +43,7 @@ class CDockAreaTabBar;
class CDockAreaWidget;
struct DockAreaTitleBarPrivate;
class CElidingLabel;
class CDockAreaTitleBar;
using tTitleBarButton = QToolButton;
@@ -59,10 +60,12 @@ class CTitleBarButton : public tTitleBarButton
private:
bool ShowInTitleBar = true;
bool HideWhenDisabled = false;
TitleBarButton TitleBarButtonId;
public:
using Super = tTitleBarButton;
CTitleBarButton(bool ShowInTitleBar = true, QWidget* parent = nullptr);
CTitleBarButton(bool ShowInTitleBar, bool HideWhenDisabled, TitleBarButton ButtonId,
QWidget* parent = nullptr);
/**
* Adjust this visibility change request with our internal settings:
@@ -74,6 +77,22 @@ public:
*/
void setShowInTitleBar(bool Show);
/**
* Identifier for the title bar button
*/
TitleBarButton buttonId() const {return TitleBarButtonId;}
/**
* Return the title bar that contains this button
*/
CDockAreaTitleBar* titleBar() const;
/**
* Returns true, if the button is in a title bar in an auto hide area
*/
bool isInAutoHideArea() const;
protected:
/**
* Handle EnabledChanged signal to set button invisible if the configured
@@ -133,6 +152,11 @@ protected:
*/
virtual void contextMenuEvent(QContextMenuEvent *event) override;
/**
* Handle resize events
*/
virtual void resizeEvent(QResizeEvent *event) override;
public Q_SLOTS:
/**
* Call this slot to tell the title bar that it should update the tabs menu
@@ -169,6 +193,11 @@ public:
*/
CElidingLabel* autoHideTitleLabel() const;
/**
* Returns the dock area widget that contains this title bar
*/
CDockAreaWidget* dockAreaWidget() const;
/**
* Updates the visibility of the dock widget actions in the title bar
*/
@@ -215,6 +244,11 @@ public:
*/
void showAutoHideControls(bool Show);
/**
* Returns true, if the auto hide controls are visible
*/
bool isAutoHide() const;
Q_SIGNALS:
/**
* This signal is emitted if a tab in the tab bar is clicked by the user

View File

@@ -52,7 +52,7 @@ class CSpacerWidget : public QWidget
Q_OBJECT
public:
using Super = QWidget;
CSpacerWidget(QWidget* Parent = 0);
CSpacerWidget(QWidget* Parent = nullptr);
virtual QSize sizeHint() const override {return QSize(0, 0);}
virtual QSize minimumSizeHint() const override {return QSize(0, 0);}
};

View File

@@ -34,7 +34,6 @@
#include <QStackedLayout>
#include <QScrollBar>
#include <QWheelEvent>
#include <QStyle>
#include <QPushButton>
#include <QDebug>
@@ -81,7 +80,7 @@ class CDockAreaLayout
{
private:
QBoxLayout* m_ParentLayout;
QList<QWidget*> m_Widgets;
QList<QPointer<QWidget>> m_Widgets;
int m_CurrentIndex = -1;
QWidget* m_CurrentWidget = nullptr;
@@ -370,10 +369,21 @@ void DockAreaWidgetPrivate::updateTitleBarButtonStates()
return;
}
TitleBar->button(TitleBarButtonClose)->setEnabled(
_this->features().testFlag(CDockWidget::DockWidgetClosable));
TitleBar->button(TitleBarButtonUndock)->setEnabled(
_this->features().testFlag(CDockWidget::DockWidgetFloatable));
if (_this->isAutoHide())
{
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideHasCloseButton))
{
TitleBar->button(TitleBarButtonClose)->setEnabled(
_this->features().testFlag(CDockWidget::DockWidgetClosable));
}
}
else
{
TitleBar->button(TitleBarButtonUndock)->setEnabled(
_this->features().testFlag(CDockWidget::DockWidgetFloatable));
TitleBar->button(TitleBarButtonClose)->setEnabled(
_this->features().testFlag(CDockWidget::DockWidgetClosable));
}
TitleBar->button(TitleBarButtonAutoHide)->setEnabled(
_this->features().testFlag(CDockWidget::DockWidgetPinnable));
TitleBar->updateDockWidgetActionsButtons();
@@ -393,7 +403,7 @@ void DockAreaWidgetPrivate::updateTitleBarButtonVisibility(bool IsTopLevel)
bool IsAutoHide = _this->isAutoHide();
if (IsAutoHide)
{
bool ShowCloseButton = CDockManager::autoHideConfigFlags().testFlag(CDockManager::AutoHideHasCloseButton);
bool ShowCloseButton = CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideHasCloseButton);
TitleBar->button(TitleBarButtonClose)->setVisible(ShowCloseButton);
TitleBar->button(TitleBarButtonAutoHide)->setVisible(true);
TitleBar->button(TitleBarButtonUndock)->setVisible(false);
@@ -410,7 +420,8 @@ void DockAreaWidgetPrivate::updateTitleBarButtonVisibility(bool IsTopLevel)
else
{
TitleBar->button(TitleBarButtonClose)->setVisible(true);
TitleBar->button(TitleBarButtonAutoHide)->setVisible(true);
bool ShowAutoHideButton = CDockManager::testAutoHideConfigFlag(CDockManager::DockAreaHasAutoHideButton);
TitleBar->button(TitleBarButtonAutoHide)->setVisible(ShowAutoHideButton);
TitleBar->button(TitleBarButtonUndock)->setVisible(true);
TitleBar->button(TitleBarButtonTabsMenu)->setVisible(true);
}
@@ -464,6 +475,13 @@ CAutoHideDockContainer* CDockAreaWidget::autoHideDockContainer() const
return d->AutoHideDockContainer;
}
//============================================================================
CDockSplitter* CDockAreaWidget::parentSplitter() const
{
return internal::findParent<CDockSplitter*>(this);
}
//============================================================================
bool CDockAreaWidget::isAutoHide() const
{
@@ -600,7 +618,7 @@ void CDockAreaWidget::hideAreaWithNoVisibleContent()
this->toggleView(false);
// Hide empty parent splitters
auto Splitter = internal::findParent<CDockSplitter*>(this);
auto Splitter = parentSplitter();
internal::hideEmptyParentSplitters(Splitter);
//Hide empty floating widget
@@ -749,7 +767,7 @@ int CDockAreaWidget::openDockWidgetsCount() const
int Count = 0;
for (int i = 0; i < d->ContentsLayout->count(); ++i)
{
if (!dockWidget(i)->isClosed())
if (dockWidget(i) && !dockWidget(i)->isClosed())
{
++Count;
}
@@ -765,7 +783,7 @@ QList<CDockWidget*> CDockAreaWidget::openedDockWidgets() const
for (int i = 0; i < d->ContentsLayout->count(); ++i)
{
CDockWidget* DockWidget = dockWidget(i);
if (!DockWidget->isClosed())
if (DockWidget && !DockWidget->isClosed())
{
DockWidgetList.append(dockWidget(i));
}
@@ -779,7 +797,7 @@ int CDockAreaWidget::indexOfFirstOpenDockWidget() const
{
for (int i = 0; i < d->ContentsLayout->count(); ++i)
{
if (!dockWidget(i)->isClosed())
if (dockWidget(i) && !dockWidget(i)->isClosed())
{
return i;
}
@@ -802,7 +820,6 @@ CDockWidget* CDockAreaWidget::dockWidget(int Index) const
return qobject_cast<CDockWidget*>(d->ContentsLayout->widget(Index));
}
//============================================================================
void CDockAreaWidget::reorderDockWidget(int fromIndex, int toIndex)
{

View File

@@ -47,6 +47,7 @@ class CDockContainerWidget;
class DockContainerWidgetPrivate;
class CDockAreaTitleBar;
class CDockingStateReader;
class CDockSplitter;
/**
@@ -216,6 +217,11 @@ public:
*/
CAutoHideDockContainer* autoHideDockContainer() const;
/**
* Returns the parent splitter that contains this dock area
*/
CDockSplitter* parentSplitter() const;
/**
* Returns true if the dock area is in an auto hide container
*/

View File

@@ -141,7 +141,7 @@ public:
CDockContainerWidget* _this;
QPointer<CDockManager> DockManager;
unsigned int zOrderIndex = 0;
QList<CDockAreaWidget*> DockAreas;
QList<QPointer<CDockAreaWidget>> DockAreas;
QList<CAutoHideDockContainer*> AutoHideWidgets;
QMap<SideBarLocation, CAutoHideSideBar*> SideTabBarWidgets;
QGridLayout* Layout = nullptr;
@@ -299,7 +299,11 @@ public:
VisibleDockAreaCount = 0;
for (auto DockArea : DockAreas)
{
VisibleDockAreaCount += DockArea->isHidden() ? 0 : 1;
if (!DockArea)
{
continue;
}
VisibleDockAreaCount += (DockArea->isHidden() ? 0 : 1);
}
}
@@ -587,16 +591,7 @@ void DockContainerWidgetPrivate::dropIntoSection(CFloatingDockContainer* Floatin
auto InsertParam = internal::dockAreaInsertParameters(area);
auto NewDockAreas = FloatingContainer->findChildren<CDockAreaWidget*>(
QString(), Qt::FindChildrenRecursively);
QSplitter* TargetAreaSplitter = internal::findParent<QSplitter*>(TargetArea);
if (!TargetAreaSplitter)
{
QSplitter* Splitter = newSplitter(InsertParam.orientation());
Layout->replaceWidget(TargetArea, Splitter);
Splitter->addWidget(TargetArea);
updateSplitterHandles(Splitter);
TargetAreaSplitter = Splitter;
}
auto TargetAreaSplitter = TargetArea->parentSplitter();
int AreaIndex = TargetAreaSplitter->indexOf(TargetArea);
auto FloatingSplitter = FloatingContainer->rootSplitter();
if (TargetAreaSplitter->orientation() == InsertParam.orientation())
@@ -742,7 +737,7 @@ void DockContainerWidgetPrivate::moveToNewSection(QWidget* Widget, CDockAreaWidg
}
auto InsertParam = internal::dockAreaInsertParameters(area);
QSplitter* TargetAreaSplitter = internal::findParent<QSplitter*>(TargetArea);
auto TargetAreaSplitter = TargetArea->parentSplitter();
int AreaIndex = TargetAreaSplitter->indexOf(TargetArea);
auto Sizes = TargetAreaSplitter->sizes();
if (TargetAreaSplitter->orientation() == InsertParam.orientation())
@@ -877,7 +872,7 @@ void DockContainerWidgetPrivate::moveToContainer(QWidget* Widget, DockWidgetArea
// it already has and do nothing, if it is the same place. It would
// also work without this check, but it looks nicer with the check
// because there will be no layout updates
auto Splitter = internal::findParent<CDockSplitter*>(DroppedDockArea);
auto Splitter = DroppedDockArea->parentSplitter();
auto InsertParam = internal::dockAreaInsertParameters(area);
if (Splitter == RootSplitter && InsertParam.orientation() == Splitter->orientation())
{
@@ -933,7 +928,10 @@ void DockContainerWidgetPrivate::addDockAreasToList(const QList<CDockAreaWidget*
//============================================================================
void DockContainerWidgetPrivate::appendDockAreas(const QList<CDockAreaWidget*> NewDockAreas)
{
DockAreas.append(NewDockAreas);
for (auto *newDockArea : NewDockAreas)
{
DockAreas.append(newDockArea);
}
for (auto DockArea : NewDockAreas)
{
QObject::connect(DockArea,
@@ -1364,7 +1362,7 @@ CDockAreaWidget* DockContainerWidgetPrivate::addDockWidgetToDockArea(DockWidgetA
NewDockArea->addDockWidget(Dockwidget);
auto InsertParam = internal::dockAreaInsertParameters(area);
QSplitter* TargetAreaSplitter = internal::findParent<QSplitter*>(TargetDockArea);
auto TargetAreaSplitter = TargetDockArea->parentSplitter();
int index = TargetAreaSplitter ->indexOf(TargetDockArea);
if (TargetAreaSplitter->orientation() == InsertParam.orientation())
{
@@ -1381,7 +1379,7 @@ CDockAreaWidget* DockContainerWidgetPrivate::addDockWidgetToDockArea(DockWidgetA
{
ADS_PRINT("TargetAreaSplitter->orientation() != InsertParam.orientation()");
auto TargetAreaSizes = TargetAreaSplitter->sizes();
QSplitter* NewSplitter = newSplitter(InsertParam.orientation());
auto NewSplitter = newSplitter(InsertParam.orientation());
NewSplitter->addWidget(TargetDockArea);
insertWidgetIntoSplitter(NewSplitter, NewDockArea, InsertParam.append());
@@ -1572,7 +1570,7 @@ void CDockContainerWidget::removeDockArea(CDockAreaWidget* area)
area->disconnect(this);
d->DockAreas.removeAll(area);
CDockSplitter* Splitter = internal::findParent<CDockSplitter*>(area);
auto Splitter = area->parentSplitter();
// Remove are from parent splitter and recursively hide tree of parent
// splitters if it has no visible content
@@ -1645,12 +1643,21 @@ emitAndExit:
}
//============================================================================
QList<QPointer<CDockAreaWidget>> CDockContainerWidget::removeAllDockAreas()
{
auto Result = d->DockAreas;
d->DockAreas.clear();
return Result;
}
//============================================================================
CDockAreaWidget* CDockContainerWidget::dockAreaAt(const QPoint& GlobalPos) const
{
for (const auto& DockArea : d->DockAreas)
{
if (DockArea->isVisible() && DockArea->rect().contains(DockArea->mapFromGlobal(GlobalPos)))
if (DockArea && DockArea->isVisible() && DockArea->rect().contains(DockArea->mapFromGlobal(GlobalPos)))
{
return DockArea;
}
@@ -1687,7 +1694,7 @@ int CDockContainerWidget::visibleDockAreaCount() const
int Result = 0;
for (auto DockArea : d->DockAreas)
{
Result += DockArea->isHidden() ? 0 : 1;
Result += (!DockArea || DockArea->isHidden()) ? 0 : 1;
}
return Result;
@@ -1758,7 +1765,7 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
if (Dropped)
{
// Fix https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/351
FloatingWidget->hideAndDeleteLater();
FloatingWidget->finishDropOperation();
// If we dropped a floating widget with only one single dock widget, then we
// drop a top level widget that changes from floating to docked now
@@ -1811,7 +1818,7 @@ QList<CDockAreaWidget*> CDockContainerWidget::openedDockAreas() const
QList<CDockAreaWidget*> Result;
for (auto DockArea : d->DockAreas)
{
if (!DockArea->isHidden())
if (DockArea && !DockArea->isHidden())
{
Result.append(DockArea);
}
@@ -1827,7 +1834,7 @@ QList<CDockWidget*> CDockContainerWidget::openedDockWidgets() const
QList<CDockWidget*> DockWidgetList;
for (auto DockArea : d->DockAreas)
{
if (!DockArea->isHidden())
if (DockArea && !DockArea->isHidden())
{
DockWidgetList.append(DockArea->openedDockWidgets());
}
@@ -1842,7 +1849,7 @@ bool CDockContainerWidget::hasOpenDockAreas() const
{
for (auto DockArea : d->DockAreas)
{
if (!DockArea->isHidden())
if (DockArea && !DockArea->isHidden())
{
return true;
}
@@ -1943,7 +1950,7 @@ bool CDockContainerWidget::restoreState(CDockingStateReader& s, bool Testing)
//============================================================================
QSplitter* CDockContainerWidget::rootSplitter() const
CDockSplitter* CDockContainerWidget::rootSplitter() const
{
return d->RootSplitter;
}
@@ -2065,8 +2072,12 @@ CDockAreaWidget* CDockContainerWidget::topLevelDockArea() const
QList<CDockWidget*> CDockContainerWidget::dockWidgets() const
{
QList<CDockWidget*> Result;
for (const auto DockArea : d->DockAreas)
for (const auto& DockArea : d->DockAreas)
{
if (!DockArea)
{
continue;
}
Result.append(DockArea->dockWidgets());
}
@@ -2097,8 +2108,12 @@ void CDockContainerWidget::removeAutoHideWidget(CAutoHideDockContainer* Autohide
CDockWidget::DockWidgetFeatures CDockContainerWidget::features() const
{
CDockWidget::DockWidgetFeatures Features(CDockWidget::AllDockWidgetFeatures);
for (const auto DockArea : d->DockAreas)
for (const auto& DockArea : d->DockAreas)
{
if (!DockArea)
{
continue;
}
Features &= DockArea->features();
}
@@ -2116,9 +2131,9 @@ CFloatingDockContainer* CDockContainerWidget::floatingWidget() const
//============================================================================
void CDockContainerWidget::closeOtherAreas(CDockAreaWidget* KeepOpenArea)
{
for (const auto DockArea : d->DockAreas)
for (const auto& DockArea : d->DockAreas)
{
if (DockArea == KeepOpenArea)
if (!DockArea || DockArea == KeepOpenArea)
{
continue;
}

View File

@@ -53,6 +53,7 @@ struct FloatingDragPreviewPrivate;
class CDockingStateReader;
class CAutoHideSideBar;
class CAutoHideTab;
class CDockSplitter;
struct AutoHideTabPrivate;
struct AutoHideDockContainerPrivate;
@@ -94,7 +95,7 @@ protected:
/**
* Access function for the internal root splitter
*/
QSplitter* rootSplitter() const;
CDockSplitter* rootSplitter() const;
/**
* Creates and initializes a dockwidget auto hide container into the given area.
@@ -138,6 +139,11 @@ protected:
*/
void removeDockArea(CDockAreaWidget* area);
/**
* Remove all dock areas and returns the list of removed dock areas
*/
QList<QPointer<CDockAreaWidget>> removeAllDockAreas();
/**
* Saves the state into the given stream
*/

View File

@@ -115,6 +115,7 @@ DockFocusControllerPrivate::DockFocusControllerPrivate(
//============================================================================
void DockFocusControllerPrivate::updateDockWidgetFocus(CDockWidget* DockWidget)
{
if (!DockWidget) return;
if (!DockWidget->features().testFlag(CDockWidget::DockWidgetFocusable))
{
return;

View File

@@ -48,6 +48,7 @@
#include <QApplication>
#include <QWindow>
#include <QWindowStateChangeEvent>
#include <QVector>
#include "FloatingDockContainer.h"
#include "DockOverlay.h"
@@ -94,6 +95,7 @@ enum eStateFileVersion
static CDockManager::ConfigFlags StaticConfigFlags = CDockManager::DefaultNonOpaqueConfig;
static CDockManager::AutoHideFlags StaticAutoHideConfigFlags; // auto hide feature is disabled by default
static QVector<QVariant> StaticConfigParams(CDockManager::ConfigParamCount);
static QString FloatingContainersTitle;
@@ -103,8 +105,8 @@ static QString FloatingContainersTitle;
struct DockManagerPrivate
{
CDockManager* _this;
QList<CFloatingDockContainer*> FloatingWidgets;
QList<CFloatingDockContainer*> HiddenFloatingWidgets;
QList<QPointer<CFloatingDockContainer>> FloatingWidgets;
QList<QPointer<CFloatingDockContainer>> HiddenFloatingWidgets;
QList<CDockContainerWidget*> Containers;
CDockOverlay* ContainerOverlay;
CDockOverlay* DockAreaOverlay;
@@ -122,6 +124,7 @@ struct DockManagerPrivate
Qt::ToolButtonStyle ToolBarStyleFloating = Qt::ToolButtonTextUnderIcon;
QSize ToolBarIconSizeDocked = QSize(16, 16);
QSize ToolBarIconSizeFloating = QSize(24, 24);
CDockWidget::DockWidgetFeatures LockedDockWidgetFeatures;
/**
* Private data constructor
@@ -153,7 +156,10 @@ struct DockManagerPrivate
// Hide updates of floating widgets from user
for (auto FloatingWidget : FloatingWidgets)
{
FloatingWidget->hide();
if (FloatingWidget)
{
FloatingWidget->hide();
}
}
}
@@ -333,7 +339,8 @@ bool DockManagerPrivate::restoreStateFromXml(const QByteArray &state, int versi
int FloatingWidgetIndex = DockContainerCount - 1;
for (int i = FloatingWidgetIndex; i < FloatingWidgets.count(); ++i)
{
auto* floatingWidget = FloatingWidgets[i];
CFloatingDockContainer* floatingWidget = FloatingWidgets[i];
if (!floatingWidget) continue;
_this->removeDockContainer(floatingWidget->dockContainer());
floatingWidget->deleteLater();
}
@@ -536,25 +543,41 @@ CDockManager::CDockManager(QWidget *parent) :
CDockManager::~CDockManager()
{
// fix memory leaks, see https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/307
std::vector<ads::CDockAreaWidget*> areas;
for ( int i = 0; i != dockAreaCount(); ++i )
{
areas.push_back( dockArea(i) );
}
for ( auto area : areas )
{
for ( auto widget : area->dockWidgets() )
delete widget;
std::vector<QPointer<ads::CDockAreaWidget>> areas;
for (int i = 0; i != dockAreaCount(); ++i)
{
areas.push_back( dockArea(i) );
}
for ( auto area : areas )
{
if (!area || area->dockManager() != this) continue;
delete area;
}
// QPointer delete safety - just in case some dock wigdet in destruction
// deletes another related/twin or child dock widget.
std::vector<QPointer<QWidget>> deleteWidgets;
for ( auto widget : area->dockWidgets() )
{
deleteWidgets.push_back(widget);
}
for ( auto ptrWdg : deleteWidgets)
{
delete ptrWdg;
}
}
auto FloatingWidgets = d->FloatingWidgets;
for (auto FloatingWidget : FloatingWidgets)
{
FloatingWidget->deleteContent();
delete FloatingWidget;
}
// Delete Dock Widgets before Areas so widgets can access them late (like dtor)
for ( auto area : areas )
{
delete area;
}
delete d;
}
@@ -568,7 +591,7 @@ bool CDockManager::eventFilter(QObject *obj, QEvent *e)
// Window always on top of the MainWindow.
if (e->type() == QEvent::WindowActivate)
{
for (auto _window : floatingWidgets())
for (auto _window : d->FloatingWidgets)
{
if (!_window->isVisible() || window()->isMinimized())
{
@@ -590,7 +613,7 @@ bool CDockManager::eventFilter(QObject *obj, QEvent *e)
}
else if (e->type() == QEvent::WindowDeactivate)
{
for (auto _window : floatingWidgets())
for (auto _window : d->FloatingWidgets)
{
if (!_window->isVisible() || window()->isMinimized())
{
@@ -613,7 +636,7 @@ bool CDockManager::eventFilter(QObject *obj, QEvent *e)
// Sync minimize with MainWindow
if (e->type() == QEvent::WindowStateChange)
{
for (auto _window : floatingWidgets())
for (auto _window : d->FloatingWidgets)
{
if (! _window->isVisible())
{
@@ -725,7 +748,12 @@ const QList<CDockContainerWidget*> CDockManager::dockContainers() const
//============================================================================
const QList<CFloatingDockContainer*> CDockManager::floatingWidgets() const
{
return d->FloatingWidgets;
QList<CFloatingDockContainer*> res;
for (auto &fl : d->FloatingWidgets)
{
if (fl) res.append(fl);
}
return res;
}
@@ -1125,7 +1153,7 @@ QAction* CDockManager::addToggleViewActionToMenu(QAction* ToggleViewAction,
bool AlphabeticallySorted = (MenuAlphabeticallySorted == d->MenuInsertionOrder);
if (!Group.isEmpty())
{
QMenu* GroupMenu = d->ViewMenuGroups.value(Group, 0);
QMenu* GroupMenu = d->ViewMenuGroups.value(Group, nullptr);
if (!GroupMenu)
{
GroupMenu = new QMenu(Group, this);
@@ -1318,7 +1346,7 @@ QList<int> CDockManager::splitterSizes(CDockAreaWidget *ContainedArea) const
{
if (ContainedArea)
{
auto Splitter = internal::findParent<CDockSplitter*>(ContainedArea);
auto Splitter = ContainedArea->parentSplitter();
if (Splitter)
{
return Splitter->sizes();
@@ -1335,7 +1363,7 @@ void CDockManager::setSplitterSizes(CDockAreaWidget *ContainedArea, const QList<
return;
}
auto Splitter = internal::findParent<CDockSplitter*>(ContainedArea);
auto Splitter = ContainedArea->parentSplitter();
if (Splitter && Splitter->count() == sizes.count())
{
Splitter->setSizes(sizes);
@@ -1422,6 +1450,47 @@ QSize CDockManager::dockWidgetToolBarIconSize(CDockWidget::eState State) const
}
//===========================================================================
void CDockManager::lockDockWidgetFeaturesGlobally(CDockWidget::DockWidgetFeatures Value)
{
// Limit the features to CDockWidget::GloballyLockableFeatures
Value &= CDockWidget::GloballyLockableFeatures;
if (d->LockedDockWidgetFeatures == Value)
{
return;
}
d->LockedDockWidgetFeatures = Value;
// Call the notifyFeaturesChanged() function for all dock widgets to update
// the state of the close and detach buttons
for (auto DockWidget : d->DockWidgetsMap)
{
DockWidget->notifyFeaturesChanged();
}
}
//===========================================================================
CDockWidget::DockWidgetFeatures CDockManager::globallyLockedDockWidgetFeatures() const
{
return d->LockedDockWidgetFeatures;
}
//===========================================================================
void CDockManager::setConfigParam(CDockManager::eConfigParam Param, QVariant Value)
{
StaticConfigParams[Param] = Value;
}
//===========================================================================
QVariant CDockManager::configParam(eConfigParam Param, QVariant Default)
{
return StaticConfigParams[Param].isValid() ? StaticConfigParams[Param] : Default;
}
} // namespace ads
//---------------------------------------------------------------------------

View File

@@ -214,6 +214,7 @@ public:
//! Users can overwrite this by setting the environment variable ADS_UseNativeTitle to "1" or "0".
MiddleMouseButtonClosesTab = 0x2000000, //! If the flag is set, the user can use the mouse middle button to close the tab under the mouse
DisableTabTextEliding = 0x4000000, //! Set this flag to disable eliding of tab texts in dock area tabs
ShowTabTextOnlyForActiveTab =0x8000000, //! Set this flag to show label texts in dock area tabs only for active tabs
DefaultDockAreaButtons = DockAreaHasCloseButton
| DockAreaHasUndockButton
@@ -253,15 +254,24 @@ public:
AutoHideCloseButtonCollapsesDock = 0x40, ///< Close button of an auto hide container collapses the dock instead of hiding it completely
AutoHideHasCloseButton = 0x80, //< If the flag is set an auto hide title bar has a close button
AutoHideHasMinimizeButton = 0x100, ///< if this flag is set, the auto hide title bar has a minimize button to collapse the dock widget
AutoHideOpenOnDragHover = 0x200, ///< if this flag is set, dragging hover the tab bar will open the dock
DefaultAutoHideConfig = AutoHideFeatureEnabled
| DockAreaHasAutoHideButton
| AutoHideCloseButtonCollapsesDock
| AutoHideHasCloseButton
| AutoHideHasMinimizeButton
};
Q_DECLARE_FLAGS(AutoHideFlags, eAutoHideFlag)
/**
* Global configuration parameters that you can set via setConfigParam()
*/
enum eConfigParam
{
AutoHideOpenOnDragHoverDelay_ms, ///< Delay in ms before the dock opens on drag hover if AutoHideOpenOnDragHover flag is set
ConfigParamCount // just a delimiter to count number of config params
};
/**
* Default Constructor.
@@ -323,6 +333,17 @@ public:
*/
static bool testAutoHideConfigFlag(eAutoHideFlag Flag);
/**
* Sets the value for the given config parameter
*/
static void setConfigParam(eConfigParam Param, QVariant Value);
/**
* Returns the value for the given config parameter or the default value
* if the parameter is not set.
*/
static QVariant configParam(eConfigParam Param, QVariant Default);
/**
* Returns the global icon provider.
* The icon provider enables the use of custom icons in case using
@@ -660,6 +681,38 @@ public:
*/
QSize dockWidgetToolBarIconSize(CDockWidget::eState State) const;
/**
* Returns all dock widget features that are globally locked by the dock
* manager.
* Globally locked features are removed from the features of all dock
* widgets.
*/
CDockWidget::DockWidgetFeatures globallyLockedDockWidgetFeatures() const;
/**
* Globally Lock features of all dock widgets to "freeze" the current
* workspace layout.
* For example, it is now possible to lock the workspace to avoid
* accidentally dragging a docked view. Locking wasnt possible before.
* So, users had to manually dock it back to the desired place after
* each accidental undock.
* You can use a combination of the following feature flags:
* - CDockWidget::DockWidgetClosable
* - CDockWidget::DockWidgetMovable
* - CDockWidget::DockWidgetFloatable
* - CDockWidget::DockWidgetPinable
*
* To clear the locked features, you can use CDockWidget::NoDockWidgetFeatures
* The following code shows how to lock and unlock dock widget features
* globally.
*
* \code
* DockManager->lockDockWidgetFeaturesGlobally();
* DockManager->lockDockWidgetFeaturesGlobally(CDockWidget::NoDockWidgetFeatures);
* \code
*/
void lockDockWidgetFeaturesGlobally(CDockWidget::DockWidgetFeatures Features = CDockWidget::GloballyLockableFeatures);
public Q_SLOTS:
/**
* Opens the perspective with the given name.

View File

@@ -80,8 +80,8 @@ struct DockWidgetPrivate
QWidget* Widget = nullptr;
CDockWidgetTab* TabWidget = nullptr;
CDockWidget::DockWidgetFeatures Features = CDockWidget::DefaultDockWidgetFeatures;
CDockManager* DockManager = nullptr;
CDockAreaWidget* DockArea = nullptr;
QPointer<CDockManager> DockManager;
QPointer<CDockAreaWidget> DockArea;
QAction* ToggleViewAction = nullptr;
bool Closed = false;
QScrollArea* ScrollArea = nullptr;
@@ -184,11 +184,11 @@ void DockWidgetPrivate::showDockWidget()
DockArea->setCurrentDockWidget(_this);
DockArea->toggleView(true);
TabWidget->show();
QSplitter* Splitter = internal::findParent<QSplitter*>(DockArea);
auto Splitter = DockArea->parentSplitter();
while (Splitter && !Splitter->isVisible() && !DockArea->isAutoHide())
{
Splitter->show();
Splitter = internal::findParent<QSplitter*>(Splitter);
Splitter = internal::findParent<CDockSplitter*>(Splitter);
}
CDockContainerWidget* Container = DockArea->dockContainer();
@@ -271,7 +271,10 @@ void DockWidgetPrivate::closeAutoHideDockWidgetsIfNeeded()
return;
}
if (!DockContainer->openedDockWidgets().isEmpty())
// If the dock container is the dock manager, or if it is not empty, then we
// don't need to do anything
if ((DockContainer == _this->dockManager())
|| !DockContainer->openedDockWidgets().isEmpty())
{
return;
}
@@ -382,7 +385,7 @@ CDockWidget::CDockWidget(const QString &title, QWidget *parent) :
//============================================================================
CDockWidget::~CDockWidget()
{
ADS_PRINT("~CDockWidget()");
ADS_PRINT("~CDockWidget(): " << this->windowTitle());
delete d;
}
@@ -511,10 +514,19 @@ void CDockWidget::setFeatures(DockWidgetFeatures features)
return;
}
d->Features = features;
notifyFeaturesChanged();
}
//============================================================================
void CDockWidget::notifyFeaturesChanged()
{
Q_EMIT featuresChanged(d->Features);
d->TabWidget->onDockWidgetFeaturesChanged();
if(CDockAreaWidget* DockArea = dockAreaWidget())
{
DockArea->onDockWidgetFeaturesChanged();
}
}
@@ -530,7 +542,14 @@ void CDockWidget::setFeature(DockWidgetFeature flag, bool on)
//============================================================================
CDockWidget::DockWidgetFeatures CDockWidget::features() const
{
return d->Features;
if (d->DockManager)
{
return d->Features &~ d->DockManager->globallyLockedDockWidgetFeatures();
}
else
{
return d->Features;
}
}
@@ -566,7 +585,7 @@ CDockContainerWidget* CDockWidget::dockContainer() const
}
else
{
return 0;
return nullptr;
}
}
@@ -749,11 +768,10 @@ void CDockWidget::toggleViewInternal(bool Open)
if (d->DockArea)
{
d->DockArea->toggleDockWidgetView(this, Open);
}
if (d->DockArea->isAutoHide())
{
d->DockArea->autoHideDockContainer()->toggleView(Open);
if (d->DockArea->isAutoHide())
{
d->DockArea->autoHideDockContainer()->toggleView(Open);
}
}
if (Open && TopLevelDockWidgetBefore)

View File

@@ -165,6 +165,7 @@ public:
DefaultDockWidgetFeatures = DockWidgetClosable | DockWidgetMovable | DockWidgetFloatable | DockWidgetFocusable | DockWidgetPinnable,
AllDockWidgetFeatures = DefaultDockWidgetFeatures | DockWidgetDeleteOnClose | CustomCloseHandling,
DockWidgetAlwaysCloseAndDelete = DockWidgetForceCloseWithArea | DockWidgetDeleteOnClose,
GloballyLockableFeatures = DockWidgetClosable | DockWidgetMovable | DockWidgetFloatable | DockWidgetPinnable,
NoDockWidgetFeatures = 0x000
};
Q_DECLARE_FLAGS(DockWidgetFeatures, DockWidgetFeature)
@@ -256,7 +257,7 @@ public:
* by calling setObjectName() after construction.
* Use the layoutFlags to configure the layout of the dock widget.
*/
CDockWidget(const QString &title, QWidget* parent = 0);
CDockWidget(const QString &title, QWidget* parent = nullptr);
/**
* Virtual Destructor
@@ -336,6 +337,11 @@ public:
*/
DockWidgetFeatures features() const;
/**
* Triggers notification of feature change signals and functions
*/
void notifyFeaturesChanged();
/**
* Returns the dock manager that manages the dock widget or 0 if the widget
* has not been assigned to any dock manager yet

View File

@@ -56,7 +56,6 @@
namespace ads
{
static const char* const LocationProperty = "Location";
using tTabLabel = CElidingLabel;
/**
@@ -225,7 +224,7 @@ struct DockWidgetTabPrivate
QMenu* Menu)
{
auto Action = Menu->addAction(Title);
Action->setProperty("Location", Location);
Action->setProperty(internal::LocationProperty, Location);
QObject::connect(Action, &QAction::triggered, _this, &CDockWidgetTab::onAutoHideToActionClicked);
return Action;
}
@@ -421,11 +420,12 @@ void CDockWidgetTab::mouseReleaseEvent(QMouseEvent* ev)
break;
default:
if (CDockManager::testConfigFlag(CDockManager::FocusHighlighting))
{
d->focusController()->setDockWidgetTabPressed(false);
}
break; // do nothing
break;
}
if (CDockManager::testConfigFlag(CDockManager::FocusHighlighting))
{
d->focusController()->setDockWidgetTabPressed(false);
}
}
else if (ev->button() == Qt::MiddleButton)
@@ -580,6 +580,14 @@ void CDockWidgetTab::setActiveTab(bool active)
{
d->updateCloseButtonVisibility(active);
if(CDockManager::testConfigFlag(CDockManager::ShowTabTextOnlyForActiveTab) && !d->Icon.isNull())
{
if(active)
d->TitleLabel->setVisible(true);
else
d->TitleLabel->setVisible(false);
}
// Focus related stuff
if (CDockManager::testConfigFlag(CDockManager::FocusHighlighting) && !d->DockWidget->dockManager()->isRestoringState())
{
@@ -755,7 +763,7 @@ void CDockWidgetTab::autoHideDockWidget()
//===========================================================================
void CDockWidgetTab::onAutoHideToActionClicked()
{
int Location = sender()->property(LocationProperty).toInt();
int Location = sender()->property(internal::LocationProperty).toInt();
d->DockWidget->toggleAutoHide((SideBarLocation)Location);
}
@@ -781,6 +789,13 @@ bool CDockWidgetTab::event(QEvent *e)
}
//============================================================================
eDragState CDockWidgetTab::dragState() const
{
return d->DragState;
}
//============================================================================
void CDockWidgetTab::onDockWidgetFeaturesChanged()
{

View File

@@ -84,7 +84,7 @@ public:
* param[in] DockWidget The dock widget this title bar belongs to
* param[in] parent The parent widget of this title bar
*/
CDockWidgetTab(CDockWidget* DockWidget, QWidget* parent = 0);
CDockWidgetTab(CDockWidget* DockWidget, QWidget* parent = nullptr);
/**
* Virtual Destructor
@@ -178,6 +178,12 @@ public:
*/
void setIconSize(const QSize& Size);
/**
* Returns the current drag state of this tab.
* Use this function to determine if the tab is currently being dragged
*/
eDragState dragState() const;
public Q_SLOTS:
virtual void setVisible(bool visible) override;

View File

@@ -58,8 +58,8 @@ protected:
public:
using Super = QLabel;
CElidingLabel(QWidget* parent = 0, Qt::WindowFlags f = Qt::WindowFlags ());
CElidingLabel(const QString& text, QWidget* parent = 0, Qt::WindowFlags f = Qt::WindowFlags ());
CElidingLabel(QWidget* parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags ());
CElidingLabel(const QString& text, QWidget* parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags ());
virtual ~CElidingLabel();
/**

View File

@@ -357,7 +357,7 @@ static const char* windowsMessageString(int MessageId)
#endif
static unsigned int zOrderCounter = 0;
static unsigned int zOrderCounterFloating = 0;
/**
* Private data class of CFloatingDockContainer class (pimpl)
*/
@@ -365,7 +365,7 @@ struct FloatingDockContainerPrivate
{
CFloatingDockContainer *_this;
CDockContainerWidget *DockContainer;
unsigned int zOrderIndex = ++zOrderCounter;
unsigned int zOrderIndex = ++zOrderCounterFloating;
QPointer<CDockManager> DockManager;
eDragState DraggingState = DraggingInactive;
QPoint DragStartMousePosition;
@@ -760,6 +760,7 @@ CFloatingDockContainer::CFloatingDockContainer(CDockWidget *DockWidget) :
d->DockManager->notifyWidgetOrAreaRelocation(DockWidget);
}
//============================================================================
CFloatingDockContainer::~CFloatingDockContainer()
{
@@ -771,6 +772,36 @@ CFloatingDockContainer::~CFloatingDockContainer()
delete d;
}
//============================================================================
void CFloatingDockContainer::deleteContent()
{
std::vector<QPointer<ads::CDockAreaWidget>> areas;
for (int i = 0; i != dockContainer()->dockAreaCount(); ++i)
{
areas.push_back( dockContainer()->dockArea(i) );
}
for (auto area : areas)
{
if (!area)
{
continue;
}
// QPointer delete safety - just in case some dock widget in destruction
// deletes another related/twin or child dock widget.
std::vector<QPointer<QWidget>> deleteWidgets;
for (auto widget : area->dockWidgets())
{
deleteWidgets.push_back(widget);
}
for (auto ptrWdg : deleteWidgets)
{
delete ptrWdg;
}
}
}
//============================================================================
CDockContainerWidget* CFloatingDockContainer::dockContainer() const
{
@@ -787,7 +818,7 @@ void CFloatingDockContainer::changeEvent(QEvent *event)
if (isActiveWindow())
{
ADS_PRINT("FloatingWidget::changeEvent QEvent::ActivationChange ");
d->zOrderIndex = ++zOrderCounter;
d->zOrderIndex = ++zOrderCounterFloating;
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
if (d->DraggingState == DraggingFloatingWidget)
@@ -1142,7 +1173,7 @@ QList<CDockWidget*> CFloatingDockContainer::dockWidgets() const
}
//============================================================================
void CFloatingDockContainer::hideAndDeleteLater()
void CFloatingDockContainer::finishDropOperation()
{
// Widget has been redocked, so it must be hidden right way (see
// https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/351)
@@ -1150,6 +1181,11 @@ void CFloatingDockContainer::hideAndDeleteLater()
// dock widgets that shall not be toggled hidden.
d->AutoHideChildren = false;
hide();
// The floating widget will be deleted now. Ensure, that the destructor
// of the floating widget does not delete any dock areas that have been
// moved to a new container - simply remove all dock areas before deleting
// the floating widget
d->DockContainer->removeAllDockAreas();
deleteLater();
if (d->DockManager)
{
@@ -1295,7 +1331,8 @@ void CFloatingDockContainer::onMaximizeRequest()
//============================================================================
void CFloatingDockContainer::showNormal(bool fixGeometry)
{
if (windowState() == Qt::WindowMaximized)
if ( (windowState() & Qt::WindowMaximized) != 0 ||
(windowState() & Qt::WindowFullScreen) != 0)
{
QRect oldNormal = normalGeometry();
Super::showNormal();

View File

@@ -131,21 +131,19 @@ protected:
virtual void startFloating(const QPoint& DragStartMousePos, const QSize& Size,
eDragState DragState, QWidget* MouseEventHandler) override;
/**
* Call this function to start dragging the floating widget
*/
void startDragging(const QPoint& DragStartMousePos, const QSize& Size,
QWidget* MouseEventHandler)
{
startFloating(DragStartMousePos, Size, DraggingFloatingWidget, MouseEventHandler);
}
/**
* Call this function if you explicitly want to signal that dragging has
* finished
*/
virtual void finishDragging() override;
/**
* This function deletes all dock widgets in it.
* This functions should be called only from dock manager in its
* destructor before deleting the floating widget
*/
void deleteContent();
/**
* Call this function if you just want to initialize the position
* and size of the floating widget
@@ -229,6 +227,15 @@ public:
*/
CDockContainerWidget* dockContainer() const;
/**
* Call this function to start dragging the floating widget
*/
void startDragging(const QPoint& DragStartMousePos, const QSize& Size,
QWidget* MouseEventHandler)
{
startFloating(DragStartMousePos, Size, DraggingFloatingWidget, MouseEventHandler);
}
/**
* This function returns true, if it can be closed.
* It can be closed, if all dock widgets in all dock areas can be closed
@@ -258,9 +265,9 @@ public:
QList<CDockWidget*> dockWidgets() const;
/**
* This function hides the floating bar instantely and delete it later.
* This function hides the floating widget instantly and delete it later.
*/
void hideAndDeleteLater();
void finishDropOperation();
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
/**

View File

@@ -92,7 +92,7 @@ xcb_atom_t xcb_get_atom(const char *name)
}
xcb_connection_t *connection = x11_connection();
xcb_intern_atom_cookie_t request = xcb_intern_atom(connection, 1, strlen(name), name);
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(connection, request, NULL);
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(connection, request, nullptr);
if (!reply)
{
return XCB_ATOM_NONE;

View File

@@ -158,7 +158,7 @@ enum SideBarLocation
SideBarBottom,
SideBarNone
};
Q_ENUMS(SideBarLocation);
Q_ENUMS(SideBarLocation)
namespace internal
@@ -167,6 +167,7 @@ static const bool RestoreTesting = true;
static const bool Restore = false;
static const char* const ClosedProperty = "close";
static const char* const DirtyProperty = "dirty";
static const char* const LocationProperty = "Location";
extern const int FloatingWidgetDragStartEvent;
extern const int DockedWidgetDragStartEvent;
@@ -268,7 +269,7 @@ T findParent(const QWidget* w)
}
parentWidget = parentWidget->parentWidget();
}
return 0;
return nullptr;
}
/**

View File

@@ -137,11 +137,11 @@ CFloatingWidgetTitleBar::CFloatingWidgetTitleBar(CFloatingDockContainer *parent)
d->FloatingWidget = parent;
d->createLayout();
auto normalPixmap = this->style()->standardPixmap(QStyle::SP_TitleBarNormalButton, 0, d->MaximizeButton);
auto normalPixmap = this->style()->standardPixmap(QStyle::SP_TitleBarNormalButton, nullptr, d->MaximizeButton);
d->NormalIcon.addPixmap(normalPixmap, QIcon::Normal);
d->NormalIcon.addPixmap(internal::createTransparentPixmap(normalPixmap, 0.25), QIcon::Disabled);
auto maxPixmap = this->style()->standardPixmap(QStyle::SP_TitleBarMaxButton, 0, d->MaximizeButton);
auto maxPixmap = this->style()->standardPixmap(QStyle::SP_TitleBarMaxButton, nullptr, d->MaximizeButton);
d->MaximizeIcon.addPixmap(maxPixmap, QIcon::Normal);
d->MaximizeIcon.addPixmap(internal::createTransparentPixmap(maxPixmap, 0.25), QIcon::Disabled);
setMaximizedIcon(d->Maximized);

View File

@@ -333,7 +333,7 @@ ads--CAutoHideDockContainer ads--CDockAreaWidget[focused="true"] ads--CDockAreaT
ads--CAutoHideDockContainer #dockAreaAutoHideButton {
qproperty-icon: url(:/ads/images/vs-pin-button-pinned-focused.svg),
qproperty-icon: url(:/ads/images/vs-pin-button-pinned-focused.svg);
qproperty-iconSize: 16px;
}