Compare commits
98 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
8d4507e9d8 | ||
|
|
5a00eece87 | ||
|
|
e2929ade14 | ||
|
|
b801f0655d | ||
|
|
f6ccaba6aa | ||
|
|
21189759dd | ||
|
|
047ea3c494 | ||
|
|
f71c8ffe5d | ||
|
|
381acb2449 | ||
|
|
09e4e6fa5a | ||
|
|
b9479dbd3d | ||
|
|
34cc91a9af | ||
|
|
36cdf4a252 | ||
|
|
85f65b3f1a | ||
|
|
92da2eb8bd | ||
|
|
27edfe63ee | ||
|
|
5517822008 | ||
|
|
702702cbfd | ||
|
|
c552fef134 | ||
|
|
916df28fcd | ||
|
|
c08d91687a | ||
|
|
ccbde05fb7 | ||
|
|
1049576349 | ||
|
|
0bfee09b17 | ||
|
|
87954e4459 | ||
|
|
0301e345b4 | ||
|
|
f9b5ef8d89 | ||
|
|
0ed1f8f429 | ||
|
|
659537916e | ||
|
|
0cac9ac507 | ||
|
|
7a79ecab8a | ||
|
|
1186d2b78c | ||
|
|
b46768537a | ||
|
|
44115d4bd9 | ||
|
|
f2d8e17981 | ||
|
|
7890a408f4 | ||
|
|
a940fc29c6 | ||
|
|
c6595563af | ||
|
|
cb24317010 | ||
|
|
fb1e427ab7 | ||
|
|
9d28a4d0d5 | ||
|
|
df34b0eb2b | ||
|
|
db3dc80170 | ||
|
|
db16c5f1b5 | ||
|
|
d28ca1e7a1 | ||
|
|
e84b4a8146 | ||
|
|
46e0d832f8 | ||
|
|
7e63919c08 | ||
|
|
1873dde358 | ||
|
|
6362d14da6 | ||
|
|
1f48f0f3ad | ||
|
|
82695d1b3d | ||
|
|
08b0f8ad54 | ||
|
|
54c2bd0c30 | ||
|
|
d8784a22b7 | ||
|
|
bc9f136f20 | ||
|
|
7192a06eb8 | ||
|
|
a4c6f1d16c | ||
|
|
009af32e61 | ||
|
|
fab41828ab | ||
|
|
cae42939c8 | ||
|
|
7b30322946 | ||
|
|
2730c135ea | ||
|
|
9c30169c42 | ||
|
|
624d21d001 | ||
|
|
378c647952 | ||
|
|
bbfe99ce7d | ||
|
|
97d675cb24 | ||
|
|
bbfad308e5 | ||
|
|
858cdb2d66 | ||
|
|
9f5e06ae13 |
40
.github/workflows/linux-builds.yml
vendored
@@ -6,7 +6,7 @@ jobs:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, ubuntu-20.04, ubuntu-18.04]
|
||||
os: [ubuntu-20.04]
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
@@ -16,8 +16,44 @@ 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
|
||||
run: make -j4
|
||||
|
||||
build_ubuntu_2204:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Cache Qt
|
||||
id: cache-qt-6-4
|
||||
uses: actions/cache@v1 # not v2!
|
||||
with:
|
||||
path: ../Qt/6.4.2
|
||||
key: ${{ runner.os }}-QtCache-Qt6-4
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v2
|
||||
with:
|
||||
version: '6.4.2'
|
||||
host: 'linux'
|
||||
target: 'desktop'
|
||||
install-deps: true
|
||||
cached: ${{ steps.cache-qt-6-4.outputs.cache-hit }}
|
||||
setup-python: true
|
||||
tools: ''
|
||||
tools-only: false
|
||||
|
||||
- name: Install needed xkbcommon symlink
|
||||
run: sudo apt-get install libxkbcommon-dev -y
|
||||
|
||||
- name: Ubuntu and Qt version
|
||||
run: |
|
||||
cat /etc/issue
|
||||
echo number of processors: $(nproc)
|
||||
qmake -v
|
||||
- name: qmake
|
||||
run: qmake
|
||||
- name: make
|
||||
run: make -j$(nproc)
|
||||
|
||||
@@ -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,11 +21,13 @@ 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()
|
||||
target_link_libraries(AdvancedDockingSystemDemo PRIVATE qtadvanceddocking)
|
||||
target_link_libraries(AdvancedDockingSystemDemo PRIVATE qt${QT_VERSION_MAJOR}advanceddocking)
|
||||
set_target_properties(AdvancedDockingSystemDemo PROPERTIES
|
||||
AUTOMOC ON
|
||||
AUTORCC ON
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
#include <QPointer>
|
||||
#include <QMap>
|
||||
#include <QElapsedTimer>
|
||||
#include <QQuickWidget>
|
||||
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
||||
@@ -407,6 +408,17 @@ struct MainWindowPrivate
|
||||
return DockWidget;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create QQuickWidget for test for OpenGL and QQuick
|
||||
*/
|
||||
ads::CDockWidget *createQQuickWidget()
|
||||
{
|
||||
QQuickWidget *widget = new QQuickWidget();
|
||||
ads::CDockWidget *dockWidget = new ads::CDockWidget("Quick");
|
||||
dockWidget->setWidget(widget);
|
||||
return dockWidget;
|
||||
}
|
||||
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
||||
@@ -424,7 +436,6 @@ struct MainWindowPrivate
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
@@ -437,8 +448,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();
|
||||
@@ -506,7 +517,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();
|
||||
@@ -544,13 +557,7 @@ void MainWindowPrivate::createContent()
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
||||
// If opaque undocking is active, then undocking of widgets while
|
||||
// active x widget is visible causes jerking while dragging a floating
|
||||
// widget
|
||||
if (!ads::CDockManager::testConfigFlag(ads::CDockManager::OpaqueUndocking))
|
||||
{
|
||||
DockManager->addDockWidget(ads::CenterDockWidgetArea, createActiveXWidget(), RighDockArea);
|
||||
}
|
||||
DockManager->addDockWidget(ads::CenterDockWidgetArea, createActiveXWidget(), RighDockArea);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -563,6 +570,11 @@ void MainWindowPrivate::createContent()
|
||||
// Create image viewer
|
||||
DockWidget = createImageViewer();
|
||||
DockManager->addDockWidget(ads::LeftDockWidgetArea, DockWidget);
|
||||
|
||||
// Create quick widget
|
||||
DockWidget = createQQuickWidget();
|
||||
DockWidget->setFeature(ads::CDockWidget::DockWidgetClosable, true);
|
||||
DockManager->addDockWidget(ads::LeftDockWidgetArea, DockWidget);
|
||||
}
|
||||
|
||||
|
||||
@@ -740,7 +752,7 @@ CMainWindow::CMainWindow(QWidget *parent) :
|
||||
CDockManager::setConfigFlag(CDockManager::FocusHighlighting, true);
|
||||
|
||||
// uncomment if you would like to enable dock widget auto hiding
|
||||
CDockManager::setAutoHideConfigFlags(CDockManager::DefaultAutoHideConfig);
|
||||
CDockManager::setAutoHideConfigFlags({CDockManager::DefaultAutoHideConfig});
|
||||
|
||||
// uncomment if you would like to enable an equal distribution of the
|
||||
// available size of a splitter to all contained dock widgets
|
||||
|
||||
@@ -2,7 +2,7 @@ ADS_OUT_ROOT = $${OUT_PWD}/..
|
||||
|
||||
TARGET = AdvancedDockingSystemDemo
|
||||
DESTDIR = $${ADS_OUT_ROOT}/lib
|
||||
QT += core gui widgets
|
||||
QT += core gui widgets quick quickwidgets
|
||||
|
||||
include(../ads.pri)
|
||||
|
||||
|
||||
BIN
doc/AutoHide_Animation.gif
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
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 |
BIN
doc/Feature_ImageViewer.png
Normal file
|
After Width: | Height: | Size: 387 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 8.0 KiB |
BIN
doc/cfg_flag_AutoHideCloseButtonCollapsesDock_false.gif
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
doc/cfg_flag_AutoHideCloseButtonCollapsesDock_true.gif
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
doc/showcase_adtf.png
Normal file
|
After Width: | Height: | Size: 112 KiB |
BIN
doc/showcase_dream3d_nx.png
Normal file
|
After Width: | Height: | Size: 364 KiB |
BIN
doc/showcase_labplot.png
Normal file
|
After Width: | Height: | Size: 256 KiB |
BIN
doc/showcase_resinsight.png
Normal file
|
After Width: | Height: | Size: 461 KiB |
BIN
doc/showcase_robox_ide.png
Normal file
|
After Width: | Height: | Size: 363 KiB |
@@ -11,7 +11,6 @@
|
||||
- [`TabCloseButtonIsToolButton`](#tabclosebuttonistoolbutton)
|
||||
- [`AllTabsHaveCloseButton`](#alltabshaveclosebutton)
|
||||
- [`RetainTabSizeWhenCloseButtonHidden`](#retaintabsizewhenclosebuttonhidden)
|
||||
- [`OpaqueUndocking`](#opaqueundocking)
|
||||
- [`DragPreviewIsDynamic`](#dragpreviewisdynamic)
|
||||
- [`DragPreviewShowsContentPixmap`](#dragpreviewshowscontentpixmap)
|
||||
- [`DragPreviewHasWindowFrame`](#dragpreviewhaswindowframe)
|
||||
@@ -40,6 +39,7 @@
|
||||
- [`AutoHideButtonCheckable`](#autohidebuttoncheckable)
|
||||
- [`AutoHideSideBarsIconOnly`](#autohidesidebarsicononly)
|
||||
- [`AutoHideShowOnMouseOver`](#autohideshowonmouseover)
|
||||
- [`AutoHideCloseButtonCollapsesDock`](#autohideclosebuttoncollapsesdock)
|
||||
- [DockWidget Feature Flags](#dockwidget-feature-flags)
|
||||
- [`DockWidgetClosable`](#dockwidgetclosable)
|
||||
- [`DockWidgetMovable`](#dockwidgetmovable)
|
||||
@@ -170,37 +170,6 @@ constant, that means, if enabled, the tabs need more space.
|
||||
|
||||

|
||||
|
||||
### `OpaqueUndocking`
|
||||
|
||||
If this flag is set, opaque undocking is active. That means, as soon as you drag a dock widget or a dock area with a number of dock widgets it will be undocked and moved into a floating widget and then the floating widget will be dragged around. That means undocking will take place immediately. You can compare this with opaque splitter resizing.
|
||||
|
||||

|
||||
|
||||
If you would like to test opaque undocking, you should set the predefined config
|
||||
flags `CDockManager::DefaultOpaqueConfig`.
|
||||
|
||||
```c++
|
||||
CDockManager::setConfigFlags(CDockManager::DefaultOpaqueConfig);
|
||||
```
|
||||
|
||||
If this flag is cleared (default), then non-opaque undocking is active. In this mode, undocking is more like a standard drag and drop operation. That means, the dragged dock widget or dock area is not undocked immediatelly. Instead, a drag preview widget is created and dragged around to indicate the future position of the dock widget or dock area. The actual dock operation is only executed when the mouse button is released. That makes it possible, to cancel an active drag operation with the escape key.
|
||||
|
||||

|
||||
|
||||
The drag preview widget can be configured by a number of global dock manager flags:
|
||||
|
||||
- `DragPreviewIsDynamic`
|
||||
- `DragPreviewShowsContentPixmap`
|
||||
- `DragPreviewHasWindowFrame`
|
||||
|
||||
Non-opaque undocking is enabled by default. If you would like to enable it
|
||||
explicitely, you can do this by setting the predefined configuration flags
|
||||
`CDockManager::DefaultNonOpaqueConfig`.
|
||||
|
||||
```c++
|
||||
CDockManager::setConfigFlags(CDockManager::DefaultNonOpaqueConfig);
|
||||
```
|
||||
|
||||
### `DragPreviewIsDynamic`
|
||||
|
||||
If non-opaque undocking is enabled, this flag defines the behavior of the drag
|
||||
@@ -621,6 +590,21 @@ is shown, if the user hovers over the Auto-Hide tab or if the users moves the
|
||||
mouse outside of the Auto-Hide widget. Showing and hiding my mouse click still
|
||||
works if this feature is enabled.
|
||||
|
||||
### `AutoHideCloseButtonCollapsesDock`
|
||||
|
||||
Some users don't understand the distinction between closing an auto hide dock and
|
||||
collapsing an auto hide dock. This may lead to situations where they press the
|
||||
close button (losing the side tab widget) instead of simply clicking outside
|
||||
the auto hide dock (collapsing the dock).
|
||||
|
||||

|
||||
|
||||
If `AutoHideCloseButtonCollapsesDock` option is active, the
|
||||
close button in an auto hide widget collapses the auto hide widget instead of
|
||||
closing it.
|
||||
|
||||

|
||||
|
||||
## DockWidget Feature Flags
|
||||
|
||||
### `DockWidgetClosable`
|
||||
@@ -631,10 +615,7 @@ If set, the dock widget will have a close button.
|
||||
|
||||
If a dock widget is movable, then it and can be moved to a new position in the
|
||||
current dock container. Disable this flag to prevent moving of a dock widget
|
||||
via mouse. If the `OpaqueUndocking` configuration flag is set, then dock widgets
|
||||
are immediately undocked into floating widgets. That means, moving is only
|
||||
possible in this case, if the dock widget is also floatable (feature flag
|
||||
`DockWidgetFloatable` is set).
|
||||
via mouse.
|
||||
|
||||
### `DockWidgetFloatable`
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ add_executable(AutoHideExample WIN32
|
||||
mainwindow.ui
|
||||
)
|
||||
target_include_directories(AutoHideExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
|
||||
target_link_libraries(AutoHideExample PRIVATE qtadvanceddocking)
|
||||
target_link_libraries(AutoHideExample PRIVATE qt${QT_VERSION_MAJOR}advanceddocking)
|
||||
target_link_libraries(AutoHideExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
|
||||
Qt${QT_VERSION_MAJOR}::Gui
|
||||
Qt${QT_VERSION_MAJOR}::Widgets)
|
||||
|
||||
@@ -9,7 +9,7 @@ add_executable(CentralWidgetExample WIN32
|
||||
mainwindow.ui
|
||||
)
|
||||
target_include_directories(CentralWidgetExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
|
||||
target_link_libraries(CentralWidgetExample PRIVATE qtadvanceddocking)
|
||||
target_link_libraries(CentralWidgetExample PRIVATE qt${QT_VERSION_MAJOR}advanceddocking)
|
||||
target_link_libraries(CentralWidgetExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
|
||||
Qt${QT_VERSION_MAJOR}::Gui
|
||||
Qt${QT_VERSION_MAJOR}::Widgets)
|
||||
|
||||
@@ -7,7 +7,7 @@ add_executable(DeleteOnCloseTest WIN32
|
||||
main.cpp
|
||||
)
|
||||
target_include_directories(DeleteOnCloseTest PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
|
||||
target_link_libraries(DeleteOnCloseTest PRIVATE qtadvanceddocking)
|
||||
target_link_libraries(DeleteOnCloseTest PRIVATE qt${QT_VERSION_MAJOR}advanceddocking)
|
||||
target_link_libraries(DeleteOnCloseTest PUBLIC Qt${QT_VERSION_MAJOR}::Core
|
||||
Qt${QT_VERSION_MAJOR}::Gui
|
||||
Qt${QT_VERSION_MAJOR}::Widgets)
|
||||
|
||||
@@ -12,7 +12,7 @@ add_executable(DockInDockExample WIN32
|
||||
mainframe.cpp
|
||||
)
|
||||
target_include_directories(DockInDockExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
|
||||
target_link_libraries(DockInDockExample PRIVATE qtadvanceddocking)
|
||||
target_link_libraries(DockInDockExample PRIVATE qt${QT_VERSION_MAJOR}advanceddocking)
|
||||
target_link_libraries(DockInDockExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
|
||||
Qt${QT_VERSION_MAJOR}::Gui
|
||||
Qt${QT_VERSION_MAJOR}::Widgets)
|
||||
|
||||
@@ -9,7 +9,7 @@ add_executable(EmptyDockAreaExample WIN32
|
||||
mainwindow.ui
|
||||
)
|
||||
target_include_directories(EmptyDockAreaExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
|
||||
target_link_libraries(EmptyDockAreaExample PRIVATE qtadvanceddocking)
|
||||
target_link_libraries(EmptyDockAreaExample PRIVATE qt${QT_VERSION_MAJOR}advanceddocking)
|
||||
target_link_libraries(EmptyDockAreaExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
|
||||
Qt${QT_VERSION_MAJOR}::Gui
|
||||
Qt${QT_VERSION_MAJOR}::Widgets)
|
||||
|
||||
@@ -9,7 +9,7 @@ add_executable(HideShowExample WIN32
|
||||
MainWindow.ui
|
||||
)
|
||||
target_include_directories(HideShowExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
|
||||
target_link_libraries(HideShowExample PRIVATE qtadvanceddocking)
|
||||
target_link_libraries(HideShowExample PRIVATE qt${QT_VERSION_MAJOR}advanceddocking)
|
||||
target_link_libraries(HideShowExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
|
||||
Qt${QT_VERSION_MAJOR}::Gui
|
||||
Qt${QT_VERSION_MAJOR}::Widgets)
|
||||
|
||||
@@ -9,7 +9,7 @@ add_executable(SidebarExample WIN32
|
||||
MainWindow.ui
|
||||
)
|
||||
target_include_directories(SidebarExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
|
||||
target_link_libraries(SidebarExample PRIVATE qtadvanceddocking)
|
||||
target_link_libraries(SidebarExample PRIVATE qt${QT_VERSION_MAJOR}advanceddocking)
|
||||
target_link_libraries(SidebarExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
|
||||
Qt${QT_VERSION_MAJOR}::Gui
|
||||
Qt${QT_VERSION_MAJOR}::Widgets)
|
||||
|
||||
@@ -9,7 +9,7 @@ add_executable(SimpleExample WIN32
|
||||
MainWindow.ui
|
||||
)
|
||||
target_include_directories(SimpleExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
|
||||
target_link_libraries(SimpleExample PRIVATE qtadvanceddocking)
|
||||
target_link_libraries(SimpleExample PRIVATE qt${QT_VERSION_MAJOR}advanceddocking)
|
||||
target_link_libraries(SimpleExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
|
||||
Qt${QT_VERSION_MAJOR}::Gui
|
||||
Qt${QT_VERSION_MAJOR}::Widgets)
|
||||
|
||||
28
project.py
@@ -1,4 +1,5 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
from pyqtbuild import PyQtBindings, PyQtProject
|
||||
from sipbuild import Option
|
||||
@@ -16,12 +17,37 @@ class ads(PyQtBindings):
|
||||
""" Initialise the bindings. """
|
||||
|
||||
super().__init__(project, 'ads')
|
||||
|
||||
def get_options(self):
|
||||
"""Our custom options that a user can pass to sip-build."""
|
||||
options = super().get_options()
|
||||
options += [
|
||||
Option('ads_incdir',
|
||||
help='the directory containing the ads header file',
|
||||
metavar='DIR'),
|
||||
Option('ads_libdir',
|
||||
help='the directory containing the ads library',
|
||||
metavar='DIR'),
|
||||
Option('ads_lib',
|
||||
help='the ads library',
|
||||
metavar='LIB'),
|
||||
]
|
||||
return options
|
||||
|
||||
def apply_user_defaults(self, tool):
|
||||
""" Set default values for user options that haven't been set yet. """
|
||||
|
||||
|
||||
resource_file = os.path.join(self.project.root_dir,'src','ads.qrc')
|
||||
print("Adding resource file to qmake project: ", resource_file)
|
||||
self.builder_settings.append('RESOURCES += '+resource_file)
|
||||
|
||||
if self.ads_lib is not None:
|
||||
self.libraries.append(self.ads_lib)
|
||||
|
||||
if self.ads_incdir is not None:
|
||||
self.include_dirs.append(self.ads_incdir)
|
||||
|
||||
if self.ads_libdir is not None:
|
||||
self.library_dirs.append(self.ads_libdir)
|
||||
|
||||
super().apply_user_defaults(tool)
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# Specify the build system.
|
||||
[build-system]
|
||||
requires = ["sip >=6.0.2, <6.6", "PyQt-builder >=1.6, <2", "PyQt5>=5.15.4", "PyQt5-sip<13,>=12.8"]
|
||||
requires = ["sip >=6.0.2, <6.3", "PyQt-builder >=1.6, <2", "PyQt5==5.15.4", "PyQt5-sip<13,>=12.8"]
|
||||
build-backend = "sipbuild.api"
|
||||
|
||||
# Specify the PEP 566 metadata for the project.
|
||||
[tool.sip.metadata]
|
||||
name = "PyQtAds"
|
||||
version = "3.8.2"
|
||||
version = "4.0.2"
|
||||
summary = "Python bindings for Qt Advanced Docking System"
|
||||
home-page = "https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/"
|
||||
license = "LGPL v2.1"
|
||||
@@ -21,8 +21,11 @@ tag-prefix = "QtAds"
|
||||
define-macros = ["ADS_SHARED_EXPORT"]
|
||||
sip-file = "ads.sip"
|
||||
include-dirs = ["src"]
|
||||
qmake-QT = ["widgets"]
|
||||
qmake-QT = ["widgets", "gui-private; platform_system == 'Linux'"]
|
||||
headers = [
|
||||
"src/AutoHideDockContainer.h",
|
||||
"src/AutoHideSideBar.h",
|
||||
"src/AutoHideTab.h",
|
||||
"src/DockAreaTabBar.h",
|
||||
"src/DockAreaTitleBar.h",
|
||||
"src/DockAreaTitleBar_p.h",
|
||||
@@ -40,10 +43,15 @@ headers = [
|
||||
"src/FloatingDockContainer.h",
|
||||
"src/FloatingDragPreview.h",
|
||||
"src/IconProvider.h",
|
||||
"src/PushButton.h",
|
||||
"src/ResizeHandle.h",
|
||||
"src/ads_globals.h",
|
||||
# "src/linux/FloatingWidgetTitleBar.h",
|
||||
"src/linux/FloatingWidgetTitleBar.h; platform_system == 'Linux'",
|
||||
]
|
||||
sources = [
|
||||
"src/AutoHideTab.cpp",
|
||||
"src/AutoHideDockContainer.cpp",
|
||||
"src/AutoHideSideBar.cpp",
|
||||
"src/DockAreaTabBar.cpp",
|
||||
"src/DockAreaTitleBar.cpp",
|
||||
"src/DockAreaWidget.cpp",
|
||||
@@ -60,6 +68,8 @@ sources = [
|
||||
"src/FloatingDockContainer.cpp",
|
||||
"src/FloatingDragPreview.cpp",
|
||||
"src/IconProvider.cpp",
|
||||
"src/PushButton.cpp",
|
||||
"src/ResizeHandle.cpp",
|
||||
"src/ads_globals.cpp",
|
||||
# "src/linux/FloatingWidgetTitleBar.cpp",
|
||||
"src/linux/FloatingWidgetTitleBar.cpp; platform_system == 'Linux'",
|
||||
]
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
[versioneer]
|
||||
VCS = git
|
||||
style = pep440
|
||||
versionfile_source = PyQtAds/_version.py
|
||||
versionfile_build = PyQtAds/_version.py
|
||||
tag_prefix =
|
||||
|
||||
396
setup.py
@@ -1,396 +0,0 @@
|
||||
import os
|
||||
import sys
|
||||
import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
import glob
|
||||
|
||||
import versioneer
|
||||
|
||||
from setuptools import setup, find_packages
|
||||
from setuptools.command.build_py import build_py
|
||||
from setuptools.extension import Extension
|
||||
from distutils import sysconfig, dir_util, spawn, log, cmd
|
||||
from distutils.dep_util import newer
|
||||
import sipdistutils
|
||||
import sipconfig
|
||||
from PyQt5.QtCore import PYQT_CONFIGURATION
|
||||
from PyQt5.pyrcc_main import processResourceFile
|
||||
|
||||
MODULE_NAME = "ads"
|
||||
SRC_PATH = "PyQtAds"
|
||||
|
||||
REQUIRE_PYQT = True
|
||||
if "--conda-recipe" in sys.argv:
|
||||
REQUIRE_PYQT = False
|
||||
sys.argv.remove("--conda-recipe")
|
||||
|
||||
|
||||
class HostPythonConfiguration(object):
|
||||
def __init__(self):
|
||||
self.platform = sys.platform
|
||||
self.version = sys.hexversion>>8
|
||||
|
||||
self.inc_dir = sysconfig.get_python_inc()
|
||||
self.venv_inc_dir = sysconfig.get_python_inc(prefix=sys.prefix)
|
||||
self.module_dir = sysconfig.get_python_lib(plat_specific=1)
|
||||
|
||||
if sys.platform == 'win32':
|
||||
self.data_dir = sys.prefix
|
||||
self.lib_dir = sys.prefix +'\\libs'
|
||||
else:
|
||||
self.data_dir = sys.prefix + '/share'
|
||||
self.lib_dir = sys.prefix + '/lib'
|
||||
|
||||
|
||||
class TargetQtConfiguration(object):
|
||||
def __init__(self, qmake):
|
||||
pipe = os.popen(' '.join([qmake, '-query']))
|
||||
|
||||
for l in pipe:
|
||||
l = l.strip()
|
||||
|
||||
tokens = l.split(':', 1)
|
||||
if isinstance(tokens, list):
|
||||
if len(tokens) != 2:
|
||||
error("Unexpected output from qmake: '%s'\n" % l)
|
||||
|
||||
name, value = tokens
|
||||
else:
|
||||
name = tokens
|
||||
value = None
|
||||
|
||||
name = name.replace('/', '_')
|
||||
setattr(self, name, value)
|
||||
|
||||
pipe.close()
|
||||
|
||||
|
||||
class build_ext(sipdistutils.build_ext):
|
||||
|
||||
description = "Builds the " + MODULE_NAME + " module."
|
||||
|
||||
user_options = sipdistutils.build_ext.user_options + [
|
||||
('qmake-bin=', None, "Path to qmake binary"),
|
||||
('sip-bin=', None, "Path to sip binary"),
|
||||
('qt-include-dir=', None, "Path to Qt headers"),
|
||||
('pyqt-sip-dir=', None, "Path to PyQt's SIP files"),
|
||||
('pyqt-sip-flags=', None, "SIP flags used to generate PyQt bindings"),
|
||||
('sip-dir=', None, "Path to module's SIP files"),
|
||||
('inc-dir=', None, "Path to module's include files")
|
||||
]
|
||||
|
||||
def initialize_options (self):
|
||||
super().initialize_options()
|
||||
self.qmake_bin = 'qmake'
|
||||
self.sip_bin = None
|
||||
self.qt_include_dir = None
|
||||
self.qt_libinfix = ''
|
||||
self.pyqt_sip_dir = None
|
||||
self.pyqt_sip_flags = None
|
||||
self.sip_files_dir = None
|
||||
self.sip_inc_dir = None
|
||||
self.inc_dir = None
|
||||
self.pyconfig = HostPythonConfiguration()
|
||||
self.qtconfig = TargetQtConfiguration(self.qmake_bin)
|
||||
self.config = sipconfig.Configuration()
|
||||
self.config.default_mod_dir = ("/usr/local/lib/python%i.%i/dist-packages" %
|
||||
(sys.version_info.major, sys.version_info.minor))
|
||||
|
||||
def finalize_options (self):
|
||||
super().finalize_options()
|
||||
|
||||
if not self.qt_include_dir:
|
||||
self.qt_include_dir = self.qtconfig.QT_INSTALL_HEADERS
|
||||
|
||||
if not self.qt_libinfix:
|
||||
try:
|
||||
with open(os.path.join(self.qtconfig.QT_INSTALL_PREFIX, 'mkspecs', 'qconfig.pri'), 'r') as f:
|
||||
for line in f.readlines():
|
||||
if line.startswith('QT_LIBINFIX'):
|
||||
self.qt_libinfix = line.split('=')[1].strip('\n').strip()
|
||||
except (FileNotFoundError, IndexError):
|
||||
pass
|
||||
|
||||
if not self.pyqt_sip_dir:
|
||||
self.pyqt_sip_dir = os.path.join(self.pyconfig.data_dir, 'sip', 'PyQt5')
|
||||
|
||||
if not self.pyqt_sip_flags:
|
||||
self.pyqt_sip_flags = PYQT_CONFIGURATION.get('sip_flags', '')
|
||||
|
||||
if not self.sip_files_dir:
|
||||
self.sip_files_dir = os.path.abspath(os.path.join(".", "sip"))
|
||||
|
||||
if not self.sip_inc_dir:
|
||||
self.sip_inc_dir = self.pyconfig.venv_inc_dir
|
||||
|
||||
if not self.inc_dir:
|
||||
self.inc_dir = os.path.abspath(os.path.join(".", "src"))
|
||||
|
||||
if not self.qt_include_dir:
|
||||
raise SystemExit('Could not find Qt5 headers. '
|
||||
'Please specify via --qt-include-dir=')
|
||||
|
||||
if not self.pyqt_sip_dir:
|
||||
raise SystemExit('Could not find PyQt SIP files. '
|
||||
'Please specify containing directory via '
|
||||
'--pyqt-sip-dir=')
|
||||
|
||||
if not self.pyqt_sip_flags:
|
||||
raise SystemExit('Could not find PyQt SIP flags. '
|
||||
'Please specify via --pyqt-sip-flags=')
|
||||
|
||||
def _find_sip(self):
|
||||
"""override _find_sip to allow for manually speficied sip path."""
|
||||
|
||||
# 1. Manually specified sip_bin
|
||||
if self.sip_bin:
|
||||
return self.sip_bin
|
||||
|
||||
# 2. Path determined from sipconfig.Configuration()
|
||||
# This may not exist, depending on conda build configuration.
|
||||
sip_bin = super()._find_sip()
|
||||
if os.path.exists(sip_bin):
|
||||
return sip_bin
|
||||
|
||||
# 3. Finally, fall back to sip binary found in path
|
||||
sip_bin = shutil.which('sip')
|
||||
if sip_bin:
|
||||
return sip_bin
|
||||
|
||||
raise SystemExit('Could not find PyQt SIP binary.')
|
||||
|
||||
def _sip_sipfiles_dir(self):
|
||||
sip_dir = super()._sip_sipfiles_dir()
|
||||
if os.path.exists(sip_dir):
|
||||
return sip_dir
|
||||
|
||||
return os.path.join(sys.prefix, 'sip', 'PyQt5')
|
||||
|
||||
def _sip_compile(self, sip_bin, source, sbf):
|
||||
target_dir = os.path.dirname(__file__) if self.inplace else self.build_lib
|
||||
pyi = os.path.join(target_dir, "PyQtAds", "QtAds", "ads.pyi")
|
||||
if not os.path.exists(os.path.dirname(pyi)):
|
||||
os.makedirs(os.path.dirname(pyi))
|
||||
|
||||
cmd = [sip_bin]
|
||||
if hasattr(self, 'sip_opts'):
|
||||
cmd += self.sip_opts
|
||||
if hasattr(self, '_sip_sipfiles_dir'):
|
||||
cmd += ['-I', self._sip_sipfiles_dir()]
|
||||
cmd += [
|
||||
"-I", self.sip_files_dir,
|
||||
"-I", self.pyqt_sip_dir,
|
||||
"-I", self.sip_inc_dir,
|
||||
"-I", self.inc_dir,
|
||||
"-c", self._sip_output_dir(),
|
||||
"-b", sbf,
|
||||
"-y", pyi,
|
||||
"-w", "-o"]
|
||||
|
||||
cmd += shlex.split(self.pyqt_sip_flags) # use same SIP flags as for PyQt5
|
||||
cmd.append(source)
|
||||
self.spawn(cmd)
|
||||
|
||||
if os.path.exists(pyi):
|
||||
with open(pyi) as f:
|
||||
content = f.readlines()
|
||||
with open(pyi, "w") as f:
|
||||
for line in content:
|
||||
if not line.startswith("class ads"):
|
||||
f.write(line)
|
||||
|
||||
def swig_sources (self, sources, extension=None):
|
||||
if not self.extensions:
|
||||
return
|
||||
|
||||
# Add the local include directory to the include path
|
||||
if extension is not None:
|
||||
extension.extra_compile_args += ['-D', 'QT_CORE_LIB',
|
||||
'-D', 'QT_GUI_LIB',
|
||||
'-D', 'QT_WIDGETS_LIB',
|
||||
'-D', 'ADS_SHARED_EXPORT']
|
||||
extension.include_dirs += [self.qt_include_dir, self.inc_dir,
|
||||
os.path.join(self.qt_include_dir, 'QtCore'),
|
||||
os.path.join(self.qt_include_dir, 'QtGui'),
|
||||
os.path.join(self.qt_include_dir, 'QtWidgets')]
|
||||
extension.libraries += ['Qt5Core' + self.qt_libinfix,
|
||||
'Qt5Gui' + self.qt_libinfix,
|
||||
'Qt5Widgets' + self.qt_libinfix]
|
||||
|
||||
if sys.platform == 'win32':
|
||||
extension.library_dirs += [self.qtconfig.QT_INSTALL_LIBS,
|
||||
self.inc_dir, self._sip_output_dir()]
|
||||
elif sys.platform == 'darwin':
|
||||
extension.extra_compile_args += ['-F' + self.qtconfig.QT_INSTALL_LIBS,
|
||||
'-std=c++11', '-stdlib=libc++', '-mmacosx-version-min=10.9']
|
||||
extension.extra_link_args += ['-F' + self.qtconfig.QT_INSTALL_LIBS,
|
||||
'-mmacosx-version-min=10.9']
|
||||
elif sys.platform == 'linux':
|
||||
extension.extra_compile_args += ['-std=c++11']
|
||||
|
||||
return super().swig_sources(sources, extension)
|
||||
|
||||
def build_extension(self, ext):
|
||||
cppsources = [source for source in ext.sources if source.endswith(".cpp")]
|
||||
headersources = ['src/DockAreaTitleBar_p.h']
|
||||
|
||||
dir_util.mkpath(self.build_temp, dry_run=self.dry_run)
|
||||
|
||||
def get_moc_args(out_file, source):
|
||||
if sys.platform.startswith('linux'):
|
||||
return ["moc", "-D", "Q_OS_LINUX=1", "-o", out_file, source]
|
||||
if sys.platform.startswith('darwin'):
|
||||
return ["moc", "-D", "Q_OS_MACOS=1", "-o", out_file, source]
|
||||
if sys.platform.startswith('win'):
|
||||
return ["moc", "-D", "Q_OS_WIN=1", "-o", out_file, source]
|
||||
return ["moc", "-o", out_file, source]
|
||||
|
||||
# Run moc on all header files.
|
||||
for source in cppsources:
|
||||
# *.cpp -> *.moc
|
||||
moc_file = os.path.basename(source).replace(".cpp", ".moc")
|
||||
out_file = os.path.join(self.build_temp, moc_file)
|
||||
|
||||
if newer(source, out_file) or self.force:
|
||||
spawn.spawn(get_moc_args(out_file, source), dry_run=self.dry_run)
|
||||
|
||||
header = source.replace(".cpp", ".h")
|
||||
if os.path.exists(header):
|
||||
# *.h -> moc_*.cpp
|
||||
moc_file = "moc_" + os.path.basename(header).replace(".h", ".cpp")
|
||||
out_file = os.path.join(self.build_temp, moc_file)
|
||||
|
||||
if newer(header, out_file) or self.force:
|
||||
spawn.spawn(get_moc_args(out_file, header), dry_run=self.dry_run)
|
||||
|
||||
if os.path.getsize(out_file) > 0:
|
||||
ext.sources.append(out_file)
|
||||
|
||||
# Run moc on all orphan header files.
|
||||
for source in headersources:
|
||||
# *.cpp -> *.moc
|
||||
moc_file = os.path.basename(source).replace(".h", ".moc")
|
||||
out_file = os.path.join(self.build_temp, moc_file)
|
||||
|
||||
if newer(source, out_file) or self.force:
|
||||
spawn.spawn(get_moc_args(out_file, source),
|
||||
dry_run=self.dry_run)
|
||||
|
||||
header = source
|
||||
if os.path.exists(header):
|
||||
# *.h -> moc_*.cpp
|
||||
moc_file = "moc_" + os.path.basename(header).replace(
|
||||
".h", ".cpp")
|
||||
out_file = os.path.join(self.build_temp, moc_file)
|
||||
|
||||
if newer(header, out_file) or self.force:
|
||||
spawn.spawn(get_moc_args(out_file, header),
|
||||
dry_run=self.dry_run)
|
||||
|
||||
if os.path.getsize(out_file) > 0:
|
||||
ext.sources.append(out_file)
|
||||
|
||||
# Add the temp build directory to include path, for compiler to find
|
||||
# the created .moc files
|
||||
ext.include_dirs += [self._sip_output_dir()]
|
||||
|
||||
# Run rcc on all resource files
|
||||
resources = [source for source in ext.sources if source.endswith(".qrc")]
|
||||
for source in resources:
|
||||
ext.sources.remove(source)
|
||||
out_file = os.path.join(self.build_temp, "qrc_" + os.path.basename(source).replace(".qrc", ".cpp"))
|
||||
if newer(header, out_file) or self.force:
|
||||
spawn.spawn(["rcc", "-name", os.path.splitext(os.path.basename(source))[0], source, "-o", out_file], dry_run=self.dry_run)
|
||||
|
||||
if os.path.getsize(out_file) > 0:
|
||||
ext.sources.append(out_file)
|
||||
|
||||
sipdistutils.build_ext.build_extension(self, ext)
|
||||
|
||||
import inspect
|
||||
sys.path.append(os.path.join(self.build_lib, 'PyQtAds', 'QtAds'))
|
||||
import ads
|
||||
|
||||
with open(os.path.join(self.build_lib, 'PyQtAds', 'QtAds', '__init__.py'), 'w') as f:
|
||||
f.write('from .._version import *\n')
|
||||
f.write('from .ads import ads\n')
|
||||
for name, member in sorted(inspect.getmembers(ads.ads)):
|
||||
if not name.startswith('_'):
|
||||
f.write('{0} = ads.{0}\n'.format(name))
|
||||
|
||||
|
||||
class ProcessResourceCommand(cmd.Command):
|
||||
"""A custom command to compile the resource file into a Python file"""
|
||||
|
||||
description = "Compile the qrc file into a python file"
|
||||
|
||||
def initialize_options(self):
|
||||
return
|
||||
|
||||
def finalize_options(self):
|
||||
return
|
||||
|
||||
def run(self):
|
||||
processResourceFile([os.path.join('src', 'ads.qrc')],
|
||||
os.path.join(SRC_PATH, 'rc.py'), False)
|
||||
|
||||
|
||||
class BuildPyCommand(build_py):
|
||||
"""Custom build command to include ProcessResource command"""
|
||||
|
||||
def run(self):
|
||||
self.run_command("process_resource")
|
||||
build_py.run(self)
|
||||
|
||||
|
||||
setup_requires = ["PyQt5"] if REQUIRE_PYQT else []
|
||||
cpp_sources = glob.glob(os.path.join('src', '*.cpp'))
|
||||
sip_sources = [os.path.join('sip', MODULE_NAME + '.sip')]
|
||||
resources = [os.path.join('src', MODULE_NAME + '.qrc')]
|
||||
if sys.platform == 'linux':
|
||||
cpp_sources += glob.glob(os.path.join('src', 'linux', '*.cpp'))
|
||||
ext_modules = [Extension('PyQtAds.QtAds.ads', cpp_sources + sip_sources + resources)]
|
||||
|
||||
install_requires = ["PyQt5"]
|
||||
if sys.platform == 'win32':
|
||||
install_requires.append("pywin32")
|
||||
|
||||
|
||||
with open('README.md', 'r') as f:
|
||||
LONG_DESCRIPTION = f.read()
|
||||
|
||||
setup(
|
||||
name = SRC_PATH,
|
||||
author = "Nicolas Elie",
|
||||
author_email = "nicolas.elie@cnrs.fr",
|
||||
url = "https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System",
|
||||
version = versioneer.get_version(),
|
||||
description = "Advanced Docking System for Qt",
|
||||
long_description = LONG_DESCRIPTION,
|
||||
keywords = ["qt"],
|
||||
license = "LGPLv2+",
|
||||
classifiers = ["Development Status :: 4 - Beta",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)",
|
||||
"Operating System :: OS Independent",
|
||||
"Topic :: Software Development :: Libraries :: Python Modules",
|
||||
"Environment :: Win32 (MS Windows)",
|
||||
"Environment :: MacOS X",
|
||||
"Environment :: X11 Applications :: Qt",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.2",
|
||||
"Programming Language :: Python :: 3.3",
|
||||
"Programming Language :: Python :: 3.4",
|
||||
"Programming Language :: Python :: 3.5",
|
||||
"Programming Language :: Python :: 3.6",
|
||||
"Programming Language :: Python :: 3.7"],
|
||||
ext_modules = ext_modules,
|
||||
cmdclass = versioneer.get_cmdclass({'process_resource': ProcessResourceCommand,
|
||||
'build_py': BuildPyCommand,
|
||||
'build_ext': build_ext}),
|
||||
packages = find_packages(),
|
||||
setup_requires = setup_requires,
|
||||
install_requires = install_requires,
|
||||
zip_safe=False
|
||||
)
|
||||
46
sip/AutoHideDockContainer.sip
Normal file
@@ -0,0 +1,46 @@
|
||||
%Import QtWidgets/QtWidgetsmod.sip
|
||||
|
||||
%If (Qt_5_0_0 -)
|
||||
|
||||
namespace ads
|
||||
{
|
||||
|
||||
class CAutoHideDockContainer : QFrame
|
||||
{
|
||||
|
||||
%TypeHeaderCode
|
||||
#include <AutoHideDockContainer.h>
|
||||
%End
|
||||
|
||||
protected:
|
||||
virtual bool eventFilter(QObject* watched, QEvent* event);
|
||||
virtual void resizeEvent(QResizeEvent* event);
|
||||
virtual void leaveEvent(QEvent *event);
|
||||
virtual bool event(QEvent* event);
|
||||
void updateSize();
|
||||
void saveState(QXmlStreamWriter& Stream);
|
||||
|
||||
public:
|
||||
CAutoHideDockContainer(ads::CDockWidget* DockWidget /Transfer/, ads::SideBarLocation area,
|
||||
ads::CDockContainerWidget* parent /TransferThis/);
|
||||
virtual ~CAutoHideDockContainer();
|
||||
ads::CAutoHideSideBar* sideBar() const;
|
||||
ads::CAutoHideTab* autoHideTab() const;
|
||||
ads::CDockWidget* dockWidget() const;
|
||||
void addDockWidget(ads::CDockWidget* DockWidget /Transfer/);
|
||||
ads::SideBarLocation sideBarLocation() const;
|
||||
void setSideBarLocation(ads::SideBarLocation SideBarLocation);
|
||||
ads::CDockAreaWidget* dockAreaWidget() const;
|
||||
ads::CDockContainerWidget* dockContainer() const;
|
||||
void moveContentsToParent();
|
||||
void cleanupAndDelete();
|
||||
void toggleView(bool Enable);
|
||||
void collapseView(bool Enable);
|
||||
void toggleCollapseState();
|
||||
void setSize(int Size);
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
%End
|
||||
43
sip/AutoHideSideBar.sip
Normal file
@@ -0,0 +1,43 @@
|
||||
%Import QtWidgets/QtWidgetsmod.sip
|
||||
|
||||
%If (Qt_5_0_0 -)
|
||||
|
||||
namespace ads
|
||||
{
|
||||
|
||||
|
||||
class CAutoHideSideBar : QScrollArea
|
||||
{
|
||||
|
||||
%TypeHeaderCode
|
||||
#include <AutoHideSideBar.h>
|
||||
%End
|
||||
|
||||
protected:
|
||||
virtual bool eventFilter(QObject *watched, QEvent *event);
|
||||
void saveState(QXmlStreamWriter& Stream) const;
|
||||
void insertTab(int Index, ads::CAutoHideTab* SideTab /Transfer/);
|
||||
|
||||
public:
|
||||
CAutoHideSideBar(ads::CDockContainerWidget* parent /TransferThis/, SideBarLocation area);
|
||||
virtual ~CAutoHideSideBar();
|
||||
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);
|
||||
Qt::Orientation orientation() const;
|
||||
ads::CAutoHideTab* tabAt(int index) const;
|
||||
int tabCount() const;
|
||||
int visibleTabCount() const;
|
||||
bool hasVisibleTabs() const;
|
||||
ads::SideBarLocation sideBarLocation() const;
|
||||
virtual QSize minimumSizeHint() const;
|
||||
virtual QSize sizeHint() const;
|
||||
int spacing() const;
|
||||
void setSpacing(int Spacing);
|
||||
CDockContainerWidget* dockContainer() const;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
%End
|
||||
36
sip/AutoHideTab.sip
Normal file
@@ -0,0 +1,36 @@
|
||||
%Import QtWidgets/QtWidgetsmod.sip
|
||||
|
||||
%If (Qt_5_0_0 -)
|
||||
|
||||
namespace ads
|
||||
{
|
||||
|
||||
class CAutoHideTab : CPushButton
|
||||
{
|
||||
|
||||
%TypeHeaderCode
|
||||
#include <AutoHideTab.h>
|
||||
%End
|
||||
|
||||
protected:
|
||||
void setSideBar(ads::CAutoHideSideBar *SideTabBar);
|
||||
void removeFromSideBar();
|
||||
virtual bool event(QEvent* event);
|
||||
|
||||
public:
|
||||
CAutoHideTab(QWidget* parent /TransferThis/ = 0);
|
||||
virtual ~CAutoHideTab();
|
||||
void updateStyle();
|
||||
ads::SideBarLocation sideBarLocation() const;
|
||||
void setOrientation(Qt::Orientation Orientation);
|
||||
Qt::Orientation orientation() const;
|
||||
bool isActiveTab() const;
|
||||
ads::CDockWidget* dockWidget() const;
|
||||
void setDockWidget(ads::CDockWidget* DockWidget);
|
||||
bool iconOnly() const;
|
||||
ads::CAutoHideSideBar* sideBar() const;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
%End
|
||||
@@ -27,10 +27,12 @@ public:
|
||||
virtual ~CDockAreaTitleBar();
|
||||
ads::CDockAreaTabBar* tabBar() const;
|
||||
QAbstractButton* 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;
|
||||
|
||||
|
||||
signals:
|
||||
|
||||
@@ -23,6 +23,7 @@ protected:
|
||||
void updateTitleBarVisibility();
|
||||
void internalSetCurrentDockWidget(ads::CDockWidget* DockWidget /Transfer/);
|
||||
void markTitleBarMenuOutdated();
|
||||
void updateTitleBarButtonVisibility(bool IsTopLevel) const;
|
||||
|
||||
protected slots:
|
||||
void toggleView(bool Open);
|
||||
@@ -52,6 +53,8 @@ public:
|
||||
ads::CDockWidget* currentDockWidget() const;
|
||||
void setCurrentDockWidget(ads::CDockWidget* DockWidget);
|
||||
void saveState(QXmlStreamWriter& Stream) const;
|
||||
static bool restoreState(ads::CDockingStateReader& Stream, ads::CDockAreaWidget*& CreatedWidget,
|
||||
bool Testing, ads::CDockContainerWidget* ParentContainer);
|
||||
ads::CDockWidget::DockWidgetFeatures features(ads::eBitwiseOperator Mode = ads::BitwiseAnd) const;
|
||||
QAbstractButton* titleBarButton(ads::TitleBarButton which) const;
|
||||
virtual void setVisible(bool Visible);
|
||||
@@ -65,6 +68,8 @@ public:
|
||||
void setDockAreaFlag(eDockAreaFlag Flag, bool On);
|
||||
|
||||
bool isCentralWidgetArea() const;
|
||||
bool containsCentralWidget() const;
|
||||
bool isTopLevelArea() const;
|
||||
|
||||
public slots:
|
||||
void setCurrentIndex(int index);
|
||||
|
||||
@@ -13,6 +13,7 @@ class CDockComponentsFactory
|
||||
public:
|
||||
virtual ~CDockComponentsFactory();
|
||||
virtual CDockWidgetTab* createDockWidgetTab(CDockWidget* DockWidget /Transfer/ ) const;
|
||||
virtual CAutoHideTab* createDockWidgetSideTab(CDockWidget* DockWidget /Transfer/) const;
|
||||
virtual CDockAreaTabBar* createDockAreaTabBar(CDockAreaWidget* DockArea /Transfer/ ) const;
|
||||
virtual CDockAreaTitleBar* createDockAreaTitleBar(CDockAreaWidget* DockArea /Transfer/ ) const;
|
||||
static const CDockComponentsFactory* factory();
|
||||
|
||||
@@ -21,6 +21,7 @@ class CDockContainerWidget : QFrame
|
||||
protected:
|
||||
virtual bool event(QEvent *e);
|
||||
QSplitter* rootSplitter() const;
|
||||
ads::CAutoHideDockContainer* createAndSetupAutoHideContainer(ads::SideBarLocation area, ads::CDockWidget* DockWidget /Transfer/);
|
||||
void createRootSplitter();
|
||||
void dropFloatingWidget(ads::CFloatingDockContainer* FloatingWidget, const QPoint& TargetPos);
|
||||
void dropWidget(QWidget* Widget, DockWidgetArea DropArea, CDockAreaWidget* TargetAreaWidget);
|
||||
@@ -33,124 +34,44 @@ protected:
|
||||
ads::CDockAreaWidget* topLevelDockArea() const;
|
||||
QList<ads::CDockWidget*> dockWidgets() const;
|
||||
void updateSplitterHandles(QSplitter* splitter);
|
||||
void registerAutoHideWidget(ads::CAutoHideDockContainer* AutoHideWidget /Transfer/);
|
||||
void removeAutoHideWidget(ads::CAutoHideDockContainer* AutoHideWidget /TransferBack/);
|
||||
void handleAutoHideWidgetEvent(QEvent* e, QWidget* w);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Default Constructor
|
||||
*/
|
||||
CDockContainerWidget(ads::CDockManager* DockManager /TransferThis/, QWidget* parent /TransferThis/ = 0);
|
||||
|
||||
/**
|
||||
* Virtual Destructor
|
||||
*/
|
||||
virtual ~CDockContainerWidget();
|
||||
|
||||
/**
|
||||
* Adds dockwidget into the given area.
|
||||
* If DockAreaWidget is not null, then the area parameter indicates the area
|
||||
* into the DockAreaWidget. If DockAreaWidget is null, the Dockwidget will
|
||||
* be dropped into the container.
|
||||
* \return Returns the dock area widget that contains the new DockWidget
|
||||
*/
|
||||
ads::CDockAreaWidget* addDockWidget(ads::DockWidgetArea area, ads::CDockWidget* Dockwidget /Transfer/,
|
||||
ads::CDockAreaWidget* DockAreaWidget /Transfer/ = 0);
|
||||
|
||||
/**
|
||||
* Removes dockwidget
|
||||
*/
|
||||
ads::CDockAreaWidget* DockAreaWidget /Transfer/ = 0,
|
||||
int Index = -1);
|
||||
void removeDockWidget(ads::CDockWidget* Dockwidget) /TransferBack/;
|
||||
|
||||
/**
|
||||
* Returns the current zOrderIndex
|
||||
*/
|
||||
virtual unsigned int zOrderIndex() const;
|
||||
|
||||
/**
|
||||
* This function returns true if this container widgets z order index is
|
||||
* higher than the index of the container widget given in Other parameter
|
||||
*/
|
||||
bool isInFrontOf(ads::CDockContainerWidget* Other) const;
|
||||
|
||||
/**
|
||||
* Returns the dock area at teh given global position or 0 if there is no
|
||||
* dock area at this position
|
||||
*/
|
||||
ads::CDockAreaWidget* dockAreaAt(const QPoint& GlobalPos) const;
|
||||
|
||||
/**
|
||||
* Returns the dock area at the given Index or 0 if the index is out of
|
||||
* range
|
||||
*/
|
||||
ads::CDockAreaWidget* dockArea(int Index) const;
|
||||
|
||||
/**
|
||||
* Returns the list of dock areas that are not closed
|
||||
* If all dock widgets in a dock area are closed, the dock area will be closed
|
||||
*/
|
||||
QList<ads::CDockAreaWidget*> openedDockAreas() const;
|
||||
QList<ads::CDockWidget*> openedDockWidgets() const;
|
||||
bool hasTopLevelDockWidget() const;
|
||||
|
||||
/**
|
||||
* Returns the number of dock areas in this container
|
||||
*/
|
||||
int dockAreaCount() const;
|
||||
|
||||
/**
|
||||
* Returns the number of visible dock areas
|
||||
*/
|
||||
int visibleDockAreaCount() const;
|
||||
|
||||
/**
|
||||
* This function returns true, if this container is in a floating widget
|
||||
*/
|
||||
bool isFloating() const;
|
||||
|
||||
/**
|
||||
* Dumps the layout for debugging purposes
|
||||
*/
|
||||
void dumpLayout();
|
||||
|
||||
/**
|
||||
* This functions returns the dock widget features of all dock widget in
|
||||
* this container.
|
||||
* A bitwise and is used to combine the flags of all dock widgets. That
|
||||
* means, if only dock widget does not support a certain flag, the whole
|
||||
* dock are does not support the flag.
|
||||
*/
|
||||
ads::CDockWidget::DockWidgetFeatures features() const;
|
||||
|
||||
/**
|
||||
* If this dock container is in a floating widget, this function returns
|
||||
* the floating widget.
|
||||
* Else, it returns a nullptr.
|
||||
*/
|
||||
ads::CFloatingDockContainer* floatingWidget() const;
|
||||
|
||||
/**
|
||||
* Call this function to close all dock areas except the KeepOpenArea
|
||||
*/
|
||||
void closeOtherAreas(ads::CDockAreaWidget* KeepOpenArea);
|
||||
ads::CAutoHideSideBar* sideTabBar(SideBarLocation area) const;
|
||||
QList<ads::CAutoHideDockContainer*> autoHideWidgets() const;
|
||||
QRect contentRect() const;
|
||||
QRect contentRectGlobal() const;
|
||||
ads::CDockManager* dockManager() const;
|
||||
|
||||
signals:
|
||||
/**
|
||||
* This signal is emitted if one or multiple dock areas has been added to
|
||||
* the internal list of dock areas.
|
||||
* If multiple dock areas are inserted, this signal is emitted only once
|
||||
*/
|
||||
void dockAreasAdded();
|
||||
|
||||
/**
|
||||
* This signal is emitted if one or multiple dock areas has been removed
|
||||
*/
|
||||
void autoHideWidgetCreated(ads::CAutoHideDockContainer* AutoHideWidget);
|
||||
void dockAreasRemoved();
|
||||
|
||||
/**
|
||||
* This signal is emitted if a dock area is opened or closed via
|
||||
* toggleView() function
|
||||
*/
|
||||
void dockAreaViewToggled(ads::CDockAreaWidget* DockArea, bool Open);
|
||||
}; // class DockContainerWidget
|
||||
};
|
||||
// namespace ads
|
||||
|
||||
};
|
||||
|
||||
%End
|
||||
|
||||
@@ -22,6 +22,8 @@ public:
|
||||
void notifyFloatingWidgetDrop(ads::CFloatingDockContainer* FloatingWidget);
|
||||
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);
|
||||
|
||||
@@ -156,7 +156,6 @@ public:
|
||||
TabCloseButtonIsToolButton,
|
||||
AllTabsHaveCloseButton,
|
||||
RetainTabSizeWhenCloseButtonHidden,
|
||||
OpaqueUndocking,
|
||||
DragPreviewIsDynamic,
|
||||
DragPreviewShowsContentPixmap,
|
||||
DragPreviewHasWindowFrame,
|
||||
@@ -180,6 +179,18 @@ public:
|
||||
NonOpaqueWithWindowFrame,
|
||||
};
|
||||
typedef QFlags<ads::CDockManager::eConfigFlag> ConfigFlags;
|
||||
enum eAutoHideFlag
|
||||
{
|
||||
AutoHideFeatureEnabled,
|
||||
DockAreaHasAutoHideButton,
|
||||
AutoHideButtonTogglesArea,
|
||||
AutoHideButtonCheckable,
|
||||
AutoHideSideBarsIconOnly,
|
||||
AutoHideShowOnMouseOver,
|
||||
DefaultAutoHideConfig,
|
||||
AutoHideCloseButtonCollapsesDock,
|
||||
};
|
||||
typedef QFlags<ads::CDockManager::eAutoHideFlag> AutoHideFlags;
|
||||
|
||||
CDockManager(QWidget* parent /TransferThis/ = 0);
|
||||
virtual ~CDockManager();
|
||||
@@ -187,13 +198,24 @@ public:
|
||||
static void setConfigFlags(const ads::CDockManager::ConfigFlags Flags);
|
||||
static void setConfigFlag(ads::CDockManager::eConfigFlag Flag, bool On = true);
|
||||
static bool testConfigFlag(eConfigFlag Flag);
|
||||
static ads::CDockManager::AutoHideFlags autoHideConfigFlags();
|
||||
static void setAutoHideConfigFlags(const ads::CDockManager::AutoHideFlags Flags);
|
||||
static void setAutoHideConfigFlag(ads::CDockManager::eAutoHideFlag Flag, bool On = true);
|
||||
static bool testAutoHideConfigFlag(eAutoHideFlag Flag);
|
||||
static ads::CIconProvider& iconProvider();
|
||||
ads::CDockAreaWidget* addDockWidget(ads::DockWidgetArea area, ads::CDockWidget* Dockwidget /Transfer/,
|
||||
ads::CDockAreaWidget* DockAreaWidget /Transfer/ = 0);
|
||||
ads::CDockAreaWidget* DockAreaWidget /Transfer/ = 0,
|
||||
int Index = -1);
|
||||
ads::CDockAreaWidget* addDockWidgetToContainer(ads::DockWidgetArea area, ads::CDockWidget* Dockwidget /Transfer/,
|
||||
ads::CDockContainerWidget* DockContainerWidget /Transfer/ = 0);
|
||||
ads::CAutoHideDockContainer* addAutoHideDockWidget(ads::SideBarLocation Location, ads::CDockWidget* Dockwidget /Transfer/);
|
||||
ads::CAutoHideDockContainer* addAutoHideDockWidgetToContainer(SideBarLocation Location,
|
||||
ads::CDockWidget* Dockwidget /Transfer/, ads::CDockContainerWidget* DockContainerWidget);
|
||||
ads::CDockAreaWidget* addDockWidgetTab(ads::DockWidgetArea area,
|
||||
ads::CDockWidget* Dockwidget /Transfer/);
|
||||
ads::CDockAreaWidget* addDockWidgetTabToArea(ads::CDockWidget* Dockwidget /Transfer/,
|
||||
ads::CDockAreaWidget* DockAreaWidget /Transfer/);
|
||||
ads::CDockAreaWidget* DockAreaWidget /Transfer/,
|
||||
int Index = -1);
|
||||
ads::CFloatingDockContainer* addDockWidgetFloating(ads::CDockWidget* DockWidget /Transfer/);
|
||||
ads::CDockWidget* findDockWidget(const QString& ObjectName) const;
|
||||
void removeDockWidget(ads::CDockWidget* Dockwidget) /TransferBack/;
|
||||
@@ -216,12 +238,16 @@ 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;
|
||||
void setSplitterSizes(ads::CDockAreaWidget *ContainedArea, const QList<int>& sizes);
|
||||
static void setFloatingContainersTitle(const QString& Title);
|
||||
static QString floatingContainersTitle();
|
||||
|
||||
public slots:
|
||||
void endLeavingMinimizedState();
|
||||
void openPerspective(const QString& PerspectiveName);
|
||||
void setDockWidgetFocused(ads::CDockWidget* DockWidget);
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ public:
|
||||
DockWidgetForceCloseWithArea,
|
||||
NoTab,
|
||||
DeleteContentOnClose,
|
||||
DockWidgetPinnable,
|
||||
DefaultDockWidgetFeatures,
|
||||
AllDockWidgetFeatures,
|
||||
DockWidgetAlwaysCloseAndDelete,
|
||||
@@ -59,7 +60,9 @@ public:
|
||||
enum eMinimumSizeHintMode
|
||||
{
|
||||
MinimumSizeHintFromDockWidget,
|
||||
MinimumSizeHintFromContent
|
||||
MinimumSizeHintFromContent,
|
||||
MinimumSizeHintFromDockWidgetMinimumSize,
|
||||
MinimumSizeHintFromContentMinimumSize,
|
||||
};
|
||||
|
||||
enum eToggleViewActionMode
|
||||
@@ -81,13 +84,19 @@ public:
|
||||
ads::CDockWidget::DockWidgetFeatures features() const;
|
||||
ads::CDockManager* dockManager() const;
|
||||
ads::CDockContainerWidget* dockContainer() const;
|
||||
ads::CFloatingDockContainer* floatingDockContainer() const;
|
||||
ads::CDockAreaWidget* dockAreaWidget() const;
|
||||
ads::CAutoHideTab* sideTabWidget() const;
|
||||
void setSideTabWidget(ads::CAutoHideTab* SideTab /Transfer/) const;
|
||||
bool isAutoHide() const;
|
||||
ads::CAutoHideDockContainer* autoHideDockContainer() 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;
|
||||
@@ -118,6 +127,8 @@ public slots:
|
||||
void closeDockWidget();
|
||||
void showFullScreen();
|
||||
void showNormal();
|
||||
void setAutoHide(bool Enable, ads::SideBarLocation Location = ads::SideBarNone);
|
||||
void toggleAutoHide(ads::SideBarLocation Location = ads::SideBarNone);
|
||||
|
||||
signals:
|
||||
void viewToggled(bool Open);
|
||||
|
||||
@@ -37,6 +37,7 @@ public:
|
||||
void updateStyle();
|
||||
QSize iconSize() const;
|
||||
void setIconSize(const QSize& Size);
|
||||
bool mousePressed() const;
|
||||
|
||||
public slots:
|
||||
virtual void setVisible(bool visible);
|
||||
|
||||
@@ -64,6 +64,7 @@ protected:
|
||||
%If (WS_X11)
|
||||
virtual void moveEvent(QMoveEvent *event);
|
||||
virtual void resizeEvent(QResizeEvent *event);
|
||||
virtual bool event(QEvent *e);
|
||||
%End
|
||||
|
||||
%If (WS_WIN)
|
||||
|
||||
@@ -27,10 +27,9 @@ public:
|
||||
public: // implements IFloatingWidget
|
||||
virtual void startFloating(const QPoint& DragStartMousePos, const QSize& Size,
|
||||
ads::eDragState DragState, QWidget* MouseEventHandler);
|
||||
|
||||
virtual void moveFloating();
|
||||
|
||||
virtual void finishDragging();
|
||||
void cleanupAutoHideContainerWidget();
|
||||
|
||||
signals:
|
||||
void draggingCanceled();
|
||||
|
||||
31
sip/PushButton.sip
Normal file
@@ -0,0 +1,31 @@
|
||||
%Import QtWidgets/QtWidgetsmod.sip
|
||||
|
||||
%If (Qt_5_0_0 -)
|
||||
|
||||
namespace ads
|
||||
{
|
||||
|
||||
|
||||
class CPushButton : QPushButton
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <PushButton.h>
|
||||
%End
|
||||
|
||||
public:
|
||||
enum Orientation {
|
||||
Horizontal,
|
||||
VerticalTopToBottom,
|
||||
VerticalBottomToTop
|
||||
};
|
||||
virtual QSize sizeHint() const;
|
||||
|
||||
ads::CPushButton::Orientation buttonOrientation() const;
|
||||
void setButtonOrientation(ads::CPushButton::Orientation orientation);
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
%End
|
||||
|
||||
36
sip/ResizeHandle.sip
Normal file
@@ -0,0 +1,36 @@
|
||||
%Import QtWidgets/QtWidgetsmod.sip
|
||||
|
||||
%If (Qt_5_0_0 -)
|
||||
|
||||
namespace ads
|
||||
{
|
||||
|
||||
class CResizeHandle : QFrame
|
||||
{
|
||||
|
||||
%TypeHeaderCode
|
||||
#include <ResizeHandle.h>
|
||||
%End
|
||||
|
||||
protected:
|
||||
void mouseMoveEvent(QMouseEvent *);
|
||||
void mousePressEvent(QMouseEvent *);
|
||||
void mouseReleaseEvent(QMouseEvent *);
|
||||
|
||||
public:
|
||||
CResizeHandle(Qt::Edge HandlePosition, QWidget* parent /TransferThis/);
|
||||
virtual ~CResizeHandle();
|
||||
void setHandlePosition(Qt::Edge HandlePosition);
|
||||
Qt::Edge handlePostion() const;
|
||||
Qt::Orientation orientation() const;
|
||||
QSize sizeHint() const;
|
||||
bool isResizing() const;
|
||||
void setMinResizeSize(int MinSize);
|
||||
void setMaxResizeSize(int MaxSize);
|
||||
void setOpaqueResize(bool opaque = true);
|
||||
bool opaqueResize() const;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
%End
|
||||
@@ -3,6 +3,9 @@
|
||||
%DefaultSupertype sip.simplewrapper
|
||||
|
||||
%Include ads_globals.sip
|
||||
%Include AutoHideDockContainer.sip
|
||||
%Include AutoHideSideBar.sip
|
||||
%Include AutoHideTab.sip
|
||||
%Include DockWidget.sip
|
||||
%Include DockAreaTabBar.sip
|
||||
%Include DockAreaTitleBar_p.sip
|
||||
@@ -20,6 +23,8 @@
|
||||
%Include FloatingDockContainer.sip
|
||||
%Include FloatingDragPreview.sip
|
||||
%Include IconProvider.sip
|
||||
%Include PushButton.sip
|
||||
%Include ResizeHandle.sip
|
||||
%If (WS_X11)
|
||||
%Include linux/FloatingWidgetTitleBar.sip
|
||||
%End
|
||||
|
||||
@@ -50,7 +50,6 @@ namespace ads
|
||||
TopDockWidgetArea,
|
||||
BottomDockWidgetArea,
|
||||
CenterDockWidgetArea,
|
||||
|
||||
InvalidDockWidgetArea,
|
||||
OuterDockAreas,
|
||||
AllDockAreas
|
||||
@@ -62,7 +61,8 @@ namespace ads
|
||||
{
|
||||
TitleBarButtonTabsMenu,
|
||||
TitleBarButtonUndock,
|
||||
TitleBarButtonClose
|
||||
TitleBarButtonClose,
|
||||
TitleBarButtonAutoHide
|
||||
};
|
||||
|
||||
enum eDragState
|
||||
@@ -76,10 +76,10 @@ namespace ads
|
||||
enum eIcon
|
||||
{
|
||||
TabCloseIcon,
|
||||
AutoHideIcon,
|
||||
DockAreaMenuIcon,
|
||||
DockAreaUndockIcon,
|
||||
DockAreaCloseIcon,
|
||||
|
||||
IconCount,
|
||||
};
|
||||
|
||||
@@ -89,6 +89,15 @@ namespace ads
|
||||
BitwiseOr
|
||||
};
|
||||
|
||||
enum SideBarLocation
|
||||
{
|
||||
SideBarTop,
|
||||
SideBarLeft,
|
||||
SideBarRight,
|
||||
SideBarBottom,
|
||||
SideBarNone
|
||||
};
|
||||
|
||||
namespace internal
|
||||
{
|
||||
void replaceSplitterWidget(QSplitter* Splitter, QWidget* From, QWidget* To);
|
||||
@@ -131,6 +140,7 @@ namespace ads
|
||||
};
|
||||
|
||||
void repolishStyle(QWidget* w, ads::internal::eRepolishChildOptions Options = ads::internal::RepolishIgnoreChildren);
|
||||
QRect globalGeometry(QWidget* w);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -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 explicitely 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 orginal dock widget size, to avoid
|
||||
// an extremely streched dock widget after insertion
|
||||
if (SideBar->orientation() != OldOrientation)
|
||||
{
|
||||
resetToInitialDockWidgetSize();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
int CAutoHideDockContainer::tabIndex() const
|
||||
{
|
||||
return d->SideTab->tabIndex();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ public:
|
||||
/**
|
||||
* Get's the side tab bar
|
||||
*/
|
||||
CAutoHideSideBar* sideBar() const;
|
||||
CAutoHideSideBar* autoHideSideBar() const;
|
||||
|
||||
/**
|
||||
* Returns the side tab
|
||||
@@ -105,6 +105,11 @@ public:
|
||||
*/
|
||||
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
|
||||
*/
|
||||
@@ -166,6 +171,30 @@ public:
|
||||
* of this auto hide container.
|
||||
*/
|
||||
void setSize(int Size);
|
||||
|
||||
/**
|
||||
* Resets the with or hight 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
|
||||
|
||||
|
||||
@@ -127,27 +127,6 @@ void AutoHideSideBarPrivate::handleViewportEvent(QEvent* e)
|
||||
}
|
||||
break;
|
||||
|
||||
case QEvent::Resize:
|
||||
if (_this->tabCount())
|
||||
{
|
||||
auto ev = static_cast<QResizeEvent*>(e);
|
||||
auto Tab = _this->tabAt(0);
|
||||
int Size = isHorizontal() ? ev->size().height() : ev->size().width();
|
||||
int TabSize = isHorizontal() ? Tab->size().height() : Tab->size().width();
|
||||
// If the size of the side bar is less than the size of the first tab
|
||||
// then there are no visible tabs in this side bar. This check will
|
||||
// fail if someone will force a very big border via CSS!!
|
||||
if (Size < TabSize)
|
||||
{
|
||||
_this->hide();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_this->hide();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -217,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);
|
||||
@@ -254,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)
|
||||
@@ -269,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());
|
||||
}
|
||||
|
||||
|
||||
@@ -288,20 +281,33 @@ void CAutoHideSideBar::removeTab(CAutoHideTab* SideTab)
|
||||
//============================================================================
|
||||
bool CAutoHideSideBar::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
if (event->type() != QEvent::ShowToParent)
|
||||
auto Tab = qobject_cast<CAutoHideTab*>(watched);
|
||||
if (!Tab)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// As soon as on tab is shown, we need to show the side tab bar
|
||||
auto Tab = qobject_cast<CAutoHideTab*>(watched);
|
||||
if (Tab)
|
||||
switch (event->type())
|
||||
{
|
||||
show();
|
||||
case QEvent::ShowToParent:
|
||||
show();
|
||||
break;
|
||||
|
||||
case QEvent::HideToParent:
|
||||
if (!hasVisibleTabs())
|
||||
{
|
||||
hide();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
Qt::Orientation CAutoHideSideBar::orientation() const
|
||||
{
|
||||
@@ -310,19 +316,67 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
int CAutoHideSideBar::visibleTabCount() const
|
||||
{
|
||||
int VisibleTabCount = 0;
|
||||
auto ParentWidget = parentWidget();
|
||||
for (auto i = 0; i < count(); i++)
|
||||
{
|
||||
if (tab(i)->isVisibleTo(ParentWidget))
|
||||
{
|
||||
VisibleTabCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return VisibleTabCount;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool CAutoHideSideBar::hasVisibleTabs() const
|
||||
{
|
||||
auto ParentWidget = parentWidget();
|
||||
for (auto i = 0; i < count(); i++)
|
||||
{
|
||||
if (tab(i)->isVisibleTo(ParentWidget))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
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
|
||||
{
|
||||
@@ -333,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;
|
||||
@@ -392,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
|
||||
|
||||
|
||||
@@ -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,45 @@ 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.
|
||||
*/
|
||||
int visibleTabCount() const;
|
||||
|
||||
/**
|
||||
* Returns true, if the sidebar contains visible tabs to its parent widget.
|
||||
* The function returns as soon as it finds the first visible tab.
|
||||
* That means, if you just want to find out if there are visible tabs
|
||||
* then this function is quicker than visibleTabCount()
|
||||
*/
|
||||
bool hasVisibleTabs() const;
|
||||
|
||||
/**
|
||||
* Getter for side tab bar area property
|
||||
|
||||
@@ -32,15 +32,20 @@
|
||||
#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
|
||||
{
|
||||
static const char* const LocationProperty = "Location";
|
||||
|
||||
/**
|
||||
* Private data class of CDockWidgetTab class (pimpl)
|
||||
*/
|
||||
@@ -51,6 +56,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 +93,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("Location", 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 +170,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 +357,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(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->isAutoHide() && 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
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(QtAdvancedDockingSystem LANGUAGES CXX VERSION ${VERSION_SHORT})
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
|
||||
if (${QT_VERSION_MAJOR})
|
||||
message(STATUS "Forced to use Qt version ${QT_VERSION_MAJOR}")
|
||||
find_package(QT NAMES Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)
|
||||
else()
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
|
||||
endif()
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Widgets REQUIRED)
|
||||
if (UNIX AND NOT APPLE)
|
||||
include_directories(${Qt${QT_VERSION_MAJOR}Gui_PRIVATE_INCLUDE_DIRS})
|
||||
@@ -64,50 +69,52 @@ if (UNIX AND NOT APPLE)
|
||||
set(ads_SRCS linux/FloatingWidgetTitleBar.cpp ${ads_SRCS})
|
||||
set(ads_HEADERS linux/FloatingWidgetTitleBar.h ${ads_HEADERS})
|
||||
endif()
|
||||
|
||||
set(library_name "qt${QT_VERSION_MAJOR}advanceddocking")
|
||||
if(BUILD_STATIC)
|
||||
add_library(qtadvanceddocking STATIC ${ads_SRCS} ${ads_HEADERS})
|
||||
target_compile_definitions(qtadvanceddocking PUBLIC ADS_STATIC)
|
||||
add_library(${library_name} STATIC ${ads_SRCS} ${ads_HEADERS})
|
||||
target_compile_definitions( ${library_name} PUBLIC ADS_STATIC)
|
||||
else()
|
||||
add_library(qtadvanceddocking SHARED ${ads_SRCS} ${ads_HEADERS})
|
||||
target_compile_definitions(qtadvanceddocking PRIVATE ADS_SHARED_EXPORT)
|
||||
add_library( ${library_name} SHARED ${ads_SRCS} ${ads_HEADERS})
|
||||
target_compile_definitions( ${library_name} PRIVATE ADS_SHARED_EXPORT)
|
||||
endif()
|
||||
|
||||
add_library(ads::qtadvanceddocking ALIAS qtadvanceddocking)
|
||||
add_library(ads::${library_name} ALIAS ${library_name})
|
||||
|
||||
target_link_libraries(qtadvanceddocking PUBLIC Qt${QT_VERSION_MAJOR}::Core
|
||||
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(qtadvanceddocking PUBLIC xcb)
|
||||
target_link_libraries(${library_name} PUBLIC xcb)
|
||||
endif()
|
||||
set_target_properties(qtadvanceddocking PROPERTIES
|
||||
set_target_properties(${library_name} PROPERTIES
|
||||
AUTOMOC ON
|
||||
AUTORCC ON
|
||||
CXX_EXTENSIONS OFF
|
||||
VERSION ${VERSION_SHORT}
|
||||
EXPORT_NAME "qtadvanceddocking"
|
||||
EXPORT_NAME ${library_name}
|
||||
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"
|
||||
)
|
||||
if(QT_VERSION_MAJOR STREQUAL "5")
|
||||
set_target_properties(qtadvanceddocking PROPERTIES
|
||||
set_target_properties(${library_name} PROPERTIES
|
||||
CXX_STANDARD 14
|
||||
CXX_STANDARD_REQUIRED ON)
|
||||
elseif(QT_VERSION_MAJOR STREQUAL "6")
|
||||
set_target_properties(qtadvanceddocking PROPERTIES
|
||||
set_target_properties(${library_name} PROPERTIES
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED ON)
|
||||
endif()
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
write_basic_package_version_file(
|
||||
"qtadvanceddockingConfigVersion.cmake"
|
||||
"${library_name}ConfigVersion.cmake"
|
||||
VERSION ${VERSION_SHORT}
|
||||
COMPATIBILITY SameMajorVersion
|
||||
)
|
||||
install(FILES ${ads_HEADERS}
|
||||
DESTINATION include
|
||||
DESTINATION include/${library_name}
|
||||
COMPONENT headers
|
||||
)
|
||||
install(FILES
|
||||
@@ -116,24 +123,27 @@ install(FILES
|
||||
DESTINATION license/ads
|
||||
COMPONENT license
|
||||
)
|
||||
install(TARGETS qtadvanceddocking
|
||||
install(TARGETS ${library_name}
|
||||
EXPORT adsTargets
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
INCLUDES DESTINATION include
|
||||
INCLUDES DESTINATION include/${library_name}
|
||||
)
|
||||
|
||||
install(EXPORT adsTargets
|
||||
FILE adsTargets.cmake
|
||||
NAMESPACE ads::
|
||||
DESTINATION lib/cmake/qtadvanceddocking
|
||||
DESTINATION lib/cmake/${library_name}
|
||||
)
|
||||
install(FILES qtadvanceddockingConfig.cmake "${CMAKE_CURRENT_BINARY_DIR}/qtadvanceddockingConfigVersion.cmake"
|
||||
DESTINATION lib/cmake/qtadvanceddocking
|
||||
install(FILES qtadvanceddockingConfig.cmake RENAME ${library_name}Config.cmake
|
||||
DESTINATION lib/cmake/${library_name}
|
||||
)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${library_name}ConfigVersion.cmake"
|
||||
DESTINATION lib/cmake/${library_name}
|
||||
)
|
||||
|
||||
target_include_directories(qtadvanceddocking PUBLIC
|
||||
target_include_directories(${library_name} PUBLIC
|
||||
$<INSTALL_INTERFACE:include>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
)
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <QBoxLayout>
|
||||
#include <QApplication>
|
||||
#include <QtGlobal>
|
||||
#include <QTimer>
|
||||
|
||||
#include "FloatingDockContainer.h"
|
||||
#include "DockAreaWidget.h"
|
||||
@@ -107,7 +108,12 @@ void DockAreaTabBarPrivate::updateTabs()
|
||||
{
|
||||
TabWidget->show();
|
||||
TabWidget->setActiveTab(true);
|
||||
_this->ensureWidgetVisible(TabWidget);
|
||||
// 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);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -498,6 +504,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
|
||||
*/
|
||||
|
||||
@@ -68,10 +68,10 @@ 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;
|
||||
QBoxLayout* Layout;
|
||||
CDockAreaWidget* DockArea;
|
||||
CDockAreaTabBar* TabBar;
|
||||
@@ -262,12 +262,15 @@ IFloatingWidget* DockAreaTitleBarPrivate::makeAreaFloating(const QPoint& Offset,
|
||||
{
|
||||
QSize Size = DockArea->size();
|
||||
this->DragState = DragState;
|
||||
bool OpaqueUndocking = CDockManager::testConfigFlag(CDockManager::OpaqueUndocking) ||
|
||||
(DraggingFloatingWidget != DragState);
|
||||
bool CreateFloatingDockContainer = (DraggingFloatingWidget != DragState);
|
||||
CFloatingDockContainer* FloatingDockContainer = nullptr;
|
||||
IFloatingWidget* FloatingWidget;
|
||||
if (OpaqueUndocking)
|
||||
if (CreateFloatingDockContainer)
|
||||
{
|
||||
if (DockArea->autoHideDockContainer())
|
||||
{
|
||||
DockArea->autoHideDockContainer()->cleanupAndDelete();
|
||||
}
|
||||
FloatingWidget = FloatingDockContainer = new CFloatingDockContainer(DockArea);
|
||||
}
|
||||
else
|
||||
@@ -297,7 +300,7 @@ IFloatingWidget* DockAreaTitleBarPrivate::makeAreaFloating(const QPoint& Offset,
|
||||
//============================================================================
|
||||
void DockAreaTitleBarPrivate::startFloating(const QPoint& Offset)
|
||||
{
|
||||
if (DockArea->autoHideDockContainer() != nullptr)
|
||||
if (DockArea->autoHideDockContainer())
|
||||
{
|
||||
DockArea->autoHideDockContainer()->hide();
|
||||
}
|
||||
@@ -412,7 +415,12 @@ void CDockAreaTitleBar::onTabsMenuAboutToShow()
|
||||
void CDockAreaTitleBar::onCloseButtonClicked()
|
||||
{
|
||||
ADS_PRINT("CDockAreaTitleBar::onCloseButtonClicked");
|
||||
if (d->testConfigFlag(CDockManager::DockAreaCloseButtonClosesTab))
|
||||
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideCloseButtonCollapsesDock) &&
|
||||
d->DockArea->autoHideDockContainer())
|
||||
{
|
||||
d->DockArea->autoHideDockContainer()->collapseView(true);
|
||||
}
|
||||
else if (d->testConfigFlag(CDockManager::DockAreaCloseButtonClosesTab))
|
||||
{
|
||||
d->TabBar->closeTab(d->TabBar->currentIndex());
|
||||
}
|
||||
@@ -428,11 +436,6 @@ void CDockAreaTitleBar::onUndockButtonClicked()
|
||||
{
|
||||
if (d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
|
||||
{
|
||||
if (d->DockArea->autoHideDockContainer())
|
||||
{
|
||||
d->DockArea->autoHideDockContainer()->cleanupAndDelete();
|
||||
}
|
||||
|
||||
d->makeAreaFloating(mapFromGlobal(QCursor::pos()), DraggingInactive);
|
||||
}
|
||||
}
|
||||
@@ -536,7 +539,7 @@ void CDockAreaTitleBar::onAutoHideToActionClicked()
|
||||
|
||||
|
||||
//============================================================================
|
||||
QAbstractButton* CDockAreaTitleBar::button(TitleBarButton which) const
|
||||
CTitleBarButton* CDockAreaTitleBar::button(TitleBarButton which) const
|
||||
{
|
||||
switch (which)
|
||||
{
|
||||
@@ -634,11 +637,9 @@ void CDockAreaTitleBar::mouseMoveEvent(QMouseEvent* ev)
|
||||
|
||||
// If one single dock widget in this area is not floatable then the whole
|
||||
// area is not floatable
|
||||
// If we do non opaque undocking, then we can create the floating drag
|
||||
// preview if the dock widget is movable
|
||||
// We can create the floating drag preview if the dock widget is movable
|
||||
auto Features = d->DockArea->features();
|
||||
if (!Features.testFlag(CDockWidget::DockWidgetFloatable)
|
||||
&& !(Features.testFlag(CDockWidget::DockWidgetMovable) && !CDockManager::testConfigFlag(CDockManager::OpaqueUndocking)))
|
||||
if (!Features.testFlag(CDockWidget::DockWidgetFloatable) && !(Features.testFlag(CDockWidget::DockWidgetMovable)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -671,15 +672,33 @@ void CDockAreaTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (d->DockArea->autoHideDockContainer())
|
||||
{
|
||||
d->DockArea->autoHideDockContainer()->cleanupAndDelete();
|
||||
}
|
||||
|
||||
d->makeAreaFloating(event->pos(), DraggingInactive);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
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)
|
||||
{
|
||||
@@ -784,9 +803,9 @@ QString CDockAreaTitleBar::titleBarButtonToolTip(TitleBarButton Button) const
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
CTitleBarButton::CTitleBarButton(bool visible, QWidget* parent)
|
||||
CTitleBarButton::CTitleBarButton(bool showInTitleBar, QWidget* parent)
|
||||
: tTitleBarButton(parent),
|
||||
Visible(visible),
|
||||
ShowInTitleBar(showInTitleBar),
|
||||
HideWhenDisabled(CDockManager::testConfigFlag(CDockManager::DockAreaHideDisabledButtons))
|
||||
{
|
||||
setFocusPolicy(Qt::NoFocus);
|
||||
@@ -796,7 +815,7 @@ 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 = 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)
|
||||
@@ -807,6 +826,18 @@ 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)
|
||||
{
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
//============================================================================
|
||||
// INCLUDES
|
||||
//============================================================================
|
||||
#include <QToolButton>
|
||||
#include <QFrame>
|
||||
|
||||
#include "ads_globals.h"
|
||||
@@ -43,6 +44,44 @@ class CDockAreaWidget;
|
||||
struct DockAreaTitleBarPrivate;
|
||||
class CElidingLabel;
|
||||
|
||||
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;
|
||||
|
||||
public:
|
||||
using Super = tTitleBarButton;
|
||||
CTitleBarButton(bool ShowInTitleBar = true, 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);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Handle EnabledChanged signal to set button invisible if the configured
|
||||
*/
|
||||
bool event(QEvent *ev) override;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Title bar of a dock area.
|
||||
* The title bar contains a tabbar with all tabs for a dock widget group and
|
||||
@@ -121,7 +160,7 @@ 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
|
||||
@@ -163,6 +202,12 @@ public:
|
||||
*/
|
||||
QString titleBarButtonToolTip(TitleBarButton Button) const;
|
||||
|
||||
/**
|
||||
* Moves the dock area into its own floating widget if the area
|
||||
* DockWidgetFloatable flag is true
|
||||
*/
|
||||
void setAreaFloating();
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -140,6 +140,7 @@ public:
|
||||
{
|
||||
LayoutItem->widget()->setParent(nullptr);
|
||||
}
|
||||
delete LayoutItem;
|
||||
m_CurrentWidget = nullptr;
|
||||
m_CurrentIndex = -1;
|
||||
}
|
||||
@@ -466,6 +467,7 @@ void CDockAreaWidget::setAutoHideDockContainer(CAutoHideDockContainer* AutoHideD
|
||||
d->AutoHideDockContainer = AutoHideDockContainer;
|
||||
updateAutoHideButtonCheckState();
|
||||
updateTitleBarButtonsToolTips();
|
||||
d->TitleBar->button(TitleBarButtonAutoHide)->setShowInTitleBar(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -625,15 +627,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();
|
||||
}
|
||||
|
||||
|
||||
@@ -1311,7 +1305,7 @@ SideBarLocation CDockAreaWidget::calculateSideTabBarArea() const
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockAreaWidget::setAutoHide(bool Enable, SideBarLocation Location)
|
||||
void CDockAreaWidget::setAutoHide(bool Enable, SideBarLocation Location, int TabIndex)
|
||||
{
|
||||
if (!isAutoHideFeatureEnabled())
|
||||
{
|
||||
@@ -1322,11 +1316,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())
|
||||
{
|
||||
@@ -1340,7 +1341,7 @@ void CDockAreaWidget::setAutoHide(bool Enable, SideBarLocation Location)
|
||||
continue;
|
||||
}
|
||||
|
||||
dockContainer()->createAndSetupAutoHideContainer(area, DockWidget);
|
||||
dockContainer()->createAndSetupAutoHideContainer(area, DockWidget, TabIndex++);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1441,6 +1442,13 @@ bool CDockAreaWidget::isTopLevelArea() const
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockAreaWidget::setFloating()
|
||||
{
|
||||
d->TitleBar->setAreaFloating();
|
||||
}
|
||||
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
//============================================================================
|
||||
bool CDockAreaWidget::event(QEvent *e)
|
||||
|
||||
@@ -221,7 +221,6 @@ public:
|
||||
*/
|
||||
bool isAutoHide() const;
|
||||
|
||||
|
||||
/**
|
||||
* Sets the current auto hide dock container
|
||||
*/
|
||||
@@ -401,7 +400,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 +413,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.
|
||||
|
||||
@@ -145,7 +145,7 @@ public:
|
||||
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);
|
||||
|
||||
|
||||
/**
|
||||
@@ -454,7 +466,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 +474,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 +517,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 +556,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 +565,7 @@ void DockContainerWidgetPrivate::dropIntoCenterOfSection(
|
||||
NewCurrentIndex = i;
|
||||
}
|
||||
}
|
||||
TargetArea->setCurrentIndex(NewCurrentIndex);
|
||||
TargetArea->setCurrentIndex(NewCurrentIndex + TabIndex);
|
||||
TargetArea->updateTitleBarVisibility();
|
||||
return;
|
||||
}
|
||||
@@ -542,13 +573,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;
|
||||
}
|
||||
|
||||
@@ -638,11 +669,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 +688,7 @@ void DockContainerWidgetPrivate::moveIntoCenterOfSection(QWidget* Widget, CDockA
|
||||
{
|
||||
OldDockArea->removeDockWidget(DroppedDockWidget);
|
||||
}
|
||||
TargetArea->insertDockWidget(0, DroppedDockWidget, true);
|
||||
TargetArea->insertDockWidget(TabIndex, DroppedDockWidget, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -664,9 +697,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 +710,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;
|
||||
}
|
||||
|
||||
@@ -738,6 +772,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 )
|
||||
{
|
||||
@@ -908,7 +984,7 @@ void DockContainerWidgetPrivate::saveAutoHideWidgetsState(QXmlStreamWriter& s)
|
||||
{
|
||||
for (const auto sideTabBar : SideTabBarWidgets.values())
|
||||
{
|
||||
if (!sideTabBar->tabCount())
|
||||
if (!sideTabBar->count())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -1101,12 +1177,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 +1269,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);
|
||||
@@ -1404,7 +1480,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 +1493,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -1528,7 +1604,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)
|
||||
@@ -1629,11 +1705,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,28 +1725,33 @@ 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);
|
||||
}
|
||||
|
||||
@@ -1697,12 +1779,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
|
||||
{
|
||||
@@ -1846,8 +1933,8 @@ bool CDockContainerWidget::restoreState(CDockingStateReader& s, bool Testing)
|
||||
}
|
||||
|
||||
d->Layout->replaceWidget(d->RootSplitter, NewRootSplitter);
|
||||
QSplitter* OldRoot = d->RootSplitter;
|
||||
d->RootSplitter = qobject_cast<QSplitter*>(NewRootSplitter);
|
||||
auto OldRoot = d->RootSplitter;
|
||||
d->RootSplitter = qobject_cast<CDockSplitter*>(NewRootSplitter);
|
||||
OldRoot->deleteLater();
|
||||
|
||||
return true;
|
||||
@@ -2051,7 +2138,7 @@ void CDockContainerWidget::closeOtherAreas(CDockAreaWidget* KeepOpenArea)
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
CAutoHideSideBar* CDockContainerWidget::sideTabBar(SideBarLocation area) const
|
||||
CAutoHideSideBar* CDockContainerWidget::autoHideSideBar(SideBarLocation area) const
|
||||
{
|
||||
return d->SideTabBarWidgets[area];
|
||||
}
|
||||
@@ -2065,7 +2152,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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ protected:
|
||||
* 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,12 +125,13 @@ 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
|
||||
*/
|
||||
void addDockArea(CDockAreaWidget* DockAreaWidget, DockWidgetArea area = CenterDockWidgetArea);
|
||||
void addDockArea(CDockAreaWidget* DockAreaWidget, DockWidgetArea area = ads::CenterDockWidgetArea);
|
||||
|
||||
/**
|
||||
* Removes the given dock area from this container
|
||||
@@ -322,7 +323,7 @@ public:
|
||||
/**
|
||||
* Returns the side tab widget for the given area
|
||||
*/
|
||||
CAutoHideSideBar* sideTabBar(SideBarLocation area) const;
|
||||
CAutoHideSideBar* autoHideSideBar(SideBarLocation area) const;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "DockManager.h"
|
||||
#include "DockAreaTitleBar.h"
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
#include "linux/FloatingWidgetTitleBar.h"
|
||||
#endif
|
||||
|
||||
@@ -44,11 +44,12 @@ struct DockFocusControllerPrivate
|
||||
QPointer<CDockWidget> FocusedDockWidget = nullptr;
|
||||
QPointer<CDockAreaWidget> FocusedArea = nullptr;
|
||||
QPointer<CDockWidget> OldFocusedDockWidget = nullptr;
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
QPointer<CFloatingDockContainer> FloatingWidget = nullptr;
|
||||
#endif
|
||||
CDockManager* DockManager;
|
||||
bool ForceFocusChangedSignal = false;
|
||||
bool TabPressed = false;
|
||||
|
||||
/**
|
||||
* Private data constructor
|
||||
@@ -84,7 +85,7 @@ static void updateDockAreaFocusStyle(CDockAreaWidget* DockArea, bool Focused)
|
||||
|
||||
|
||||
//===========================================================================
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
static void updateFloatingWidgetFocusStyle(CFloatingDockContainer* FloatingWidget, bool Focused)
|
||||
{
|
||||
if (FloatingWidget->hasNativeTitleBar())
|
||||
@@ -168,7 +169,7 @@ void DockFocusControllerPrivate::updateDockWidgetFocus(CDockWidget* DockWidget)
|
||||
}
|
||||
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
// This code is required for styling the floating widget titlebar for linux
|
||||
// depending on the current focus state
|
||||
if (FloatingWidget != NewFloatingWidget)
|
||||
@@ -267,7 +268,9 @@ void CDockFocusController::onApplicationFocusChanged(QWidget* focusedOld, QWidge
|
||||
{
|
||||
Q_UNUSED(focusedOld);
|
||||
|
||||
if (d->DockManager->isRestoringState())
|
||||
// Ignore focus changes if we are restoring state, or if user clicked
|
||||
// a tab wich in turn caused the focus change
|
||||
if (d->DockManager->isRestoringState() || d->TabPressed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -285,7 +288,7 @@ void CDockFocusController::onApplicationFocusChanged(QWidget* focusedOld, QWidge
|
||||
DockWidget = internal::findParent<CDockWidget*>(focusedNow);
|
||||
}
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
if (!DockWidget)
|
||||
{
|
||||
return;
|
||||
@@ -418,6 +421,12 @@ CDockWidget* CDockFocusController::focusedDockWidget() const
|
||||
return d->FocusedDockWidget.data();
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
void CDockFocusController::setDockWidgetTabPressed(bool Value)
|
||||
{
|
||||
d->TabPressed = Value;
|
||||
}
|
||||
} // namespace ads
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -80,6 +80,12 @@ public:
|
||||
*/
|
||||
void clearDockWidgetFocus(CDockWidget* dockWidget);
|
||||
|
||||
/**
|
||||
* Notifies the dock focus controller, that a the mouse is pressed or
|
||||
* released
|
||||
*/
|
||||
void setDockWidgetTabPressed(bool Value);
|
||||
|
||||
public Q_SLOTS:
|
||||
/**
|
||||
* Request a focus change to the given dock widget
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include <QMenu>
|
||||
#include <QApplication>
|
||||
#include <QWindow>
|
||||
#include <QWindowStateChangeEvent>
|
||||
|
||||
#include "FloatingDockContainer.h"
|
||||
#include "DockOverlay.h"
|
||||
@@ -59,7 +60,7 @@
|
||||
#include "DockFocusController.h"
|
||||
#include "DockSplitter.h"
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
#include "linux/FloatingWidgetTitleBar.h"
|
||||
#endif
|
||||
|
||||
@@ -116,6 +117,7 @@ struct DockManagerPrivate
|
||||
QVector<CFloatingDockContainer*> UninitializedFloatingWidgets;
|
||||
CDockFocusController* FocusController = nullptr;
|
||||
CDockWidget* CentralWidget = nullptr;
|
||||
bool IsLeavingMinimized = false;
|
||||
|
||||
/**
|
||||
* Private data constructor
|
||||
@@ -192,7 +194,7 @@ void DockManagerPrivate::loadStylesheet()
|
||||
QString FileName = ":ads/stylesheets/";
|
||||
FileName += CDockManager::testConfigFlag(CDockManager::FocusHighlighting)
|
||||
? "focus_highlighting" : "default";
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
FileName += "_linux";
|
||||
#endif
|
||||
FileName += ".css";
|
||||
@@ -510,9 +512,10 @@ CDockManager::CDockManager(QWidget *parent) :
|
||||
d->FocusController = new CDockFocusController(this);
|
||||
}
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
|
||||
window()->installEventFilter(this);
|
||||
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
connect(qApp, &QApplication::focusWindowChanged, [](QWindow* focusWindow)
|
||||
{
|
||||
// bring modal dialogs to foreground to ensure that they are in front of any
|
||||
@@ -552,7 +555,7 @@ CDockManager::~CDockManager()
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
bool CDockManager::eventFilter(QObject *obj, QEvent *e)
|
||||
{
|
||||
// Emulate Qt:Tool behaviour.
|
||||
@@ -629,8 +632,39 @@ bool CDockManager::eventFilter(QObject *obj, QEvent *e)
|
||||
}
|
||||
return Super::eventFilter(obj, e);
|
||||
}
|
||||
#else
|
||||
//============================================================================
|
||||
bool CDockManager::eventFilter(QObject *obj, QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::WindowStateChange)
|
||||
{
|
||||
QWindowStateChangeEvent* ev = static_cast<QWindowStateChangeEvent*>(e);
|
||||
if (ev->oldState().testFlag(Qt::WindowMinimized))
|
||||
{
|
||||
d->IsLeavingMinimized = true;
|
||||
QMetaObject::invokeMethod(this, "endLeavingMinimizedState", Qt::QueuedConnection);
|
||||
}
|
||||
}
|
||||
return Super::eventFilter(obj, e);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockManager::endLeavingMinimizedState()
|
||||
{
|
||||
d->IsLeavingMinimized = false;
|
||||
this->activateWindow();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool CDockManager::isLeavingMinimizedState() const
|
||||
{
|
||||
return d->IsLeavingMinimized;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockManager::registerFloatingWidget(CFloatingDockContainer* FloatingWidget)
|
||||
{
|
||||
|
||||
@@ -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,14 @@ private:
|
||||
friend class CDockAreaTitleBar;
|
||||
friend class CAutoHideDockContainer;
|
||||
friend CAutoHideSideBar;
|
||||
friend CAutoHideTab;
|
||||
friend AutoHideTabPrivate;
|
||||
|
||||
public Q_SLOTS:
|
||||
/**
|
||||
* Ends the isRestoringFromMinimizedState
|
||||
*/
|
||||
void endLeavingMinimizedState();
|
||||
|
||||
|
||||
protected:
|
||||
@@ -180,7 +190,6 @@ public:
|
||||
TabCloseButtonIsToolButton = 0x0040,//! If enabled the tab close buttons will be QToolButtons instead of QPushButtons - disabled by default
|
||||
AllTabsHaveCloseButton = 0x0080, //!< if this flag is set, then all tabs that are closable show a close button
|
||||
RetainTabSizeWhenCloseButtonHidden = 0x0100, //!< if this flag is set, the space for the close button is reserved even if the close button is not visible
|
||||
OpaqueUndocking = 0x0200,///< If enabled, the widgets are immediately undocked into floating widgets, if disabled, only a draw preview is undocked and the real undocking is deferred until the mouse is released
|
||||
DragPreviewIsDynamic = 0x0400,///< If opaque undocking is disabled, this flag defines the behavior of the drag preview window, if this flag is enabled, the preview will be adjusted dynamically to the drop area
|
||||
DragPreviewShowsContentPixmap = 0x0800,///< If opaque undocking is disabled, the created drag preview window shows a copy of the content of the dock widget / dock are that is dragged
|
||||
DragPreviewHasWindowFrame = 0x1000,///< If opaque undocking is disabled, then this flag configures if the drag preview is frameless or looks like a real window
|
||||
@@ -216,7 +225,7 @@ public:
|
||||
|
||||
DefaultOpaqueConfig = DefaultBaseConfig
|
||||
| OpaqueSplitterResize
|
||||
| OpaqueUndocking, ///< the default configuration with opaque operations - this may cause issues if ActiveX or Qt 3D windows are involved
|
||||
| DragPreviewShowsContentPixmap, ///< the default configuration for non opaque operations
|
||||
|
||||
DefaultNonOpaqueConfig = DefaultBaseConfig
|
||||
| DragPreviewShowsContentPixmap, ///< the default configuration for non opaque operations
|
||||
@@ -240,9 +249,12 @@ public:
|
||||
AutoHideButtonCheckable = 0x08, //!< If the flag is set, the auto hide button will be checked and unchecked depending on the auto hide state. Mainly for styling purposes.
|
||||
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
|
||||
|
||||
DefaultAutoHideConfig = AutoHideFeatureEnabled
|
||||
| DockAreaHasAutoHideButton ///< the default configuration for left and right side bars
|
||||
| DockAreaHasAutoHideButton
|
||||
| AutoHideCloseButtonCollapsesDock
|
||||
|
||||
};
|
||||
Q_DECLARE_FLAGS(AutoHideFlags, eAutoHideFlag)
|
||||
|
||||
@@ -540,6 +552,15 @@ public:
|
||||
*/
|
||||
bool isRestoringState() const;
|
||||
|
||||
/**
|
||||
* This function returns true, if the DockManager window is restoring from
|
||||
* minimized state.
|
||||
* The DockManager is in this state starting from the QWindowStateChangeEvent
|
||||
* that signals the state change from minimized to normal until
|
||||
* endLeavingMinimizedState() function is called.
|
||||
*/
|
||||
bool isLeavingMinimizedState() const;
|
||||
|
||||
/**
|
||||
* The distance the user needs to move the mouse with the left button
|
||||
* hold down before a dock widget start floating
|
||||
@@ -561,9 +582,7 @@ public:
|
||||
widget->setFocus(Qt::OtherFocusReason);
|
||||
}
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
bool eventFilter(QObject *obj, QEvent *e) override;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns the dock widget that has focus style in the ui or a nullptr if
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -139,7 +158,7 @@ struct DockOverlayCrossPrivate
|
||||
*/
|
||||
qreal dropIndicatiorWidth(QLabel* l) const
|
||||
{
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
Q_UNUSED(l)
|
||||
return 40;
|
||||
#else
|
||||
@@ -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),
|
||||
@@ -333,7 +403,7 @@ CDockOverlay::CDockOverlay(QWidget* parent, eMode Mode) :
|
||||
{
|
||||
d->Mode = Mode;
|
||||
d->Cross = new CDockOverlayCross(this);
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
|
||||
#else
|
||||
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
|
||||
@@ -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();
|
||||
@@ -595,7 +738,7 @@ CDockOverlayCross::CDockOverlayCross(CDockOverlay* overlay) :
|
||||
d(new DockOverlayCrossPrivate(this))
|
||||
{
|
||||
d->DockOverlay = overlay;
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
|
||||
#else
|
||||
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
|
||||
@@ -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
|
||||
|
||||
@@ -555,6 +555,13 @@ bool CDockWidget::isAutoHide() const
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
SideBarLocation CDockWidget::autoHideLocation() const
|
||||
{
|
||||
return isAutoHide() ? autoHideDockContainer()->sideBarLocation() : SideBarNone;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool CDockWidget::isFloating() const
|
||||
{
|
||||
@@ -622,6 +629,13 @@ void CDockWidget::setMinimumSizeHintMode(eMinimumSizeHintMode Mode)
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
CDockWidget::eMinimumSizeHintMode CDockWidget::minimumSizeHintMode() const
|
||||
{
|
||||
return d->MinimumSizeHintMode;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool CDockWidget::isCentralWidget() const
|
||||
{
|
||||
@@ -643,14 +657,20 @@ void CDockWidget::toggleView(bool Open)
|
||||
// If the dock widget state is different, then we really need to toggle
|
||||
// the state. If we are in the right state, then we simply make this
|
||||
// dock widget the current dock widget
|
||||
auto AutoHideContainer = autoHideDockContainer();
|
||||
if (d->Closed != !Open)
|
||||
{
|
||||
toggleViewInternal(Open);
|
||||
}
|
||||
else if (Open && d->DockArea)
|
||||
else if (Open && d->DockArea && !AutoHideContainer)
|
||||
{
|
||||
raise();
|
||||
}
|
||||
|
||||
if (Open && AutoHideContainer)
|
||||
{
|
||||
AutoHideContainer->collapseView(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -984,14 +1004,20 @@ void CDockWidget::setClosedState(bool Closed)
|
||||
//============================================================================
|
||||
QSize CDockWidget::minimumSizeHint() const
|
||||
{
|
||||
if (d->MinimumSizeHintMode == CDockWidget::MinimumSizeHintFromDockWidget || !d->Widget)
|
||||
if (!d->Widget)
|
||||
{
|
||||
return QSize(60, 40);
|
||||
}
|
||||
else
|
||||
|
||||
switch (d->MinimumSizeHintMode)
|
||||
{
|
||||
return d->Widget->minimumSizeHint();
|
||||
case MinimumSizeHintFromDockWidget: return QSize(60, 40);
|
||||
case MinimumSizeHintFromContent: return d->Widget->minimumSizeHint();
|
||||
case MinimumSizeHintFromDockWidgetMinimumSize: return minimumSize();
|
||||
case MinimumSizeHintFromContentMinimumSize: return d->Widget->minimumSize();
|
||||
}
|
||||
|
||||
return d->Widget->minimumSizeHint();
|
||||
}
|
||||
|
||||
|
||||
@@ -1002,7 +1028,15 @@ void CDockWidget::setFloating()
|
||||
{
|
||||
return;
|
||||
}
|
||||
d->TabWidget->detachDockWidget();
|
||||
|
||||
if (this->isAutoHide())
|
||||
{
|
||||
dockAreaWidget()->setFloating();
|
||||
}
|
||||
else
|
||||
{
|
||||
d->TabWidget->detachDockWidget();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1025,6 +1059,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)
|
||||
{
|
||||
@@ -1171,7 +1221,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))
|
||||
{
|
||||
@@ -1179,20 +1229,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -208,12 +208,17 @@ public:
|
||||
* reimplements minimumSizeHint() function to return a very small minimum
|
||||
* size hint. If you would like to adhere the minimumSizeHint() from the
|
||||
* content widget, then set the minimumSizeHintMode() to
|
||||
* MinimumSizeHintFromContent.
|
||||
* MinimumSizeHintFromContent. If you would like to use the minimumSize()
|
||||
* value of the content widget or the dock widget, then you can use the
|
||||
* MinimumSizeHintFromDockWidgetMinimumSize or
|
||||
* MinimumSizeHintFromContentMinimumSize modes.
|
||||
*/
|
||||
enum eMinimumSizeHintMode
|
||||
{
|
||||
MinimumSizeHintFromDockWidget,
|
||||
MinimumSizeHintFromContent
|
||||
MinimumSizeHintFromContent,
|
||||
MinimumSizeHintFromDockWidgetMinimumSize,
|
||||
MinimumSizeHintFromContentMinimumSize,
|
||||
};
|
||||
|
||||
|
||||
@@ -372,6 +377,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
|
||||
@@ -411,6 +422,11 @@ public:
|
||||
*/
|
||||
void setMinimumSizeHintMode(eMinimumSizeHintMode Mode);
|
||||
|
||||
/**
|
||||
* Get the minimum size hint mode configured by setMinimumSizeHintMode
|
||||
*/
|
||||
eMinimumSizeHintMode minimumSizeHintMode() const;
|
||||
|
||||
/**
|
||||
* Returns true if the dock widget is set as central widget of it's dock manager
|
||||
*/
|
||||
@@ -568,10 +584,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
|
||||
@@ -596,7 +621,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
|
||||
|
||||
@@ -162,9 +162,9 @@ struct DockWidgetTabPrivate
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
IFloatingWidget* createFloatingWidget(T* Widget, bool OpaqueUndocking)
|
||||
IFloatingWidget* createFloatingWidget(T* Widget, bool CreateContainer)
|
||||
{
|
||||
if (OpaqueUndocking)
|
||||
if (CreateContainer)
|
||||
{
|
||||
return new CFloatingDockContainer(Widget);
|
||||
}
|
||||
@@ -312,8 +312,7 @@ bool DockWidgetTabPrivate::startFloating(eDragState DraggingState)
|
||||
ADS_PRINT("startFloating");
|
||||
DragState = DraggingState;
|
||||
IFloatingWidget* FloatingWidget = nullptr;
|
||||
bool OpaqueUndocking = CDockManager::testConfigFlag(CDockManager::OpaqueUndocking) ||
|
||||
(DraggingFloatingWidget != DraggingState);
|
||||
bool CreateContainer = (DraggingFloatingWidget != DraggingState);
|
||||
|
||||
// If section widget has multiple tabs, we take only one tab
|
||||
// If it has only one single tab, we can move the complete
|
||||
@@ -321,12 +320,12 @@ bool DockWidgetTabPrivate::startFloating(eDragState DraggingState)
|
||||
QSize Size;
|
||||
if (DockArea->dockWidgetsCount() > 1)
|
||||
{
|
||||
FloatingWidget = createFloatingWidget(DockWidget, OpaqueUndocking);
|
||||
FloatingWidget = createFloatingWidget(DockWidget, CreateContainer);
|
||||
Size = DockWidget->size();
|
||||
}
|
||||
else
|
||||
{
|
||||
FloatingWidget = createFloatingWidget(DockArea, OpaqueUndocking);
|
||||
FloatingWidget = createFloatingWidget(DockArea, CreateContainer);
|
||||
Size = DockArea->size();
|
||||
}
|
||||
|
||||
@@ -377,6 +376,7 @@ void CDockWidgetTab::mousePressEvent(QMouseEvent* ev)
|
||||
d->DragState = DraggingMousePressed;
|
||||
if (CDockManager::testConfigFlag(CDockManager::FocusHighlighting))
|
||||
{
|
||||
d->focusController()->setDockWidgetTabPressed(true);
|
||||
d->focusController()->setDockWidgetTabFocused(this);
|
||||
}
|
||||
Q_EMIT clicked();
|
||||
@@ -413,7 +413,12 @@ void CDockWidgetTab::mouseReleaseEvent(QMouseEvent* ev)
|
||||
d->FloatingWidget->finishDragging();
|
||||
break;
|
||||
|
||||
default:; // do nothing
|
||||
default:
|
||||
if (CDockManager::testConfigFlag(CDockManager::FocusHighlighting))
|
||||
{
|
||||
d->focusController()->setDockWidgetTabPressed(false);
|
||||
}
|
||||
break; // do nothing
|
||||
}
|
||||
}
|
||||
else if (ev->button() == Qt::MiddleButton)
|
||||
@@ -477,15 +482,13 @@ void CDockWidgetTab::mouseMoveEvent(QMouseEvent* ev)
|
||||
|
||||
|
||||
// Floating is only allowed for widgets that are floatable
|
||||
// If we do non opaque undocking, then can create the drag preview
|
||||
// if the widget is movable.
|
||||
// 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) && !CDockManager::testConfigFlag(CDockManager::OpaqueUndocking)))
|
||||
if (Features.testFlag(CDockWidget::DockWidgetFloatable) || (Features.testFlag(CDockWidget::DockWidgetMovable)))
|
||||
{
|
||||
// If we undock, we need to restore the initial position of this
|
||||
// tab because it looks strange if it remains on its dragged position
|
||||
if (d->isDraggingState(DraggingTab) && !CDockManager::testConfigFlag(CDockManager::OpaqueUndocking))
|
||||
if (d->isDraggingState(DraggingTab))
|
||||
{
|
||||
parentWidget()->layout()->update();
|
||||
}
|
||||
@@ -805,6 +808,7 @@ void CDockWidgetTab::setIconSize(const QSize& Size)
|
||||
d->IconSize = Size;
|
||||
d->updateIcon();
|
||||
}
|
||||
|
||||
} // namespace ads
|
||||
//---------------------------------------------------------------------------
|
||||
// EOF DockWidgetTab.cpp
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
#pragma comment(lib, "User32.lib")
|
||||
#endif
|
||||
#endif
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
#include "linux/FloatingWidgetTitleBar.h"
|
||||
#include <xcb/xcb.h>
|
||||
#endif
|
||||
@@ -374,10 +374,11 @@ struct FloatingDockContainerPrivate
|
||||
QPoint DragStartPos;
|
||||
bool Hiding = false;
|
||||
bool AutoHideChildren = true;
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
QWidget* MouseEventHandler = nullptr;
|
||||
CFloatingWidgetTitleBar* TitleBar = nullptr;
|
||||
bool IsResizing = false;
|
||||
bool MousePressed = false;
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -424,7 +425,7 @@ struct FloatingDockContainerPrivate
|
||||
|
||||
void setWindowTitle(const QString &Text)
|
||||
{
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
if (TitleBar)
|
||||
{
|
||||
TitleBar->setTitle(Text);
|
||||
@@ -498,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())
|
||||
@@ -509,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());
|
||||
}
|
||||
@@ -532,6 +536,7 @@ void FloatingDockContainerPrivate::titleMouseReleaseEvent()
|
||||
DockManager->dockAreaOverlay()->hideOverlay();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void FloatingDockContainerPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
||||
{
|
||||
@@ -540,7 +545,7 @@ void FloatingDockContainerPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
// Prevent display of drop overlays and docking as long as a model dialog
|
||||
// is active
|
||||
if (qApp->activeModalWidget())
|
||||
@@ -585,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);
|
||||
@@ -641,7 +660,7 @@ CFloatingDockContainer::CFloatingDockContainer(CDockManager *DockManager) :
|
||||
connect(d->DockContainer, SIGNAL(dockAreasRemoved()), this,
|
||||
SLOT(onDockAreasAddedOrRemoved()));
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
QDockWidget::setWidget(d->DockContainer);
|
||||
QDockWidget::setFloating(true);
|
||||
QDockWidget::setFeatures(QDockWidget::DockWidgetClosable
|
||||
@@ -674,6 +693,17 @@ CFloatingDockContainer::CFloatingDockContainer(CDockManager *DockManager) :
|
||||
native_window = window_manager != "KWIN";
|
||||
}
|
||||
|
||||
if (native_window)
|
||||
{
|
||||
// Native windows do not work if wayland is used. Ubuntu 22.04 uses wayland by default. To use
|
||||
// native windows, switch to Xorg
|
||||
QString XdgSessionType = qgetenv("XDG_SESSION_TYPE").toLower();
|
||||
if ("wayland" == XdgSessionType)
|
||||
{
|
||||
native_window = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (native_window)
|
||||
{
|
||||
setTitleBarWidget(new QWidget());
|
||||
@@ -752,18 +782,43 @@ CDockContainerWidget* CFloatingDockContainer::dockContainer() const
|
||||
void CFloatingDockContainer::changeEvent(QEvent *event)
|
||||
{
|
||||
Super::changeEvent(event);
|
||||
if ((event->type() == QEvent::ActivationChange) && isActiveWindow())
|
||||
switch (event->type())
|
||||
{
|
||||
ADS_PRINT("FloatingWidget::changeEvent QEvent::ActivationChange ");
|
||||
d->zOrderIndex = ++zOrderCounter;
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
if (d->DraggingState == DraggingFloatingWidget)
|
||||
case QEvent::ActivationChange:
|
||||
if (isActiveWindow())
|
||||
{
|
||||
d->titleMouseReleaseEvent();
|
||||
d->DraggingState = DraggingInactive;
|
||||
}
|
||||
ADS_PRINT("FloatingWidget::changeEvent QEvent::ActivationChange ");
|
||||
d->zOrderIndex = ++zOrderCounter;
|
||||
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
if (d->DraggingState == DraggingFloatingWidget)
|
||||
{
|
||||
d->titleMouseReleaseEvent();
|
||||
d->DraggingState = DraggingInactive;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case QEvent::WindowStateChange:
|
||||
// If the DockManager window is restored from minimized on Windows
|
||||
// then the FloatingWidgets are not properly restored to maximized but
|
||||
// to normal state.
|
||||
// We simply check here, if the FloatingWidget was maximized before
|
||||
// and if the DockManager is just leaving the minimized state. In this
|
||||
// case, we restore the maximized state of this floating widget
|
||||
if (d->DockManager->isLeavingMinimizedState())
|
||||
{
|
||||
QWindowStateChangeEvent* ev = static_cast<QWindowStateChangeEvent*>(event);
|
||||
if (ev->oldState().testFlag(Qt::WindowMaximized))
|
||||
{
|
||||
this->showMaximized();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break; // do nothing
|
||||
}
|
||||
}
|
||||
|
||||
@@ -909,7 +964,7 @@ void CFloatingDockContainer::hideEvent(QHideEvent *event)
|
||||
void CFloatingDockContainer::showEvent(QShowEvent *event)
|
||||
{
|
||||
Super::showEvent(event);
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
if (CDockManager::testConfigFlag(CDockManager::FocusHighlighting))
|
||||
{
|
||||
this->window()->activateWindow();
|
||||
@@ -922,7 +977,7 @@ void CFloatingDockContainer::showEvent(QShowEvent *event)
|
||||
void CFloatingDockContainer::startFloating(const QPoint &DragStartMousePos,
|
||||
const QSize &Size, eDragState DragState, QWidget *MouseEventHandler)
|
||||
{
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
if (!isMaximized())
|
||||
{
|
||||
resize(Size);
|
||||
@@ -974,7 +1029,7 @@ void CFloatingDockContainer::moveFloating()
|
||||
// the main window as the active window for some reason. This fixes
|
||||
// that by resetting the active window to the floating widget after
|
||||
// updating the overlays.
|
||||
QApplication::setActiveWindow(this);
|
||||
activateWindow();
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
@@ -1059,7 +1114,7 @@ bool CFloatingDockContainer::restoreState(CDockingStateReader &Stream,
|
||||
return false;
|
||||
}
|
||||
onDockAreasAddedOrRemoved();
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
if(d->TitleBar)
|
||||
{
|
||||
d->TitleBar->setMaximizedIcon(windowState() == Qt::WindowMaximized);
|
||||
@@ -1097,13 +1152,18 @@ void CFloatingDockContainer::hideAndDeleteLater()
|
||||
d->AutoHideChildren = false;
|
||||
hide();
|
||||
deleteLater();
|
||||
if (d->DockManager)
|
||||
{
|
||||
d->DockManager->removeFloatingWidget(this);
|
||||
d->DockManager->removeDockContainer(this->dockContainer());
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void CFloatingDockContainer::finishDragging()
|
||||
{
|
||||
ADS_PRINT("CFloatingDockContainer::finishDragging");
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
setWindowOpacity(1);
|
||||
activateWindow();
|
||||
if (d->MouseEventHandler)
|
||||
@@ -1207,7 +1267,7 @@ void CFloatingDockContainer::moveEvent(QMoveEvent *event)
|
||||
// the main window as the active window for some reason. This fixes
|
||||
// that by resetting the active window to the floating widget after
|
||||
// updating the overlays.
|
||||
QApplication::setActiveWindow(this);
|
||||
activateWindow();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -1218,7 +1278,7 @@ void CFloatingDockContainer::moveEvent(QMoveEvent *event)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
//============================================================================
|
||||
void CFloatingDockContainer::onMaximizeRequest()
|
||||
{
|
||||
@@ -1287,12 +1347,12 @@ void CFloatingDockContainer::resizeEvent(QResizeEvent *event)
|
||||
Super::resizeEvent(event);
|
||||
}
|
||||
|
||||
static bool s_mousePressed = false;
|
||||
|
||||
//============================================================================
|
||||
void CFloatingDockContainer::moveEvent(QMoveEvent *event)
|
||||
{
|
||||
Super::moveEvent(event);
|
||||
if (!d->IsResizing && event->spontaneous() && s_mousePressed)
|
||||
if (!d->IsResizing && event->spontaneous() && d->MousePressed)
|
||||
{
|
||||
d->setState(DraggingFloatingWidget);
|
||||
d->updateDropOverlays(QCursor::pos());
|
||||
@@ -1308,10 +1368,10 @@ bool CFloatingDockContainer::event(QEvent *e)
|
||||
switch (e->type())
|
||||
{
|
||||
case QEvent::WindowActivate:
|
||||
s_mousePressed = false;
|
||||
d->MousePressed = false;
|
||||
break;
|
||||
case QEvent::WindowDeactivate:
|
||||
s_mousePressed = true;
|
||||
d->MousePressed = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
#include <QRubberBand>
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
#include <QDockWidget>
|
||||
#define tFloatingWidgetBase QDockWidget
|
||||
#else
|
||||
@@ -182,10 +182,8 @@ protected: // reimplements QWidget
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
virtual bool event(QEvent *e) override;
|
||||
virtual void moveEvent(QMoveEvent *event) override;
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
virtual void moveEvent(QMoveEvent *event) override;
|
||||
#elif defined(Q_OS_UNIX)
|
||||
virtual void moveEvent(QMoveEvent *event) override;
|
||||
virtual void resizeEvent(QResizeEvent *event) override;
|
||||
virtual bool event(QEvent *e) override;
|
||||
@@ -264,7 +262,7 @@ public:
|
||||
*/
|
||||
void hideAndDeleteLater();
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
/**
|
||||
* This is a function that responds to FloatingWidgetTitleBar::maximizeRequest()
|
||||
* Maximize or normalize the container size.
|
||||
@@ -300,7 +298,6 @@ public:
|
||||
*/
|
||||
bool hasNativeTitleBar();
|
||||
#endif
|
||||
|
||||
}; // class FloatingDockContainer
|
||||
}
|
||||
// namespace ads
|
||||
|
||||
@@ -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;
|
||||
@@ -72,6 +75,42 @@ struct FloatingDragPreviewPrivate
|
||||
* outside of any drop area
|
||||
*/
|
||||
void createFloatingWidget();
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
return DockWidget->features();
|
||||
}
|
||||
|
||||
CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(Content);
|
||||
if (DockArea)
|
||||
{
|
||||
return DockArea->features();
|
||||
}
|
||||
|
||||
return CDockWidget::DockWidgetFeatures();
|
||||
}
|
||||
};
|
||||
// struct LedArrayPanelPrivate
|
||||
|
||||
@@ -106,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)
|
||||
{
|
||||
@@ -120,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
|
||||
@@ -129,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
|
||||
@@ -158,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)
|
||||
@@ -229,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))
|
||||
{
|
||||
@@ -242,14 +295,12 @@ CFloatingDragPreview::CFloatingDragPreview(QWidget* Content, QWidget* parent) :
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
}
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
auto Flags = windowFlags();
|
||||
Flags |= Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint;
|
||||
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
|
||||
@@ -328,30 +379,38 @@ void CFloatingDragPreview::finishDragging()
|
||||
{
|
||||
ADS_PRINT("CFloatingDragPreview::finishDragging");
|
||||
|
||||
cleanupAutoHideContainerWidget();
|
||||
|
||||
auto DockDropArea = d->DockManager->dockAreaOverlay()->visibleDropAreaUnderCursor();
|
||||
auto ContainerDropArea = d->DockManager->containerOverlay()->visibleDropAreaUnderCursor();
|
||||
bool ValidDropArea = (DockDropArea != InvalidDockWidgetArea) || (ContainerDropArea != InvalidDockWidgetArea);
|
||||
|
||||
// Non floatable auto hide widgets should stay in its current auto hide
|
||||
// state if they are dragged into a floating window
|
||||
if (ValidDropArea || d->isContentFloatable())
|
||||
{
|
||||
cleanupAutoHideContainerWidget(ContainerDropArea);
|
||||
}
|
||||
|
||||
if (!d->DropContainer)
|
||||
{
|
||||
d->createFloatingWidget();
|
||||
}
|
||||
else if (DockDropArea != InvalidDockWidgetArea)
|
||||
{
|
||||
d->DropContainer->dropWidget(d->Content, DockDropArea, d->DropContainer->dockAreaAt(QCursor::pos()));
|
||||
d->DropContainer->dropWidget(d->Content, DockDropArea, d->DropContainer->dockAreaAt(QCursor::pos()),
|
||||
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
|
||||
{
|
||||
@@ -365,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();
|
||||
}
|
||||
|
||||
|
||||
@@ -390,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,7 @@
|
||||
<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>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#include "IconProvider.h"
|
||||
#include "ads_globals.h"
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
#include <QSettings>
|
||||
#include <QFile>
|
||||
#include <QApplication>
|
||||
@@ -52,7 +52,7 @@ namespace internal
|
||||
{
|
||||
const int FloatingWidgetDragStartEvent = QEvent::registerEventType();
|
||||
const int DockedWidgetDragStartEvent = QEvent::registerEventType();
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
static QString _window_manager;
|
||||
static QHash<QString, xcb_atom_t> _xcb_atom_cache;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
@@ -371,7 +412,7 @@ void setButtonIcon(QAbstractButton* Button, QStyle::StandardPixmap StandarPixmap
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
Button->setIcon(Button->style()->standardIcon(StandarPixmap));
|
||||
#else
|
||||
// The standard icons does not look good on high DPI screens so we create
|
||||
|
||||
@@ -38,7 +38,9 @@
|
||||
#include <QStyle>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#include <iostream>
|
||||
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
#include <xcb/xcb.h>
|
||||
#endif
|
||||
|
||||
@@ -80,14 +82,26 @@ 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,
|
||||
@@ -154,7 +168,7 @@ static const char* const DirtyProperty = "dirty";
|
||||
extern const int FloatingWidgetDragStartEvent;
|
||||
extern const int DockedWidgetDragStartEvent;
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
// Utils to directly communicate with the X server
|
||||
/**
|
||||
* Get atom from cache or request it from the XServer.
|
||||
@@ -192,6 +206,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
|
||||
@@ -210,6 +225,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
|
||||
|
||||
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_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 |