Compare commits

..

52 Commits
4.1.0 ... 4.3.0

Author SHA1 Message Date
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
Uwe Kindler
59b4dfb89c Updated documentation 2023-11-07 12:23:01 +01:00
Uwe Kindler
bfa5124999 Merge branch 'master' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System 2023-11-06 12:18:40 +01:00
Uwe Kindler
234cf9ac58 Improved disabled pin button 2023-11-06 12:17:39 +01:00
Uwe Kindler
8f77f4b42a Added documentation for new Auto Hide Minimize button 2023-11-06 12:08:31 +01:00
Uwe Kindler
fa94da00d4 Added optional Minimize button to AutoHide dock widget title bar 2023-11-06 11:06:12 +01:00
gafusss
40beef964b Fix memory leak in CDockContainerWidget::restoreState (#576)
delete old root splitter layout item
2023-11-04 06:49:01 +01:00
Uwe Kindler
420baeedfe Added support for global dock manager toolbar style and custom dock widget toolbar style for dock widgets 2023-10-19 10:25:23 +02:00
Uwe Kindler
0f8096e314 Added minimize and close action to Auto Hide context menu 2023-10-19 09:10:26 +02:00
uggas
9ec97a8867 Add ability to set user defined toggle view action (#562)
Co-authored-by: Harbinder Saggu <harbinder.saggu@safe.com>
2023-10-19 08:07:55 +02:00
Nate Skulic
55ef6ef863 Improve Python Support (#567)
- Reduce requirements for the python build.
- Fix version number.
- Generate type hints for *.pyi files.
- Make functional for sip-build
- Reduced the unnecessary depth of the package.

NOTE: This is a breaking change for python users, where, `from PyQtAds import QtAds` is changed to `import PyQtAds as QtAds`( or simply `import PyQtAds`)
2023-10-05 07:23:54 +02:00
Henning
c0985f6497 Fix empty floating widget on linux (#563) 2023-09-22 20:03:02 +02:00
Uwe Kindler
2f1ef61f82 Fixed documentation issue - wrong location of picture 2023-09-19 08:53:04 +02:00
Uwe Kindler
62d2dd213d Implemented #554 - Add a configuration that avoid tab label eliding 2023-09-19 08:44:31 +02:00
vhutter
3c941a2312 Enabled modifying MSVC runtime in cmake (#559) 2023-09-11 14:57:09 +02:00
603185423
4634b5617c CMake Script - Add debug postfix "d" (#406) (#558)
https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/406
2023-09-11 12:56:32 +02:00
André Meyer
2178b52621 Delete implicit ScrollArea when content Widget is deleted in hideDockWidget() (#551) 2023-08-24 11:20:32 +02:00
Ahmad Syarifuddin
61573cba16 Fix crash in auto hide tab (#552)
- Crash is caused by dragging an autohide tab out when it is an icon only.
- The crash can actually happen with non icon only tabs, but is masked by the orientation check.
- Soln: Check if auto hide container exists first on mouse finish dragging event.
2023-08-24 11:15:43 +02:00
Joel Bodenmann
2d2de53dcd Fix CMake scripts for FreeBSD (#550)
This fixes linking of the XCB library on FreeBSD.
2023-08-17 17:57:16 +02:00
luzpaz
0d10c6e2d9 Fix various typos (#547)
Typos found via `codespell -q 3 -L te,ridiculus,varius`
2023-08-08 19:46:12 +02:00
Uwe Kindler
767933d0cb Merge branch 'master' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System 2023-08-03 15:58:07 +02:00
Uwe Kindler
7a362b7ee3 Fixed issue #544 - crash in CDockAreaTabBar::currentTab() 2023-08-03 15:57:57 +02:00
Nicolas Elie
77ed9b0661 Update PyQt bindings to 4.1.1 (#542) 2023-08-02 20:23:49 +02:00
Uwe Kindler
65600a4dcd Removed unimolemented superfluous function definitions 2023-07-14 08:07:37 +02:00
81 changed files with 1200 additions and 272 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,9 @@
cmake_minimum_required(VERSION 3.5)
if (POLICY CMP0091)
cmake_policy(SET CMP0091 NEW)
endif (POLICY CMP0091)
# By default, the version information is extracted from the git index. However,
# we can override this behavior by explicitly setting ADS_VERSION and
# skipping the git checks. This is useful for cases where this project is being

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

@@ -271,6 +271,10 @@ struct MainWindowPrivate
auto ToolBar = DockWidget->createDefaultToolBar();
ToolBar->addAction(ui.actionSaveState);
ToolBar->addAction(ui.actionRestoreState);
// For testing all calendar dock widgets have a the tool button style
// Qt::ToolButtonTextUnderIcon
DockWidget->setToolBarStyleSource(ads::CDockWidget::ToolBarStyleFromDockWidget);
DockWidget->setToolBarStyle(Qt::ToolButtonTextUnderIcon, ads::CDockWidget::StateFloating);
return DockWidget;
}
@@ -527,6 +531,7 @@ void MainWindowPrivate::createContent()
// Tests CustomCloseHandling without DeleteOnClose
LabelDockWidget->setFeature(ads::CDockWidget::CustomCloseHandling, true);
LabelDockWidget->setWindowTitle(LabelDockWidget->windowTitle() + " [Custom Close]");
QObject::connect(LabelDockWidget, &ads::CDockWidget::closeRequested, [LabelDockWidget, this]()
{
int Result = QMessageBox::question(_this, "Custom Close Request",
@@ -587,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"));
@@ -621,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"));
@@ -763,6 +779,7 @@ CMainWindow::CMainWindow(QWidget *parent) :
// Now create the dock manager and its content
d->DockManager = new CDockManager(this);
d->DockManager->setDockWidgetToolBarStyle(Qt::ToolButtonIconOnly, ads::CDockWidget::StateFloating);
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
connect(d->PerspectiveComboBox, SIGNAL(activated(QString)),
@@ -1024,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

@@ -2,7 +2,7 @@ import os
import sys
from PyQt5 import uic
from PyQtAds import QtAds
import PyQtAds as QtAds
UI_FILE = os.path.join(os.path.dirname(__file__), 'StatusDialog.ui')
StatusDialogUI, StatusDialogBase = uic.loadUiType(UI_FILE)

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)
@@ -65,7 +65,7 @@ If this flag is cleared, the widget resizing is deferred until the mouse button
### Opaque and non-opaque undocking
By default, opaque undocking is active. That means, as soon as you drag a dock widget or a dock area with a number of dock widgets it will be undocked and moved into a floating widget and then the floating widget will be dragged around. That means undocking will take place immediatelly. You can compare this with opaque splitter resizing. If the flag `OpaqueUndocking` is cleared, then non-opaque undocking is active. In this mode, undocking is more like a standard drag and drop operation. That means, the dragged dock widget or dock area is not undocked immediatelly. Instead, a drag preview widget is created and dragged around to indicate the future position of the dock widget or dock area. The actual dock operation is only executed when the mouse button is released. That makes it possible, to cancel an active drag operation with the escape key.
By default, opaque undocking is active. That means, as soon as you drag a dock widget or a dock area with a number of dock widgets it will be undocked and moved into a floating widget and then the floating widget will be dragged around. That means undocking will take place immediately. You can compare this with opaque splitter resizing. If the flag `OpaqueUndocking` is cleared, then non-opaque undocking is active. In this mode, undocking is more like a standard drag and drop operation. That means, the dragged dock widget or dock area is not undocked immediately. Instead, a drag preview widget is created and dragged around to indicate the future position of the dock widget or dock area. The actual dock operation is only executed when the mouse button is released. That makes it possible, to cancel an active drag operation with the escape key.
The drag preview widget can be configured by a number of global dock manager flags:

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -27,10 +27,17 @@
- [`FloatingContainerForceNativeTitleBar` (Linux only)](#floatingcontainerforcenativetitlebar-linux-only)
- [`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)
- [Show / Hide Auto-Hide Widgets via Mouse Over](#show--hide-auto-hide-widgets-via-mouse-over)
- [Drag \& Drop to Auto-Hide](#drag--drop-to-auto-hide)
- [Auto-Hide Tab Insertion Order](#auto-hide-tab-insertion-order)
- [Auto-Hide Tab Sorting](#auto-hide-tab-sorting)
- [Auto-Hide Drag to Float / Dock](#auto-hide-drag-to-float--dock)
- [Auto-Hide Context Menu](#auto-hide-context-menu)
- [Adding Auto Hide Widgets](#adding-auto-hide-widgets)
- [Setting Auto-Hide Flags](#setting-auto-hide-flags)
- [`AutoHideFeatureEnabled`](#autohidefeatureenabled)
@@ -40,6 +47,8 @@
- [`AutoHideSideBarsIconOnly`](#autohidesidebarsicononly)
- [`AutoHideShowOnMouseOver`](#autohideshowonmouseover)
- [`AutoHideCloseButtonCollapsesDock`](#autohideclosebuttoncollapsesdock)
- [`AutoHideHasCloseButton`](#autohidehasclosebutton)
- [`AutoHideHasMinimizeButton`](#autohidehasminimizebutton)
- [DockWidget Feature Flags](#dockwidget-feature-flags)
- [`DockWidgetClosable`](#dockwidgetclosable)
- [`DockWidgetMovable`](#dockwidgetmovable)
@@ -294,8 +303,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.
@@ -467,6 +477,24 @@ possible in various web browsers.
![MiddleMouseButtonClosesTab true](cfg_flag_MiddleMouseButtonClosesTab.gif)
### `DisableTabTextEliding`
Set this flag to disable eliding of tab texts in dock area tabs:
![DisableTabTextEliding true](cfg_flag_DisableTabTextEliding_true.png)
The flag is disabled by default and the text in all tabs is elided to show as
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
@@ -481,7 +509,7 @@ Enabling this feature adds a button with a pin icon to each dock area.
![DockAreaHasAutoHideButton true](cfg_flag_DockAreaHasAutoHideButton.png)
By clicking this button, the current dock widget (or the complete area - depending on the
configuration flags) will be pinned to a certain border. The border is choosen
configuration flags) will be pinned to a certain border. The border is chosen
depending on the location of the dock area. If you click the pin button while
holding down the **Ctrl** key, the whole dock area will be pinned to a certain
border.
@@ -503,6 +531,59 @@ the Auto-Hide widget is shown, if the user hovers over the Auto-Hide tab and is
collapsed if the mouse cursor leaves the Auto-Hide widget. Showing and hiding
by mouse click still works if this feature is enabled.
### Drag & Drop to Auto-Hide
You can easily drag any dock widget or any floating widget to the
borders of a window to pin it as a auto-hide tab in one of the 4 sidebars.
If you drag a dock widget close the one of the four window borders, special
drop overlays will be shown to indicate the drop area for auto-hide widgets:
![Auo-Hide drag to Sidebar](AutoHide_Drag_to_Sidebar.gif)
Of course, this also works with dock areas:
![Auo-Hide drag Dock Area](AutoHide_Drag_DockArea.gif)
If you drag a dock widget or dock area into a sidebar, then you even have
control over where tabs are inserted. Simply drag your mouse over a specific
auto-hide tab, and your dragged dock widget will be inserted before this tab.
Drag to the sidebar area behind the last tab, and the dragged widget will be
appended as last tab. In the following screen capture, the **Image Viewer 1** will
be inserted before the **Table 0** Auto-Hide tab and the **Image Viewer 2**
is appended behind the last tab:
![Auo-Hide tab insert order](AutoHide_Tab_Insert_Order.gif)
### Auto-Hide Tab Insertion Order
It is also possible to drag Auto-Hide tabs to a new auto-hide position.
That means, you can drag them to a different border or sidebar:
![Auto-Hide change sidebar](AutoHide_Change_Sidebar.gif)
### Auto-Hide Tab Sorting
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)
### Auto-Hide Drag to Float / Dock
But that is not all. You can also simply move Auto-Hide tabs to another
floating widget or dock them via drag and drop:
![Auo-Hide drag to float or dock](AutoHide_Drag_to_Float_or_Dock.gif)
### Auto-Hide Context Menu
All Auto-Hide tabs now have a context menu, that provides all the functionality
that you know from Dock widget tabs. With the **Pin To...** item from the
context menu it is very easy to move an Auto-Hide tab to a different Auto-Hide
sidebar:
![Auo-Hide context menu](AutoHide_Context_Menu.png)
### Adding Auto Hide Widgets
Adding an auto hide widget is similar to adding a dock widget, simply call
@@ -605,6 +686,24 @@ closing it.
![AutoHideCloseButtonCollapsesDock true](cfg_flag_AutoHideCloseButtonCollapsesDock_true.gif)
If you enable the `AutoHideHasMinimizeButton` flag, you should disable this
flag our you will have two buttons with minimize functionality.
### `AutoHideHasCloseButton`
If this flag is set (default), then each auto hide widget has a close button:
![AutoHideHasCloseButton](cfg_flag_AutoHideHasCloseButton.png)
The functionality of the close button (close or minimize) is configured by the
`AutoHideCloseButtonCollapsesDock` flag.
### `AutoHideHasMinimizeButton`
If this flag is set (disabled by default), then each auto hide widget has a minimize button.
![AutoHideHasMinimizeButton](cfg_flag_AutoHideHasMinimizeButton.png)
## DockWidget Feature Flags
### `DockWidgetClosable`

View File

@@ -8,7 +8,7 @@ from PyQt5.QtWidgets import (QApplication, QLabel, QCalendarWidget, QFrame, QTre
QTableWidget, QFileSystemModel, QPlainTextEdit, QToolBar,
QWidgetAction, QComboBox, QAction, QSizePolicy, QInputDialog)
from PyQtAds import QtAds
import PyQtAds as QtAds
UI_FILE = os.path.join(os.path.dirname(__file__), 'mainwindow.ui')
MainWindowUI, MainWindowBase = uic.loadUiType(UI_FILE)

View File

@@ -8,7 +8,7 @@ from PyQt5.QtWidgets import (QApplication, QLabel, QCalendarWidget, QFrame, QTre
QTableWidget, QFileSystemModel, QPlainTextEdit, QToolBar,
QWidgetAction, QComboBox, QAction, QSizePolicy, QInputDialog)
from PyQtAds import QtAds
import PyQtAds as QtAds
UI_FILE = os.path.join(os.path.dirname(__file__), 'mainwindow.ui')
MainWindowUI, MainWindowBase = uic.loadUiType(UI_FILE)

View File

@@ -1,6 +1,6 @@
import sys
from PyQtAds import QtAds
import PyQtAds as QtAds
from PyQt5.QtGui import QCloseEvent
from PyQt5.QtCore import (qDebug, pyqtSlot, QObject, pyqtSignal)
from PyQt5.QtWidgets import (QMainWindow, QAction, QTextEdit, QApplication,
@@ -70,4 +70,4 @@ if __name__ == '__main__':
action.triggered.connect(on_action2_triggered)
w.show()
app.exec_()
app.exec_()

View File

@@ -3,7 +3,7 @@ import sys
from PyQt5.QtWidgets import (QApplication, QWidget, QVBoxLayout, QMessageBox,
QInputDialog, QMenu, QLineEdit)
from PyQt5.QtGui import QIcon
from PyQtAds import QtAds
import PyQtAds as QtAds
from dockindockmanager import DockInDockManager
from perspectiveactions import LoadPerspectiveAction, RemovePerspectiveAction
@@ -200,4 +200,4 @@ class DockInDockWidget(QWidget):
for closed in self.getManager().dockWidgetsMap().values():
if not closed in visible_widgets:
self.dumpStatus(widget=closed, tab=tab, suffix=" (closed)")
self.dumpStatus(widget=closed, tab=tab, suffix=" (closed)")

View File

@@ -1,7 +1,7 @@
from PyQt5.QtWidgets import QAction, QMenu, QInputDialog, QLineEdit
from PyQt5.QtCore import QSettings
from PyQtAds import QtAds
import PyQtAds as QtAds
CHILD_PREFIX = "Child-"
@@ -211,4 +211,4 @@ class MoveDockWidgetAction(QAction):
widget.dockManager().removeDockWidget(widget)
move_to.addDockWidget(QtAds.CenterDockWidgetArea, widget, move_to.getInsertDefaultPos())
else:
assert False
assert False

View File

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

View File

@@ -4,7 +4,7 @@ import atexit
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel
from PyQt5.QtCore import Qt
from PyQtAds import QtAds
import PyQtAds as QtAds
from perspectives import PerspectivesManager
from dockindock import DockInDockWidget
@@ -69,4 +69,4 @@ if __name__ == '__main__':
w = MainWindow()
w.show()
app.exec_()
app.exec_()

View File

@@ -4,7 +4,7 @@ import shutil
import atexit
from PyQt5.QtCore import pyqtSignal, QSettings, QObject
from PyQtAds import QtAds
import PyQtAds as QtAds
from dockindockmanager import DockInDockManager
from dockindock import DockInDockWidget
@@ -200,4 +200,4 @@ class PerspectivesManager(QObject):
except FileNotFoundError:
pass
if not shutil.copy(settings.fileName(), to_save):
assert False
assert False

View File

@@ -6,7 +6,7 @@ from PyQt5.QtCore import Qt, QSignalBlocker
from PyQt5.QtWidgets import (QApplication, QMainWindow, QLabel, QComboBox, QTableWidget,
QAction, QWidgetAction, QSizePolicy, QInputDialog)
from PyQt5.QtGui import QCloseEvent
from PyQtAds import QtAds
import PyQtAds as QtAds
UI_FILE = os.path.join(os.path.dirname(__file__), 'mainwindow.ui')
@@ -105,4 +105,4 @@ if __name__ == '__main__':
w = CMainWindow()
w.show()
app.exec_()
app.exec_()

View File

@@ -5,7 +5,7 @@ from PyQt5 import uic
from PyQt5.QtCore import Qt, QMargins
from PyQt5.QtWidgets import QApplication, QLabel, QVBoxLayout, QPlainTextEdit
from PyQtAds import QtAds
import PyQtAds as QtAds
UI_FILE = os.path.join(os.path.dirname(__file__), 'MainWindow.ui')
MainWindowUI, MainWindowBase = uic.loadUiType(UI_FILE)

View File

@@ -6,7 +6,7 @@ from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtGui import QCloseEvent
from PyQt5.QtWidgets import QApplication, QLabel
from PyQtAds import QtAds
import PyQtAds as QtAds
UI_FILE = os.path.join(os.path.dirname(__file__), 'MainWindow.ui')
MainWindowUI, MainWindowBase = uic.loadUiType(UI_FILE)

View File

@@ -1,12 +1,12 @@
# Specify the build system.
[build-system]
requires = ["sip >=6.0.2, <6.3", "PyQt-builder >=1.6, <2", "PyQt5==5.15.4", "PyQt5-sip<13,>=12.8"]
requires = ["sip >=6.0.2", "PyQt-builder >=1.6", "PyQt5>=5.15", "PyQt5-sip>=12.8"]
build-backend = "sipbuild.api"
# Specify the PEP 566 metadata for the project.
[tool.sip.metadata]
name = "PyQtAds"
version = "4.0.2"
version = "4.4.1"
summary = "Python bindings for Qt Advanced Docking System"
home-page = "https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/"
license = "LGPL v2.1"
@@ -16,8 +16,10 @@ description-content-type = "text/markdown"
[tool.sip.project]
tag-prefix = "QtAds"
dunder-init = true
[tool.sip.bindings.ads]
pep484-pyi = true
define-macros = ["ADS_SHARED_EXPORT"]
sip-file = "ads.sip"
include-dirs = ["src"]

View File

@@ -24,9 +24,10 @@ public:
CAutoHideDockContainer(ads::CDockWidget* DockWidget /Transfer/, ads::SideBarLocation area,
ads::CDockContainerWidget* parent /TransferThis/);
virtual ~CAutoHideDockContainer();
ads::CAutoHideSideBar* sideBar() const;
ads::CAutoHideSideBar* autoHideSideBar() const;
ads::CAutoHideTab* autoHideTab() const;
ads::CDockWidget* dockWidget() const;
int tabIndex() const;
void addDockWidget(ads::CDockWidget* DockWidget /Transfer/);
ads::SideBarLocation sideBarLocation() const;
void setSideBarLocation(ads::SideBarLocation SideBarLocation);
@@ -38,7 +39,9 @@ public:
void collapseView(bool Enable);
void toggleCollapseState();
void setSize(int Size);
void resetToInitialDockWidgetSize();
Qt::Orientation orientation() const;
void moveToNewSideBarLocation(ads::SideBarLocation);
};
};

View File

@@ -24,10 +24,13 @@ public:
void removeTab(ads::CAutoHideTab* SideTab) /TransferBack/;
ads::CAutoHideDockContainer* insertDockWidget(int Index, ads::CDockWidget* DockWidget /Transfer/);
void removeAutoHideWidget(ads::CAutoHideDockContainer* AutoHideWidget) /TransferBack/;
void addAutoHideWidget(ads::CAutoHideDockContainer* AutoHideWidget);
void addAutoHideWidget(ads::CAutoHideDockContainer* AutoHideWidget, int Index);
Qt::Orientation orientation() const;
ads::CAutoHideTab* tabAt(int index) const;
int tabCount() const;
ads::CAutoHideTab* tab(int index) const;
int tabAt(const QPoint& Pos) const;
int tabInsertIndexAt(const QPoint& Pos) const;
int indexOfTab(const CAutoHideTab& Tab) const;
int count() const;
int visibleTabCount() const;
bool hasVisibleTabs() const;
ads::SideBarLocation sideBarLocation() const;

View File

@@ -16,6 +16,10 @@ protected:
void setSideBar(ads::CAutoHideSideBar *SideTabBar);
void removeFromSideBar();
virtual bool event(QEvent* event);
virtual void contextMenuEvent(QContextMenuEvent* ev);
virtual void mousePressEvent(QMouseEvent* ev);
virtual void mouseReleaseEvent(QMouseEvent* ev);
virtual void mouseMoveEvent(QMouseEvent* ev);
public:
CAutoHideTab(QWidget* parent /TransferThis/ = 0);
@@ -29,6 +33,10 @@ public:
void setDockWidget(ads::CDockWidget* DockWidget);
bool iconOnly() const;
ads::CAutoHideSideBar* sideBar() const;
int tabIndex() const;
void setDockWidgetFloating();
void unpinDockWidget();
void requestCloseDockWidget();
};
};

View File

@@ -23,6 +23,8 @@ public:
int currentIndex() const;
ads::CDockWidgetTab* currentTab() const;
ads::CDockWidgetTab* tab(int Index) const;
int tabAt(const QPoint& Pos) const;
int tabInsertIndexAt(const QPoint& Pos) const;
virtual bool eventFilter(QObject *watched, QEvent *event);
bool isTabOpen(int Index) const;
virtual QSize minimumSizeHint() const;

View File

@@ -5,6 +5,22 @@
namespace ads
{
class CTitleBarButton : QToolButton
{
%TypeHeaderCode
#include <DockAreaTitleBar.h>
%End
public:
CTitleBarButton(bool visible = true, QWidget* parent /TransferThis/ = Q_NULLPTR );
virtual void setVisible(bool);
void setShowInTitleBar(bool);
protected:
bool event(QEvent *ev);
};
class CDockAreaTitleBar : QFrame
{
%TypeHeaderCode
@@ -26,14 +42,15 @@ public:
CDockAreaTitleBar(ads::CDockAreaWidget* parent /TransferThis/);
virtual ~CDockAreaTitleBar();
ads::CDockAreaTabBar* tabBar() const;
QAbstractButton* button(ads::TitleBarButton which) const;
ads::CTitleBarButton* button(ads::TitleBarButton which) const;
ads::CElidingLabel* autoHideTitleLabel() 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();
signals:
void tabBarClicked(int index);

View File

@@ -5,21 +5,6 @@
namespace ads
{
class CTitleBarButton : QToolButton
{
%TypeHeaderCode
#include <DockAreaTitleBar_p.h>
%End
protected:
bool event(QEvent *ev);
public:
CTitleBarButton(bool visible = true, QWidget* parent /TransferThis/ = Q_NULLPTR );
virtual void setVisible(bool visible);
};
class CSpacerWidget : QWidget
{
%TypeHeaderCode

View File

@@ -40,6 +40,9 @@ public:
virtual ~CDockAreaWidget();
ads::CDockManager* dockManager() const;
ads::CDockContainerWidget* dockContainer() const;
ads::CAutoHideDockContainer* autoHideDockContainer() const;
bool isAutoHide() const;
void setAutoHideDockContainer(CAutoHideDockContainer*);
virtual QSize minimumSizeHint() const;
QRect titleBarGeometry() const;
QRect contentAreaGeometry() const;
@@ -74,7 +77,10 @@ public:
public slots:
void setCurrentIndex(int index);
void closeArea();
void setAutoHide(bool Enable, SideBarLocation Location = ads::SideBarNone, int TabIndex = -1);
void toggleAutoHide(SideBarLocation Location = ads::SideBarNone);
void closeOtherAreas();
void setFloating();
signals:
void tabBarClicked(int index);

View File

@@ -9,8 +9,8 @@ namespace ads
* Container that manages a number of dock areas with single dock widgets
* or tabyfied dock widgets in each area.
* Each window that support docking has a DockContainerWidget. That means
* the main application window and all floating windows are ore contain
* an DockContainerWidget.
* the main application window and all floating windows contain a
* DockContainerWidget.
*/
class CDockContainerWidget : QFrame
{
@@ -21,10 +21,10 @@ class CDockContainerWidget : QFrame
protected:
virtual bool event(QEvent *e);
QSplitter* rootSplitter() const;
ads::CAutoHideDockContainer* createAndSetupAutoHideContainer(ads::SideBarLocation area, ads::CDockWidget* DockWidget /Transfer/);
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);
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/);
void saveState(QXmlStreamWriter& Stream) const;
@@ -59,7 +59,7 @@ public:
ads::CDockWidget::DockWidgetFeatures features() const;
ads::CFloatingDockContainer* floatingWidget() const;
void closeOtherAreas(ads::CDockAreaWidget* KeepOpenArea);
ads::CAutoHideSideBar* sideTabBar(SideBarLocation area) const;
ads::CAutoHideSideBar* autoHideSideBar(SideBarLocation area) const;
QList<ads::CAutoHideDockContainer*> autoHideWidgets() const;
QRect contentRect() const;
QRect contentRectGlobal() const;

View File

@@ -187,8 +187,8 @@ public:
AutoHideButtonCheckable,
AutoHideSideBarsIconOnly,
AutoHideShowOnMouseOver,
DefaultAutoHideConfig,
AutoHideCloseButtonCollapsesDock,
DefaultAutoHideConfig,
};
typedef QFlags<ads::CDockManager::eAutoHideFlag> AutoHideFlags;

View File

@@ -22,8 +22,10 @@ public:
CDockOverlay(QWidget* parent /TransferThis/, eMode Mode = ads::CDockOverlay::ModeDockAreaOverlay);
virtual ~CDockOverlay();
void setAllowedAreas(ads::DockWidgetAreas areas);
void setAllowedArea(ads::DockWidgetArea area, bool Enable);
ads::DockWidgetAreas allowedAreas() const;
ads::DockWidgetArea dropAreaUnderCursor() const;
int tabIndexUnderCursor() const;
ads::DockWidgetArea visibleDropAreaUnderCursor() const;
ads::DockWidgetArea showOverlay(QWidget* target);
void hideOverlay();

View File

@@ -90,6 +90,7 @@ public:
void setSideTabWidget(ads::CAutoHideTab* SideTab /Transfer/) const;
bool isAutoHide() const;
ads::CAutoHideDockContainer* autoHideDockContainer() const;
ads::SideBarLocation autoHideLocation() const;
bool isFloating() const;
bool isInFloatingContainer() const;
bool isClosed() const;
@@ -125,9 +126,10 @@ public slots:
void setFloating();
void deleteDockWidget();
void closeDockWidget();
void requestCloseDockWidget();
void showFullScreen();
void showNormal();
void setAutoHide(bool Enable, ads::SideBarLocation Location = ads::SideBarNone);
void setAutoHide(bool Enable, ads::SideBarLocation Location = ads::SideBarNone, int TabIndex = -1);
void toggleAutoHide(ads::SideBarLocation Location = ads::SideBarNone);
signals:

View File

@@ -37,7 +37,6 @@ public:
void updateStyle();
QSize iconSize() const;
void setIconSize(const QSize& Size);
bool mousePressed() const;
public slots:
virtual void setVisible(bool visible);

View File

@@ -29,7 +29,7 @@ public: // implements IFloatingWidget
ads::eDragState DragState, QWidget* MouseEventHandler);
virtual void moveFloating();
virtual void finishDragging();
void cleanupAutoHideContainerWidget();
void cleanupAutoHideContainerWidget(ads::DockWidgetArea ContainerDropArea);
signals:
void draggingCanceled();

View File

@@ -1,4 +1,6 @@
%Module(name=PyQtAds, call_super_init=True, keyword_arguments="Optional", use_limited_api=True)
%HideNamespace(name=ads)
%Import QtCore/QtCoremod.sip
%DefaultSupertype sip.simplewrapper

View File

@@ -50,13 +50,24 @@ namespace ads
TopDockWidgetArea,
BottomDockWidgetArea,
CenterDockWidgetArea,
LeftAutoHideArea,
RightAutoHideArea,
TopAutoHideArea,
BottomAutoHideArea,
InvalidDockWidgetArea,
OuterDockAreas,
AutoHideDockAreas,
AllDockAreas
};
typedef QFlags<ads::DockWidgetArea> DockWidgetAreas;
enum eTabIndex
{
TabDefaultInsertIndex,
TabInvalidIndex
};
enum TitleBarButton
{
TitleBarButtonTabsMenu,
@@ -115,6 +126,9 @@ namespace ads
int insertOffset() const;
};
ads::internal::CDockInsertParam dockAreaInsertParameters(ads::DockWidgetArea Area);
ads::SideBarLocation toSideBarLocation(ads::DockWidgetArea Area);
bool isHorizontalSideBarLocation(ads::SideBarLocation Location);
bool isSideBarArea(ads::DockWidgetArea Area);
SIP_PYOBJECT findParent(SIP_PYTYPE type, const QWidget *w) const /TypeHint="QObject"/;
%MethodCode

View File

@@ -355,7 +355,7 @@ void CAutoHideDockContainer::addDockWidget(CDockWidget* DockWidget)
d->DockArea->addDockWidget(DockWidget);
updateSize();
// The dock area is not visible and will not update the size when updateSize()
// is called for this auto hide container. Therefore we explicitely resize
// is called for this auto hide container. Therefore we explicitly resize
// it here. As soon as it will become visible, it will get the right size
d->DockArea->resize(size());
}
@@ -693,8 +693,8 @@ void CAutoHideDockContainer::moveToNewSideBarLocation(SideBarLocation NewSideBar
auto SideBar = dockContainer()->autoHideSideBar(NewSideBarLocation);
SideBar->addAutoHideWidget(this, TabIndex);
// If we move a horizontal auto hide container to a vertical position
// then we resize it to the orginal dock widget size, to avoid
// an extremely streched dock widget after insertion
// then we resize it to the original dock widget size, to avoid
// an extremely stretched dock widget after insertion
if (SideBar->orientation() != OldOrientation)
{
resetToInitialDockWidgetSize();

View File

@@ -34,7 +34,7 @@
#include <QSplitter>
#include "AutoHideTab.h"
class QXmlStreamWriter;
QT_FORWARD_DECLARE_CLASS(QXmlStreamWriter)
namespace ads
{
@@ -91,7 +91,7 @@ public:
virtual ~CAutoHideDockContainer();
/**
* Get's the side tab bar
* Gets the side tab bar
*/
CAutoHideSideBar* autoHideSideBar() const;
@@ -101,7 +101,7 @@ public:
CAutoHideTab* autoHideTab() const;
/**
* Get's the dock widget in this dock container
* Gets the dock widget in this dock container
*/
CDockWidget* dockWidget() const;
@@ -167,13 +167,13 @@ public:
/**
* Use this instead of resize.
* Depending on the sidebar location this will set the width or heigth
* Depending on the sidebar location this will set the width or height
* of this auto hide container.
*/
void setSize(int Size);
/**
* Resets the with or hight to the initial dock widget size dependinng on
* Resets the width or height to the initial dock widget size dependinng on
* the orientation.
* If the orientation is Qt::Horizontal, then the height is reset to
* the initial size and if orientation is Qt::Vertical, then the width is

View File

@@ -33,7 +33,7 @@
#include "ads_globals.h"
#include "AutoHideTab.h"
class QXmlStreamWriter;
QT_FORWARD_DECLARE_CLASS(QXmlStreamWriter)
namespace ads
{
@@ -173,7 +173,7 @@ public:
/**
* Overrides the minimumSizeHint() function of QScrollArea
* The minimumSizeHint() is bigger than the sizeHint () for the scroll
* area because even if the scrollbars are invisible, the required speace
* area because even if the scrollbars are invisible, the required space
* is reserved in the minimumSizeHint(). This override simply returns
* sizeHint();
*/

View File

@@ -44,7 +44,6 @@
namespace ads
{
static const char* const LocationProperty = "Location";
/**
* Private data class of CDockWidgetTab class (pimpl)
@@ -102,7 +101,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 +173,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;
@@ -419,7 +418,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);
}
@@ -478,7 +477,7 @@ void CAutoHideTab::mouseReleaseEvent(QMouseEvent* ev)
case DraggingFloatingWidget:
ev->accept();
d->FloatingWidget->finishDragging();
if (d->DockWidget->isAutoHide() && d->DragStartOrientation != orientation())
if (d->DockWidget->autoHideDockContainer() && d->DragStartOrientation != orientation())
{
d->DockWidget->autoHideDockContainer()->resetToInitialDockWidgetSize();
}

View File

@@ -36,7 +36,7 @@ set(ads_SRCS
AutoHideTab.cpp
AutoHideDockContainer.cpp
PushButton.cpp
ResizeHandle.cpp
ResizeHandle.cpp
ads.qrc
)
set(ads_HEADERS
@@ -62,7 +62,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)
@@ -85,7 +85,12 @@ target_link_libraries(${library_name} PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)
if (UNIX AND NOT APPLE)
target_link_libraries(${library_name} PUBLIC xcb)
if (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
find_package(X11 REQUIRED)
target_link_libraries(${library_name} PUBLIC X11::xcb)
else()
target_link_libraries(${library_name} PUBLIC xcb)
endif()
endif()
set_target_properties(${library_name} PROPERTIES
AUTOMOC ON
@@ -93,6 +98,7 @@ set_target_properties(${library_name} PROPERTIES
CXX_EXTENSIONS OFF
VERSION ${VERSION_SHORT}
EXPORT_NAME ${library_name}
DEBUG_POSTFIX "d"
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"
@@ -114,7 +120,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
@@ -125,25 +131,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, TabWidget, [&, TabWidget]
{
_this->ensureWidgetVisible(TabWidget);
});
}
else
@@ -300,7 +301,7 @@ int CDockAreaTabBar::currentIndex() const
//===========================================================================
CDockWidgetTab* CDockAreaTabBar::currentTab() const
{
if (d->CurrentIndex < 0)
if (d->CurrentIndex < 0 || d->CurrentIndex >= d->TabsLayout->count())
{
return nullptr;
}

View File

@@ -141,7 +141,7 @@ public:
/**
* Overrides the minimumSizeHint() function of QScrollArea
* The minimumSizeHint() is bigger than the sizeHint () for the scroll
* area because even if the scrollbars are invisible, the required speace
* area because even if the scrollbars are invisible, the required space
* is reserved in the minimumSizeHint(). This override simply returns
* sizeHint();
*/

View File

@@ -60,7 +60,6 @@
namespace ads
{
static const char* const LocationProperty = "Location";
/**
* Private data class of CDockAreaTitleBar class (pimpl)
@@ -72,10 +71,11 @@ struct DockAreaTitleBarPrivate
QPointer<CTitleBarButton> AutoHideButton;
QPointer<CTitleBarButton> UndockButton;
QPointer<CTitleBarButton> CloseButton;
QPointer<CTitleBarButton> MinimizeButton;
QBoxLayout* Layout;
CDockAreaWidget* DockArea;
CDockAreaTabBar* TabBar;
CElidingLabel* AutoHideTitleLabel;
CElidingLabel* AutoHideTitleLabel = nullptr;
bool MenuOutdated = true;
QMenu* TabsMenu;
QList<tTitleBarButton*> DockWidgetActionsButtons;
@@ -158,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;
}
@@ -178,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);
@@ -196,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"));
@@ -207,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));
@@ -218,8 +221,21 @@ void DockAreaTitleBarPrivate::createButtons()
Layout->addWidget(AutoHideButton, 0);
_this->connect(AutoHideButton, SIGNAL(clicked()), SLOT(onAutoHideButtonClicked()));
// Minimize button
MinimizeButton = new CTitleBarButton(testAutoHideConfigFlag(CDockManager::AutoHideHasMinimizeButton),
false, TitleBarButtonMinimize);
MinimizeButton->setObjectName("dockAreaMinimizeButton");
MinimizeButton->setAutoRaise(true);
MinimizeButton->setVisible(false);
internal::setButtonIcon(MinimizeButton, QStyle::SP_TitleBarMinButton, ads::DockAreaMinimizeIcon);
internal::setToolTip(MinimizeButton, QObject::tr("Minimize"));
MinimizeButton->setSizePolicy(ButtonSizePolicy);
Layout->addWidget(MinimizeButton, 0);
_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);
@@ -236,7 +252,10 @@ void DockAreaTitleBarPrivate::createAutoHideTitleLabel()
{
AutoHideTitleLabel = new CElidingLabel("");
AutoHideTitleLabel->setObjectName("autoHideTitleLabel");
Layout->addWidget(AutoHideTitleLabel);
// At position 0 is the tab bar - insert behind tab bar
Layout->insertWidget(1, AutoHideTitleLabel);
AutoHideTitleLabel->setVisible(false); // Default hidden
Layout->insertWidget(2 ,new CSpacerWidget(_this));
}
@@ -324,10 +343,8 @@ CDockAreaTitleBar::CDockAreaTitleBar(CDockAreaWidget* parent) :
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
d->createTabBar();
d->createAutoHideTitleLabel();
d->AutoHideTitleLabel->setVisible(false); // Default hidden
d->Layout->addWidget(new CSpacerWidget(this));
d->createButtons();
d->createAutoHideTitleLabel();
setFocusPolicy(Qt::NoFocus);
}
@@ -431,6 +448,24 @@ void CDockAreaTitleBar::onCloseButtonClicked()
}
//============================================================================
void CDockAreaTitleBar::onAutoHideCloseActionTriggered()
{
d->DockArea->closeArea();
}
//============================================================================
void CDockAreaTitleBar::minimizeAutoHideContainer()
{
auto AutoHideContainer = d->DockArea->autoHideDockContainer();
if (AutoHideContainer)
{
AutoHideContainer->collapseView(true);
}
}
//============================================================================
void CDockAreaTitleBar::onUndockButtonClicked()
{
@@ -479,7 +514,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);
@@ -533,7 +568,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);
}
@@ -547,6 +582,7 @@ CTitleBarButton* CDockAreaTitleBar::button(TitleBarButton which) const
case TitleBarButtonUndock: return d->UndockButton;
case TitleBarButtonClose: return d->CloseButton;
case TitleBarButtonAutoHide: return d->AutoHideButton;
case TitleBarButtonMinimize: return d->MinimizeButton;
default:
return nullptr;
}
@@ -735,7 +771,17 @@ void CDockAreaTitleBar::contextMenuEvent(QContextMenuEvent* ev)
}
Menu.addSeparator();
}
Action = Menu.addAction(isAutoHide ? tr("Close") : tr("Close Group"), this, SLOT(onCloseButtonClicked()));
if (isAutoHide)
{
Action = Menu.addAction(tr("Minimize"), this, SLOT(minimizeAutoHideContainer()));
Action = Menu.addAction(tr("Close"), this, SLOT(onAutoHideCloseActionTriggered()));
}
else
{
Action = Menu.addAction(isAutoHide ? tr("Close") : tr("Close Group"), this, SLOT(onCloseButtonClicked()));
}
Action->setEnabled(d->DockArea->features().testFlag(CDockWidget::DockWidgetClosable));
if (!isAutoHide && !isTopLevelArea)
{
@@ -782,7 +828,8 @@ QString CDockAreaTitleBar::titleBarButtonToolTip(TitleBarButton Button) const
case TitleBarButtonClose:
if (d->DockArea->isAutoHide())
{
return tr("Close");
bool Minimize = CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideCloseButtonCollapsesDock);
return Minimize ? tr("Minimize") : tr("Close");
}
if (CDockManager::testConfigFlag(CDockManager::DockAreaCloseButtonClosesTab))
@@ -802,11 +849,36 @@ QString CDockAreaTitleBar::titleBarButtonToolTip(TitleBarButton Button) const
return QString();
}
//============================================================================
CTitleBarButton::CTitleBarButton(bool showInTitleBar, QWidget* parent)
void CDockAreaTitleBar::showAutoHideControls(bool Show)
{
d->TabBar->setVisible(!Show); // Auto hide toolbar never has tabs
d->MinimizeButton->setVisible(Show);
d->AutoHideTitleLabel->setVisible(Show);
}
//============================================================================
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);
}
@@ -814,7 +886,7 @@ CTitleBarButton::CTitleBarButton(bool showInTitleBar, QWidget* parent)
//============================================================================
void CTitleBarButton::setVisible(bool visible)
{
// 'visible' can stay 'true' if and only if this button is configured to generaly visible:
// 'visible' can stay 'true' if and only if this button is configured to generally visible:
visible = visible && this->ShowInTitleBar;
// 'visible' can stay 'true' unless: this button is configured to be invisible when it is disabled and it is currently disabled:
@@ -841,16 +913,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)
{
@@ -858,6 +961,7 @@ CSpacerWidget::CSpacerWidget(QWidget* Parent /*= 0*/) : Super(Parent)
setStyleSheet("border: none; background: none;");
}
} // namespace ads
//---------------------------------------------------------------------------

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
@@ -97,6 +116,8 @@ private:
private Q_SLOTS:
void onTabsMenuAboutToShow();
void onCloseButtonClicked();
void onAutoHideCloseActionTriggered();
void minimizeAutoHideContainer();
void onUndockButtonClicked();
void onTabsMenuActionTriggered(QAction* Action);
void onCurrentTabChanged(int Index);
@@ -167,6 +188,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
*/
@@ -208,6 +234,16 @@ public:
*/
void setAreaFloating();
/**
* Call this function, to create all the required auto hide controls
*/
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

@@ -81,7 +81,7 @@ class CDockAreaLayout
{
private:
QBoxLayout* m_ParentLayout;
QList<QWidget*> m_Widgets;
QList<QPointer<QWidget>> m_Widgets;
int m_CurrentIndex = -1;
QWidget* m_CurrentWidget = nullptr;
@@ -317,12 +317,12 @@ struct DockAreaWidgetPrivate
}
/**
* Udpates the enable state of the close and detach button
* Updates the enable state of the close and detach button
*/
void updateTitleBarButtonStates();
/**
* Udpates the enable state of the close and detach button
* Updates the enable state of the close and detach button
*/
void updateTitleBarButtonVisibility(bool isTopLevel);
@@ -370,10 +370,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();
@@ -390,20 +401,30 @@ void DockAreaWidgetPrivate::updateTitleBarButtonVisibility(bool IsTopLevel)
return;
}
if (IsTopLevel)
bool IsAutoHide = _this->isAutoHide();
if (IsAutoHide)
{
bool ShowCloseButton = CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideHasCloseButton);
TitleBar->button(TitleBarButtonClose)->setVisible(ShowCloseButton);
TitleBar->button(TitleBarButtonAutoHide)->setVisible(true);
TitleBar->button(TitleBarButtonUndock)->setVisible(false);
TitleBar->button(TitleBarButtonTabsMenu)->setVisible(false);
}
else if (IsTopLevel)
{
TitleBar->button(TitleBarButtonClose)->setVisible(!container->isFloating());
TitleBar->button(TitleBarButtonAutoHide)->setVisible(!container->isFloating());
// Undock and tabs should never show when auto hidden
TitleBar->button(TitleBarButtonUndock)->setVisible(!container->isFloating() && !_this->isAutoHide());
TitleBar->button(TitleBarButtonTabsMenu)->setVisible(!_this->isAutoHide());
TitleBar->button(TitleBarButtonUndock)->setVisible(!container->isFloating());
TitleBar->button(TitleBarButtonTabsMenu)->setVisible(true);
}
else
{
TitleBar->button(TitleBarButtonClose)->setVisible(true);
TitleBar->button(TitleBarButtonAutoHide)->setVisible(true);
TitleBar->button(TitleBarButtonUndock)->setVisible(!_this->isAutoHide());
TitleBar->button(TitleBarButtonTabsMenu)->setVisible(!_this->isAutoHide());
bool ShowAutoHideButton = CDockManager::testAutoHideConfigFlag(CDockManager::DockAreaHasAutoHideButton);
TitleBar->button(TitleBarButtonAutoHide)->setVisible(ShowAutoHideButton);
TitleBar->button(TitleBarButtonUndock)->setVisible(true);
TitleBar->button(TitleBarButtonTabsMenu)->setVisible(true);
}
}
@@ -455,6 +476,13 @@ CAutoHideDockContainer* CDockAreaWidget::autoHideDockContainer() const
return d->AutoHideDockContainer;
}
//============================================================================
CDockSplitter* CDockAreaWidget::parentSplitter() const
{
return internal::findParent<CDockSplitter*>(this);
}
//============================================================================
bool CDockAreaWidget::isAutoHide() const
{
@@ -591,7 +619,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
@@ -740,7 +768,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;
}
@@ -756,7 +784,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));
}
@@ -770,7 +798,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;
}
@@ -793,7 +821,6 @@ CDockWidget* CDockAreaWidget::dockWidget(int Index) const
return qobject_cast<CDockWidget*>(d->ContentsLayout->widget(Index));
}
//============================================================================
void CDockAreaWidget::reorderDockWidget(int fromIndex, int toIndex)
{
@@ -847,9 +874,7 @@ void CDockAreaWidget::updateTitleBarVisibility()
if (isAutoHideFeatureEnabled())
{
auto tabBar = d->TitleBar->tabBar();
tabBar->setVisible(!IsAutoHide); // Never show tab bar when auto hidden
d->TitleBar->autoHideTitleLabel()->setVisible(IsAutoHide); // Always show when auto hidden, never otherwise
d->TitleBar->showAutoHideControls(IsAutoHide);
updateTitleBarButtonVisibility(Container->topLevelDockArea() == this);
}
}
@@ -1283,17 +1308,17 @@ SideBarLocation CDockAreaWidget::calculateSideTabBarArea() const
case BorderHorizontalLeft: SideTab = SideBarLocation::SideBarLeft; break;
case BorderHorizontalRight: SideTab = SideBarLocation::SideBarRight; break;
// 3. Its touching horizontal or vertical borders
// 3. It's touching horizontal or vertical borders
case BorderVertical : SideTab = SideBarLocation::SideBarBottom; break;
case BorderHorizontal: SideTab = SideBarLocation::SideBarRight; break;
// 4. Its in a corner
// 4. It's in a corner
case BorderTopLeft : SideTab = HorizontalOrientation ? SideBarLocation::SideBarTop : SideBarLocation::SideBarLeft; break;
case BorderTopRight : SideTab = HorizontalOrientation ? SideBarLocation::SideBarTop : SideBarLocation::SideBarRight; break;
case BorderBottomLeft : SideTab = HorizontalOrientation ? SideBarLocation::SideBarBottom : SideBarLocation::SideBarLeft; break;
case BorderBottomRight : SideTab = HorizontalOrientation ? SideBarLocation::SideBarBottom : SideBarLocation::SideBarRight; break;
// 5 Ists touching only one border
// 5. It's touching only one border
case BorderLeft: SideTab = SideBarLocation::SideBarLeft; break;
case BorderRight: SideTab = SideBarLocation::SideBarRight; break;
case BorderTop: SideTab = SideBarLocation::SideBarTop; break;

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;
@@ -250,7 +250,7 @@ public:
* \param[out] CreatedWidget The widget created from parsed data or 0 if
* the parsed widget was an empty splitter
* \param[in] Testing If Testing is true, only the stream data is
* parsed without modifiying anything.
* parsed without modifying anything.
*/
bool restoreChildNodes(CDockingStateReader& Stream, QWidget*& CreatedWidget,
bool Testing);
@@ -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;
}
@@ -1932,17 +1939,18 @@ bool CDockContainerWidget::restoreState(CDockingStateReader& s, bool Testing)
NewRootSplitter = d->newSplitter(Qt::Horizontal);
}
d->Layout->replaceWidget(d->RootSplitter, NewRootSplitter);
QLayoutItem* li = d->Layout->replaceWidget(d->RootSplitter, NewRootSplitter);
auto OldRoot = d->RootSplitter;
d->RootSplitter = qobject_cast<CDockSplitter*>(NewRootSplitter);
OldRoot->deleteLater();
delete li;
return true;
}
//============================================================================
QSplitter* CDockContainerWidget::rootSplitter() const
CDockSplitter* CDockContainerWidget::rootSplitter() const
{
return d->RootSplitter;
}
@@ -2064,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());
}
@@ -2096,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();
}
@@ -2115,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.
@@ -103,13 +104,6 @@ protected:
*/
CAutoHideDockContainer* createAndSetupAutoHideContainer(SideBarLocation area, CDockWidget* DockWidget, int TabIndex = -1);
/**
* The funtion does the same like createAndSetupAutoHideContainer() but checks
* if the given DockWidget is pinnable. If it is not pinnable, the
* function returns a nullptr.
*/
CAutoHideDockContainer* createAutoHideContainerIfPinnable(SideBarLocation area, CDockWidget* DockWidget);
/**
* Helper function for creation of the root splitter
*/
@@ -145,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;
@@ -269,7 +270,7 @@ void CDockFocusController::onApplicationFocusChanged(QWidget* focusedOld, QWidge
Q_UNUSED(focusedOld);
// Ignore focus changes if we are restoring state, or if user clicked
// a tab wich in turn caused the focus change
// a tab which in turn caused the focus change
if (d->DockManager->isRestoringState() || d->TabPressed)
{
return;

View File

@@ -103,8 +103,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;
@@ -118,6 +118,11 @@ struct DockManagerPrivate
CDockFocusController* FocusController = nullptr;
CDockWidget* CentralWidget = nullptr;
bool IsLeavingMinimized = false;
Qt::ToolButtonStyle ToolBarStyleDocked = Qt::ToolButtonIconOnly;
Qt::ToolButtonStyle ToolBarStyleFloating = Qt::ToolButtonTextUnderIcon;
QSize ToolBarIconSizeDocked = QSize(16, 16);
QSize ToolBarIconSizeFloating = QSize(24, 24);
CDockWidget::DockWidgetFeatures LockedDockWidgetFeatures;
/**
* Private data constructor
@@ -149,7 +154,10 @@ struct DockManagerPrivate
// Hide updates of floating widgets from user
for (auto FloatingWidget : FloatingWidgets)
{
FloatingWidget->hide();
if (FloatingWidget)
{
FloatingWidget->hide();
}
}
}
@@ -329,7 +337,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();
}
@@ -532,25 +541,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;
}
@@ -564,7 +589,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())
{
@@ -586,7 +611,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())
{
@@ -609,7 +634,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())
{
@@ -721,7 +746,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;
}
@@ -1121,7 +1151,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);
@@ -1285,7 +1315,7 @@ void CDockManager::hideManagerAndFloatingWidgets()
d->HiddenFloatingWidgets.push_back( FloatingWidget );
FloatingWidget->hide();
// hidding floating widget automatically marked contained CDockWidgets as hidden
// hiding floating widget automatically marked contained CDockWidgets as hidden
// but they must remain marked as visible as we want them to be restored visible
// when CDockManager will be shown back
for ( auto dockWidget : VisibleWidgets )
@@ -1314,7 +1344,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();
@@ -1331,7 +1361,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);
@@ -1361,6 +1391,90 @@ QString CDockManager::floatingContainersTitle()
return FloatingContainersTitle;
}
//===========================================================================
void CDockManager::setDockWidgetToolBarStyle(Qt::ToolButtonStyle Style, CDockWidget::eState State)
{
if (CDockWidget::StateFloating == State)
{
d->ToolBarStyleFloating = Style;
}
else
{
d->ToolBarStyleDocked = Style;
}
}
//===========================================================================
Qt::ToolButtonStyle CDockManager::dockWidgetToolBarStyle(CDockWidget::eState State) const
{
if (CDockWidget::StateFloating == State)
{
return d->ToolBarStyleFloating;
}
else
{
return d->ToolBarStyleDocked;
}
}
//===========================================================================
void CDockManager::setDockWidgetToolBarIconSize(const QSize& IconSize, CDockWidget::eState State)
{
if (CDockWidget::StateFloating == State)
{
d->ToolBarIconSizeFloating = IconSize;
}
else
{
d->ToolBarIconSizeDocked = IconSize;
}
}
//===========================================================================
QSize CDockManager::dockWidgetToolBarIconSize(CDockWidget::eState State) const
{
if (CDockWidget::StateFloating == State)
{
return d->ToolBarIconSizeFloating;
}
else
{
return d->ToolBarIconSizeDocked;
}
}
//===========================================================================
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;
}
} // namespace ads
//---------------------------------------------------------------------------

View File

@@ -154,7 +154,7 @@ protected:
virtual void showEvent(QShowEvent *event) override;
/**
* Acces for the internal dock focus controller.
* Access for the internal dock focus controller.
* This function only returns a valid object, if the FocusHighlighting
* flag is set.
*/
@@ -213,6 +213,8 @@ public:
//!< If neither this nor FloatingContainerForceNativeTitleBar is set (the default) native titlebars are used except on known bad systems.
//! 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
@@ -250,10 +252,12 @@ public:
AutoHideSideBarsIconOnly = 0x10,///< show only icons in auto hide side tab - if a tab has no icon, then the text will be shown
AutoHideShowOnMouseOver = 0x20, ///< show the auto hide window on mouse over tab and hide it if mouse leaves auto hide container
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
DefaultAutoHideConfig = AutoHideFeatureEnabled
| DockAreaHasAutoHideButton
| AutoHideCloseButtonCollapsesDock
| AutoHideHasMinimizeButton
};
Q_DECLARE_FLAGS(AutoHideFlags, eAutoHideFlag)
@@ -541,7 +545,7 @@ public:
* The order defines how the actions are added to the view menu.
* The default insertion order is MenuAlphabeticallySorted to make it
* easier for users to find the menu entry for a certain dock widget.
* You need to call this function befor you insert the first menu item
* You need to call this function before you insert the first menu item
* into the view menu.
*/
void setViewMenuInsertionOrder(eViewMenuInsertionOrder Order);
@@ -626,6 +630,68 @@ public:
*/
static QString floatingContainersTitle();
/**
* This function sets the tool button style for the given dock widget state.
* It is possible to switch the tool button style depending on the state.
* If a dock widget is floating, then here are more space and it is
* possible to select a style that requires more space like
* Qt::ToolButtonTextUnderIcon. For the docked state Qt::ToolButtonIconOnly
* might be better.
*/
void setDockWidgetToolBarStyle(Qt::ToolButtonStyle Style, CDockWidget::eState State);
/**
* Returns the tool button style for the given docking state.
* \see setToolBarStyle()
*/
Qt::ToolButtonStyle dockWidgetToolBarStyle(CDockWidget::eState State) const;
/**
* This function sets the tool button icon size for the given state.
* If a dock widget is floating, there is more space and increasing the
* icon size is possible. For docked widgets, small icon sizes, eg. 16 x 16
* might be better.
*/
void setDockWidgetToolBarIconSize(const QSize& IconSize, CDockWidget::eState State);
/**
* Returns the icon size for a given docking state.
* \see setToolBarIconSize()
*/
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

@@ -39,7 +39,7 @@ struct DockSplitterPrivate;
/**
* Splitter used internally instead of QSplitter with some additional
* fuctionality.
* functionality.
*/
class ADS_EXPORT CDockSplitter : public QSplitter
{

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;
@@ -95,6 +95,7 @@ struct DockWidgetPrivate
CDockWidget::eMinimumSizeHintMode MinimumSizeHintMode = CDockWidget::MinimumSizeHintFromDockWidget;
WidgetFactory* Factory = nullptr;
QPointer<CAutoHideTab> SideTabWidget;
CDockWidget::eToolBarStyleSource ToolBarStyleSource = CDockWidget::ToolBarStyleFromDockManager;
/**
* Private data constructor
@@ -139,6 +140,11 @@ struct DockWidgetPrivate
* returns true on success.
*/
bool createWidgetFromFactory();
/**
* Use the dock manager toolbar style and icon size for the different states
*/
void setToolBarStyleFromDockManager();
};
// struct DockWidgetPrivate
@@ -178,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();
@@ -213,6 +219,12 @@ void DockWidgetPrivate::hideDockWidget()
if (Features.testFlag(CDockWidget::DeleteContentOnClose))
{
if (ScrollArea)
{
ScrollArea->takeWidget();
delete ScrollArea;
ScrollArea = nullptr;
}
Widget->deleteLater();
Widget = nullptr;
}
@@ -259,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;
}
@@ -325,6 +340,22 @@ bool DockWidgetPrivate::createWidgetFromFactory()
}
//============================================================================
void DockWidgetPrivate::setToolBarStyleFromDockManager()
{
if (!DockManager)
{
return;
}
auto State = CDockWidget::StateDocked;
_this->setToolBarIconSize(DockManager->dockWidgetToolBarIconSize(State), State);
_this->setToolBarStyle(DockManager->dockWidgetToolBarStyle(State), State);
State = CDockWidget::StateFloating;
_this->setToolBarIconSize(DockManager->dockWidgetToolBarIconSize(State), State);
_this->setToolBarStyle(DockManager->dockWidgetToolBarStyle(State), State);
}
//============================================================================
CDockWidget::CDockWidget(const QString &title, QWidget *parent) :
QFrame(parent),
@@ -354,10 +385,24 @@ CDockWidget::CDockWidget(const QString &title, QWidget *parent) :
//============================================================================
CDockWidget::~CDockWidget()
{
ADS_PRINT("~CDockWidget()");
ADS_PRINT("~CDockWidget(): " << this->windowTitle());
delete d;
}
//============================================================================
void CDockWidget::setToggleViewAction(QAction* action)
{
if (!action)
{
return;
}
d->ToggleViewAction->setParent(nullptr);
delete d->ToggleViewAction;
d->ToggleViewAction = action;
d->ToggleViewAction->setParent(this);
connect(d->ToggleViewAction, &QAction::triggered, this, &CDockWidget::toggleView);
}
//============================================================================
void CDockWidget::setToggleViewActionChecked(bool Checked)
@@ -469,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();
}
}
@@ -488,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;
}
}
@@ -503,6 +564,15 @@ CDockManager* CDockWidget::dockManager() const
void CDockWidget::setDockManager(CDockManager* DockManager)
{
d->DockManager = DockManager;
if (!DockManager)
{
return;
}
if (ToolBarStyleFromDockManager == d->ToolBarStyleSource)
{
d->setToolBarStyleFromDockManager();
}
}
@@ -515,7 +585,7 @@ CDockContainerWidget* CDockWidget::dockContainer() const
}
else
{
return 0;
return nullptr;
}
}
@@ -698,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)
@@ -1264,6 +1333,24 @@ void CDockWidget::toggleAutoHide(SideBarLocation Location)
}
//============================================================================
void CDockWidget::setToolBarStyleSource(eToolBarStyleSource Source)
{
d->ToolBarStyleSource = Source;
if (ToolBarStyleFromDockManager == d->ToolBarStyleSource)
{
d->setToolBarStyleFromDockManager();
}
}
//============================================================================
CDockWidget::eToolBarStyleSource CDockWidget::toolBarStyleSource() const
{
return d->ToolBarStyleSource;
}
} // namespace ads
//---------------------------------------------------------------------------

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)
@@ -176,6 +177,12 @@ public:
StateFloating
};
enum eToolBarStyleSource
{
ToolBarStyleFromDockManager,
ToolBarStyleFromDockWidget
};
/**
* Sets the widget for the dock widget to widget.
* The InsertMode defines how the widget is inserted into the dock widget.
@@ -246,11 +253,11 @@ public:
* object name is required by the dock manager to properly save and restore
* the state of the dock widget. That means, the title needs to be unique.
* If your title is not unique or if you would like to change the title
* during runtime, you need to set a unique object name explicitely
* during runtime, you need to set a unique object name explicitly
* 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
@@ -330,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
@@ -409,6 +421,12 @@ public:
*/
QAction* toggleViewAction() const;
/**
* Use provided action to be the default toggle view action for this dock widget.
* This dock widget now owns the action.
*/
void setToggleViewAction(QAction* action);
/**
* Configures the behavior of the toggle view action.
* \see eToggleViewActionMode for a detailed description
@@ -445,7 +463,7 @@ public:
/**
* This function returns the dock widget top tool bar.
* If no toolbar is assigned, this function returns nullptr. To get a vaild
* If no toolbar is assigned, this function returns nullptr. To get a valid
* toolbar you either need to create a default empty toolbar via
* createDefaultToolBar() function or you need to assign your custom
* toolbar via setToolBar().
@@ -467,6 +485,17 @@ public:
*/
void setToolBar(QToolBar* ToolBar);
/**
* Configures, if the dock widget uses the global tool bar styles from
* dock manager or if it uses its own tool bar style
*/
void setToolBarStyleSource(eToolBarStyleSource Source);
/**
* Returns the configured tool bar style source
*/
eToolBarStyleSource toolBarStyleSource() const;
/**
* This function sets the tool button style for the given dock widget state.
* It is possible to switch the tool button style depending on the state.

View File

@@ -56,7 +56,6 @@
namespace ads
{
static const char* const LocationProperty = "Location";
using tTabLabel = CElidingLabel;
/**
@@ -79,7 +78,6 @@ struct DockWidgetTabPrivate
QSpacerItem* IconTextSpacer;
QPoint TabDragStartPosition;
QSize IconSize;
bool MousePressed = false;
/**
* Private data constructor
@@ -226,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;
}
@@ -246,7 +244,14 @@ DockWidgetTabPrivate::DockWidgetTabPrivate(CDockWidgetTab* _public) :
void DockWidgetTabPrivate::createLayout()
{
TitleLabel = new tTabLabel();
TitleLabel->setElideMode(Qt::ElideRight);
if (CDockManager::testConfigFlag(CDockManager::DisableTabTextEliding))
{
TitleLabel->setElideMode(Qt::ElideNone);
}
else
{
TitleLabel->setElideMode(Qt::ElideRight);
}
TitleLabel->setText(DockWidget->windowTitle());
TitleLabel->setObjectName("dockWidgetTabLabel");
TitleLabel->setAlignment(Qt::AlignCenter);
@@ -373,7 +378,6 @@ void CDockWidgetTab::mousePressEvent(QMouseEvent* ev)
if (ev->button() == Qt::LeftButton)
{
ev->accept();
d->MousePressed = true;
d->saveDragStartMousePosition(internal::globalPositionOf(ev));
d->DragState = DraggingMousePressed;
if (CDockManager::testConfigFlag(CDockManager::FocusHighlighting))
@@ -394,7 +398,6 @@ void CDockWidgetTab::mouseReleaseEvent(QMouseEvent* ev)
{
if (ev->button() == Qt::LeftButton)
{
d->MousePressed = false;
auto CurrentDragState = d->DragState;
d->GlobalDragStartMousePosition = QPoint();
d->DragStartMousePosition = QPoint();
@@ -417,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)
@@ -502,7 +506,7 @@ void CDockWidgetTab::mouseMoveEvent(QMouseEvent* ev)
else if (d->DockArea->openDockWidgetsCount() > 1
&& (internal::globalPositionOf(ev) - d->GlobalDragStartMousePosition).manhattanLength() >= QApplication::startDragDistance()) // Wait a few pixels before start moving
{
// If we start dragging the tab, we save its inital position to
// If we start dragging the tab, we save its initial position to
// restore it later
if (DraggingTab != d->DragState)
{
@@ -576,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())
{
@@ -751,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);
}

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
@@ -173,17 +173,11 @@ public:
/**
* Set an explicit icon size.
* If no icon size has been set explicitely, than the tab sets the icon size
* If no icon size has been set explicitly, than the tab sets the icon size
* depending on the style
*/
void setIconSize(const QSize& Size);
/**
* Returns true, if the tab has been clicked and the mouse is currently
* pressed.
*/
bool mousePressed() 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

@@ -62,7 +62,7 @@ namespace ads
#ifdef Q_OS_WIN
#if 0 // set to 1 if you need this function for debugging
/**
* Just for debuging to convert windows message identifiers to strings
* Just for debugging to convert windows message identifiers to strings
*/
static const char* windowsMessageString(int MessageId)
{
@@ -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;
@@ -662,7 +662,6 @@ CFloatingDockContainer::CFloatingDockContainer(CDockManager *DockManager) :
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
QDockWidget::setWidget(d->DockContainer);
QDockWidget::setFloating(true);
QDockWidget::setFeatures(QDockWidget::DockWidgetClosable
| QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable);
@@ -761,6 +760,7 @@ CFloatingDockContainer::CFloatingDockContainer(CDockWidget *DockWidget) :
d->DockManager->notifyWidgetOrAreaRelocation(DockWidget);
}
//============================================================================
CFloatingDockContainer::~CFloatingDockContainer()
{
@@ -772,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
{
@@ -788,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)
@@ -1143,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)
@@ -1151,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)
{

View File

@@ -146,6 +146,13 @@ protected:
*/
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
@@ -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

@@ -20,5 +20,8 @@
<file>images/vs-pin-button-pinned-focused.svg</file>
<file>images/vs-pin-button_45.svg</file>
<file>images/pin-button-big.svg</file>
<file>images/minimize-button.svg</file>
<file>images/minimize-button-focused.svg</file>
<file>images/vs-pin-button-disabled.svg</file>
</qresource>
</RCC>

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;
@@ -290,7 +290,7 @@ QString detectWindowManagerX11()
QString ret = xcb_get_prop_string(support_win, "_NET_WM_NAME");
if(ret.length() == 0)
{
ADS_PRINT("Empty WM name occured.");
ADS_PRINT("Empty WM name occurred.");
return "UNKNOWN";
}
return ret;

View File

@@ -107,7 +107,8 @@ enum TitleBarButton
TitleBarButtonTabsMenu,
TitleBarButtonUndock,
TitleBarButtonClose,
TitleBarButtonAutoHide
TitleBarButtonAutoHide,
TitleBarButtonMinimize
};
/**
@@ -131,6 +132,7 @@ enum eIcon
DockAreaMenuIcon, //!< DockAreaMenuIcon
DockAreaUndockIcon,//!< DockAreaUndockIcon
DockAreaCloseIcon, //!< DockAreaCloseIcon
DockAreaMinimizeIcon,
IconCount, //!< just a delimiter for range checks
};
@@ -165,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;
@@ -189,7 +192,7 @@ void xcb_update_prop(bool set, WId window, const char *type, const char *prop, c
bool xcb_dump_props(WId window, const char *type);
/**
* Gets the active window manager from the X11 Server.
* Requires a EWMH conform window manager (Allmost all common used ones are).
* Requires a EWMH conform window manager (Almost all common used ones are).
* Returns "UNKNOWN" otherwise.
*/
QString windowManager();
@@ -266,7 +269,7 @@ T findParent(const QWidget* w)
}
parentWidget = parentWidget->parentWidget();
}
return 0;
return nullptr;
}
/**

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16" height="16" enable-background="new 0 0 122.879 122.867" version="1.1" viewBox="0 0 16 16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect x="4" y="10" width="7" height="2" fill="#fff"/><style/><style/><style/><style/></svg>

After

Width:  |  Height:  |  Size: 293 B

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16" height="16" enable-background="new 0 0 122.879 122.867" version="1.1" viewBox="0 0 16 16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect x="4" y="10" width="7" height="2"/></svg>

After

Width:  |  Height:  |  Size: 249 B

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16" height="16" enable-background="new 0 0 122.879 122.867" version="1.1" viewBox="0 0 16 16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="m6 3v6h-1v1h3v4h1v-4h3v-1h-1v-6h-4zm1 1h2v5h-2z" color="#000000" fill-opacity=".25" style="-inkscape-stroke:none"/></svg>

After

Width:  |  Height:  |  Size: 332 B

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

@@ -288,7 +288,8 @@ ads--CAutoHideDockContainer ads--CDockAreaWidget[focused="true"] ads--CDockAreaT
* CAutoHideDockContainer titlebar buttons
*****************************************************************************/
#dockAreaAutoHideButton {
qproperty-icon: url(:/ads/images/vs-pin-button.svg);
qproperty-icon: url(:/ads/images/vs-pin-button.svg),
url(:/ads/images/vs-pin-button-disabled.svg) disabled;
qproperty-iconSize: 16px;
}
@@ -298,6 +299,12 @@ ads--CAutoHideDockContainer #dockAreaAutoHideButton {
}
ads--CAutoHideDockContainer #dockAreaMinimizeButton {
qproperty-icon: url(:/ads/images/minimize-button-focused.svg);
qproperty-iconSize: 16px;
}
ads--CAutoHideDockContainer #dockAreaCloseButton{
qproperty-icon: url(:/ads/images/close-button-focused.svg)
}

View File

@@ -324,8 +324,9 @@ ads--CAutoHideDockContainer ads--CDockAreaWidget[focused="true"] ads--CDockAreaT
* CAutoHideDockContainer titlebar buttons
*****************************************************************************/
#dockAreaAutoHideButton {
qproperty-icon: url(:/ads/images/vs-pin-button.svg);
qproperty-iconSize: 16px;
qproperty-icon: url(:/ads/images/vs-pin-button.svg),
url(:/ads/images/vs-pin-button-disabled.svg) disabled;
qproperty-iconSize: 16px;
}
ads--CAutoHideDockContainer #dockAreaAutoHideButton {
@@ -334,6 +335,12 @@ ads--CAutoHideDockContainer #dockAreaAutoHideButton {
}
ads--CAutoHideDockContainer #dockAreaMinimizeButton {
qproperty-icon: url(:/ads/images/minimize-button-focused.svg);
qproperty-iconSize: 16px;
}
ads--CAutoHideDockContainer #dockAreaCloseButton{
qproperty-icon: url(:/ads/images/close-button-focused.svg)
}

View File

@@ -326,16 +326,24 @@ ads--CAutoHideDockContainer ads--CDockAreaWidget[focused="true"] ads--CDockAreaT
* CAutoHideDockContainer titlebar buttons
*****************************************************************************/
#dockAreaAutoHideButton {
qproperty-icon: url(:/ads/images/vs-pin-button.svg);
qproperty-icon: url(:/ads/images/vs-pin-button.svg),
url(:/ads/images/vs-pin-button-disabled.svg) disabled;
qproperty-iconSize: 16px;
}
ads--CAutoHideDockContainer #dockAreaAutoHideButton {
qproperty-icon: url(:/ads/images/vs-pin-button-pinned-focused.svg);
qproperty-iconSize: 16px;
}
ads--CAutoHideDockContainer #dockAreaMinimizeButton {
qproperty-icon: url(:/ads/images/minimize-button-focused.svg);
qproperty-iconSize: 16px;
}
ads--CAutoHideDockContainer #dockAreaCloseButton{
qproperty-icon: url(:/ads/images/close-button-focused.svg)
}

View File

@@ -401,8 +401,9 @@ ads--CAutoHideDockContainer ads--CDockAreaWidget[focused="true"] ads--CDockAreaT
* CAutoHideDockContainer titlebar buttons
*****************************************************************************/
#dockAreaAutoHideButton {
qproperty-icon: url(:/ads/images/vs-pin-button.svg);
qproperty-iconSize: 16px;
qproperty-icon: url(:/ads/images/vs-pin-button.svg),
url(:/ads/images/vs-pin-button-disabled.svg) disabled;
qproperty-iconSize: 16px;
}
ads--CAutoHideDockContainer #dockAreaAutoHideButton {
@@ -411,6 +412,12 @@ ads--CAutoHideDockContainer #dockAreaAutoHideButton {
}
ads--CAutoHideDockContainer #dockAreaMinimizeButton {
qproperty-icon: url(:/ads/images/minimize-button-focused.svg);
qproperty-iconSize: 16px;
}
ads--CAutoHideDockContainer #dockAreaCloseButton{
qproperty-icon: url(:/ads/images/close-button-focused.svg)
}