Compare commits
86 Commits
qtquick_op
...
4.3.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8da0713bf0 | ||
|
|
08da925fde | ||
|
|
fb58c435ef | ||
|
|
6bf593ef4b | ||
|
|
6b3b7750cb | ||
|
|
541db8e214 | ||
|
|
644c828f00 | ||
|
|
ed6636ae26 | ||
|
|
1a543e946d | ||
|
|
9bdefd6055 | ||
|
|
8fd691968c | ||
|
|
7abc698d09 | ||
|
|
5b23248fb8 | ||
|
|
46a5cee9c9 | ||
|
|
6c2c9888be | ||
|
|
44ff9e9956 | ||
|
|
f848df74c3 | ||
|
|
6c98c29855 | ||
|
|
c34d479d5c | ||
|
|
a7a97e6978 | ||
|
|
ec018a4c70 | ||
|
|
0fabebb0fe | ||
|
|
521e1fbe39 | ||
|
|
5f2aeaef00 | ||
|
|
818e568f4a | ||
|
|
5d6831d179 | ||
|
|
a2c94c16b5 | ||
|
|
68f1084bf0 | ||
|
|
761bfc50d6 | ||
|
|
59b4dfb89c | ||
|
|
bfa5124999 | ||
|
|
234cf9ac58 | ||
|
|
8f77f4b42a | ||
|
|
fa94da00d4 | ||
|
|
40beef964b | ||
|
|
420baeedfe | ||
|
|
0f8096e314 | ||
|
|
9ec97a8867 | ||
|
|
55ef6ef863 | ||
|
|
c0985f6497 | ||
|
|
2f1ef61f82 | ||
|
|
62d2dd213d | ||
|
|
3c941a2312 | ||
|
|
4634b5617c | ||
|
|
2178b52621 | ||
|
|
61573cba16 | ||
|
|
2d2de53dcd | ||
|
|
0d10c6e2d9 | ||
|
|
767933d0cb | ||
|
|
7a362b7ee3 | ||
|
|
77ed9b0661 | ||
|
|
65600a4dcd | ||
|
|
ac1879d5cb | ||
|
|
f00ef60fb3 | ||
|
|
1a1352e456 | ||
|
|
65ae86a46d | ||
|
|
e239cdb354 | ||
|
|
7140e5e32a | ||
|
|
f5cfe9e05a | ||
|
|
be727c5890 | ||
|
|
f4fc0dab29 | ||
|
|
39bc7f1780 | ||
|
|
364ee33f9c | ||
|
|
cb5e9f60a1 | ||
|
|
2760fb1fe9 | ||
|
|
8a82e4cf57 | ||
|
|
0627b3183f | ||
|
|
df1bc94d9e | ||
|
|
6924e69b6b | ||
|
|
0a6c58fd66 | ||
|
|
bf22e54fc3 | ||
|
|
4307f48d99 | ||
|
|
4bdc04e9d8 | ||
|
|
1c6d86e70f | ||
|
|
6e642ec423 | ||
|
|
0b3c3f0123 | ||
|
|
957afe3a07 | ||
|
|
4ab726fee3 | ||
|
|
e2929ade14 | ||
|
|
b801f0655d | ||
|
|
f6ccaba6aa | ||
|
|
21189759dd | ||
|
|
047ea3c494 | ||
|
|
f71c8ffe5d | ||
|
|
381acb2449 | ||
|
|
b9479dbd3d |
146
.clang-format
Normal 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
|
||||
2
.github/workflows/linux-builds.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
||||
run: |
|
||||
sudo apt-get update --fix-missing
|
||||
sudo apt-get install qt5-default
|
||||
sudo apt-get install qtbase5-private-dev
|
||||
sudo apt-get install qtbase5-private-dev qtdeclarative5-dev
|
||||
- name: qmake
|
||||
run: qmake
|
||||
- name: make
|
||||
|
||||
5
.gitignore
vendored
@@ -1,4 +1,4 @@
|
||||
*.pro.user
|
||||
*.pro.user*
|
||||
/build
|
||||
*.o
|
||||
*.dylib
|
||||
@@ -7,6 +7,9 @@ qrc_*
|
||||
moc_*
|
||||
ui_*
|
||||
Makefile
|
||||
*.dll
|
||||
*.a
|
||||
build-*
|
||||
|
||||
# IDEs
|
||||
.idea
|
||||
|
||||
@@ -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
|
||||
|
||||
80
README.md
@@ -22,6 +22,70 @@ integrated development environments (IDEs) such as Visual Studio.
|
||||
|
||||
## New and Noteworthy
|
||||
|
||||
Release [4.1](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/releases/latest) significantly improves the Auto-Hide functionality and also brings improvements
|
||||
for Drag and Drop of dock widgets into dock area tabs. These are the highlights of the new version:
|
||||
|
||||
#### Drag & Drop to Auto-Hide
|
||||
|
||||
Now 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:
|
||||
|
||||

|
||||
|
||||
Of course, this also works with dock areas:
|
||||
|
||||

|
||||
|
||||
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 appende behind the last tab:
|
||||
|
||||

|
||||
|
||||
#### 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 Tab Sorting
|
||||
|
||||
You can drag Auto-Hide tabs to a new position in the current sidebar
|
||||
to sort them:
|
||||
|
||||

|
||||
|
||||
#### 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:
|
||||
|
||||

|
||||
|
||||
#### 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:
|
||||
|
||||

|
||||
|
||||
#### Dock Area Tab Insert Order
|
||||
|
||||
And last but not least the new version also improves the docking of widgets
|
||||
into the tabs of a Dock area. Just as with Auto-Hide tabs, you can now determine the position at which a tab is inserted by moving the mouse over an already existing tab (insertion before the tab) or behind the last tab
|
||||
(appending):
|
||||
|
||||

|
||||
|
||||
The [release 4.0](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/releases/latest)
|
||||
adds the following features:
|
||||
|
||||
@@ -77,6 +141,12 @@ know it from Visual Studio.
|
||||
### Overview
|
||||
|
||||
- [New and Noteworthy](#new-and-noteworthy)
|
||||
- [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)
|
||||
- [Dock Area Tab Insert Order](#dock-area-tab-insert-order)
|
||||
- [Features](#features)
|
||||
- [Overview](#overview)
|
||||
- [Docking everywhere - no central widget](#docking-everywhere---no-central-widget)
|
||||
@@ -298,7 +368,7 @@ The application can be compiled for macOS. A user reported, that the library wor
|
||||
[](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System)
|
||||
[](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.
|
||||
|
||||
@@ -320,7 +390,9 @@ Screenshot Ubuntu:
|
||||
## Build
|
||||
|
||||
The Linux build requires private header files. Make sure that they are installed.
|
||||
The library uses SVG icons, so ensure that Qt SVG support is installed.
|
||||
The library uses SVG icons, so ensure that Qt SVG support is installed. The demo
|
||||
application creates a `QQuickWidget` for testing, so ensure that the required
|
||||
libraries are installed.
|
||||
|
||||
### Qt5 on Ubuntu 18.04 or 20.04
|
||||
|
||||
@@ -331,13 +403,13 @@ sudo apt install qt5-default qtbase5-private-dev
|
||||
### Qt5 on Ubuntu 22.04
|
||||
|
||||
```bash
|
||||
sudo apt install qtbase5-dev qtbase5-private-dev qtbase5-dev-tools libqt5svg5
|
||||
sudo apt install qtbase5-dev qtbase5-private-dev qtbase5-dev-tools libqt5svg5 libqt5qml5 qtdeclarative5-dev
|
||||
```
|
||||
|
||||
### Qt6 on Ubuntu 22.04
|
||||
|
||||
```bash
|
||||
sudo apt install qt6-base-dev qt6-base-private-dev qt6-tools-dev libqt6svg6
|
||||
sudo apt install qt6-default qt6-base-dev qt6-base-private-dev qt6-tools-dev libqt6svg6 qt6-qtdeclarative
|
||||
```
|
||||
|
||||
Open the `ads.pro` file with QtCreator and start the build, that's it.
|
||||
|
||||
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.5)
|
||||
project(ads_demo VERSION ${VERSION_SHORT})
|
||||
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets Quick QuickWidgets REQUIRED)
|
||||
if(WIN32 AND QT_VERSION_MAJOR LESS 6)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS AxContainer REQUIRED)
|
||||
endif()
|
||||
@@ -21,7 +21,9 @@ add_executable(AdvancedDockingSystemDemo WIN32 ${ads_demo_SRCS})
|
||||
target_include_directories(AdvancedDockingSystemDemo PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../src")
|
||||
target_link_libraries(AdvancedDockingSystemDemo PUBLIC Qt${QT_VERSION_MAJOR}::Core
|
||||
Qt${QT_VERSION_MAJOR}::Gui
|
||||
Qt${QT_VERSION_MAJOR}::Widgets)
|
||||
Qt${QT_VERSION_MAJOR}::Widgets
|
||||
Qt${QT_VERSION_MAJOR}::Quick
|
||||
Qt${QT_VERSION_MAJOR}::QuickWidgets)
|
||||
if(WIN32 AND QT_VERSION_MAJOR LESS 6)
|
||||
target_link_libraries(AdvancedDockingSystemDemo PUBLIC Qt${QT_VERSION_MAJOR}::AxContainer)
|
||||
endif()
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -448,8 +452,8 @@ void MainWindowPrivate::createContent()
|
||||
|
||||
// For this Special Dock Area we want to avoid dropping on the center of it (i.e. we don't want this widget to be ever tabbified):
|
||||
{
|
||||
SpecialDockArea->setAllowedAreas(ads::OuterDockAreas);
|
||||
//SpecialDockArea->setAllowedAreas({ads::LeftDockWidgetArea, ads::RightDockWidgetArea}); // just for testing
|
||||
//SpecialDockArea->setAllowedAreas(ads::OuterDockAreas);
|
||||
SpecialDockArea->setAllowedAreas({ads::LeftDockWidgetArea, ads::RightDockWidgetArea, ads::TopDockWidgetArea}); // just for testing
|
||||
}
|
||||
|
||||
DockWidget = createLongTextLabelDockWidget();
|
||||
@@ -517,7 +521,9 @@ void MainWindowPrivate::createContent()
|
||||
|
||||
// Test dock area docking
|
||||
auto RighDockArea = DockManager->addDockWidget(ads::RightDockWidgetArea, createLongTextLabelDockWidget(), TopDockArea);
|
||||
DockManager->addDockWidget(ads::TopDockWidgetArea, createLongTextLabelDockWidget(), RighDockArea);
|
||||
DockWidget = createLongTextLabelDockWidget();
|
||||
DockWidget->setFeature(ads::CDockWidget::DockWidgetPinnable, false);
|
||||
DockManager->addDockWidget(ads::TopDockWidgetArea, DockWidget, RighDockArea);
|
||||
auto BottomDockArea = DockManager->addDockWidget(ads::BottomDockWidgetArea, createLongTextLabelDockWidget(), RighDockArea);
|
||||
DockManager->addDockWidget(ads::CenterDockWidgetArea, createLongTextLabelDockWidget(), RighDockArea);
|
||||
auto LabelDockWidget = createLongTextLabelDockWidget();
|
||||
@@ -525,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",
|
||||
@@ -585,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"));
|
||||
@@ -619,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"));
|
||||
@@ -761,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)),
|
||||
@@ -1022,3 +1041,17 @@ void CMainWindow::createImageViewer()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CMainWindow::lockWorkspace(bool Value)
|
||||
{
|
||||
if (Value)
|
||||
{
|
||||
d->DockManager->lockDockWidgetFeaturesGlobally();
|
||||
}
|
||||
else
|
||||
{
|
||||
d->DockManager->lockDockWidgetFeaturesGlobally(ads::CDockWidget::NoDockWidgetFeatures);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ private slots:
|
||||
void toggleDockWidgetWindowTitle();
|
||||
void applyVsStyle();
|
||||
void createImageViewer();
|
||||
void lockWorkspace(bool Value);
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
||||
@@ -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
@@ -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 |
6
demo/images/lock_open.svg
Normal 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 |
6
demo/images/lock_outline.svg
Normal 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 |
@@ -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)
|
||||
|
||||
BIN
doc/AutoHide_Change_Sidebar.gif
Normal file
|
After Width: | Height: | Size: 312 KiB |
BIN
doc/AutoHide_Context_Menu.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
doc/AutoHide_Drag_DockArea.gif
Normal file
|
After Width: | Height: | Size: 330 KiB |
BIN
doc/AutoHide_Drag_to_Float_or_Dock.gif
Normal file
|
After Width: | Height: | Size: 642 KiB |
BIN
doc/AutoHide_Drag_to_Sidebar.gif
Normal file
|
After Width: | Height: | Size: 559 KiB |
BIN
doc/AutoHide_Sort_Tabs.gif
Normal file
|
After Width: | Height: | Size: 299 KiB |
BIN
doc/AutoHide_Tab_Insert_Order.gif
Normal file
|
After Width: | Height: | Size: 303 KiB |
BIN
doc/DockArea_Tab_Insertion_Order.gif
Normal file
|
After Width: | Height: | Size: 376 KiB |
@@ -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.
|
||||
|
||||

|
||||
@@ -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:
|
||||
|
||||
|
||||
BIN
doc/cfg_flag_AutoHideHasCloseButton.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
doc/cfg_flag_AutoHideHasMinimizeButton.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
doc/cfg_flag_DisableTabTextEliding_false.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
doc/cfg_flag_DisableTabTextEliding_true.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
doc/cfg_flag_ShowTabTextOnlyForActiveTab_true.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
@@ -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.
|
||||
|
||||

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

|
||||
|
||||
### `DisableTabTextEliding`
|
||||
|
||||
Set this flag to disable eliding of tab texts in dock area tabs:
|
||||
|
||||

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

|
||||
|
||||
### `ShowTabTextOnlyForActiveTab`
|
||||
|
||||
Set this flag (default = false) to show label texts in dock area tabs only
|
||||
for active tabs. Inactive tabs only show their icon:
|
||||
|
||||

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

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

|
||||
|
||||
Of course, this also works with dock areas:
|
||||
|
||||

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

|
||||
|
||||
### 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 Tab Sorting
|
||||
|
||||
You can drag Auto-Hide tabs to a new position in the current sidebar
|
||||
to sort them:
|
||||
|
||||

|
||||
|
||||
### 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:
|
||||
|
||||

|
||||
|
||||
### 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:
|
||||
|
||||

|
||||
|
||||
### Adding Auto Hide Widgets
|
||||
|
||||
Adding an auto hide widget is similar to adding a dock widget, simply call
|
||||
@@ -605,6 +686,24 @@ closing it.
|
||||
|
||||

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

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

|
||||
|
||||
## DockWidget Feature Flags
|
||||
|
||||
### `DockWidgetClosable`
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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_()
|
||||
|
||||
@@ -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)")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <QApplication>
|
||||
#include "../../examples/simple/MainWindow.h"
|
||||
#include "mainframe.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
@@ -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_()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -24,10 +24,15 @@ 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;
|
||||
virtual QSize minimumSizeHint() const;
|
||||
virtual QSize sizeHint() const;
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -23,6 +23,7 @@ public:
|
||||
ads::CDockWidget* focusedDockWidget() const;
|
||||
void setDockWidgetTabFocused(ads::CDockWidgetTab* Tab);
|
||||
void clearDockWidgetFocus(ads::CDockWidget* dockWidget);
|
||||
void setDockWidgetTabPressed(bool Value);
|
||||
|
||||
public slots:
|
||||
void setDockWidgetFocused(ads::CDockWidget* focusedNow);
|
||||
|
||||
@@ -187,6 +187,7 @@ public:
|
||||
AutoHideButtonCheckable,
|
||||
AutoHideSideBarsIconOnly,
|
||||
AutoHideShowOnMouseOver,
|
||||
AutoHideCloseButtonCollapsesDock,
|
||||
DefaultAutoHideConfig,
|
||||
};
|
||||
typedef QFlags<ads::CDockManager::eAutoHideFlag> AutoHideFlags;
|
||||
@@ -237,6 +238,7 @@ public:
|
||||
QMenu* viewMenu() const;
|
||||
void setViewMenuInsertionOrder(ads::CDockManager::eViewMenuInsertionOrder Order);
|
||||
bool isRestoringState() const;
|
||||
bool isLeavingMinimizedState() const;
|
||||
static int startDragDistance();
|
||||
ads::CDockWidget* focusedDockWidget() const;
|
||||
QList<int> splitterSizes(ads::CDockAreaWidget *ContainedArea) const;
|
||||
@@ -245,6 +247,7 @@ public:
|
||||
static QString floatingContainersTitle();
|
||||
|
||||
public slots:
|
||||
void endLeavingMinimizedState();
|
||||
void openPerspective(const QString& PerspectiveName);
|
||||
void setDockWidgetFocused(ads::CDockWidget* DockWidget);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -60,7 +60,9 @@ public:
|
||||
enum eMinimumSizeHintMode
|
||||
{
|
||||
MinimumSizeHintFromDockWidget,
|
||||
MinimumSizeHintFromContent
|
||||
MinimumSizeHintFromContent,
|
||||
MinimumSizeHintFromDockWidgetMinimumSize,
|
||||
MinimumSizeHintFromContentMinimumSize,
|
||||
};
|
||||
|
||||
enum eToggleViewActionMode
|
||||
@@ -88,12 +90,14 @@ 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;
|
||||
QAction* toggleViewAction() const;
|
||||
void setToggleViewActionMode(ads::CDockWidget::eToggleViewActionMode Mode);
|
||||
void setMinimumSizeHintMode(ads::CDockWidget::eMinimumSizeHintMode Mode);
|
||||
ads::CDockWidget::eMinimumSizeHintMode minimumSizeHintMode() const;
|
||||
bool isCentralWidget() const;
|
||||
void setIcon(const QIcon& Icon);
|
||||
QIcon icon() const;
|
||||
@@ -122,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:
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -117,6 +117,7 @@ struct AutoHideDockContainerPrivate
|
||||
CResizeHandle* ResizeHandle = nullptr;
|
||||
QSize Size; // creates invalid size
|
||||
QPointer<CAutoHideTab> SideTab;
|
||||
QSize SizeCache;
|
||||
|
||||
/**
|
||||
* Private data constructor
|
||||
@@ -215,6 +216,7 @@ CAutoHideDockContainer::CAutoHideDockContainer(CDockWidget* DockWidget, SideBarL
|
||||
bool OpaqueResize = CDockManager::testConfigFlag(CDockManager::OpaqueSplitterResize);
|
||||
d->ResizeHandle->setOpaqueResize(OpaqueResize);
|
||||
d->Size = d->DockArea->size();
|
||||
d->SizeCache = DockWidget->size();
|
||||
|
||||
addDockWidget(DockWidget);
|
||||
parent->registerAutoHideWidget(this);
|
||||
@@ -237,7 +239,6 @@ void CAutoHideDockContainer::updateSize()
|
||||
}
|
||||
|
||||
auto rect = dockContainerParent->contentRect();
|
||||
|
||||
switch (sideBarLocation())
|
||||
{
|
||||
case SideBarLocation::SideBarTop:
|
||||
@@ -271,6 +272,15 @@ void CAutoHideDockContainer::updateSize()
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (orientation() == Qt::Horizontal)
|
||||
{
|
||||
d->SizeCache.setHeight(this->height());
|
||||
}
|
||||
else
|
||||
{
|
||||
d->SizeCache.setWidth(this->width());
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
@@ -294,7 +304,7 @@ CAutoHideDockContainer::~CAutoHideDockContainer()
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
CAutoHideSideBar* CAutoHideDockContainer::sideBar() const
|
||||
CAutoHideSideBar* CAutoHideDockContainer::autoHideSideBar() const
|
||||
{
|
||||
if (d->SideTab)
|
||||
{
|
||||
@@ -303,7 +313,7 @@ CAutoHideSideBar* CAutoHideDockContainer::sideBar() const
|
||||
else
|
||||
{
|
||||
auto DockContainer = dockContainer();
|
||||
return DockContainer ? DockContainer->sideTabBar(d->SideTabBarArea) : nullptr;
|
||||
return DockContainer ? DockContainer->autoHideSideBar(d->SideTabBarArea) : nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,6 +354,10 @@ 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 explicitly resize
|
||||
// it here. As soon as it will become visible, it will get the right size
|
||||
d->DockArea->resize(size());
|
||||
}
|
||||
|
||||
|
||||
@@ -643,5 +657,56 @@ bool CAutoHideDockContainer::event(QEvent* event)
|
||||
return Super::event(event);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
Qt::Orientation CAutoHideDockContainer::orientation() const
|
||||
{
|
||||
return ads::internal::isHorizontalSideBarLocation(d->SideTabBarArea)
|
||||
? Qt::Horizontal : Qt::Vertical;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CAutoHideDockContainer::resetToInitialDockWidgetSize()
|
||||
{
|
||||
if (orientation() == Qt::Horizontal)
|
||||
{
|
||||
setSize(d->SizeCache.height());
|
||||
}
|
||||
else
|
||||
{
|
||||
setSize(d->SizeCache.width());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CAutoHideDockContainer::moveToNewSideBarLocation(SideBarLocation NewSideBarLocation,
|
||||
int TabIndex)
|
||||
{
|
||||
if (NewSideBarLocation == sideBarLocation() && TabIndex == this->tabIndex())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto OldOrientation = orientation();
|
||||
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 original dock widget size, to avoid
|
||||
// an extremely stretched dock widget after insertion
|
||||
if (SideBar->orientation() != OldOrientation)
|
||||
{
|
||||
resetToInitialDockWidgetSize();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
int CAutoHideDockContainer::tabIndex() const
|
||||
{
|
||||
return d->SideTab->tabIndex();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include <QSplitter>
|
||||
#include "AutoHideTab.h"
|
||||
|
||||
class QXmlStreamWriter;
|
||||
QT_FORWARD_DECLARE_CLASS(QXmlStreamWriter)
|
||||
|
||||
namespace ads
|
||||
{
|
||||
@@ -91,9 +91,9 @@ public:
|
||||
virtual ~CAutoHideDockContainer();
|
||||
|
||||
/**
|
||||
* Get's the side tab bar
|
||||
* Gets the side tab bar
|
||||
*/
|
||||
CAutoHideSideBar* sideBar() const;
|
||||
CAutoHideSideBar* autoHideSideBar() const;
|
||||
|
||||
/**
|
||||
* Returns the side tab
|
||||
@@ -101,10 +101,15 @@ public:
|
||||
CAutoHideTab* autoHideTab() const;
|
||||
|
||||
/**
|
||||
* Get's the dock widget in this dock container
|
||||
* Gets the dock widget in this dock container
|
||||
*/
|
||||
CDockWidget* dockWidget() const;
|
||||
|
||||
/**
|
||||
* Returns the index of this container in the sidebar
|
||||
*/
|
||||
int tabIndex() const;
|
||||
|
||||
/**
|
||||
* Adds a dock widget and removes the previous dock widget
|
||||
*/
|
||||
@@ -162,10 +167,34 @@ 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 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
|
||||
* reset to the initial size
|
||||
*/
|
||||
void resetToInitialDockWidgetSize();
|
||||
|
||||
/**
|
||||
* Returns orientation of this container.
|
||||
* Left and right containers have a Qt::Vertical orientation and top / bottom
|
||||
* containers have a Qt::Horizontal orientation.
|
||||
* The function returns the orientation of the corresponding auto hide
|
||||
* side bar.
|
||||
*/
|
||||
Qt::Orientation orientation() const;
|
||||
|
||||
/**
|
||||
* Removes the AutoHide container from the current side bar and adds
|
||||
* it to the new side bar given in SideBarLocation
|
||||
*/
|
||||
void moveToNewSideBarLocation(SideBarLocation SideBarLocation, int TabIndex = -1);
|
||||
};
|
||||
} // namespace ads
|
||||
|
||||
|
||||
@@ -196,6 +196,7 @@ void CAutoHideSideBar::insertTab(int Index, CAutoHideTab* SideTab)
|
||||
{
|
||||
SideTab->setSideBar(this);
|
||||
SideTab->installEventFilter(this);
|
||||
// Default insertion is append
|
||||
if (Index < 0)
|
||||
{
|
||||
d->TabsLayout->insertWidget(d->TabsLayout->count() - 1, SideTab);
|
||||
@@ -233,12 +234,25 @@ void CAutoHideSideBar::removeAutoHideWidget(CAutoHideDockContainer* AutoHideWidg
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void CAutoHideSideBar::addAutoHideWidget(CAutoHideDockContainer* AutoHideWidget)
|
||||
void CAutoHideSideBar::addAutoHideWidget(CAutoHideDockContainer* AutoHideWidget,
|
||||
int TabIndex)
|
||||
{
|
||||
auto SideBar = AutoHideWidget->autoHideTab()->sideBar();
|
||||
if (SideBar == this)
|
||||
{
|
||||
return;
|
||||
// If we move to the same tab index or if we insert before the next
|
||||
// tab index, then we will end at the same tab position and can leave
|
||||
if (AutoHideWidget->tabIndex() == TabIndex || (AutoHideWidget->tabIndex() + 1) == TabIndex)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// We remove this auto hide widget from the sidebar in the code below
|
||||
// and therefore need to correct the TabIndex here
|
||||
if (AutoHideWidget->tabIndex() < TabIndex)
|
||||
{
|
||||
--TabIndex;
|
||||
}
|
||||
}
|
||||
|
||||
if (SideBar)
|
||||
@@ -248,7 +262,7 @@ void CAutoHideSideBar::addAutoHideWidget(CAutoHideDockContainer* AutoHideWidget)
|
||||
AutoHideWidget->setParent(d->ContainerWidget);
|
||||
AutoHideWidget->setSideBarLocation(d->SideTabArea);
|
||||
d->ContainerWidget->registerAutoHideWidget(AutoHideWidget);
|
||||
insertTab(-1, AutoHideWidget->autoHideTab());
|
||||
insertTab(TabIndex, AutoHideWidget->autoHideTab());
|
||||
}
|
||||
|
||||
|
||||
@@ -302,14 +316,14 @@ Qt::Orientation CAutoHideSideBar::orientation() const
|
||||
|
||||
|
||||
//============================================================================
|
||||
CAutoHideTab* CAutoHideSideBar::tabAt(int index) const
|
||||
CAutoHideTab* CAutoHideSideBar::tab(int index) const
|
||||
{
|
||||
return qobject_cast<CAutoHideTab*>(d->TabsLayout->itemAt(index)->widget());
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
int CAutoHideSideBar::tabCount() const
|
||||
int CAutoHideSideBar::count() const
|
||||
{
|
||||
return d->TabsLayout->count() - 1;
|
||||
}
|
||||
@@ -318,17 +332,17 @@ int CAutoHideSideBar::tabCount() const
|
||||
//============================================================================
|
||||
int CAutoHideSideBar::visibleTabCount() const
|
||||
{
|
||||
int count = 0;
|
||||
int VisibleTabCount = 0;
|
||||
auto ParentWidget = parentWidget();
|
||||
for (auto i = 0; i < tabCount(); i++)
|
||||
for (auto i = 0; i < count(); i++)
|
||||
{
|
||||
if (tabAt(i)->isVisibleTo(ParentWidget))
|
||||
if (tab(i)->isVisibleTo(ParentWidget))
|
||||
{
|
||||
count++;
|
||||
VisibleTabCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
return VisibleTabCount;
|
||||
}
|
||||
|
||||
|
||||
@@ -336,9 +350,9 @@ int CAutoHideSideBar::visibleTabCount() const
|
||||
bool CAutoHideSideBar::hasVisibleTabs() const
|
||||
{
|
||||
auto ParentWidget = parentWidget();
|
||||
for (auto i = 0; i < tabCount(); i++)
|
||||
for (auto i = 0; i < count(); i++)
|
||||
{
|
||||
if (tabAt(i)->isVisibleTo(ParentWidget))
|
||||
if (tab(i)->isVisibleTo(ParentWidget))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -348,6 +362,21 @@ bool CAutoHideSideBar::hasVisibleTabs() const
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
int CAutoHideSideBar::indexOfTab(const CAutoHideTab& Tab) const
|
||||
{
|
||||
for (auto i = 0; i < count(); i++)
|
||||
{
|
||||
if (tab(i) == &Tab)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
SideBarLocation CAutoHideSideBar::sideBarLocation() const
|
||||
{
|
||||
@@ -358,18 +387,18 @@ SideBarLocation CAutoHideSideBar::sideBarLocation() const
|
||||
//============================================================================
|
||||
void CAutoHideSideBar::saveState(QXmlStreamWriter& s) const
|
||||
{
|
||||
if (!tabCount())
|
||||
if (!count())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
s.writeStartElement("SideBar");
|
||||
s.writeAttribute("Area", QString::number(sideBarLocation()));
|
||||
s.writeAttribute("Tabs", QString::number(tabCount()));
|
||||
s.writeAttribute("Tabs", QString::number(count()));
|
||||
|
||||
for (auto i = 0; i < tabCount(); ++i)
|
||||
for (auto i = 0; i < count(); ++i)
|
||||
{
|
||||
auto Tab = tabAt(i);
|
||||
auto Tab = tab(i);
|
||||
if (!Tab)
|
||||
{
|
||||
continue;
|
||||
@@ -417,5 +446,56 @@ CDockContainerWidget* CAutoHideSideBar::dockContainer() const
|
||||
return d->ContainerWidget;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
int CAutoHideSideBar::tabAt(const QPoint& Pos) const
|
||||
{
|
||||
if (!isVisible())
|
||||
{
|
||||
return TabInvalidIndex;
|
||||
}
|
||||
|
||||
if (orientation() == Qt::Horizontal)
|
||||
{
|
||||
if (Pos.x() < tab(0)->geometry().x())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Pos.y() < tab(0)->geometry().y())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < count(); ++i)
|
||||
{
|
||||
if (tab(i)->geometry().contains(Pos))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return count();
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
int CAutoHideSideBar::tabInsertIndexAt(const QPoint& Pos) const
|
||||
{
|
||||
int Index = tabAt(Pos);
|
||||
if (Index == TabInvalidIndex)
|
||||
{
|
||||
return TabDefaultInsertIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (Index < 0) ? 0 : Index;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ads
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include "ads_globals.h"
|
||||
#include "AutoHideTab.h"
|
||||
|
||||
class QXmlStreamWriter;
|
||||
QT_FORWARD_DECLARE_CLASS(QXmlStreamWriter)
|
||||
|
||||
namespace ads
|
||||
{
|
||||
@@ -117,7 +117,7 @@ public:
|
||||
* If the AutoHideWidget is in another sidebar, then it will be removed
|
||||
* from this sidebar.
|
||||
*/
|
||||
void addAutoHideWidget(CAutoHideDockContainer* AutoHideWidget);
|
||||
void addAutoHideWidget(CAutoHideDockContainer* AutoHideWidget, int Index = TabDefaultInsertIndex);
|
||||
|
||||
/**
|
||||
* Returns orientation of side tab.
|
||||
@@ -125,14 +125,32 @@ public:
|
||||
Qt::Orientation orientation() const;
|
||||
|
||||
/*
|
||||
* get the side tab widget at position, returns nullptr if it's out of bounds
|
||||
* Get the side tab widget at position, returns nullptr if it's out of bounds
|
||||
*/
|
||||
CAutoHideTab* tabAt(int index) const;
|
||||
CAutoHideTab* tab(int index) const;
|
||||
|
||||
/**
|
||||
* Returns the tab at the given position.
|
||||
* Returns -1 if the position is left of the first tab and count() if the
|
||||
* position is right of the last tab. Returns InvalidTabIndex (-2) to
|
||||
* indicate an invalid value.
|
||||
*/
|
||||
int tabAt(const QPoint& Pos) const;
|
||||
|
||||
/**
|
||||
* Returns the tab insertion index for the given mouse cursor position
|
||||
*/
|
||||
int tabInsertIndexAt(const QPoint& Pos) const;
|
||||
|
||||
/**
|
||||
* Returns the index of the given tab
|
||||
*/
|
||||
int indexOfTab(const CAutoHideTab& Tab) const;
|
||||
|
||||
/*
|
||||
* Gets the count of the tab widgets
|
||||
*/
|
||||
int tabCount() const;
|
||||
int count() const;
|
||||
|
||||
/**
|
||||
* Returns the number of visible tabs to its parent widget.
|
||||
@@ -155,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();
|
||||
*/
|
||||
|
||||
@@ -32,15 +32,19 @@
|
||||
#include <QBoxLayout>
|
||||
#include <QApplication>
|
||||
#include <QElapsedTimer>
|
||||
#include <QMenu>
|
||||
|
||||
#include "AutoHideDockContainer.h"
|
||||
#include "AutoHideSideBar.h"
|
||||
#include "DockAreaWidget.h"
|
||||
#include "DockManager.h"
|
||||
#include "DockWidget.h"
|
||||
#include "FloatingDragPreview.h"
|
||||
#include "DockOverlay.h"
|
||||
|
||||
namespace ads
|
||||
{
|
||||
|
||||
/**
|
||||
* Private data class of CDockWidgetTab class (pimpl)
|
||||
*/
|
||||
@@ -51,6 +55,12 @@ struct AutoHideTabPrivate
|
||||
CAutoHideSideBar* SideBar = nullptr;
|
||||
Qt::Orientation Orientation{Qt::Vertical};
|
||||
QElapsedTimer TimeSinceHoverMousePress;
|
||||
bool MousePressed = false;
|
||||
eDragState DragState = DraggingInactive;
|
||||
QPoint GlobalDragStartMousePosition;
|
||||
QPoint DragStartMousePosition;
|
||||
IFloatingWidget* FloatingWidget = nullptr;
|
||||
Qt::Orientation DragStartOrientation;
|
||||
|
||||
/**
|
||||
* Private data constructor
|
||||
@@ -82,6 +92,55 @@ struct AutoHideTabPrivate
|
||||
DockContainer->handleAutoHideWidgetEvent(event, _this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to create and initialize the menu entries for
|
||||
* the "Auto Hide Group To..." menu
|
||||
*/
|
||||
QAction* createAutoHideToAction(const QString& Title, SideBarLocation Location,
|
||||
QMenu* Menu)
|
||||
{
|
||||
auto Action = Menu->addAction(Title);
|
||||
Action->setProperty(internal::LocationProperty, Location);
|
||||
QObject::connect(Action, &QAction::triggered, _this, &CAutoHideTab::onAutoHideToActionClicked);
|
||||
Action->setEnabled(Location != _this->sideBarLocation());
|
||||
return Action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test function for current drag state
|
||||
*/
|
||||
bool isDraggingState(eDragState dragState) const
|
||||
{
|
||||
return this->DragState == dragState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the drag start position in global and local coordinates
|
||||
*/
|
||||
void saveDragStartMousePosition(const QPoint& GlobalPos)
|
||||
{
|
||||
GlobalDragStartMousePosition = GlobalPos;
|
||||
DragStartMousePosition = _this->mapFromGlobal(GlobalPos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts floating of the dock widget that belongs to this title bar
|
||||
* Returns true, if floating has been started and false if floating
|
||||
* is not possible for any reason
|
||||
*/
|
||||
bool startFloating(eDragState DraggingState = DraggingFloatingWidget);
|
||||
|
||||
template <typename T>
|
||||
IFloatingWidget* createFloatingWidget(T* Widget)
|
||||
{
|
||||
auto w = new CFloatingDragPreview(Widget);
|
||||
_this->connect(w, &CFloatingDragPreview::draggingCanceled, [=]()
|
||||
{
|
||||
DragState = DraggingInactive;
|
||||
});
|
||||
return w;
|
||||
}
|
||||
}; // struct DockWidgetTabPrivate
|
||||
|
||||
|
||||
@@ -110,6 +169,53 @@ void AutoHideTabPrivate::updateOrientation()
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool AutoHideTabPrivate::startFloating(eDragState DraggingState)
|
||||
{
|
||||
auto DockArea = DockWidget->dockAreaWidget();
|
||||
ADS_PRINT("isFloating " << dockContainer()->isFloating());
|
||||
|
||||
ADS_PRINT("startFloating");
|
||||
DragState = DraggingState;
|
||||
IFloatingWidget* FloatingWidget = nullptr;
|
||||
FloatingWidget = createFloatingWidget(DockArea);
|
||||
auto Size = DockArea->size();
|
||||
auto StartPos = DragStartMousePosition;
|
||||
auto AutoHideContainer = DockWidget->autoHideDockContainer();
|
||||
DragStartOrientation = AutoHideContainer->orientation();
|
||||
switch (SideBar->sideBarLocation())
|
||||
{
|
||||
case SideBarLeft:
|
||||
StartPos.rx() = AutoHideContainer->rect().left() + 10;
|
||||
break;
|
||||
|
||||
case SideBarRight:
|
||||
StartPos.rx() = AutoHideContainer->rect().right() - 10;
|
||||
break;
|
||||
|
||||
case SideBarTop:
|
||||
StartPos.ry() = AutoHideContainer->rect().top() + 10;
|
||||
break;
|
||||
|
||||
case SideBarBottom:
|
||||
StartPos.ry() = AutoHideContainer->rect().bottom() - 10;
|
||||
break;
|
||||
|
||||
case SideBarNone:
|
||||
return false;
|
||||
}
|
||||
FloatingWidget->startFloating(StartPos, Size, DraggingFloatingWidget, _this);
|
||||
auto DockManager = DockWidget->dockManager();
|
||||
auto Overlay = DockManager->containerOverlay();
|
||||
Overlay->setAllowedAreas(OuterDockAreas);
|
||||
this->FloatingWidget = FloatingWidget;
|
||||
qApp->postEvent(DockWidget, new QEvent((QEvent::Type)internal::DockedWidgetDragStartEvent));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CAutoHideTab::setSideBar(CAutoHideSideBar* SideTabBar)
|
||||
{
|
||||
@@ -250,32 +356,205 @@ bool CAutoHideTab::event(QEvent* event)
|
||||
d->forwardEventToDockContainer(event);
|
||||
break;
|
||||
|
||||
case QEvent::MouseButtonPress:
|
||||
// If AutoHideShowOnMouseOver is active, then the showing is triggered
|
||||
// by a MousePressEvent sent to this tab. To prevent accidental hiding
|
||||
// of the tab by a mouse click, we wait at least 500 ms before we accept
|
||||
// the mouse click
|
||||
if (!event->spontaneous())
|
||||
{
|
||||
d->TimeSinceHoverMousePress.restart();
|
||||
d->forwardEventToDockContainer(event);
|
||||
}
|
||||
else if (d->TimeSinceHoverMousePress.hasExpired(500))
|
||||
{
|
||||
d->forwardEventToDockContainer(event);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Super::event(event);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool CAutoHideTab::iconOnly() const
|
||||
{
|
||||
return CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideSideBarsIconOnly) && !icon().isNull();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CAutoHideTab::contextMenuEvent(QContextMenuEvent* ev)
|
||||
{
|
||||
ev->accept();
|
||||
d->saveDragStartMousePosition(ev->globalPos());
|
||||
|
||||
const bool isFloatable = d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable);
|
||||
QAction* Action;
|
||||
QMenu Menu(this);
|
||||
|
||||
Action = Menu.addAction(tr("Detach"), this, SLOT(setDockWidgetFloating()));
|
||||
Action->setEnabled(isFloatable);
|
||||
auto IsPinnable = d->DockWidget->features().testFlag(CDockWidget::DockWidgetPinnable);
|
||||
Action->setEnabled(IsPinnable);
|
||||
|
||||
auto menu = Menu.addMenu(tr("Pin To..."));
|
||||
menu->setEnabled(IsPinnable);
|
||||
d->createAutoHideToAction(tr("Top"), SideBarTop, menu);
|
||||
d->createAutoHideToAction(tr("Left"), SideBarLeft, menu);
|
||||
d->createAutoHideToAction(tr("Right"), SideBarRight, menu);
|
||||
d->createAutoHideToAction(tr("Bottom"), SideBarBottom, menu);
|
||||
|
||||
Action = Menu.addAction(tr("Unpin (Dock)"), this, SLOT(unpinDockWidget()));
|
||||
Menu.addSeparator();
|
||||
Action = Menu.addAction(tr("Close"), this, SLOT(requestCloseDockWidget()));
|
||||
Action->setEnabled(d->DockWidget->features().testFlag(CDockWidget::DockWidgetClosable));
|
||||
|
||||
Menu.exec(ev->globalPos());
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CAutoHideTab::setDockWidgetFloating()
|
||||
{
|
||||
d->DockWidget->setFloating();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CAutoHideTab::unpinDockWidget()
|
||||
{
|
||||
d->DockWidget->setAutoHide(false);
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
void CAutoHideTab::onAutoHideToActionClicked()
|
||||
{
|
||||
int Location = sender()->property(internal::LocationProperty).toInt();
|
||||
d->DockWidget->setAutoHide(true, (SideBarLocation)Location);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CAutoHideTab::mousePressEvent(QMouseEvent* ev)
|
||||
{
|
||||
// If AutoHideShowOnMouseOver is active, then the showing is triggered
|
||||
// by a MousePressEvent sent to this tab. To prevent accidental hiding
|
||||
// of the tab by a mouse click, we wait at least 500 ms before we accept
|
||||
// the mouse click
|
||||
if (!ev->spontaneous())
|
||||
{
|
||||
d->TimeSinceHoverMousePress.restart();
|
||||
d->forwardEventToDockContainer(ev);
|
||||
}
|
||||
else if (d->TimeSinceHoverMousePress.hasExpired(500))
|
||||
{
|
||||
d->forwardEventToDockContainer(ev);
|
||||
}
|
||||
|
||||
if (ev->button() == Qt::LeftButton)
|
||||
{
|
||||
ev->accept();
|
||||
d->MousePressed = true;
|
||||
d->saveDragStartMousePosition(internal::globalPositionOf(ev));
|
||||
d->DragState = DraggingMousePressed;
|
||||
}
|
||||
Super::mousePressEvent(ev);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CAutoHideTab::mouseReleaseEvent(QMouseEvent* ev)
|
||||
{
|
||||
if (ev->button() == Qt::LeftButton)
|
||||
{
|
||||
d->MousePressed = false;
|
||||
auto CurrentDragState = d->DragState;
|
||||
d->GlobalDragStartMousePosition = QPoint();
|
||||
d->DragStartMousePosition = QPoint();
|
||||
d->DragState = DraggingInactive;
|
||||
|
||||
switch (CurrentDragState)
|
||||
{
|
||||
case DraggingTab:
|
||||
// End of tab moving, emit signal
|
||||
/*if (d->DockArea)
|
||||
{
|
||||
ev->accept();
|
||||
Q_EMIT moved(internal::globalPositionOf(ev));
|
||||
}*/
|
||||
break;
|
||||
|
||||
case DraggingFloatingWidget:
|
||||
ev->accept();
|
||||
d->FloatingWidget->finishDragging();
|
||||
if (d->DockWidget->autoHideDockContainer() && d->DragStartOrientation != orientation())
|
||||
{
|
||||
d->DockWidget->autoHideDockContainer()->resetToInitialDockWidgetSize();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break; // do nothing
|
||||
}
|
||||
}
|
||||
|
||||
Super::mouseReleaseEvent(ev);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CAutoHideTab::mouseMoveEvent(QMouseEvent* ev)
|
||||
{
|
||||
if (!(ev->buttons() & Qt::LeftButton) || d->isDraggingState(DraggingInactive))
|
||||
{
|
||||
d->DragState = DraggingInactive;
|
||||
Super::mouseMoveEvent(ev);
|
||||
return;
|
||||
}
|
||||
|
||||
// move floating window
|
||||
if (d->isDraggingState(DraggingFloatingWidget))
|
||||
{
|
||||
d->FloatingWidget->moveFloating();
|
||||
Super::mouseMoveEvent(ev);
|
||||
return;
|
||||
}
|
||||
|
||||
// move tab
|
||||
if (d->isDraggingState(DraggingTab))
|
||||
{
|
||||
// Moving the tab is always allowed because it does not mean moving the
|
||||
// dock widget around
|
||||
//d->moveTab(ev);
|
||||
}
|
||||
|
||||
auto MappedPos = mapToParent(ev->pos());
|
||||
bool MouseOutsideBar = (MappedPos.x() < 0) || (MappedPos.x() > parentWidget()->rect().right());
|
||||
// Maybe a fixed drag distance is better here ?
|
||||
int DragDistanceY = qAbs(d->GlobalDragStartMousePosition.y() - internal::globalPositionOf(ev).y());
|
||||
if (DragDistanceY >= CDockManager::startDragDistance() || MouseOutsideBar)
|
||||
{
|
||||
// Floating is only allowed for widgets that are floatable
|
||||
// We can create the drag preview if the widget is movable.
|
||||
auto Features = d->DockWidget->features();
|
||||
if (Features.testFlag(CDockWidget::DockWidgetFloatable) || (Features.testFlag(CDockWidget::DockWidgetMovable)))
|
||||
{
|
||||
d->startFloating();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Super::mouseMoveEvent(ev);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CAutoHideTab::requestCloseDockWidget()
|
||||
{
|
||||
d->DockWidget->requestCloseDockWidget();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
int CAutoHideTab::tabIndex() const
|
||||
{
|
||||
if (!d->SideBar)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return d->SideBar->indexOfTab(*this);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -65,11 +65,17 @@ private:
|
||||
friend class CDockContainerWidget;
|
||||
friend DockContainerWidgetPrivate;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onAutoHideToActionClicked();
|
||||
|
||||
protected:
|
||||
void setSideBar(CAutoHideSideBar *SideTabBar);
|
||||
void removeFromSideBar();
|
||||
virtual bool event(QEvent* event) override;
|
||||
virtual void contextMenuEvent(QContextMenuEvent* ev) override;
|
||||
virtual void mousePressEvent(QMouseEvent* ev) override;
|
||||
virtual void mouseReleaseEvent(QMouseEvent* ev) override;
|
||||
virtual void mouseMoveEvent(QMouseEvent* ev) override;
|
||||
|
||||
public:
|
||||
using Super = CPushButton;
|
||||
@@ -133,6 +139,27 @@ public:
|
||||
* not in a side bar
|
||||
*/
|
||||
CAutoHideSideBar* sideBar() const;
|
||||
|
||||
/**
|
||||
* Returns the index of this tab in the sideBar
|
||||
*/
|
||||
int tabIndex() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
/**
|
||||
* Set the dock widget floating, if it is floatable
|
||||
*/
|
||||
void setDockWidgetFloating();
|
||||
|
||||
/**
|
||||
* Unpin and dock the auto hide widget
|
||||
*/
|
||||
void unpinDockWidget();
|
||||
|
||||
/**
|
||||
* Calls the requestCloseDockWidget() function for the assigned dock widget
|
||||
*/
|
||||
void requestCloseDockWidget();
|
||||
}; // class AutoHideTab
|
||||
}
|
||||
// namespace ads
|
||||
|
||||
@@ -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}>
|
||||
)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -504,6 +505,46 @@ QSize CDockAreaTabBar::sizeHint() const
|
||||
return d->TabsContainerWidget->sizeHint();
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
int CDockAreaTabBar::tabAt(const QPoint& Pos) const
|
||||
{
|
||||
if (!isVisible())
|
||||
{
|
||||
return TabInvalidIndex;
|
||||
}
|
||||
|
||||
if (Pos.x() < tab(0)->geometry().x())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < count(); ++i)
|
||||
{
|
||||
if (tab(i)->geometry().contains(Pos))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return count();
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
int CDockAreaTabBar::tabInsertIndexAt(const QPoint& Pos) const
|
||||
{
|
||||
int Index = tabAt(Pos);
|
||||
if (Index == TabInvalidIndex)
|
||||
{
|
||||
return TabDefaultInsertIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (Index < 0) ? 0 : Index;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ads
|
||||
|
||||
|
||||
|
||||
@@ -113,6 +113,19 @@ public:
|
||||
*/
|
||||
CDockWidgetTab* tab(int Index) const;
|
||||
|
||||
/**
|
||||
* Returns the tab at the given position.
|
||||
* Returns -1 if the position is left of the first tab and count() if the
|
||||
* position is right of the last tab. Returns -2 to indicate an invalid
|
||||
* value.
|
||||
*/
|
||||
int tabAt(const QPoint& Pos) const;
|
||||
|
||||
/**
|
||||
* Returns the tab insertion index for the given mouse cursor position
|
||||
*/
|
||||
int tabInsertIndexAt(const QPoint& Pos) const;
|
||||
|
||||
/**
|
||||
* Filters the tab widget events
|
||||
*/
|
||||
@@ -128,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();
|
||||
*/
|
||||
|
||||
@@ -60,7 +60,6 @@
|
||||
|
||||
namespace ads
|
||||
{
|
||||
static const char* const LocationProperty = "Location";
|
||||
|
||||
/**
|
||||
* Private data class of CDockAreaTitleBar class (pimpl)
|
||||
@@ -68,14 +67,15 @@ static const char* const LocationProperty = "Location";
|
||||
struct DockAreaTitleBarPrivate
|
||||
{
|
||||
CDockAreaTitleBar* _this;
|
||||
QPointer<tTitleBarButton> TabsMenuButton;
|
||||
QPointer<tTitleBarButton> AutoHideButton;
|
||||
QPointer<tTitleBarButton> UndockButton;
|
||||
QPointer<tTitleBarButton> CloseButton;
|
||||
QPointer<CTitleBarButton> TabsMenuButton;
|
||||
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,13 +568,13 @@ void CDockAreaTitleBar::onAutoHideDockAreaActionClicked()
|
||||
//============================================================================
|
||||
void CDockAreaTitleBar::onAutoHideToActionClicked()
|
||||
{
|
||||
int Location = sender()->property(LocationProperty).toInt();
|
||||
int Location = sender()->property(internal::LocationProperty).toInt();
|
||||
d->DockArea->toggleAutoHide((SideBarLocation)Location);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
QAbstractButton* CDockAreaTitleBar::button(TitleBarButton which) const
|
||||
CTitleBarButton* CDockAreaTitleBar::button(TitleBarButton which) const
|
||||
{
|
||||
switch (which)
|
||||
{
|
||||
@@ -547,6 +582,7 @@ QAbstractButton* 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;
|
||||
}
|
||||
@@ -677,6 +713,28 @@ void CDockAreaTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockAreaTitleBar::setAreaFloating()
|
||||
{
|
||||
// If this is the last dock area in a dock container it does not make
|
||||
// sense to move it to a new floating widget and leave this one
|
||||
// empty.
|
||||
auto DockContainer = d->DockArea->dockContainer();
|
||||
if (DockContainer->isFloating() && DockContainer->dockAreaCount() == 1
|
||||
&& !d->DockArea->isAutoHide())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
d->makeAreaFloating(mapFromGlobal(QCursor::pos()), DraggingInactive);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockAreaTitleBar::contextMenuEvent(QContextMenuEvent* ev)
|
||||
{
|
||||
@@ -713,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)
|
||||
{
|
||||
@@ -760,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))
|
||||
@@ -780,11 +849,36 @@ QString CDockAreaTitleBar::titleBarButtonToolTip(TitleBarButton Button) const
|
||||
return QString();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
CTitleBarButton::CTitleBarButton(bool visible, 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),
|
||||
Visible(visible),
|
||||
HideWhenDisabled(CDockManager::testConfigFlag(CDockManager::DockAreaHideDisabledButtons))
|
||||
ShowInTitleBar(showInTitleBar),
|
||||
HideWhenDisabled(CDockManager::testConfigFlag(CDockManager::DockAreaHideDisabledButtons) && hideWhenDisabled),
|
||||
TitleBarButtonId(ButtonId)
|
||||
{
|
||||
setFocusPolicy(Qt::NoFocus);
|
||||
}
|
||||
@@ -792,8 +886,8 @@ CTitleBarButton::CTitleBarButton(bool visible, QWidget* parent)
|
||||
//============================================================================
|
||||
void CTitleBarButton::setVisible(bool visible)
|
||||
{
|
||||
// 'visible' can stay 'true' if and only if this button is configured to generaly visible:
|
||||
visible = visible && this->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:
|
||||
if (visible && HideWhenDisabled)
|
||||
@@ -804,19 +898,62 @@ void CTitleBarButton::setVisible(bool visible)
|
||||
Super::setVisible(visible);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CTitleBarButton::setShowInTitleBar(bool Show)
|
||||
{
|
||||
this->ShowInTitleBar = Show;
|
||||
if (!Show)
|
||||
{
|
||||
setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
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)
|
||||
{
|
||||
@@ -824,6 +961,7 @@ CSpacerWidget::CSpacerWidget(QWidget* Parent /*= 0*/) : Super(Parent)
|
||||
setStyleSheet("border: none; background: none;");
|
||||
}
|
||||
|
||||
|
||||
} // namespace ads
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
//============================================================================
|
||||
// INCLUDES
|
||||
//============================================================================
|
||||
#include <QToolButton>
|
||||
#include <QFrame>
|
||||
|
||||
#include "ads_globals.h"
|
||||
@@ -42,6 +43,63 @@ class CDockAreaTabBar;
|
||||
class CDockAreaWidget;
|
||||
struct DockAreaTitleBarPrivate;
|
||||
class CElidingLabel;
|
||||
class CDockAreaTitleBar;
|
||||
|
||||
using tTitleBarButton = QToolButton;
|
||||
|
||||
/**
|
||||
* Title bar button of a dock area that customizes tTitleBarButton appearance/behaviour
|
||||
* according to various config flags such as:
|
||||
* CDockManager::DockAreaHas_xxx_Button - if set to 'false' keeps the button always invisible
|
||||
* CDockManager::DockAreaHideDisabledButtons - if set to 'true' hides button when it is disabled
|
||||
*/
|
||||
class CTitleBarButton : public tTitleBarButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
bool ShowInTitleBar = true;
|
||||
bool HideWhenDisabled = false;
|
||||
TitleBarButton TitleBarButtonId;
|
||||
|
||||
public:
|
||||
using Super = tTitleBarButton;
|
||||
CTitleBarButton(bool ShowInTitleBar, bool HideWhenDisabled, TitleBarButton ButtonId,
|
||||
QWidget* parent = nullptr);
|
||||
|
||||
/**
|
||||
* Adjust this visibility change request with our internal settings:
|
||||
*/
|
||||
virtual void setVisible(bool visible) override;
|
||||
|
||||
/**
|
||||
* Configures, if the title bar button should be shown in title bar
|
||||
*/
|
||||
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
|
||||
*/
|
||||
bool event(QEvent *ev) override;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Title bar of a dock area.
|
||||
@@ -58,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);
|
||||
@@ -121,13 +181,18 @@ public:
|
||||
/**
|
||||
* Returns the button corresponding to the given title bar button identifier
|
||||
*/
|
||||
QAbstractButton* button(TitleBarButton which) const;
|
||||
CTitleBarButton* button(TitleBarButton which) const;
|
||||
|
||||
/**
|
||||
* Returns the auto hide title label, used when the dock area is expanded and auto hidden
|
||||
*/
|
||||
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
|
||||
*/
|
||||
@@ -163,6 +228,22 @@ public:
|
||||
*/
|
||||
QString titleBarButtonToolTip(TitleBarButton Button) const;
|
||||
|
||||
/**
|
||||
* Moves the dock area into its own floating widget if the area
|
||||
* DockWidgetFloatable flag is true
|
||||
*/
|
||||
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
|
||||
|
||||
@@ -31,43 +31,12 @@
|
||||
// INCLUDES
|
||||
//============================================================================
|
||||
#include <QFrame>
|
||||
#include <QToolButton>
|
||||
|
||||
#include "ads_globals.h"
|
||||
|
||||
namespace ads
|
||||
{
|
||||
using tTitleBarButton = QToolButton;
|
||||
|
||||
/**
|
||||
* Title bar button of a dock area that customizes tTitleBarButton appearance/behaviour
|
||||
* according to various config flags such as:
|
||||
* CDockManager::DockAreaHas_xxx_Button - if set to 'false' keeps the button always invisible
|
||||
* CDockManager::DockAreaHideDisabledButtons - if set to 'true' hides button when it is disabled
|
||||
*/
|
||||
class CTitleBarButton : public tTitleBarButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
bool Visible = true;
|
||||
bool HideWhenDisabled = false;
|
||||
|
||||
public:
|
||||
using Super = tTitleBarButton;
|
||||
CTitleBarButton(bool visible = true, QWidget* parent = nullptr);
|
||||
|
||||
/**
|
||||
* Adjust this visibility change request with our internal settings:
|
||||
*/
|
||||
virtual void setVisible(bool visible) override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Handle EnabledChanged signal to set button invisible if the configured
|
||||
*/
|
||||
bool event(QEvent *ev) override;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@@ -83,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);}
|
||||
};
|
||||
|
||||
@@ -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
|
||||
{
|
||||
@@ -467,6 +495,7 @@ void CDockAreaWidget::setAutoHideDockContainer(CAutoHideDockContainer* AutoHideD
|
||||
d->AutoHideDockContainer = AutoHideDockContainer;
|
||||
updateAutoHideButtonCheckState();
|
||||
updateTitleBarButtonsToolTips();
|
||||
d->TitleBar->button(TitleBarButtonAutoHide)->setShowInTitleBar(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -590,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
|
||||
@@ -626,15 +655,7 @@ void CDockAreaWidget::hideAreaWithNoVisibleContent()
|
||||
void CDockAreaWidget::onTabCloseRequested(int Index)
|
||||
{
|
||||
ADS_PRINT("CDockAreaWidget::onTabCloseRequested " << Index);
|
||||
auto* DockWidget = dockWidget(Index);
|
||||
if (DockWidget->features().testFlag(CDockWidget::DockWidgetDeleteOnClose) || DockWidget->features().testFlag(CDockWidget::CustomCloseHandling))
|
||||
{
|
||||
DockWidget->closeDockWidgetInternal();
|
||||
}
|
||||
else
|
||||
{
|
||||
DockWidget->toggleView(false);
|
||||
}
|
||||
dockWidget(Index)->requestCloseDockWidget();
|
||||
}
|
||||
|
||||
|
||||
@@ -747,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;
|
||||
}
|
||||
@@ -763,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));
|
||||
}
|
||||
@@ -777,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;
|
||||
}
|
||||
@@ -800,7 +821,6 @@ CDockWidget* CDockAreaWidget::dockWidget(int Index) const
|
||||
return qobject_cast<CDockWidget*>(d->ContentsLayout->widget(Index));
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockAreaWidget::reorderDockWidget(int fromIndex, int toIndex)
|
||||
{
|
||||
@@ -854,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);
|
||||
}
|
||||
}
|
||||
@@ -1290,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;
|
||||
@@ -1312,7 +1330,7 @@ SideBarLocation CDockAreaWidget::calculateSideTabBarArea() const
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockAreaWidget::setAutoHide(bool Enable, SideBarLocation Location)
|
||||
void CDockAreaWidget::setAutoHide(bool Enable, SideBarLocation Location, int TabIndex)
|
||||
{
|
||||
if (!isAutoHideFeatureEnabled())
|
||||
{
|
||||
@@ -1323,11 +1341,18 @@ void CDockAreaWidget::setAutoHide(bool Enable, SideBarLocation Location)
|
||||
{
|
||||
if (isAutoHide())
|
||||
{
|
||||
autoHideDockContainer()->moveContentsToParent();
|
||||
d->AutoHideDockContainer->moveContentsToParent();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If this is already an auto hide container, then move it to new location
|
||||
if (isAutoHide())
|
||||
{
|
||||
d->AutoHideDockContainer->moveToNewSideBarLocation(Location, TabIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
auto area = (SideBarNone == Location) ? calculateSideTabBarArea() : Location;
|
||||
for (const auto DockWidget : openedDockWidgets())
|
||||
{
|
||||
@@ -1341,7 +1366,7 @@ void CDockAreaWidget::setAutoHide(bool Enable, SideBarLocation Location)
|
||||
continue;
|
||||
}
|
||||
|
||||
dockContainer()->createAndSetupAutoHideContainer(area, DockWidget);
|
||||
dockContainer()->createAndSetupAutoHideContainer(area, DockWidget, TabIndex++);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1442,6 +1467,13 @@ bool CDockAreaWidget::isTopLevelArea() const
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockAreaWidget::setFloating()
|
||||
{
|
||||
d->TitleBar->setAreaFloating();
|
||||
}
|
||||
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
//============================================================================
|
||||
bool CDockAreaWidget::event(QEvent *e)
|
||||
|
||||
@@ -47,6 +47,7 @@ class CDockContainerWidget;
|
||||
class DockContainerWidgetPrivate;
|
||||
class CDockAreaTitleBar;
|
||||
class CDockingStateReader;
|
||||
class CDockSplitter;
|
||||
|
||||
|
||||
/**
|
||||
@@ -216,12 +217,16 @@ 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
|
||||
*/
|
||||
bool isAutoHide() const;
|
||||
|
||||
|
||||
/**
|
||||
* Sets the current auto hide dock container
|
||||
*/
|
||||
@@ -401,7 +406,7 @@ public Q_SLOTS:
|
||||
* If the dock area is switched to auto hide mode, then all dock widgets
|
||||
* that are pinable will be added to the sidebar
|
||||
*/
|
||||
void setAutoHide(bool Enable, SideBarLocation Location = SideBarNone);
|
||||
void setAutoHide(bool Enable, SideBarLocation Location = SideBarNone, int TabIndex = -1);
|
||||
|
||||
/**
|
||||
* Switches the dock area to auto hide mode or vice versa depending on its
|
||||
@@ -414,6 +419,12 @@ public Q_SLOTS:
|
||||
*/
|
||||
void closeOtherAreas();
|
||||
|
||||
/**
|
||||
* Moves the dock area into its own floating widget if the area
|
||||
* DockWidgetFloatable flag is true
|
||||
*/
|
||||
void setFloating();
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* This signal is emitted when user clicks on a tab at an index.
|
||||
|
||||
@@ -141,11 +141,11 @@ 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;
|
||||
QSplitter* RootSplitter = nullptr;
|
||||
CDockSplitter* RootSplitter = nullptr;
|
||||
bool isFloating = false;
|
||||
CDockAreaWidget* LastAddedAreaCache[5];
|
||||
int VisibleDockAreaCount = -1;
|
||||
@@ -181,17 +181,29 @@ public:
|
||||
*/
|
||||
void dropIntoContainer(CFloatingDockContainer* FloatingWidget, DockWidgetArea area);
|
||||
|
||||
/**
|
||||
* Drop floating widget into auto hide side bar
|
||||
*/
|
||||
void dropIntoAutoHideSideBar(CFloatingDockContainer* FloatingWidget, DockWidgetArea area);
|
||||
|
||||
/**
|
||||
* Creates a new tab for a widget dropped into the center of a section
|
||||
*/
|
||||
void dropIntoCenterOfSection(CFloatingDockContainer* FloatingWidget,
|
||||
CDockAreaWidget* TargetArea, int TabIndex = 0);
|
||||
|
||||
/**
|
||||
* Drop floating widget into dock area
|
||||
*/
|
||||
void dropIntoSection(CFloatingDockContainer* FloatingWidget,
|
||||
CDockAreaWidget* TargetArea, DockWidgetArea area);
|
||||
CDockAreaWidget* TargetArea, DockWidgetArea area, int TabIndex = 0);
|
||||
|
||||
/**
|
||||
* Moves the dock widget or dock area given in Widget parameter to a
|
||||
* new dock widget area
|
||||
*/
|
||||
void moveToNewSection(QWidget* Widget, CDockAreaWidget* TargetArea, DockWidgetArea area);
|
||||
void moveToNewSection(QWidget* Widget, CDockAreaWidget* TargetArea, DockWidgetArea area,
|
||||
int TabIndex = 0);
|
||||
|
||||
/**
|
||||
* Moves the dock widget or dock area given in Widget parameter to a
|
||||
@@ -202,13 +214,13 @@ public:
|
||||
/**
|
||||
* Creates a new tab for a widget dropped into the center of a section
|
||||
*/
|
||||
void dropIntoCenterOfSection(CFloatingDockContainer* FloatingWidget,
|
||||
CDockAreaWidget* TargetArea);
|
||||
void moveIntoCenterOfSection(QWidget* Widget, CDockAreaWidget* TargetArea, int TabIndex = 0);
|
||||
|
||||
/**
|
||||
* Creates a new tab for a widget dropped into the center of a section
|
||||
* Moves the dock widget or dock area given in Widget parameter to
|
||||
* a auto hide sidebar area
|
||||
*/
|
||||
void moveIntoCenterOfSection(QWidget* Widget, CDockAreaWidget* TargetArea);
|
||||
void moveToAutoHideSideBar(QWidget* Widget, DockWidgetArea area, int TabIndex = TabDefaultInsertIndex);
|
||||
|
||||
|
||||
/**
|
||||
@@ -238,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);
|
||||
@@ -287,7 +299,11 @@ public:
|
||||
VisibleDockAreaCount = 0;
|
||||
for (auto DockArea : DockAreas)
|
||||
{
|
||||
VisibleDockAreaCount += DockArea->isHidden() ? 0 : 1;
|
||||
if (!DockArea)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
VisibleDockAreaCount += (DockArea->isHidden() ? 0 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -454,7 +470,7 @@ void DockContainerWidgetPrivate::dropIntoContainer(CFloatingDockContainer* Float
|
||||
CDockContainerWidget* FloatingDockContainer = FloatingWidget->dockContainer();
|
||||
auto NewDockAreas = FloatingDockContainer->findChildren<CDockAreaWidget*>(
|
||||
QString(), Qt::FindChildrenRecursively);
|
||||
QSplitter* Splitter = RootSplitter;
|
||||
auto Splitter = RootSplitter;
|
||||
|
||||
if (DockAreas.count() <= 1)
|
||||
{
|
||||
@@ -462,7 +478,7 @@ void DockContainerWidgetPrivate::dropIntoContainer(CFloatingDockContainer* Float
|
||||
}
|
||||
else if (Splitter->orientation() != InsertParam.orientation())
|
||||
{
|
||||
QSplitter* NewSplitter = newSplitter(InsertParam.orientation());
|
||||
auto NewSplitter = newSplitter(InsertParam.orientation());
|
||||
QLayoutItem* li = Layout->replaceWidget(Splitter, NewSplitter);
|
||||
NewSplitter->addWidget(Splitter);
|
||||
updateSplitterHandles(NewSplitter);
|
||||
@@ -505,14 +521,33 @@ void DockContainerWidgetPrivate::dropIntoContainer(CFloatingDockContainer* Float
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void DockContainerWidgetPrivate::dropIntoAutoHideSideBar(CFloatingDockContainer* FloatingWidget, DockWidgetArea area)
|
||||
{
|
||||
auto SideBarLocation = internal::toSideBarLocation(area);
|
||||
auto NewDockAreas = FloatingWidget->findChildren<CDockAreaWidget*>(
|
||||
QString(), Qt::FindChildrenRecursively);
|
||||
int TabIndex = DockManager->containerOverlay()->tabIndexUnderCursor();
|
||||
for (auto DockArea : NewDockAreas)
|
||||
{
|
||||
auto DockWidgets = DockArea->dockWidgets();
|
||||
for (auto DockWidget : DockWidgets)
|
||||
{
|
||||
_this->createAndSetupAutoHideContainer(SideBarLocation, DockWidget, TabIndex++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void DockContainerWidgetPrivate::dropIntoCenterOfSection(
|
||||
CFloatingDockContainer* FloatingWidget, CDockAreaWidget* TargetArea)
|
||||
CFloatingDockContainer* FloatingWidget, CDockAreaWidget* TargetArea, int TabIndex)
|
||||
{
|
||||
CDockContainerWidget* FloatingContainer = FloatingWidget->dockContainer();
|
||||
auto NewDockWidgets = FloatingContainer->dockWidgets();
|
||||
auto TopLevelDockArea = FloatingContainer->topLevelDockArea();
|
||||
int NewCurrentIndex = -1;
|
||||
TabIndex = qMax(0, TabIndex);
|
||||
|
||||
// If the floating widget contains only one single dock are, then the
|
||||
// current dock widget of the dock area will also be the future current
|
||||
@@ -525,7 +560,7 @@ void DockContainerWidgetPrivate::dropIntoCenterOfSection(
|
||||
for (int i = 0; i < NewDockWidgets.count(); ++i)
|
||||
{
|
||||
CDockWidget* DockWidget = NewDockWidgets[i];
|
||||
TargetArea->insertDockWidget(i, DockWidget, false);
|
||||
TargetArea->insertDockWidget(TabIndex + i, DockWidget, false);
|
||||
// If the floating widget contains multiple visible dock areas, then we
|
||||
// simply pick the first visible open dock widget and make it
|
||||
// the current one.
|
||||
@@ -534,7 +569,7 @@ void DockContainerWidgetPrivate::dropIntoCenterOfSection(
|
||||
NewCurrentIndex = i;
|
||||
}
|
||||
}
|
||||
TargetArea->setCurrentIndex(NewCurrentIndex);
|
||||
TargetArea->setCurrentIndex(NewCurrentIndex + TabIndex);
|
||||
TargetArea->updateTitleBarVisibility();
|
||||
return;
|
||||
}
|
||||
@@ -542,13 +577,13 @@ void DockContainerWidgetPrivate::dropIntoCenterOfSection(
|
||||
|
||||
//============================================================================
|
||||
void DockContainerWidgetPrivate::dropIntoSection(CFloatingDockContainer* FloatingWidget,
|
||||
CDockAreaWidget* TargetArea, DockWidgetArea area)
|
||||
CDockAreaWidget* TargetArea, DockWidgetArea area, int TabIndex)
|
||||
{
|
||||
// Dropping into center means all dock widgets in the dropped floating
|
||||
// widget will become tabs of the drop area
|
||||
if (CenterDockWidgetArea == area)
|
||||
{
|
||||
dropIntoCenterOfSection(FloatingWidget, TargetArea);
|
||||
dropIntoCenterOfSection(FloatingWidget, TargetArea, TabIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -556,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())
|
||||
@@ -638,11 +664,13 @@ void DockContainerWidgetPrivate::dropIntoSection(CFloatingDockContainer* Floatin
|
||||
|
||||
|
||||
//============================================================================
|
||||
void DockContainerWidgetPrivate::moveIntoCenterOfSection(QWidget* Widget, CDockAreaWidget* TargetArea)
|
||||
void DockContainerWidgetPrivate::moveIntoCenterOfSection(QWidget* Widget, CDockAreaWidget* TargetArea,
|
||||
int TabIndex)
|
||||
{
|
||||
auto DroppedDockWidget = qobject_cast<CDockWidget*>(Widget);
|
||||
auto DroppedArea = qobject_cast<CDockAreaWidget*>(Widget);
|
||||
|
||||
TabIndex = qMax(0, TabIndex);
|
||||
if (DroppedDockWidget)
|
||||
{
|
||||
CDockAreaWidget* OldDockArea = DroppedDockWidget->dockAreaWidget();
|
||||
@@ -655,7 +683,7 @@ void DockContainerWidgetPrivate::moveIntoCenterOfSection(QWidget* Widget, CDockA
|
||||
{
|
||||
OldDockArea->removeDockWidget(DroppedDockWidget);
|
||||
}
|
||||
TargetArea->insertDockWidget(0, DroppedDockWidget, true);
|
||||
TargetArea->insertDockWidget(TabIndex, DroppedDockWidget, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -664,9 +692,9 @@ void DockContainerWidgetPrivate::moveIntoCenterOfSection(QWidget* Widget, CDockA
|
||||
for (int i = 0; i < NewDockWidgets.count(); ++i)
|
||||
{
|
||||
CDockWidget* DockWidget = NewDockWidgets[i];
|
||||
TargetArea->insertDockWidget(i, DockWidget, false);
|
||||
TargetArea->insertDockWidget(TabIndex + i, DockWidget, false);
|
||||
}
|
||||
TargetArea->setCurrentIndex(NewCurrentIndex);
|
||||
TargetArea->setCurrentIndex(TabIndex + NewCurrentIndex);
|
||||
DroppedArea->dockContainer()->removeDockArea(DroppedArea);
|
||||
DroppedArea->deleteLater();
|
||||
}
|
||||
@@ -677,13 +705,14 @@ void DockContainerWidgetPrivate::moveIntoCenterOfSection(QWidget* Widget, CDockA
|
||||
|
||||
|
||||
//============================================================================
|
||||
void DockContainerWidgetPrivate::moveToNewSection(QWidget* Widget, CDockAreaWidget* TargetArea, DockWidgetArea area)
|
||||
void DockContainerWidgetPrivate::moveToNewSection(QWidget* Widget, CDockAreaWidget* TargetArea, DockWidgetArea area,
|
||||
int TabIndex)
|
||||
{
|
||||
// Dropping into center means all dock widgets in the dropped floating
|
||||
// widget will become tabs of the drop area
|
||||
if (CenterDockWidgetArea == area)
|
||||
{
|
||||
moveIntoCenterOfSection(Widget, TargetArea);
|
||||
moveIntoCenterOfSection(Widget, TargetArea, TabIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -708,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())
|
||||
@@ -738,6 +767,48 @@ void DockContainerWidgetPrivate::moveToNewSection(QWidget* Widget, CDockAreaWidg
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void DockContainerWidgetPrivate::moveToAutoHideSideBar(QWidget* Widget, DockWidgetArea area, int TabIndex)
|
||||
{
|
||||
CDockWidget* DroppedDockWidget = qobject_cast<CDockWidget*>(Widget);
|
||||
CDockAreaWidget* DroppedDockArea = qobject_cast<CDockAreaWidget*>(Widget);
|
||||
auto SideBarLocation = internal::toSideBarLocation(area);
|
||||
|
||||
if (DroppedDockWidget)
|
||||
{
|
||||
if (_this == DroppedDockWidget->dockContainer())
|
||||
{
|
||||
DroppedDockWidget->setAutoHide(true, SideBarLocation, TabIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
_this->createAndSetupAutoHideContainer(SideBarLocation, DroppedDockWidget, TabIndex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_this == DroppedDockArea->dockContainer())
|
||||
{
|
||||
DroppedDockArea->setAutoHide(true, SideBarLocation, TabIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const auto DockWidget : DroppedDockArea->openedDockWidgets())
|
||||
{
|
||||
if (!DockWidget->features().testFlag(
|
||||
CDockWidget::DockWidgetPinnable))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
_this->createAndSetupAutoHideContainer(SideBarLocation,
|
||||
DockWidget, TabIndex++);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void DockContainerWidgetPrivate::updateSplitterHandles( QSplitter* splitter )
|
||||
{
|
||||
@@ -801,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())
|
||||
{
|
||||
@@ -857,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,
|
||||
@@ -908,7 +982,7 @@ void DockContainerWidgetPrivate::saveAutoHideWidgetsState(QXmlStreamWriter& s)
|
||||
{
|
||||
for (const auto sideTabBar : SideTabBarWidgets.values())
|
||||
{
|
||||
if (!sideTabBar->tabCount())
|
||||
if (!sideTabBar->count())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -1101,12 +1175,12 @@ bool DockContainerWidgetPrivate::restoreSideBar(CDockingStateReader& s,
|
||||
continue;
|
||||
}
|
||||
|
||||
auto SideBar = _this->sideTabBar(Area);
|
||||
auto SideBar = _this->autoHideSideBar(Area);
|
||||
CAutoHideDockContainer* AutoHideContainer;
|
||||
if (DockWidget->isAutoHide())
|
||||
{
|
||||
AutoHideContainer = DockWidget->autoHideDockContainer();
|
||||
if (AutoHideContainer->sideBar() != SideBar)
|
||||
if (AutoHideContainer->autoHideSideBar() != SideBar)
|
||||
{
|
||||
SideBar->addAutoHideWidget(AutoHideContainer);
|
||||
}
|
||||
@@ -1193,7 +1267,7 @@ void DockContainerWidgetPrivate::addDockArea(CDockAreaWidget* NewDockArea, DockW
|
||||
}
|
||||
else
|
||||
{
|
||||
QSplitter* NewSplitter = newSplitter(InsertParam.orientation());
|
||||
auto NewSplitter = newSplitter(InsertParam.orientation());
|
||||
if (InsertParam.append())
|
||||
{
|
||||
QLayoutItem* li = Layout->replaceWidget(Splitter, NewSplitter);
|
||||
@@ -1288,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())
|
||||
{
|
||||
@@ -1305,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());
|
||||
@@ -1404,7 +1478,7 @@ CDockAreaWidget* CDockContainerWidget::addDockWidget(DockWidgetArea area, CDockW
|
||||
|
||||
//============================================================================
|
||||
CAutoHideDockContainer* CDockContainerWidget::createAndSetupAutoHideContainer(
|
||||
SideBarLocation area, CDockWidget* DockWidget)
|
||||
SideBarLocation area, CDockWidget* DockWidget, int TabIndex)
|
||||
{
|
||||
if (!CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideFeatureEnabled))
|
||||
{
|
||||
@@ -1417,7 +1491,7 @@ CAutoHideDockContainer* CDockContainerWidget::createAndSetupAutoHideContainer(
|
||||
DockWidget->setDockManager(d->DockManager); // Auto hide Dock Container needs a valid dock manager
|
||||
}
|
||||
|
||||
return sideTabBar(area)->insertDockWidget(-1, DockWidget);
|
||||
return autoHideSideBar(area)->insertDockWidget(TabIndex, DockWidget);
|
||||
}
|
||||
|
||||
|
||||
@@ -1496,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
|
||||
@@ -1528,7 +1602,7 @@ void CDockContainerWidget::removeDockArea(CDockAreaWidget* area)
|
||||
}
|
||||
|
||||
QWidget* widget = Splitter->widget(0);
|
||||
QSplitter* ChildSplitter = qobject_cast<QSplitter*>(widget);
|
||||
auto ChildSplitter = qobject_cast<CDockSplitter*>(widget);
|
||||
// If the one and only content widget of the splitter is not a splitter
|
||||
// then we are finished
|
||||
if (!ChildSplitter)
|
||||
@@ -1569,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;
|
||||
}
|
||||
@@ -1611,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;
|
||||
@@ -1629,11 +1712,12 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
|
||||
ADS_PRINT("CDockContainerWidget::dropFloatingWidget");
|
||||
CDockWidget* SingleDroppedDockWidget = FloatingWidget->topLevelDockWidget();
|
||||
CDockWidget* SingleDockWidget = topLevelDockWidget();
|
||||
CDockAreaWidget* DockArea = dockAreaAt(TargetPos);
|
||||
auto dropArea = InvalidDockWidgetArea;
|
||||
auto ContainerDropArea = d->DockManager->containerOverlay()->dropAreaUnderCursor();
|
||||
bool Dropped = false;
|
||||
|
||||
CDockAreaWidget* DockArea = dockAreaAt(TargetPos);
|
||||
// mouse is over dock area
|
||||
if (DockArea)
|
||||
{
|
||||
auto dropOverlay = d->DockManager->dockAreaOverlay();
|
||||
@@ -1648,35 +1732,40 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
|
||||
if (dropArea != InvalidDockWidgetArea)
|
||||
{
|
||||
ADS_PRINT("Dock Area Drop Content: " << dropArea);
|
||||
d->dropIntoSection(FloatingWidget, DockArea, dropArea);
|
||||
int TabIndex = d->DockManager->dockAreaOverlay()->tabIndexUnderCursor();
|
||||
d->dropIntoSection(FloatingWidget, DockArea, dropArea, TabIndex);
|
||||
Dropped = true;
|
||||
}
|
||||
}
|
||||
|
||||
// mouse is over container
|
||||
if (InvalidDockWidgetArea == dropArea)
|
||||
// mouse is over container or auto hide side bar
|
||||
if (InvalidDockWidgetArea == dropArea && InvalidDockWidgetArea != ContainerDropArea)
|
||||
{
|
||||
dropArea = ContainerDropArea;
|
||||
ADS_PRINT("Container Drop Content: " << dropArea);
|
||||
if (dropArea != InvalidDockWidgetArea)
|
||||
{
|
||||
d->dropIntoContainer(FloatingWidget, dropArea);
|
||||
Dropped = true;
|
||||
}
|
||||
if (internal::isSideBarArea(ContainerDropArea))
|
||||
{
|
||||
ADS_PRINT("Container Drop Content: " << ContainerDropArea);
|
||||
d->dropIntoAutoHideSideBar(FloatingWidget, ContainerDropArea);
|
||||
}
|
||||
else
|
||||
{
|
||||
ADS_PRINT("Container Drop Content: " << ContainerDropArea);
|
||||
d->dropIntoContainer(FloatingWidget, ContainerDropArea);
|
||||
}
|
||||
Dropped = true;
|
||||
}
|
||||
|
||||
// Remove the auto hide widgets from the FloatingWidget and insert
|
||||
// them into this widget
|
||||
for (auto AutohideWidget : FloatingWidget->dockContainer()->autoHideWidgets())
|
||||
{
|
||||
auto SideBar = sideTabBar(AutohideWidget->sideBarLocation());
|
||||
auto SideBar = autoHideSideBar(AutohideWidget->sideBarLocation());
|
||||
SideBar->addAutoHideWidget(AutohideWidget);
|
||||
}
|
||||
|
||||
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
|
||||
@@ -1697,12 +1786,17 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockContainerWidget::dropWidget(QWidget* Widget, DockWidgetArea DropArea, CDockAreaWidget* TargetAreaWidget)
|
||||
void CDockContainerWidget::dropWidget(QWidget* Widget, DockWidgetArea DropArea, CDockAreaWidget* TargetAreaWidget,
|
||||
int TabIndex)
|
||||
{
|
||||
CDockWidget* SingleDockWidget = topLevelDockWidget();
|
||||
if (TargetAreaWidget)
|
||||
{
|
||||
d->moveToNewSection(Widget, TargetAreaWidget, DropArea);
|
||||
d->moveToNewSection(Widget, TargetAreaWidget, DropArea, TabIndex);
|
||||
}
|
||||
else if (internal::isSideBarArea(DropArea))
|
||||
{
|
||||
d->moveToAutoHideSideBar(Widget, DropArea, TabIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1724,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);
|
||||
}
|
||||
@@ -1740,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());
|
||||
}
|
||||
@@ -1755,7 +1849,7 @@ bool CDockContainerWidget::hasOpenDockAreas() const
|
||||
{
|
||||
for (auto DockArea : d->DockAreas)
|
||||
{
|
||||
if (!DockArea->isHidden())
|
||||
if (DockArea && !DockArea->isHidden())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -1845,17 +1939,18 @@ bool CDockContainerWidget::restoreState(CDockingStateReader& s, bool Testing)
|
||||
NewRootSplitter = d->newSplitter(Qt::Horizontal);
|
||||
}
|
||||
|
||||
d->Layout->replaceWidget(d->RootSplitter, NewRootSplitter);
|
||||
QSplitter* OldRoot = d->RootSplitter;
|
||||
d->RootSplitter = qobject_cast<QSplitter*>(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;
|
||||
}
|
||||
@@ -1977,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());
|
||||
}
|
||||
|
||||
@@ -2009,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();
|
||||
}
|
||||
|
||||
@@ -2028,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;
|
||||
}
|
||||
@@ -2051,7 +2154,7 @@ void CDockContainerWidget::closeOtherAreas(CDockAreaWidget* KeepOpenArea)
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
CAutoHideSideBar* CDockContainerWidget::sideTabBar(SideBarLocation area) const
|
||||
CAutoHideSideBar* CDockContainerWidget::autoHideSideBar(SideBarLocation area) const
|
||||
{
|
||||
return d->SideTabBarWidgets[area];
|
||||
}
|
||||
@@ -2065,7 +2168,21 @@ QRect CDockContainerWidget::contentRect() const
|
||||
return QRect();
|
||||
}
|
||||
|
||||
return d->RootSplitter->geometry();
|
||||
if (d->RootSplitter->hasVisibleContent())
|
||||
{
|
||||
return d->RootSplitter->geometry();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto ContentRect = this->rect();
|
||||
ContentRect.adjust(
|
||||
autoHideSideBar(SideBarLeft)->sizeHint().width(),
|
||||
autoHideSideBar(SideBarTop)->sizeHint().height(),
|
||||
-autoHideSideBar(SideBarRight)->sizeHint().width(),
|
||||
-autoHideSideBar(SideBarBottom)->sizeHint().height());
|
||||
|
||||
return ContentRect;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ struct FloatingDragPreviewPrivate;
|
||||
class CDockingStateReader;
|
||||
class CAutoHideSideBar;
|
||||
class CAutoHideTab;
|
||||
class CDockSplitter;
|
||||
struct AutoHideTabPrivate;
|
||||
struct AutoHideDockContainerPrivate;
|
||||
|
||||
@@ -94,14 +95,14 @@ 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.
|
||||
* Initializing inserts the tabs into the side tab widget and hides it
|
||||
* Returns nullptr if you try and insert into an area where the configuration is not enabled
|
||||
*/
|
||||
CAutoHideDockContainer* createAndSetupAutoHideContainer(SideBarLocation area, CDockWidget* DockWidget);
|
||||
CAutoHideDockContainer* createAndSetupAutoHideContainer(SideBarLocation area, CDockWidget* DockWidget, int TabIndex = -1);
|
||||
|
||||
/**
|
||||
* Helper function for creation of the root splitter
|
||||
@@ -125,7 +126,8 @@ protected:
|
||||
* a nullptr, then the DropArea indicates the drop area in the given
|
||||
* TargetAreaWidget
|
||||
*/
|
||||
void dropWidget(QWidget* Widget, DockWidgetArea DropArea, CDockAreaWidget* TargetAreaWidget);
|
||||
void dropWidget(QWidget* Widget, DockWidgetArea DropArea, CDockAreaWidget* TargetAreaWidget,
|
||||
int TabIndex = -1);
|
||||
|
||||
/**
|
||||
* Adds the given dock area to this container widget
|
||||
@@ -137,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
|
||||
*/
|
||||
@@ -322,7 +329,7 @@ public:
|
||||
/**
|
||||
* Returns the side tab widget for the given area
|
||||
*/
|
||||
CAutoHideSideBar* sideTabBar(SideBarLocation area) const;
|
||||
CAutoHideSideBar* autoHideSideBar(SideBarLocation area) const;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -55,6 +55,8 @@ class CIconProvider;
|
||||
class CDockComponentsFactory;
|
||||
class CDockFocusController;
|
||||
class CAutoHideSideBar;
|
||||
class CAutoHideTab;
|
||||
struct AutoHideTabPrivate;
|
||||
|
||||
/**
|
||||
* The central dock manager that maintains the complete docking system.
|
||||
@@ -87,6 +89,8 @@ private:
|
||||
friend class CDockAreaTitleBar;
|
||||
friend class CAutoHideDockContainer;
|
||||
friend CAutoHideSideBar;
|
||||
friend CAutoHideTab;
|
||||
friend AutoHideTabPrivate;
|
||||
|
||||
public Q_SLOTS:
|
||||
/**
|
||||
@@ -150,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.
|
||||
*/
|
||||
@@ -209,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
|
||||
@@ -246,9 +252,13 @@ 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 ///< the default configuration for left and right side bars
|
||||
| DockAreaHasAutoHideButton
|
||||
| AutoHideHasMinimizeButton
|
||||
|
||||
};
|
||||
Q_DECLARE_FLAGS(AutoHideFlags, eAutoHideFlag)
|
||||
|
||||
@@ -535,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);
|
||||
@@ -620,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 wasn’t 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.
|
||||
|
||||
@@ -38,11 +38,18 @@
|
||||
|
||||
#include "DockAreaWidget.h"
|
||||
#include "DockAreaTitleBar.h"
|
||||
#include "DockContainerWidget.h"
|
||||
#include "AutoHideSideBar.h"
|
||||
#include "DockManager.h"
|
||||
#include "DockAreaTabBar.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace ads
|
||||
{
|
||||
static const int AutoHideAreaWidth = 32;
|
||||
static const int AutoHideAreaMouseZone = 8;
|
||||
static const int InvalidTabIndex = -2;
|
||||
|
||||
/**
|
||||
* Private data class of CDockOverlay
|
||||
@@ -57,11 +64,23 @@ struct DockOverlayPrivate
|
||||
bool DropPreviewEnabled = true;
|
||||
CDockOverlay::eMode Mode = CDockOverlay::ModeDockAreaOverlay;
|
||||
QRect DropAreaRect;
|
||||
int TabIndex = InvalidTabIndex;
|
||||
|
||||
/**
|
||||
* Private data constructor
|
||||
*/
|
||||
DockOverlayPrivate(CDockOverlay* _public) : _this(_public) {}
|
||||
|
||||
/**
|
||||
* Returns the overlay width / height depending on the visibility
|
||||
* of the sidebar
|
||||
*/
|
||||
int sideBarOverlaySize(SideBarLocation sideBarLocation);
|
||||
|
||||
/**
|
||||
* The area where the mouse is considered in the sidebar
|
||||
*/
|
||||
int sideBarMouseZone(SideBarLocation sideBarLocation);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -155,8 +174,20 @@ struct DockOverlayCrossPrivate
|
||||
QLabel* l = new QLabel();
|
||||
l->setObjectName("DockWidgetAreaLabel");
|
||||
|
||||
const qreal metric = dropIndicatiorWidth(l);
|
||||
const QSizeF size(metric, metric);
|
||||
qreal metric = dropIndicatiorWidth(l);
|
||||
QSizeF size(metric, metric);
|
||||
if (internal::isSideBarArea(DockWidgetArea))
|
||||
{
|
||||
auto SideBarLocation = internal::toSideBarLocation(DockWidgetArea);
|
||||
if (internal::isHorizontalSideBarLocation(SideBarLocation))
|
||||
{
|
||||
size.setHeight(size.height() / 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
size.setWidth(size.width() / 2);
|
||||
}
|
||||
}
|
||||
|
||||
l->setPixmap(createHighDpiDropIndicatorPixmap(size, DockWidgetArea, Mode));
|
||||
l->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
|
||||
@@ -182,6 +213,11 @@ struct DockOverlayCrossPrivate
|
||||
{
|
||||
QColor borderColor = iconColor(CDockOverlayCross::FrameColor);
|
||||
QColor backgroundColor = iconColor(CDockOverlayCross::WindowBackgroundColor);
|
||||
QColor overlayColor = iconColor(CDockOverlayCross::OverlayColor);
|
||||
if (overlayColor.alpha() == 255)
|
||||
{
|
||||
overlayColor.setAlpha(64);
|
||||
}
|
||||
|
||||
#if QT_VERSION >= 0x050600
|
||||
double DevicePixelRatio = _this->window()->devicePixelRatioF();
|
||||
@@ -239,22 +275,22 @@ struct DockOverlayCrossPrivate
|
||||
}
|
||||
|
||||
QSizeF baseSize = baseRect.size();
|
||||
if (CDockOverlay::ModeContainerOverlay == Mode && DockWidgetArea != CenterDockWidgetArea)
|
||||
bool IsOuterContainerArea = (CDockOverlay::ModeContainerOverlay == Mode)
|
||||
&& (DockWidgetArea != CenterDockWidgetArea)
|
||||
&& !internal::isSideBarArea(DockWidgetArea);
|
||||
|
||||
if (IsOuterContainerArea)
|
||||
{
|
||||
baseRect = areaRect;
|
||||
}
|
||||
|
||||
p.fillRect(baseRect, backgroundColor);
|
||||
|
||||
if (areaRect.isValid())
|
||||
{
|
||||
pen = p.pen();
|
||||
pen.setColor(borderColor);
|
||||
QColor Color = iconColor(CDockOverlayCross::OverlayColor);
|
||||
if (Color.alpha() == 255)
|
||||
{
|
||||
Color.setAlpha(64);
|
||||
}
|
||||
p.setBrush(Color);
|
||||
p.setBrush(overlayColor);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawRect(areaRect);
|
||||
|
||||
@@ -267,6 +303,7 @@ struct DockOverlayCrossPrivate
|
||||
}
|
||||
p.restore();
|
||||
|
||||
|
||||
p.save();
|
||||
// Draw outer border
|
||||
pen = p.pen();
|
||||
@@ -282,8 +319,9 @@ struct DockOverlayCrossPrivate
|
||||
p.drawRect(FrameRect);
|
||||
p.restore();
|
||||
|
||||
|
||||
// Draw arrow for outer container drop indicators
|
||||
if (CDockOverlay::ModeContainerOverlay == Mode && DockWidgetArea != CenterDockWidgetArea)
|
||||
if (IsOuterContainerArea)
|
||||
{
|
||||
QRectF ArrowRect;
|
||||
ArrowRect.setSize(baseSize);
|
||||
@@ -326,6 +364,38 @@ struct DockOverlayCrossPrivate
|
||||
};
|
||||
|
||||
|
||||
//============================================================================
|
||||
int DockOverlayPrivate::sideBarOverlaySize(SideBarLocation sideBarLocation)
|
||||
{
|
||||
auto Container = qobject_cast<CDockContainerWidget*>(TargetWidget.data());
|
||||
auto SideBar = Container->autoHideSideBar(sideBarLocation);
|
||||
if (!SideBar || !SideBar->isVisibleTo(Container))
|
||||
{
|
||||
return AutoHideAreaWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (SideBar->orientation() == Qt::Horizontal) ? SideBar->height() : SideBar->width();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
int DockOverlayPrivate::sideBarMouseZone(SideBarLocation sideBarLocation)
|
||||
{
|
||||
auto Container = qobject_cast<CDockContainerWidget*>(TargetWidget.data());
|
||||
auto SideBar = Container->autoHideSideBar(sideBarLocation);
|
||||
if (!SideBar || !SideBar->isVisibleTo(Container))
|
||||
{
|
||||
return AutoHideAreaMouseZone;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (SideBar->orientation() == Qt::Horizontal) ? SideBar->height() : SideBar->width();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
CDockOverlay::CDockOverlay(QWidget* parent, eMode Mode) :
|
||||
QFrame(parent),
|
||||
@@ -359,12 +429,26 @@ CDockOverlay::~CDockOverlay()
|
||||
void CDockOverlay::setAllowedAreas(DockWidgetAreas areas)
|
||||
{
|
||||
if (areas == d->AllowedAreas)
|
||||
{
|
||||
return;
|
||||
}
|
||||
d->AllowedAreas = areas;
|
||||
d->Cross->reset();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockOverlay::setAllowedArea(DockWidgetArea area, bool Enable)
|
||||
{
|
||||
auto AreasOld = d->AllowedAreas;
|
||||
d->AllowedAreas.setFlag(area, Enable);
|
||||
if (AreasOld != d->AllowedAreas)
|
||||
{
|
||||
d->Cross->reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
DockWidgetAreas CDockOverlay::allowedAreas() const
|
||||
{
|
||||
@@ -375,22 +459,68 @@ DockWidgetAreas CDockOverlay::allowedAreas() const
|
||||
//============================================================================
|
||||
DockWidgetArea CDockOverlay::dropAreaUnderCursor() const
|
||||
{
|
||||
d->TabIndex = InvalidTabIndex;
|
||||
if (!d->TargetWidget)
|
||||
{
|
||||
return InvalidDockWidgetArea;
|
||||
}
|
||||
|
||||
DockWidgetArea Result = d->Cross->cursorLocation();
|
||||
if (Result != InvalidDockWidgetArea)
|
||||
{
|
||||
return Result;
|
||||
}
|
||||
|
||||
CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(d->TargetWidget.data());
|
||||
if (!DockArea)
|
||||
auto CursorPos = QCursor::pos();
|
||||
auto DockArea = qobject_cast<CDockAreaWidget*>(d->TargetWidget.data());
|
||||
if (!DockArea && CDockManager::autoHideConfigFlags().testFlag(CDockManager::AutoHideFeatureEnabled))
|
||||
{
|
||||
auto Rect = rect();
|
||||
const QPoint pos = mapFromGlobal(QCursor::pos());
|
||||
if ((pos.x() < d->sideBarMouseZone(SideBarLeft))
|
||||
&& d->AllowedAreas.testFlag(LeftAutoHideArea))
|
||||
{
|
||||
Result = LeftAutoHideArea;
|
||||
}
|
||||
else if (pos.x() > (Rect.width() - d->sideBarMouseZone(SideBarRight))
|
||||
&& d->AllowedAreas.testFlag(RightAutoHideArea))
|
||||
{
|
||||
Result = RightAutoHideArea;
|
||||
}
|
||||
else if (pos.y() < d->sideBarMouseZone(SideBarTop)
|
||||
&& d->AllowedAreas.testFlag(TopAutoHideArea))
|
||||
{
|
||||
Result = TopAutoHideArea;
|
||||
}
|
||||
else if (pos.y() > (Rect.height() - d->sideBarMouseZone(SideBarBottom))
|
||||
&& d->AllowedAreas.testFlag(BottomAutoHideArea))
|
||||
{
|
||||
Result = BottomAutoHideArea;
|
||||
}
|
||||
|
||||
auto SideBarLocation = ads::internal::toSideBarLocation(Result);
|
||||
if (SideBarLocation != SideBarNone)
|
||||
{
|
||||
auto Container = qobject_cast<CDockContainerWidget*>(d->TargetWidget.data());
|
||||
auto SideBar = Container->autoHideSideBar(SideBarLocation);
|
||||
if (SideBar->isVisible())
|
||||
{
|
||||
d->TabIndex = SideBar->tabInsertIndexAt(SideBar->mapFromGlobal(CursorPos));
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
else if (!DockArea)
|
||||
{
|
||||
return Result;
|
||||
}
|
||||
|
||||
if (DockArea->allowedAreas().testFlag(CenterDockWidgetArea)
|
||||
&& !DockArea->titleBar()->isHidden()
|
||||
&& DockArea->titleBarGeometry().contains(DockArea->mapFromGlobal(QCursor::pos())))
|
||||
&& DockArea->titleBarGeometry().contains(DockArea->mapFromGlobal(CursorPos)))
|
||||
{
|
||||
auto TabBar = DockArea->titleBar()->tabBar();
|
||||
d->TabIndex = TabBar->tabInsertIndexAt(TabBar->mapFromGlobal(CursorPos));
|
||||
return CenterDockWidgetArea;
|
||||
}
|
||||
|
||||
@@ -398,6 +528,13 @@ DockWidgetArea CDockOverlay::dropAreaUnderCursor() const
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
int CDockOverlay::tabIndexUnderCursor() const
|
||||
{
|
||||
return d->TabIndex;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
DockWidgetArea CDockOverlay::visibleDropAreaUnderCursor() const
|
||||
{
|
||||
@@ -471,6 +608,7 @@ bool CDockOverlay::dropPreviewEnabled() const
|
||||
void CDockOverlay::paintEvent(QPaintEvent* event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
|
||||
// Draw rect based on location
|
||||
if (!d->DropPreviewEnabled)
|
||||
{
|
||||
@@ -490,8 +628,13 @@ void CDockOverlay::paintEvent(QPaintEvent* event)
|
||||
case BottomDockWidgetArea: r.setY(r.height() * (1 - 1 / Factor)); break;
|
||||
case LeftDockWidgetArea: r.setWidth(r.width() / Factor); break;
|
||||
case CenterDockWidgetArea: r = rect();break;
|
||||
case LeftAutoHideArea: r.setWidth(d->sideBarOverlaySize(SideBarLeft)); break;
|
||||
case RightAutoHideArea: r.setX(r.width() - d->sideBarOverlaySize(SideBarRight)); break;
|
||||
case TopAutoHideArea: r.setHeight(d->sideBarOverlaySize(SideBarTop)); break;
|
||||
case BottomAutoHideArea: r.setY(r.height() - d->sideBarOverlaySize(SideBarBottom)); break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
QPainter painter(this);
|
||||
QColor Color = palette().color(QPalette::Active, QPalette::Highlight);
|
||||
QPen Pen = painter.pen();
|
||||
@@ -627,6 +770,7 @@ void CDockOverlayCross::setupOverlayCross(CDockOverlay::eMode Mode)
|
||||
areaWidgets.insert(BottomDockWidgetArea, d->createDropIndicatorWidget(BottomDockWidgetArea, Mode));
|
||||
areaWidgets.insert(LeftDockWidgetArea, d->createDropIndicatorWidget(LeftDockWidgetArea, Mode));
|
||||
areaWidgets.insert(CenterDockWidgetArea, d->createDropIndicatorWidget(CenterDockWidgetArea, Mode));
|
||||
|
||||
#if QT_VERSION >= 0x050600
|
||||
d->LastDevicePixelRatio = devicePixelRatioF();
|
||||
#else
|
||||
|
||||
@@ -72,6 +72,11 @@ public:
|
||||
*/
|
||||
void setAllowedAreas(DockWidgetAreas areas);
|
||||
|
||||
/**
|
||||
* Enable / disable a certain area
|
||||
*/
|
||||
void setAllowedArea(DockWidgetArea area, bool Enable);
|
||||
|
||||
/**
|
||||
* Returns flags with all allowed drop areas
|
||||
*/
|
||||
@@ -82,6 +87,17 @@ public:
|
||||
*/
|
||||
DockWidgetArea dropAreaUnderCursor() const;
|
||||
|
||||
/**
|
||||
* If the drop area is the CenterDockWidgetArea or a sidebar area,
|
||||
* then this function returns the index of the tab under cursor.
|
||||
* Call this function after call to dropAreaUnderCursor() because this
|
||||
* function updates the tab index.
|
||||
* A value of -1 indicates a position before the first tab and a value of
|
||||
* tabCount() indicates a position behind the last tab.
|
||||
* A value of -2 indicates an valid value
|
||||
*/
|
||||
int tabIndexUnderCursor() const;
|
||||
|
||||
/**
|
||||
* This function returns the same like dropAreaUnderCursor() if this
|
||||
* overlay is not hidden and if drop preview is enabled and returns
|
||||
|
||||
@@ -39,7 +39,7 @@ struct DockSplitterPrivate;
|
||||
|
||||
/**
|
||||
* Splitter used internally instead of QSplitter with some additional
|
||||
* fuctionality.
|
||||
* functionality.
|
||||
*/
|
||||
class ADS_EXPORT CDockSplitter : public QSplitter
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -555,6 +625,13 @@ bool CDockWidget::isAutoHide() const
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
SideBarLocation CDockWidget::autoHideLocation() const
|
||||
{
|
||||
return isAutoHide() ? autoHideDockContainer()->sideBarLocation() : SideBarNone;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool CDockWidget::isFloating() const
|
||||
{
|
||||
@@ -691,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)
|
||||
@@ -1021,7 +1097,15 @@ void CDockWidget::setFloating()
|
||||
{
|
||||
return;
|
||||
}
|
||||
d->TabWidget->detachDockWidget();
|
||||
|
||||
if (this->isAutoHide())
|
||||
{
|
||||
dockAreaWidget()->setFloating();
|
||||
}
|
||||
else
|
||||
{
|
||||
d->TabWidget->detachDockWidget();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1044,6 +1128,22 @@ void CDockWidget::closeDockWidget()
|
||||
}
|
||||
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockWidget::requestCloseDockWidget()
|
||||
{
|
||||
if (features().testFlag(CDockWidget::DockWidgetDeleteOnClose)
|
||||
|| features().testFlag(CDockWidget::CustomCloseHandling))
|
||||
{
|
||||
closeDockWidgetInternal(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
toggleView(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool CDockWidget::closeDockWidgetInternal(bool ForceClose)
|
||||
{
|
||||
@@ -1190,7 +1290,7 @@ void CDockWidget::raise()
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockWidget::setAutoHide(bool Enable, SideBarLocation Location)
|
||||
void CDockWidget::setAutoHide(bool Enable, SideBarLocation Location, int TabIndex)
|
||||
{
|
||||
if (!CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideFeatureEnabled))
|
||||
{
|
||||
@@ -1198,20 +1298,25 @@ void CDockWidget::setAutoHide(bool Enable, SideBarLocation Location)
|
||||
}
|
||||
|
||||
// Do nothing if nothing changes
|
||||
if (Enable == isAutoHide())
|
||||
if (Enable == isAutoHide() && Location == autoHideLocation())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto DockArea = dockAreaWidget();
|
||||
|
||||
if (!Enable)
|
||||
{
|
||||
DockArea->setAutoHide(false);
|
||||
}
|
||||
else if (isAutoHide())
|
||||
{
|
||||
autoHideDockContainer()->moveToNewSideBarLocation(Location);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto area = (SideBarNone == Location) ? DockArea->calculateSideTabBarArea() : Location;
|
||||
dockContainer()->createAndSetupAutoHideContainer(area, this);
|
||||
dockContainer()->createAndSetupAutoHideContainer(area, this, TabIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1228,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
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -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
|
||||
@@ -377,6 +389,12 @@ public:
|
||||
*/
|
||||
CAutoHideDockContainer* autoHideDockContainer() const;
|
||||
|
||||
/**
|
||||
* Returns the auto hide side bar location or SideBarNone if, this is not
|
||||
* an autohide dock widget
|
||||
*/
|
||||
SideBarLocation autoHideLocation() const;
|
||||
|
||||
/**
|
||||
* This property holds whether the dock widget is floating.
|
||||
* A dock widget is only floating, if it is the one and only widget inside
|
||||
@@ -403,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
|
||||
@@ -439,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().
|
||||
@@ -461,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.
|
||||
@@ -578,10 +613,19 @@ public Q_SLOTS:
|
||||
void deleteDockWidget();
|
||||
|
||||
/**
|
||||
* Closes the dock widget
|
||||
* Closes the dock widget.
|
||||
* The function forces closing of the dock widget even for CustomCloseHandling.
|
||||
*/
|
||||
void closeDockWidget();
|
||||
|
||||
/**
|
||||
* Request closing of the dock widget.
|
||||
* For DockWidget with default close handling, the function does the same
|
||||
* like clodeDockWidget() but if the flas CustomCloseHandling is set,
|
||||
* the function only emits the closeRequested() signal.
|
||||
*/
|
||||
void requestCloseDockWidget();
|
||||
|
||||
/**
|
||||
* Shows the widget in full-screen mode.
|
||||
* Normally this function only affects windows. To make the interface
|
||||
@@ -606,7 +650,7 @@ public Q_SLOTS:
|
||||
* Sets the dock widget into auto hide mode if this feature is enabled
|
||||
* via CDockManager::setAutoHideFlags(CDockManager::AutoHideFeatureEnabled)
|
||||
*/
|
||||
void setAutoHide(bool Enable, SideBarLocation Location = SideBarNone);
|
||||
void setAutoHide(bool Enable, SideBarLocation Location = SideBarNone, int TabIndex = -1);
|
||||
|
||||
/**
|
||||
* Switches the dock widget to auto hide mode or vice versa depending on its
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
@@ -499,10 +499,8 @@ void FloatingDockContainerPrivate::titleMouseReleaseEvent()
|
||||
return;
|
||||
}
|
||||
|
||||
if (DockManager->dockAreaOverlay()->dropAreaUnderCursor()
|
||||
!= InvalidDockWidgetArea
|
||||
|| DockManager->containerOverlay()->dropAreaUnderCursor()
|
||||
!= InvalidDockWidgetArea)
|
||||
if (DockManager->dockAreaOverlay()->dropAreaUnderCursor() != InvalidDockWidgetArea
|
||||
|| DockManager->containerOverlay()->dropAreaUnderCursor() != InvalidDockWidgetArea)
|
||||
{
|
||||
CDockOverlay *Overlay = DockManager->containerOverlay();
|
||||
if (!Overlay->dropOverlayRect().isValid())
|
||||
@@ -510,21 +508,26 @@ void FloatingDockContainerPrivate::titleMouseReleaseEvent()
|
||||
Overlay = DockManager->dockAreaOverlay();
|
||||
}
|
||||
|
||||
// Resize the floating widget to the size of the highlighted drop area
|
||||
// rectangle
|
||||
QRect Rect = Overlay->dropOverlayRect();
|
||||
int FrameWidth = (_this->frameSize().width() - _this->rect().width())
|
||||
/ 2;
|
||||
int TitleBarHeight = _this->frameSize().height()
|
||||
- _this->rect().height() - FrameWidth;
|
||||
if (Rect.isValid())
|
||||
// Do not resize if we drop into an autohide sidebar area to preserve
|
||||
// the dock area size for the initial size of the auto hide area
|
||||
if (!ads::internal::isSideBarArea(Overlay->dropAreaUnderCursor()))
|
||||
{
|
||||
QPoint TopLeft = Overlay->mapToGlobal(Rect.topLeft());
|
||||
TopLeft.ry() += TitleBarHeight;
|
||||
_this->setGeometry(
|
||||
QRect(TopLeft,
|
||||
QSize(Rect.width(), Rect.height() - TitleBarHeight)));
|
||||
QApplication::processEvents();
|
||||
// Resize the floating widget to the size of the highlighted drop area
|
||||
// rectangle
|
||||
QRect Rect = Overlay->dropOverlayRect();
|
||||
int FrameWidth = (_this->frameSize().width() - _this->rect().width())
|
||||
/ 2;
|
||||
int TitleBarHeight = _this->frameSize().height()
|
||||
- _this->rect().height() - FrameWidth;
|
||||
if (Rect.isValid())
|
||||
{
|
||||
QPoint TopLeft = Overlay->mapToGlobal(Rect.topLeft());
|
||||
TopLeft.ry() += TitleBarHeight;
|
||||
_this->setGeometry(
|
||||
QRect(TopLeft,
|
||||
QSize(Rect.width(), Rect.height() - TitleBarHeight)));
|
||||
QApplication::processEvents();
|
||||
}
|
||||
}
|
||||
DropContainer->dropFloatingWidget(_this, QCursor::pos());
|
||||
}
|
||||
@@ -533,6 +536,7 @@ void FloatingDockContainerPrivate::titleMouseReleaseEvent()
|
||||
DockManager->dockAreaOverlay()->hideOverlay();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void FloatingDockContainerPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
||||
{
|
||||
@@ -586,11 +590,25 @@ void FloatingDockContainerPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
||||
}
|
||||
|
||||
int VisibleDockAreas = TopContainer->visibleDockAreaCount();
|
||||
ContainerOverlay->setAllowedAreas(
|
||||
VisibleDockAreas > 1 ? OuterDockAreas : AllDockAreas);
|
||||
DockWidgetAreas AllowedContainerAreas = (VisibleDockAreas > 1) ? OuterDockAreas : AllDockAreas;
|
||||
auto DockArea = TopContainer->dockAreaAt(GlobalPos);
|
||||
// If the dock container contains only one single DockArea, then we need
|
||||
// to respect the allowed areas - only the center area is relevant here because
|
||||
// all other allowed areas are from the container
|
||||
if (VisibleDockAreas == 1 && DockArea)
|
||||
{
|
||||
AllowedContainerAreas.setFlag(CenterDockWidgetArea, DockArea->allowedAreas().testFlag(CenterDockWidgetArea));
|
||||
}
|
||||
|
||||
if (DockContainer->features().testFlag(CDockWidget::DockWidgetPinnable))
|
||||
{
|
||||
AllowedContainerAreas |= AutoHideDockAreas;
|
||||
}
|
||||
|
||||
ContainerOverlay->setAllowedAreas(AllowedContainerAreas);
|
||||
|
||||
DockWidgetArea ContainerArea = ContainerOverlay->showOverlay(TopContainer);
|
||||
ContainerOverlay->enableDropPreview(ContainerArea != InvalidDockWidgetArea);
|
||||
auto DockArea = TopContainer->dockAreaAt(GlobalPos);
|
||||
if (DockArea && DockArea->isVisible() && VisibleDockAreas > 0)
|
||||
{
|
||||
DockAreaOverlay->enableDropPreview(true);
|
||||
@@ -644,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);
|
||||
|
||||
@@ -743,6 +760,7 @@ CFloatingDockContainer::CFloatingDockContainer(CDockWidget *DockWidget) :
|
||||
d->DockManager->notifyWidgetOrAreaRelocation(DockWidget);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
CFloatingDockContainer::~CFloatingDockContainer()
|
||||
{
|
||||
@@ -754,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
|
||||
{
|
||||
@@ -770,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)
|
||||
@@ -1125,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)
|
||||
@@ -1133,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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
/**
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#include "DockManager.h"
|
||||
#include "DockContainerWidget.h"
|
||||
#include "DockOverlay.h"
|
||||
#include "AutoHideDockContainer.h"
|
||||
#include "ads_globals.h"
|
||||
|
||||
namespace ads
|
||||
{
|
||||
@@ -33,6 +35,7 @@ struct FloatingDragPreviewPrivate
|
||||
{
|
||||
CFloatingDragPreview *_this;
|
||||
QWidget* Content;
|
||||
CDockWidget::DockWidgetFeatures ContentFeatures;
|
||||
CDockAreaWidget* ContentSourceArea = nullptr;
|
||||
QPoint DragStartMousePosition;
|
||||
CDockManager* DockManager;
|
||||
@@ -77,20 +80,36 @@ struct FloatingDragPreviewPrivate
|
||||
* Returns true, if the content is floatable
|
||||
*/
|
||||
bool isContentFloatable() const
|
||||
{
|
||||
return this->ContentFeatures.testFlag(CDockWidget::DockWidgetFloatable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true, if the content is pinnable
|
||||
*/
|
||||
bool isContentPinnable() const
|
||||
{
|
||||
return this->ContentFeatures.testFlag(CDockWidget::DockWidgetPinnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content features
|
||||
*/
|
||||
CDockWidget::DockWidgetFeatures contentFeatures() const
|
||||
{
|
||||
CDockWidget* DockWidget = qobject_cast<CDockWidget*>(Content);
|
||||
if (DockWidget && DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable))
|
||||
if (DockWidget)
|
||||
{
|
||||
return true;
|
||||
return DockWidget->features();
|
||||
}
|
||||
|
||||
CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(Content);
|
||||
if (DockArea && DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
|
||||
if (DockArea)
|
||||
{
|
||||
return true;
|
||||
return DockArea->features();
|
||||
}
|
||||
|
||||
return false;
|
||||
return CDockWidget::DockWidgetFeatures();
|
||||
}
|
||||
};
|
||||
// struct LedArrayPanelPrivate
|
||||
@@ -126,8 +145,6 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
||||
DropContainer = TopContainer;
|
||||
auto ContainerOverlay = DockManager->containerOverlay();
|
||||
auto DockAreaOverlay = DockManager->dockAreaOverlay();
|
||||
auto DockDropArea = DockAreaOverlay->dropAreaUnderCursor();
|
||||
auto ContainerDropArea = ContainerOverlay->dropAreaUnderCursor();
|
||||
|
||||
if (!TopContainer)
|
||||
{
|
||||
@@ -140,6 +157,9 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
||||
return;
|
||||
}
|
||||
|
||||
auto DockDropArea = DockAreaOverlay->dropAreaUnderCursor();
|
||||
auto ContainerDropArea = ContainerOverlay->dropAreaUnderCursor();
|
||||
|
||||
int VisibleDockAreas = TopContainer->visibleDockAreaCount();
|
||||
|
||||
// Include the overlay widget we're dragging as a visible widget
|
||||
@@ -149,13 +169,27 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
||||
VisibleDockAreas++;
|
||||
}
|
||||
|
||||
ContainerOverlay->setAllowedAreas( VisibleDockAreas > 1 ? OuterDockAreas : AllDockAreas);
|
||||
DockWidgetAreas AllowedContainerAreas = (VisibleDockAreas > 1) ? OuterDockAreas : AllDockAreas;
|
||||
//ContainerOverlay->enableDropPreview(ContainerDropArea != InvalidDockWidgetArea);
|
||||
auto DockArea = TopContainer->dockAreaAt(GlobalPos);
|
||||
// If the dock container contains only one single DockArea, then we need
|
||||
// to respect the allowed areas - only the center area is relevant here because
|
||||
// all other allowed areas are from the container
|
||||
if (VisibleDockAreas == 1 && DockArea)
|
||||
{
|
||||
AllowedContainerAreas.setFlag(CenterDockWidgetArea, DockArea->allowedAreas().testFlag(CenterDockWidgetArea));
|
||||
}
|
||||
|
||||
if (isContentPinnable())
|
||||
{
|
||||
AllowedContainerAreas |= AutoHideDockAreas;
|
||||
}
|
||||
ContainerOverlay->setAllowedAreas(AllowedContainerAreas);
|
||||
ContainerOverlay->enableDropPreview(ContainerDropArea != InvalidDockWidgetArea);
|
||||
if (DockArea && DockArea->isVisible() && VisibleDockAreas >= 0 && DockArea != ContentSourceArea)
|
||||
{
|
||||
DockAreaOverlay->enableDropPreview(true);
|
||||
DockAreaOverlay->setAllowedAreas( (VisibleDockAreas == 1) ? NoDockWidgetArea : DockArea->allowedAreas());
|
||||
|
||||
DockWidgetArea Area = DockAreaOverlay->showOverlay(DockArea);
|
||||
|
||||
// A CenterDockWidgetArea for the dockAreaOverlay() indicates that
|
||||
@@ -178,15 +212,13 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
||||
DockAreaOverlay->hideOverlay();
|
||||
// If there is only one single visible dock area in a container, then
|
||||
// it does not make sense to show a dock overlay because the dock area
|
||||
// would be removed and inserted at the same position
|
||||
// would be removed and inserted at the same position. Only auto hide
|
||||
// area is allowed
|
||||
if (VisibleDockAreas == 1)
|
||||
{
|
||||
ContainerOverlay->hideOverlay();
|
||||
}
|
||||
else
|
||||
{
|
||||
ContainerOverlay->showOverlay(TopContainer);
|
||||
ContainerOverlay->setAllowedAreas(AutoHideDockAreas);
|
||||
}
|
||||
ContainerOverlay->showOverlay(TopContainer);
|
||||
|
||||
|
||||
if (DockArea == ContentSourceArea && InvalidDockWidgetArea == ContainerDropArea)
|
||||
@@ -249,6 +281,7 @@ CFloatingDragPreview::CFloatingDragPreview(QWidget* Content, QWidget* parent) :
|
||||
d(new FloatingDragPreviewPrivate(this))
|
||||
{
|
||||
d->Content = Content;
|
||||
d->ContentFeatures = d->contentFeatures();
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
if (CDockManager::testConfigFlag(CDockManager::DragPreviewHasWindowFrame))
|
||||
{
|
||||
@@ -268,8 +301,6 @@ CFloatingDragPreview::CFloatingDragPreview(QWidget* Content, QWidget* parent) :
|
||||
setWindowFlags(Flags);
|
||||
#endif
|
||||
|
||||
setWindowOpacity(0.6);
|
||||
|
||||
// Create a static image of the widget that should get undocked
|
||||
// This is like some kind preview image like it is uses in drag and drop
|
||||
// operations
|
||||
@@ -356,7 +387,7 @@ void CFloatingDragPreview::finishDragging()
|
||||
// state if they are dragged into a floating window
|
||||
if (ValidDropArea || d->isContentFloatable())
|
||||
{
|
||||
cleanupAutoHideContainerWidget();
|
||||
cleanupAutoHideContainerWidget(ContainerDropArea);
|
||||
}
|
||||
|
||||
if (!d->DropContainer)
|
||||
@@ -365,20 +396,21 @@ void CFloatingDragPreview::finishDragging()
|
||||
}
|
||||
else if (DockDropArea != InvalidDockWidgetArea)
|
||||
{
|
||||
d->DropContainer->dropWidget(d->Content, DockDropArea, d->DropContainer->dockAreaAt(QCursor::pos()));
|
||||
d->DropContainer->dropWidget(d->Content, DockDropArea, d->DropContainer->dockAreaAt(QCursor::pos()),
|
||||
d->DockManager->dockAreaOverlay()->tabIndexUnderCursor());
|
||||
}
|
||||
else if (ContainerDropArea != InvalidDockWidgetArea)
|
||||
{
|
||||
CDockAreaWidget* DockArea = nullptr;
|
||||
// If there is only one single dock area, and we drop into the center
|
||||
// then we tabify the dropped widget into the only visible dock area
|
||||
if (d->DropContainer->visibleDockAreaCount() <= 1 && CenterDockWidgetArea == ContainerDropArea)
|
||||
{
|
||||
d->DropContainer->dropWidget(d->Content, ContainerDropArea, d->DropContainer->dockAreaAt(QCursor::pos()));
|
||||
}
|
||||
else
|
||||
{
|
||||
d->DropContainer->dropWidget(d->Content, ContainerDropArea, nullptr);
|
||||
DockArea = d->DropContainer->dockAreaAt(QCursor::pos());
|
||||
}
|
||||
|
||||
d->DropContainer->dropWidget(d->Content, ContainerDropArea, DockArea,
|
||||
d->DockManager->containerOverlay()->tabIndexUnderCursor());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -392,18 +424,29 @@ void CFloatingDragPreview::finishDragging()
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CFloatingDragPreview::cleanupAutoHideContainerWidget()
|
||||
void CFloatingDragPreview::cleanupAutoHideContainerWidget(DockWidgetArea ContainerDropArea)
|
||||
{
|
||||
auto DroppedDockWidget = qobject_cast<CDockWidget*>(d->Content);
|
||||
auto DroppedArea = qobject_cast<CDockAreaWidget*>(d->Content);
|
||||
if (DroppedDockWidget && DroppedDockWidget->autoHideDockContainer())
|
||||
auto AutoHideContainer = DroppedDockWidget
|
||||
? DroppedDockWidget->autoHideDockContainer()
|
||||
: DroppedArea->autoHideDockContainer();
|
||||
|
||||
if (!AutoHideContainer)
|
||||
{
|
||||
DroppedDockWidget->autoHideDockContainer()->cleanupAndDelete();
|
||||
return;
|
||||
}
|
||||
if (DroppedArea && DroppedArea->autoHideDockContainer())
|
||||
|
||||
// If the dropped widget is already an auto hide widget and if it is moved
|
||||
// to a new side bar location in the same container, then we do not need
|
||||
// to cleanup
|
||||
if (ads::internal::isSideBarArea(ContainerDropArea)
|
||||
&& (d->DropContainer == AutoHideContainer->dockContainer()))
|
||||
{
|
||||
DroppedArea->autoHideDockContainer()->cleanupAndDelete();
|
||||
return;
|
||||
}
|
||||
|
||||
AutoHideContainer->cleanupAndDelete();
|
||||
}
|
||||
|
||||
|
||||
@@ -417,6 +460,7 @@ void CFloatingDragPreview::paintEvent(QPaintEvent* event)
|
||||
}
|
||||
|
||||
QPainter painter(this);
|
||||
painter.setOpacity(0.6);
|
||||
if (CDockManager::testConfigFlag(CDockManager::DragPreviewShowsContentPixmap))
|
||||
{
|
||||
painter.drawPixmap(QPoint(0, 0), d->ContentPreviewPixmap);
|
||||
|
||||
@@ -95,7 +95,7 @@ public: // implements IFloatingWidget -----------------------------------------
|
||||
/**
|
||||
* Cleanup auto hide container if the dragged widget has one
|
||||
*/
|
||||
void cleanupAutoHideContainerWidget();
|
||||
void cleanupAutoHideContainerWidget(DockWidgetArea ContainerDropArea);
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
|
||||
@@ -18,5 +18,10 @@
|
||||
<file>images/vs-pin-button.svg</file>
|
||||
<file>images/vs-pin-button-pinned.svg</file>
|
||||
<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>
|
||||
|
||||
@@ -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;
|
||||
@@ -333,6 +333,47 @@ CDockInsertParam dockAreaInsertParameters(DockWidgetArea Area)
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
SideBarLocation toSideBarLocation(DockWidgetArea Area)
|
||||
{
|
||||
switch (Area)
|
||||
{
|
||||
case LeftAutoHideArea: return SideBarLeft;
|
||||
case RightAutoHideArea: return SideBarRight;
|
||||
case TopAutoHideArea: return SideBarTop;
|
||||
case BottomAutoHideArea: return SideBarBottom;
|
||||
default:
|
||||
return SideBarNone;
|
||||
}
|
||||
|
||||
return SideBarNone;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool isHorizontalSideBarLocation(SideBarLocation Location)
|
||||
{
|
||||
switch (Location)
|
||||
{
|
||||
case SideBarTop:
|
||||
case SideBarBottom: return true;
|
||||
case SideBarLeft:
|
||||
case SideBarRight: return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool isSideBarArea(DockWidgetArea Area)
|
||||
{
|
||||
return toSideBarLocation(Area) != SideBarNone;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
QPixmap createTransparentPixmap(const QPixmap& Source, qreal Opacity)
|
||||
{
|
||||
|
||||
@@ -82,20 +82,33 @@ enum DockWidgetArea
|
||||
TopDockWidgetArea = 0x04,
|
||||
BottomDockWidgetArea = 0x08,
|
||||
CenterDockWidgetArea = 0x10,
|
||||
LeftAutoHideArea = 0x20,
|
||||
RightAutoHideArea = 0x40,
|
||||
TopAutoHideArea = 0x80,
|
||||
BottomAutoHideArea = 0x100,
|
||||
|
||||
InvalidDockWidgetArea = NoDockWidgetArea,
|
||||
OuterDockAreas = TopDockWidgetArea | LeftDockWidgetArea | RightDockWidgetArea | BottomDockWidgetArea,
|
||||
AutoHideDockAreas = LeftAutoHideArea | RightAutoHideArea | TopAutoHideArea | BottomAutoHideArea,
|
||||
AllDockAreas = OuterDockAreas | CenterDockWidgetArea
|
||||
};
|
||||
Q_DECLARE_FLAGS(DockWidgetAreas, DockWidgetArea)
|
||||
|
||||
|
||||
enum eTabIndex
|
||||
{
|
||||
TabDefaultInsertIndex = -1,
|
||||
TabInvalidIndex = -2
|
||||
};
|
||||
|
||||
|
||||
enum TitleBarButton
|
||||
{
|
||||
TitleBarButtonTabsMenu,
|
||||
TitleBarButtonUndock,
|
||||
TitleBarButtonClose,
|
||||
TitleBarButtonAutoHide
|
||||
TitleBarButtonAutoHide,
|
||||
TitleBarButtonMinimize
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -119,6 +132,7 @@ enum eIcon
|
||||
DockAreaMenuIcon, //!< DockAreaMenuIcon
|
||||
DockAreaUndockIcon,//!< DockAreaUndockIcon
|
||||
DockAreaCloseIcon, //!< DockAreaCloseIcon
|
||||
DockAreaMinimizeIcon,
|
||||
|
||||
IconCount, //!< just a delimiter for range checks
|
||||
};
|
||||
@@ -153,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;
|
||||
|
||||
@@ -177,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();
|
||||
@@ -194,6 +209,7 @@ void replaceSplitterWidget(QSplitter* Splitter, QWidget* From, QWidget* To);
|
||||
*/
|
||||
void hideEmptyParentSplitters(CDockSplitter* FirstParentSplitter);
|
||||
|
||||
|
||||
/**
|
||||
* Convenience class for QPair to provide better naming than first and
|
||||
* second
|
||||
@@ -212,6 +228,25 @@ public:
|
||||
*/
|
||||
CDockInsertParam dockAreaInsertParameters(DockWidgetArea Area);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the SieBarLocation for the AutoHide dock widget areas
|
||||
*/
|
||||
SideBarLocation toSideBarLocation(DockWidgetArea Area);
|
||||
|
||||
|
||||
/**
|
||||
* Returns true for the top or bottom side bar ansd false for the
|
||||
* left and right side bar
|
||||
*/
|
||||
bool isHorizontalSideBarLocation(SideBarLocation Location);
|
||||
|
||||
|
||||
/**
|
||||
* Returns true, if the given dock area is a SideBar area
|
||||
*/
|
||||
bool isSideBarArea(DockWidgetArea Area);
|
||||
|
||||
/**
|
||||
* Searches for the parent widget of the given type.
|
||||
* Returns the parent widget of the given widget or 0 if the widget is not
|
||||
@@ -234,7 +269,7 @@ T findParent(const QWidget* w)
|
||||
}
|
||||
parentWidget = parentWidget->parentWidget();
|
||||
}
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
2
src/images/minimize-button-focused.svg
Normal 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 |
2
src/images/minimize-button.svg
Normal 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 |
2
src/images/pin-button-big.svg
Normal 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"><g transform="matrix(.12293 0 0 .12294 .39712 .49812)" fill="#ffffff" stroke="#000000" stroke-width="8.1347"><path d="m83.88 0.451 38.547 38.549c0.603 0.601 0.603 1.585 0 2.188l-13.128 13.125c-0.602 0.604-1.586 0.604-2.187 0l-3.732-3.73-17.303 17.3c3.882 14.621 0.095 30.857-11.37 42.32-0.266 0.268-0.535 0.529-0.808 0.787-1.004 0.955-0.843 0.949-1.813-0.021l-24.489-24.489-47.597 36.387 36.399-47.584-24.525-24.523c-0.978-0.98-0.896-0.826 0.066-1.837 0.24-0.251 0.485-0.503 0.734-0.753 11.463-11.463 27.702-15.253 42.322-11.37l17.301-17.3-3.733-3.732c-0.601-0.601-0.601-1.585 0-2.188l13.127-13.129c0.604-0.601 1.588-0.601 2.189 0z" clip-rule="evenodd" fill="#ffffff" fill-rule="evenodd" stroke="#000000" stroke-width="8.1347"/></g></svg>
|
||||
|
After Width: | Height: | Size: 940 B |
2
src/images/vs-pin-button-disabled.svg
Normal 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 |
2
src/images/vs-pin-button_45.svg
Normal 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="m10.286-1.055e-6 -6.8571 6.8571-1.1429-1.1429-1.1429 1.1429 3.4286 3.4286-4.5714 4.5714 1.1429 1.1429 4.5714-4.5714 3.4286 3.4286 1.1429-1.1429-1.1429-1.1429 6.8571-6.8571-4.5714-4.5714zm0 2.2857 2.2857 2.2857-5.7143 5.7143-2.2857-2.2857z" fill="#000000"/></svg>
|
||||
|
After Width: | Height: | Size: 473 B |
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||