Compare commits

...

134 Commits

Author SHA1 Message Date
Gary Wang
985ff74ccf feat: config flag to avoid QtADS using Qt StyleSheet (#835)
Resolve: githubuser0xFFFF/Qt-Advanced-Docking-System#833
2026-04-23 22:44:23 +02:00
Michael Jackson
a9aa10f4c2 BUG: Fixes overrides a destructor but is not marked 'override' (#836)
- If compiling with flag [-Werror,-Winconsistent-missing-destructor-override]
2026-04-23 22:43:02 +02:00
Lee Jae-Jin
7b30229355 feat: add preferred auto-hide sidebar location per dock widget (#829)
Add preferredAutoHideSideBarLocation property to CDockWidget that allows
applications to specify where a widget should be pinned, overriding
geometry-based detection. When unpinning, widgets with the same preferred
location merge as tabs instead of creating new splits.

Default is SideBarNone (existing geometry-based behavior preserved).
2026-04-05 09:03:15 +02:00
Luca
4a0b636148 Make all tab text readable in dark mode (753) (#828) 2026-04-05 08:59:35 +02:00
Andreas Ringlstetter
544c624f07 Unbind containers from DockManager to prevent accidental reuse before deletion (#823) 2026-04-05 08:58:29 +02:00
ma-robox
bbde511603 Toggling visibility of floating docked windows protected against external hide/show cycle by QWebEngineView. (#821)
Co-authored-by: AlbertoM <ma-robox@users.noreply.github.com>
2026-03-10 18:34:45 +01:00
Ruben de Bruin
ee3a526adb Fixes handling of native / alien widgets when (un)docking (#820)
* Initial plan

* Fix drawing artifacts when content widgets call winId()

When a content widget (e.g. VTK/OpenGL) calls winId() to get a native
window handle, Qt propagates native-window creation up the ancestor chain.
This makes CDockWidget, CDockAreaWidget, and CDockContainerWidget all
become native OS windows unexpectedly. Reparenting these native dock
widgets during floating or resizing then causes drawing artifacts.

Fix: set Qt::WA_DontCreateNativeAncestors on the content widget in
CDockWidget::setWidget() to stop native-window creation from propagating
up into the dock hierarchy.

Co-authored-by: RubendeBruin <34062862+RubendeBruin@users.noreply.github.com>

* Fix docking system to handle mix of native and alien Qt widgets

Three targeted fixes for the native/alien widget mixing problem:

1. Revert WA_DontCreateNativeAncestors from CDockWidget::setWidget().
   Setting it on the content widget created a broken native-inside-alien
   hierarchy: the QScrollArea (alien) could not clip its native child, so
   content escaped the scrollbox bounds; and alien CAutoHideDockContainer
   could not appear above the native content widget.
   Allowing natural propagation means QScrollArea also goes native, and OS
   parent/child window clipping works correctly.

2. Fix CDockContainerWidget::removeDockArea to use internalWinId() instead
   of testAttribute(WA_NativeWindow). WA_NativeWindow is only set when a
   widget is explicitly made native; widgets that became native through
   upward propagation from a descendant calling winId() have a real native
   window handle (internalWinId() != 0) but WA_NativeWindow may be unset.
   Setting their parent to nullptr would create a free-floating invisible
   OS window and cause drawing artifacts.

3. Fix CAutoHideDockContainer::collapseView: when the parent dock container
   is native but the auto-hide panel is still alien, promote the panel to a
   native window (winId()) before raise(). The OS always renders native
   child windows above a parent window's painted alien content, so an alien
   auto-hide panel can never appear above native sibling dock areas. Once
   the panel has its own OS-level window, raise() operates on OS Z-order
   and correctly places it above native content siblings.

Co-authored-by: RubendeBruin <34062862+RubendeBruin@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-03-10 18:34:08 +01:00
Alessandro de Jesus
e2c960238d Fixed Undock Button getting hidden after undocking and docking again a floating widget that contains only one single visble dock area (#816) 2026-03-08 08:11:09 +01:00
ZFail
62bc6fced7 Fixes that allows use project as submodule (#815)
* Fix ADS_VERSION support for builds without git dependency

- Move CMAKE_MODULE_PATH outside if(NOT ADS_VERSION) block so it's always available
- Parse ADS_VERSION to set PROJECT_VERSION_* variables for Versioning.cmake
- Update Versioning.cmake to use predefined version when available, fallback to git

This allows building with -DADS_VERSION=X.Y.Z without requiring git repository.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* Add ADS_PLATFORM_DIR option to customize output directory

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: ArtemNabok <nabok.artem@yandex.ru>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-03-08 08:10:51 +01:00
Andreas Ringlstetter
dd83812b29 Toogle visibility of custom title bar based on fullscreen state (#814) 2026-02-16 21:51:40 +01:00
André Meyer
88db64451e FloatingDockContainer uses windowIcon from parent Widgets before falling back to QApplication (#812) 2026-02-11 06:02:56 +01:00
André Vautour
1a96a06cb6 Account for the tabs height when they are at the bottom. (#811)
Thank you
2026-02-11 06:01:01 +01:00
zhulongcc
00f88d9666 fix: Fix copy-paste errors in configflags CMakeLists. (#810) 2026-02-06 05:43:37 +01:00
mborgerson
664d02edd4 Raise dialogs only if they are modal (#808) 2026-02-06 05:41:12 +01:00
vhutter
72e5c566b7 Fix label color in CDockWidgetTab in dark mode (#804) 2026-01-27 06:37:17 +01:00
André Vautour
e78133b7b2 Update title bar label when the widget's title changes. (#798) 2026-01-15 21:42:18 +01:00
André Vautour
f9ad1d7801 Use Native Windows (#797)
* Avoid changing to a top-level window when moving a native window.

* Support using native windows for the dock/area widgets.
2026-01-15 21:39:51 +01:00
Boris Barbulovski
34b68d6eab Change git command working directory to this project (#796)
If this project is used as subproject of another CMake project, then git commands will fail because git will be executed from wrong location.
2026-01-13 07:00:14 +01:00
Boris Barbulovski
f8143d5419 Conditionally add Windows version resources (#795) 2026-01-11 21:20:35 +01:00
Uwe Kindler
d01ffe3bee Removed superfluous appveyour badge 2026-01-11 18:21:54 +01:00
Uwe Kindler
87cffe5d40 Updated New and Noteworthy in README.md for new feature TabsAtBottom 2026-01-11 17:59:34 +01:00
Uwe Kindler
d47d87e4b8 Updated showcase section for PiSoWorks application 2026-01-11 17:53:19 +01:00
Uwe Kindler
3b0f6f92a9 Updated TabsAtBottom documentation 2026-01-11 17:49:13 +01:00
Uwe Kindler
12cb417682 Removed appveyor and travis CI support 2026-01-11 17:48:50 +01:00
Uwe Kindler
a674eea1cd Merge branch 'master' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System 2025-11-26 08:53:10 +01:00
Uwe Kindler
a2854a7740 Added cmake modules to integrate version information into Windows DLLs 2025-11-26 08:51:22 +01:00
Uwe Kindler
cd984881e5 Improved raising of dock widget application on linux. 2025-11-24 22:15:42 +01:00
Michael Jackson
eb22a9aef6 COMP: Fix warnings about override on public destructors (#788) 2025-11-12 08:22:45 +01:00
Ivan Ugryumov
d709230510 Replace qDebug with ADS_PRINT (#787) 2025-11-10 20:44:55 +01:00
hormnek
d467b21960 Fix qApp connection (#778) 2025-10-09 21:27:30 +02:00
anoy.
893af516b2 Remove GuiPrivate dependency for Windows builds (#777) 2025-10-09 21:26:38 +02:00
Uwe Kindler
9fd5002886 Added documentation for TabsAtBottom flag 2025-09-26 22:08:14 +02:00
Uwe Kindler
39c8407e0c Updated autohidedragndrop example to use new TabsAtBottom config flag 2025-09-26 21:52:49 +02:00
Vautour, André
e922a1e5bc Updated the title label styling in all of the stylesheets. 2025-09-24 13:48:26 -03:00
Vautour, André
66e10e022b Don't show title bar for floating widgets with tabs at bottom. 2025-09-24 09:36:38 -03:00
Vautour, André
3342fd6596 Support tabs at the bottom of dock widgets. 2025-09-23 16:38:44 -03:00
Uwe Kindler
c1977c51fa Added PySoWorks to showcase section 2025-09-17 22:00:47 +02:00
Jan Grulich
dc1e76d60c Introduce SOVERSION for ABI compatibility (#771)
This commit sets the library's SOVERSION to its major version number.

Setting the soname this way establishes a clear ABI promise. This allows
users to safely upgrade to minor or patch releases without needing to
recompile their applications, as long as the major version remains the
same.
2025-09-10 13:43:55 +02:00
Nicolas Elie
6c073b2833 Add gui-private include dirs for Qt5 (#768) 2025-09-03 08:50:03 +02:00
TheComet
11004ebaa0 Fix C++23 Warnings (#764)
Co-authored-by: Alexander Murray <alexander.murray@franke.com>
2025-08-25 20:09:04 +02:00
Uwe Kindler
2583408420 Removed color from release badge because orange is used for releases < 1.0 2025-08-22 10:25:20 +02:00
Uwe Kindler
dec0442007 Fixed issue #762 - Context menu entries for DockWidget tab missing for last dock widget 2025-08-22 10:07:21 +02:00
Michael Jackson
c020f82a6c BUG: Fixes Linux + Qt 6.9 cmake configuration and linker errors (#752)
Signed-off-by: Michael Jackson <mike.jackson@bluequartz.net>
2025-06-13 10:16:17 +02:00
Uwe Kindler
c1555c30cc Merge branch 'master' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System 2025-06-12 15:45:06 +02:00
Cole Beezley
d6cb127320 Fixed typo in DockContainerWidget.h (#750) 2025-06-12 15:02:41 +02:00
Uwe Kindler
c2373eb7de Updated documentation link in README.md 2025-06-12 15:01:44 +02:00
Uwe Kindler
d5843ff7d3 Documented the use of Qt::AA_ShareOpenGLContexts when using OpenGL with ADS 2025-06-12 14:55:31 +02:00
Uwe Kindler
c135782001 Updated examples and demo to use createDockWidget() function for dock manager instead of deprecated DockWidgetr constructor 2025-06-12 14:50:16 +02:00
Uwe Kindler
79c208da4f Added documentation for xfce4 focus stealing issue 2025-06-12 14:18:50 +02:00
Uwe Kindler
b67c4a0c84 Added Scrutiny Debugger to showcase section 2025-06-12 14:01:12 +02:00
Uwe Kindler
6b9105b813 Added showcase image for scrutiny 2025-06-12 13:34:30 +02:00
Uwe Kindler
6c6e0333a9 Merge branch 'ci-dev' 2025-06-11 23:14:57 +02:00
Uwe Kindler
d55387d087 Added windows-cmake.yml file 2025-06-11 23:08:33 +02:00
Uwe Kindler
bf9560f8ea Updated README.md with workflow badges 2025-06-11 23:01:33 +02:00
Uwe Kindler
949ed40006 Updated mingw tool to mingw1310 2025-06-11 22:33:21 +02:00
Uwe Kindler
f2a9dd4db4 Updated Windows workflow to use Qt MinGW 9 2025-06-01 19:53:32 +02:00
Uwe Kindler
ed67081b74 Removed caching from MinGW build 2025-06-01 18:21:41 +02:00
Uwe Kindler
705d931231 Updated MinGW build 2025-06-01 18:17:57 +02:00
Uwe Kindler
d1367c9dd4 Updated the MinGW build 2025-06-01 18:16:17 +02:00
Uwe Kindler
31402ee9f8 Updated windows-cmake.yml to use bundled Qt MinGW toolchain 2025-06-01 18:10:16 +02:00
Uwe Kindler
b7cbac88b3 Merge branch 'ci-dev' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System into ci-dev 2025-06-01 17:56:34 +02:00
Uwe Kindler
fe8c88771f Swicthed MinGW build from Ninja to MinGW 2025-06-01 17:56:23 +02:00
githubuser0xFFFF
befcd9eadf Update windows-cmake.yml 2025-06-01 17:41:30 +02:00
Uwe Kindler
46e5aea61c Updated arch 2025-06-01 17:20:26 +02:00
Uwe Kindler
103db689ff Updated CI MinGW Qt version to 6.8.2 2025-06-01 17:11:54 +02:00
Uwe Kindler
bc34470d3c Updated windows-cmake.yml 2025-06-01 17:07:17 +02:00
Uwe Kindler
646bddfea3 Workaround bug in install-qt-action 2025-06-01 16:57:59 +02:00
Uwe Kindler
ec196715e0 Removed non working windows-cmake.yml workflow 2025-06-01 13:46:33 +02:00
Uwe Kindler
cb63f0e6ea And another try 2025-06-01 12:12:23 +02:00
Uwe Kindler
c941b2dfde Updated MinGW build to work properly 2025-06-01 12:08:37 +02:00
Uwe Kindler
671b932804 An another try 2025-06-01 12:03:55 +02:00
Uwe Kindler
f76d3b4834 And another try 2025-06-01 11:59:28 +02:00
Uwe Kindler
c248f79971 And another try 2025-06-01 11:58:13 +02:00
Uwe Kindler
0566677a9d Updated workflow 2025-06-01 11:52:11 +02:00
Uwe Kindler
268998961b Updated windows-cmake.yml 2025-06-01 11:48:50 +02:00
Uwe Kindler
716d6f7f25 Updated run command in yaml for MSVC 2025-06-01 11:15:26 +02:00
Uwe Kindler
ceb7c91844 Updated workflow file to fix wrong CMake detection of MSVC 2025-06-01 11:06:38 +02:00
Uwe Kindler
0a78dcf460 Add workflow to build with CMake and MSVC / MinGW on Windows 2025-06-01 10:48:14 +02:00
Uwe Kindler
da7d23c127 Merge branch 'master' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System 2025-06-01 10:39:10 +02:00
Michael Jackson
64d80b2c53 LIC: Move installation of license file to share/ads folder (#748)
Signed-off-by: Michael A. Jackson <mike.jackson@bluequartz.net>
2025-05-30 20:19:14 +02:00
githubuser0xFFFF
f2a029a0c6 Update linux-builds.yml 2025-05-08 22:03:21 +02:00
githubuser0xFFFF
c1b60959ae Update linux-builds.yml 2025-05-08 21:59:12 +02:00
githubuser0xFFFF
d53728c0a8 Update linux-builds.yml 2025-05-08 21:45:55 +02:00
githubuser0xFFFF
a7ad4386e4 Update linux-builds.yml 2025-05-08 21:37:14 +02:00
Pier-Yves Lessard
4e90a38c52 Remove dangling pointer to tab widget when a dock widget is removed from autohide side bar (#740) 2025-05-08 21:18:11 +02:00
Uwe Kindler
4947548224 Merge branch 'master' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System 2025-05-08 21:06:32 +02:00
FelixBer
991b69cc51 fix compile with Qt 6.9.0 - qplatformnativeinterface.h missing (#736)
Co-authored-by: fb <f@b.com>
2025-04-23 19:10:16 +02:00
Federico Fuga
df1fa27127 Fix nasty and still unclear bug with "Close Other" not closing all tabs in certain conditions. (#725) 2025-03-17 10:38:10 +01:00
Uwe Kindler
936eba01cd Bring all floating widgets to foreground on Linux if a dockwidget is
dragged
2025-03-14 11:45:50 +01:00
Uwe Kindler
9f8dd99cac Improved fix #722 - it now works always even if focus highlighting is
disabled
2025-03-13 14:19:47 +01:00
Uwe Kindler
90e5adde29 Fixed #722 - Ensure that application is in front of other application what dragging floating windows 2025-03-07 09:59:24 +01:00
André Meyer
ddbed9ea14 Always show TitleBar if it contains any explicit actions (#720) 2025-03-07 08:55:42 +01:00
Josiah Bills
c305432ab2 Fixed crash caused by unparented widgets after restoring layout. (#724)
This is essentially due to `setDockArea` undoing the earlier
`setParent`.
2025-03-07 08:52:48 +01:00
Uwe Kindler
e836b154eb Fixed #711 - Focus loss when closing other dock widgets 2025-03-06 14:59:36 +01:00
githubuser0xFFFF
782589523e Update linux-builds.yml
Updated actions/cache@v1 to actions/cache@v3
2025-03-06 13:24:13 +01:00
Talley Lambert
bb105d2ef6 Mention pyqt6 bindings in readme (#723) 2025-03-03 21:38:40 +01:00
Michael Jackson
483bb7354a DOC: Update DREAM3D-NX information and screen shot (#712)
Signed-off-by: Michael Jackson <mike.jackson@bluequartz.net>
2025-02-07 10:03:16 +01:00
anoy.
7d9f9b43a7 update minimum CMake version to 3.16 (#710) 2025-02-05 11:52:17 +01:00
Uwe Kindler
7fd5cbe9d7 Improved user-guide.md 2025-01-16 08:07:08 +01:00
luzpaz
a16d17a8bf Fix various typos (#692)
* Fix various typos
Found via `codespell -q 3 -L te,ridiculus,varius`

* Add another typo fix
2025-01-15 09:00:47 +01:00
Uwe Kindler
faf24cd531 Implemented issue #694 - added auto hide configuration flag AutoHideCloseOnOutsideMouseClick 2025-01-15 08:37:43 +01:00
Uwe Kindler
979d76aa47 Imporved user guide - added documentation for some undocumented flags. 2024-12-20 11:09:11 +01:00
Uwe Kindler
0a55bcd586 Updated README.md to use the new factory function CDockManager::createDockWidget() 2024-12-20 10:35:22 +01:00
Uwe Kindler
f41a6f06fe Merge branch 'master' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System 2024-12-20 10:27:35 +01:00
Uwe Kindler
349d584228 Adjusted MyDockAreaTitleBar source code style 2024-12-20 10:26:59 +01:00
Uwe Kindler
fcad7763ff Add factory method to Dock manager as an alternative method to create DockWidget, supporting custom factory 2024-12-20 10:21:57 +01:00
Uwe Kindler
1bec4234c3 Added support for componentsFactory per dock manager 2024-12-20 10:12:46 +01:00
Nolan Kramer
0be5ba8cf6 Fix issue with windeployqt (#683)
* Fix issue with windeployqt

* Rename library to requested format
2024-12-13 21:57:00 +01:00
Uwe Kindler
7245dced84 Added new config flag DoubleClickUndocksWidget to configure if double clicking a DockWidget tab or titlebar undocks the widget 2024-12-12 15:38:29 +01:00
Uwe Kindler
e2f611ea9a CDockAreaTitleBar::resizeEvent function to fix issue #656 2024-12-12 14:53:24 +01:00
Ivan Ugryumov
1f21eb0200 Improved tab bar scrolling (#678)
* Improved tab bar scrolling

* Fix: tab bar scroll for mouse
2024-12-12 13:13:01 +01:00
Federico Fuga
f2378636e2 Add ability to customize the DockArea Title Bar and DockWidget Tab context menu 2024-11-20 15:38:39 +01:00
Federico Fuga
509b2356d1 Fix missing declarations 2024-11-20 15:38:21 +01:00
Uwe Kindler
30b802bd10 Fixed Qt5 build issues 2024-11-20 15:31:31 +01:00
Uwe Kindler
e857421fdf Added all build* subfolders to .gitignore 2024-10-28 15:41:46 +01:00
Uwe Kindler
8dcdc8fad2 Improved autohidedragndrop example to check, if it also works when dragging with multiple auto hide tabs 2024-10-28 15:40:32 +01:00
Uwe Kindler
f964ce2c68 Refactored, fixed and improved drag hover functionality 2024-10-28 15:39:29 +01:00
Uwe Kindler
eb9b439d11 Added support for setting config parameters to CDockManager 2024-10-28 15:30:29 +01:00
TheBoje
a13ed7e4d6 Add AutoHideDragNDrop example 2024-10-22 22:36:53 +02:00
TheBoje
8cfa5c8e0e Fix formatting#2 (#663) 2024-10-04 22:27:15 +02:00
TheBoje
2878559ee6 Fix formatting (#663) 2024-10-04 22:23:40 +02:00
TheBoje
6ff39bccf8 Add open auto-hide dock on hover from drag and drop (#663) 2024-10-04 22:17:42 +02:00
gavininfinity
952131a1e9 Make startDragging public (#658) 2024-08-19 07:37:51 +02:00
Uwe Kindler
5edbcc1970 Fixed issue #654 - Wheel event on DockAreaTabBar 2024-07-25 08:42:30 +02:00
Uwe Kindler
04f6d9168e Fixed #642 - The floating window can not back to normal size after maximizing it 2024-07-08 14:32:33 +02:00
Uwe Kindler
cea1327dac Fixed #653 - DisablingTabTextEliding not letting DockAreaDynamicTabsMenuButtonVisibility to function and program crashes 2024-07-08 12:15:00 +02:00
Uwe Kindler
1c41cbff82 Fixed issue #641 - Unexpected behaviour with tab drag on scrollable tab bar 2024-07-08 10:43:02 +02:00
invisibleGG
06e8451fc0 Update DockAreaTabBar.cpp (#640)
This fix seems to have introduced a regression when _this is deleted before the lambda slot occurred, for example deleting the DockManager (and consequently _this) immediately after the execution of updateTabs function (we encountered this problem in linux)
2024-06-03 08:29:59 +02:00
Uwe Kindler
3ff6918b1f Added configflags example to test use of CDockManager config flags 2024-05-21 08:37:35 +02:00
Uwe Kindler
ac3af4c6cd Merge branch 'master' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System 2024-05-08 14:44:44 +02:00
Uwe Kindler
41bb861417 Fixed problem in AutoHideSideBar that prevented the dock container, that contained a vertical sidebar with many tabs, from shrinking vertically 2024-05-08 14:43:53 +02:00
Stefan Gerlach
6e63418798 Fix "extra ;" warning (#624) 2024-04-08 11:40:06 +02:00
Nicolas Elie
65781b7cac Include GNUInstallDirs for CMAKE_INSTALL_* vars to be defined (#621) 2024-04-03 23:49:37 +02:00
Nicolas Elie
d7e6c613c6 Update PyQt bindings to 4.3.0 (#622) 2024-04-03 23:49:08 +02:00
96 changed files with 2408 additions and 826 deletions

View File

@@ -1,151 +0,0 @@
version: '{build}'
branches:
only:
- master
image: Visual Studio 2017
environment:
global:
# Appveyor doesn't have Qt 12 yet
LatestQtVersion: 5.13
matrix:
# 32 bit builds
# MSVC 2015 builds
# Dynamic Library builds
# LTS version of Qt, dll, 32bit, MSVC 2015, qmake
- QT5: C:\Qt\%LatestQtVersion%\msvc2017
COMPILER: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build
targetPlatform: x86
use_mingw: "false"
use_static: "false"
use_cmake: "false"
# LTS version of Qt, dll, 32bit, MSVC 2015, cmake
- QT5: C:\Qt\%LatestQtVersion%\msvc2017
COMPILER: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build
targetPlatform: x86
use_mingw: "false"
use_static: "false"
use_cmake: "true"
# end Dynamic Library builds
# Static Library builds
# LTS version of Qt, static, 32bit, MSVC 2015, qmake
- QT5: C:\Qt\%LatestQtVersion%\msvc2017
COMPILER: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build
targetPlatform: x86
use_mingw: "false"
use_static: "true"
use_cmake: "false"
# LTS version of Qt, static, 32bit, MSVC 2015, cmake
- QT5: C:\Qt\%LatestQtVersion%\msvc2017
COMPILER: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build
targetPlatform: x86
use_mingw: "false"
use_static: "true"
use_cmake: "true"
# end Static Library builds
# end MSVC 2015 builds
# MinGW builds
# Dynamic Library builds
# LTS version of Qt, dll, 32bit, MinGW, qmake
- QT5: C:\Qt\%LatestQtVersion%\mingw73_32
COMPILER: C:\Qt\Tools\mingw730_32
targetPlatform: x86
use_mingw: "true"
use_static: "false"
use_cmake: "false"
# LTS version of Qt, dll, 32bit, MinGW, cmake
- QT5: C:\Qt\%LatestQtVersion%\mingw73_32
COMPILER: C:\Qt\Tools\mingw730_32
targetPlatform: x86
use_mingw: "true"
use_static: "false"
use_cmake: "true"
# end Dynamic Library builds
# Static Library builds
# LTS version of Qt, static, 32bit, MinGW, qmake
- QT5: C:\Qt\%LatestQtVersion%\mingw73_32
COMPILER: C:\Qt\Tools\mingw730_32
targetPlatform: x86
use_mingw: "true"
use_static: "true"
use_cmake: "false"
# LTS version of Qt, static, 32bit, MinGW, cmake
- QT5: C:\Qt\%LatestQtVersion%\mingw73_32
COMPILER: C:\Qt\Tools\mingw730_32
targetPlatform: x86
use_mingw: "true"
use_static: "true"
use_cmake: "true"
# end Static Library builds
# end MinGW builds
# end 32 bit builds
# 64 bit builds
# MSVC 2015 builds
# Dynamic Library builds
# LTS version of Qt, dll, 64bit, MSVC 2015, qmake
- QT5: C:\Qt\%LatestQtVersion%\msvc2017_64
COMPILER: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build
targetPlatform: amd64
use_mingw: "false"
use_static: "false"
use_cmake: "false"
# LTS version of Qt, dll, 64bit, MSVC 2015, cmake
- QT5: C:\Qt\%LatestQtVersion%\msvc2017_64
COMPILER: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build
targetPlatform: amd64
use_mingw: "false"
use_static: "false"
use_cmake: "true"
# end Dynamic Library builds
# Static Library builds
# LTS version of Qt, static, 64bit, MSVC 2015, qmake
- QT5: C:\Qt\%LatestQtVersion%\msvc2017_64
COMPILER: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build
targetPlatform: amd64
use_mingw: "false"
use_static: "true"
use_cmake: "false"
# LTS version of Qt, static, 64bit, MSVC 2015, cmake
- QT5: C:\Qt\%LatestQtVersion%\msvc2017_64
COMPILER: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build
targetPlatform: amd64
use_mingw: "false"
use_static: "true"
use_cmake: "true"
# end Static Library builds
# end MSVC 2015 builds
# end 64 bit builds
matrix:
fast_finish: true
before_build:
- set originalWD=%CD%
- call "%QT5%\bin\qtenv2.bat"
- cd /D %originalWD%
- if %use_mingw%==false call "%COMPILER%\vcvarsall.bat" %targetPlatform%
- if %use_static%==true (set USESTATIC=ON) else (set USESTATIC=OFF)
- if %use_mingw%==true (set CMAKEGENERATOR="MinGW Makefiles") else (set CMAKEGENERATOR="NMake Makefiles")
- if %use_mingw%==true (set MAKEENGINE=mingw32-make) else (set MAKEENGINE=nmake)
- if %use_mingw%==true set PATH=%PATH:C:\Program Files\Git\usr\bin;=%
build_script:
- if %use_cmake%==true mkdir build
- if %use_cmake%==true cd build
- if %use_cmake%==true cmake --version
- if %use_cmake%==true cmake -G %CMAKEGENERATOR% -DCMAKE_BUILD_TYPE=DEBUG -DBUILD_EXAMPLES=ON -DCMAKE_DEBUG_POSTFIX=d -DBUILD_STATIC=%USESTATIC% -DCMAKE_INSTALL_PREFIX="./installed" ../
- if %use_cmake%==true cmake --build .
- if %use_cmake%==true cmake --build . --target install
- if %use_cmake%==true cmake -G %CMAKEGENERATOR% -DCMAKE_BUILD_TYPE=RELEASE -DBUILD_EXAMPLES=ON -DBUILD_STATIC=%USESTATIC% -DCMAKE_INSTALL_PREFIX="./installed" ../
- if %use_cmake%==true cmake --build .
- if %use_cmake%==true cmake --build . --target install
- if %use_cmake%==false if %use_static%==true qmake "CONFIG+=adsBuildStatic"
- if %use_cmake%==false if %use_static%==false qmake
- if %use_cmake%==false %MAKEENGINE% debug
- if %use_cmake%==false %MAKEENGINE% install
- if %use_cmake%==false %MAKEENGINE% release
- if %use_cmake%==false %MAKEENGINE% install
after_build:
- if %use_mingw%==true set PATH=C:\Program Files\Git\usr\bin;%PATH%

View File

@@ -1,26 +1,51 @@
name: linux-builds
on: [push]
on:
push:
workflow_dispatch:
jobs:
build:
strategy:
matrix:
os: [ubuntu-20.04]
build_ubuntu_2204_cmake:
runs-on: ubuntu-22.04
runs-on: ${{ matrix.os }}
env:
QT_VERSION: 6.4.2
QT_DIR: ${{ github.workspace }}/Qt
steps:
- uses: actions/checkout@v1
- name: install qt
- name: Checkout source
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch full history and tags
- name: Install dependencies
run: |
sudo apt-get update --fix-missing
sudo apt-get install qt5-default
sudo apt-get install qtbase5-private-dev qtdeclarative5-dev
- name: qmake
run: qmake
- name: make
run: make -j4
sudo apt-get update
sudo apt-get install -y build-essential cmake ninja-build libgl1-mesa-dev libxkbcommon-x11-0 libx11-dev
- name: Install Qt
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
target: desktop
host: linux
arch: gcc_64
dir: ${{ env.QT_DIR }}
setup-python: false
- name: Configure with CMake
run: |
cmake -S . -B build \
-DCMAKE_PREFIX_PATH="${{ env.QT_DIR }}/Qt/${{ env.QT_VERSION }}/gcc_64" \
-DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/install \
-DCMAKE_BUILD_TYPE=Release \
-G Ninja
- name: Build
run: cmake --build build
- name: Run CMake install (optional)
run: cmake --install build
build_ubuntu_2204:
runs-on: ubuntu-22.04
@@ -28,7 +53,7 @@ jobs:
- uses: actions/checkout@v2
- name: Cache Qt
id: cache-qt-6-4
uses: actions/cache@v1 # not v2!
uses: actions/cache@v3
with:
path: ../Qt/6.4.2
key: ${{ runner.os }}-QtCache-Qt6-4

102
.github/workflows/windows-cmake.yml vendored Normal file
View File

@@ -0,0 +1,102 @@
name: windows-builds
on:
push:
workflow_dispatch:
jobs:
build_windows_msvc:
name: Build with MSVC and Ninja
runs-on: windows-2022
env:
QT_VERSION: 6.4.2
QT_DIR: ${{ github.workspace }}\Qt
steps:
- name: 📦 Checkout source code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: ⚙️ Install Ninja build system
run: choco install ninja --no-progress
- name: 📥 Install Qt for MSVC
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
target: desktop
host: windows
arch: win64_msvc2019_64
dir: ${{ env.QT_DIR }}
setup-python: false
- name: 🏗️ Setup MSVC Developer Environment
uses: TheMrMilchmann/setup-msvc-dev@v3
with:
arch: x64
- name: 🛠️ Configure CMake with Ninja + MSVC
run: |
cmake -S . -B build -G Ninja `
-DCMAKE_PREFIX_PATH="${{ env.QT_DIR }}\Qt\${{ env.QT_VERSION }}\msvc2019_64" `
-DCMAKE_INSTALL_PREFIX="${{ github.workspace }}\install" `
-DCMAKE_BUILD_TYPE=Release
shell: powershell
- name: 🔨 Build with Ninja + MSVC
run: cmake --build build
shell: powershell
- name: 📦 Install built files
run: cmake --install build
shell: powershell
build_windows_mingw:
name: Build with Qt's MinGW and CMake (no Ninja)
runs-on: windows-2022
env:
QT_VERSION: 6.8.3
QT_DIR: ${{ github.workspace }}\Qt
steps:
- name: 📦 Checkout source code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: 📥 Install Qt + MinGW
uses: jurplel/install-qt-action@v4
with:
aqtversion: '==3.1.19'
version: ${{ env.QT_VERSION }}
target: desktop
host: windows
arch: win64_mingw
dir: ${{ env.QT_DIR }}
tools: 'tools_mingw1310'
setup-python: false
- name: Add Qt-bundled MinGW to PATH
shell: powershell
run: |
echo "${{ env.QT_DIR }}\Tools\mingw1310_64\bin" >> $env:GITHUB_PATH
- name: 🛠️ Configure CMake (MinGW)
shell: powershell
run: |
cmake -S . -B build-mingw `
-DCMAKE_PREFIX_PATH="${{ env.QT_DIR }}\Qt\${{ env.QT_VERSION }}\mingw_64" `
-DCMAKE_INSTALL_PREFIX=${{ github.workspace }}\install `
-DCMAKE_BUILD_TYPE=Release `
-G "MinGW Makefiles"
- name: 🔨 Build with CMake (MinGW)
shell: powershell
run: cmake --build build-mingw -- -j2
- name: 📦 Install built files (MinGW)
shell: powershell
run: cmake --install build-mingw

2
.gitignore vendored
View File

@@ -9,7 +9,7 @@ ui_*
Makefile
*.dll
*.a
build-*
build*
# IDEs
.idea

View File

@@ -1,233 +0,0 @@
language: cpp
# gcc is clang on mac
compiler: gcc
matrix:
fast_finish: true
include:
- name: Ubuntu qmake Qt5.5.1
os: linux
dist: trusty
group: stable
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:beineri/opt-qt551-trusty'
update: true
packages:
- qt55base
- qt55tools
- gcc-9
- g++-9
script:
- PATH="/opt/qt55/bin:$PATH"
- CXX="g++-9"
- CC="gcc-9"
- qt55-env.sh
- qmake
- make
- make install
- name: Ubuntu qmake dll
os: linux
dist: bionic
group: stable
services:
- xvfb
compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:beineri/opt-qt-5.14.2-bionic'
update: true
packages:
- qt514base
- qt514tools
- gcc-9
- g++-9
- libc6-i386
- libgl-dev
- libgl1-mesa-dev
- mesa-common-dev
script:
- PATH="/opt/qt514/bin:$PATH"
- CXX="g++-9"
- CC="gcc-9"
- qt514-env.sh
- qmake
- make
- make install
- name: Ubuntu qmake static
os: linux
dist: bionic
group: stable
services:
- xvfb
compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:beineri/opt-qt-5.14.2-bionic'
update: true
packages:
- qt514base
- qt514tools
- gcc-9
- g++-9
- libc6-i386
- libgl-dev
- libgl1-mesa-dev
- mesa-common-dev
script:
- PATH="/opt/qt514/bin:$PATH"
- CXX="g++-9"
- CC="gcc-9"
- qt514-env.sh
- qmake "CONFIG+=adsBuildStatic"
- make
- make install
- name: Ubuntu CMake dll
os: linux
dist: bionic
group: stable
services:
- xvfb
compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:beineri/opt-qt-5.14.2-bionic'
update: true
packages:
- qt514base
- qt514tools
- gcc-9
- g++-9
- libc6-i386
- libgl-dev
- libgl1-mesa-dev
- mesa-common-dev
script:
- PATH="/opt/qt514/bin:$PATH"
- CXX="g++-9"
- CC="gcc-9"
- qt514-env.sh
- mkdir ./build
- cd ./build
- cmake --version
- cmake -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=RELEASE -DBUILD_STATIC=OFF -DBUILD_EXAMPLES=ON -DCMAKE_INSTALL_PREFIX="./installed" ../
- cmake --build .
- cmake --build . --target install
- cmake -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=DEBUG -DBUILD_STATIC=OFF -DBUILD_EXAMPLES=ON -DCMAKE_DEBUG_POSTFIX=d -DCMAKE_INSTALL_PREFIX="./installed" ../
- cmake --build .
- cmake --build . --target install
- name: Ubuntu CMake Static
os: linux
dist: bionic
group: stable
services:
- xvfb
compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:beineri/opt-qt-5.14.2-bionic'
update: true
packages:
- qt514base
- qt514tools
- gcc-9
- g++-9
- libc6-i386
- libgl-dev
- libgl1-mesa-dev
- mesa-common-dev
script:
- PATH="/opt/qt514/bin:$PATH"
- CXX="g++-9"
- CC="gcc-9"
- qt514-env.sh
- mkdir ./build
- cd ./build
- cmake --version
- cmake -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=RELEASE -DBUILD_STATIC=ON -DBUILD_EXAMPLES=ON -DCMAKE_INSTALL_PREFIX="./installed" ../
- cmake --build .
- cmake --build . --target install
- cmake -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=DEBUG -DBUILD_STATIC=ON -DBUILD_EXAMPLES=ON -DCMAKE_DEBUG_POSTFIX=d -DCMAKE_INSTALL_PREFIX="./installed" ../
- cmake --build .
- cmake --build . --target install
- name: macOS CMake dll
os: osx
osx_image: xcode11.3
compiler: clang
addons:
homebrew:
packages:
- qt
update: true
script:
- PATH="/usr/local/opt/qt5/bin:$PATH"
- mkdir -p build
- cd build
- cmake --version
- cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=DEBUG -DCMAKE_DEBUG_POSTFIX=_debug -DBUILD_EXAMPLES=ON -DBUILD_STATIC=OFF -DCMAKE_INSTALL_PREFIX="./installed" ../
- cmake --build .
- cmake --build . --target install
- cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=RELEASE -DBUILD_EXAMPLES=ON -DBUILD_STATIC=OFF -DCMAKE_INSTALL_PREFIX="./installed" ../
- cmake --build .
- cmake --build . --target install
- name: macOS CMake static
os: osx
osx_image: xcode11.3
compiler: clang
addons:
homebrew:
packages:
- qt
update: true
script:
- PATH="/usr/local/opt/qt5/bin:$PATH"
- mkdir -p build
- cd build
- cmake --version
- cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=DEBUG -DCMAKE_DEBUG_POSTFIX=_debug -DBUILD_EXAMPLES=ON -DBUILD_STATIC=ON -DCMAKE_INSTALL_PREFIX="./installed" ../
- cmake --build .
- cmake --build . --target install
- cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=RELEASE -DBUILD_EXAMPLES=ON -DBUILD_STATIC=ON -DCMAKE_INSTALL_PREFIX="./installed" ../
- cmake --build .
- cmake --build . --target install
- name: macOS qmake dll
os: osx
osx_image: xcode11.3
compiler: clang
addons:
homebrew:
packages:
- qt
update: true
script:
- PATH="/usr/local/opt/qt5/bin:$PATH"
- qmake
- make
- make install
- name: macOS qmake static
os: osx
osx_image: xcode11.3
compiler: clang
addons:
homebrew:
packages:
- qt
update: true
script:
- PATH="/usr/local/opt/qt5/bin:$PATH"
- qmake "CONFIG+=adsBuildStatic"
- make
- make install
notifications:
email: false

View File

@@ -1,26 +1,35 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.16)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
if (POLICY CMP0091)
cmake_policy(SET CMP0091 NEW)
endif (POLICY CMP0091)
# Add cmake modules path (required for Versioning.cmake and git revision description)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules ${CMAKE_MODULE_PATH})
# By default, the version information is extracted from the git index. However,
# we can override this behavior by explicitly setting ADS_VERSION and
# skipping the git checks. This is useful for cases where this project is being
# used independently of its original git repo (e.g. vendored in another project)
if(NOT ADS_VERSION)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules ${CMAKE_MODULE_PATH})
include(GetGitRevisionDescription)
git_describe(GitTagVersion --tags)
string(REGEX REPLACE "^([0-9]+)\\..*" "\\1" VERSION_MAJOR "${GitTagVersion}")
string(REGEX REPLACE "^[0-9]+\\.([0-9]+).*" "\\1" VERSION_MINOR "${GitTagVersion}")
string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" VERSION_PATCH "${GitTagVersion}")
set(VERSION_SHORT "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
set(VERSION_SONAME "${VERSION_MAJOR}")
else()
string(REGEX MATCHALL "[\.]" VERSION_DOT_MATCHES ${ADS_VERSION})
list(LENGTH VERSION_DOT_MATCHES VERSION_DOT_COUNT)
if(VERSION_DOT_COUNT EQUAL 2)
set(VERSION_SHORT ${ADS_VERSION})
string(REGEX REPLACE "^([0-9]+)\\..*" "\\1" VERSION_SONAME "${ADS_VERSION}")
# Set PROJECT_VERSION_* variables for Versioning.cmake
string(REGEX MATCHALL "[0-9]+" VERSION_PARTS "${ADS_VERSION}")
list(GET VERSION_PARTS 0 PROJECT_VERSION_MAJOR)
list(GET VERSION_PARTS 1 PROJECT_VERSION_MINOR)
list(GET VERSION_PARTS 2 PROJECT_VERSION_PATCH)
else()
message(FATAL_ERROR "ADS_VERSION must be in major.minor.patch format, e.g. 3.8.1. Got ${ADS_VERSION}")
endif()
@@ -32,11 +41,16 @@ project(QtADS LANGUAGES CXX VERSION ${VERSION_SHORT})
option(BUILD_STATIC "Build the static library" OFF)
option(BUILD_EXAMPLES "Build the examples" ON)
# Platform directory: auto-detected based on pointer size, or manually set
if(NOT ADS_PLATFORM_DIR)
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4")
set(ads_PlatformDir "x86")
else()
set(ads_PlatformDir "x64")
endif()
else()
set(ads_PlatformDir "${ADS_PLATFORM_DIR}")
endif()
add_subdirectory(src)

104
README.md
View File

@@ -4,10 +4,10 @@
------------------
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/githubuser0xFFFF/Qt-Advanced-Docking-System?color=%23ff9833)](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/releases/latest)
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/githubuser0xFFFF/Qt-Advanced-Docking-System)](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/releases/latest)
[![License: LGPL v2.1](https://img.shields.io/badge/License-LGPL%20v2.1-blue.svg)](gnu-lgpl-v2.1.md)
[![Build status](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/workflows/linux-builds/badge.svg)](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/actions?query=workflow%3Alinux-builds)
[![Build status](https://ci.appveyor.com/api/projects/status/qcfb3cy932jw9mpy/branch/master?svg=true)](https://ci.appveyor.com/project/githubuser0xFFFF/qt-advanced-docking-system/branch/master)
[![windows-builds](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/actions/workflows/windows-cmake.yml/badge.svg?branch=master)](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/actions/workflows/windows-cmake.yml)
[![GitHub contributors](https://img.shields.io/github/contributors/githubuser0xFFFF/Qt-Advanced-Docking-System?color=ffdf00)](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/graphs/contributors)
Qt Advanced Docking System lets you create customizable layouts using a full
@@ -15,13 +15,25 @@ featured window docking system similar to what is found in many popular
integrated development environments (IDEs) such as Visual Studio.
- [What's new...](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/releases/latest)
- [Documentation](doc/user-guide.md)
- Original Repository: https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System
- [Documentation](https://githubuser0xffff.github.io/Qt-Advanced-Docking-System/doc/user-guide.html)
- Original Repository: [https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System)
[![Video Advanced Docking](doc/advanced-docking_video.png)](https://www.youtube.com/watch?v=7pdNfafg3Qc)
## New and Noteworthy
### Release 4.5
#### Tabs at Bottom
A new global dock manager flag `TabsAtBottom` has been added to configuration flags. This flag allows to configure if the tabs of dock areas are shown at the top (default) or at the bottom of the respective container.
If the flag is set, tabs will be shown at the bottom instead of in the title bar.
![TabsAtBottom true](doc/cfg_flag_TabsAtBottom_true.png)
### Release 4.1
Release [4.1](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/releases/latest) significantly improves the Auto-Hide functionality and also brings improvements
for Drag and Drop of dock widgets into dock area tabs. These are the highlights of the new version:
@@ -141,6 +153,9 @@ know it from Visual Studio.
### Overview
- [New and Noteworthy](#new-and-noteworthy)
- [Release 4.5](#release-45)
- [Tabs at Bottom](#tabs-at-bottom)
- [Release 4.1](#release-41)
- [Drag \& Drop to Auto-Hide](#drag--drop-to-auto-hide)
- [Auto-Hide Tab Insertion Order](#auto-hide-tab-insertion-order)
- [Auto-Hide Tab Sorting](#auto-hide-tab-sorting)
@@ -161,6 +176,7 @@ know it from Visual Studio.
- [Auto-Hide Functionality](#auto-hide-functionality)
- [Python Bindings](#python-bindings)
- [PySide6](#pyside6)
- [PyQt6](#pyqt6)
- [PyQt5](#pyqt5)
- [Tested Compatible Environments](#tested-compatible-environments)
- [Supported Qt Versions](#supported-qt-versions)
@@ -189,8 +205,10 @@ know it from Visual Studio.
- [RDE Robox Development Environment](#rde--robox-development-environment)
- [ResInsight](#resinsight)
- [ADTF 3](#adtf-3)
- [DREAM.3D NX](#dream3d-nx)
- [DREAM3D-NX](#dream3d-nx)
- [LabPlot](#labplot)
- [Scrutiny Debugger](#scrutiny-debugger)
- [PiSoWorks](#pisoworks)
- [Alternative Docking System Implementations](#alternative-docking-system-implementations)
- [KDDockWidgets](#kddockwidgets)
- [QtitanDocking](#qtitandocking)
@@ -252,6 +270,7 @@ If this flag is cleared, the widget resizing is deferred until the mouse button
In contrast to the standard Qt docking system, docking with the ADS works more like a drag & drop operation. That means, the dragged dock widget or dock area is not undocked immediately. Instead, a drag preview widget is created and dragged around to indicate the future position of the dock widget or dock area. The actual dock operation is only executed when the mouse button is released. That makes it possible, to cancel an active drag operation with the escape key.
The drag preview widget can be configured by a number of global dock manager flags:
- `DragPreviewIsDynamic`: if this flag is enabled, the preview will be adjusted dynamically to the drop area
- `DragPreviewShowsContentPixmap`: the created drag preview window shows a static copy of the content of the dock widget / dock are that is dragged
- `DragPreviewHasWindowFrame`: this flag configures if the drag preview is frameless like a QRubberBand or looks like a real window
@@ -308,7 +327,7 @@ More about the auto hide configuration options in the [online documentation...](
![Python Logo](doc/python_logo.png)
Thanks to the contribution of several users, the Advanced Docking System comes
with a complete Python integration. Python bindings are available for **PyQt5** and
with a complete Python integration. Python bindings are available for **PyQt5**, **PyQt6**, and
**PySide6**.
### PySide6
@@ -321,13 +340,30 @@ pip install PySide6-QtAds
```
Sample code is available [here](https://github.com/mborgerson/Qt-Advanced-Docking-System/tree/pyside6/examples). To run the samples, you'll also need to install latest qtpy
from source (pip install https://github.com/spyder-ide/qtpy/archive/refs/heads/master.zip).
from source (pip install <https://github.com/spyder-ide/qtpy/archive/refs/heads/master.zip>).
The PySide6 bindings were contributed by:
- [mborgerson](https://github.com/mborgerson)
Please file PySide6-QtAds-specific issues on its [pyside6_qtads](https://github.com/mborgerson/pyside6_qtads) fork for tracking. For more information about the PySide6 bindings read [this](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/298) issue.
### PyQt6
A PyQt6 ADS package is available via PyPi and can be installed on Windows,
macOS, and Linux with:
```bash
pip install PyQt6Ads
```
Sample code is available [here](https://github.com/pyapp-kit/PyQt6Ads/tree/main/examples).
The PyQt6 bindings were contributed by:
- [tlambert03](https://github.com/tlambert03)
Please file PyQt6Ads-specific issues at [pyapp-kit/PyQt6Ads](https://github.com/pyapp-kit/PyQt6Ads).
### PyQt5
A package is available via [conda-forge](https://github.com/conda-forge/pyqtads-feedstock).
@@ -351,21 +387,19 @@ The library supports **Qt5** and **Qt6**.
### Windows
Windows 10 [![Build status](https://ci.appveyor.com/api/projects/status/qcfb3cy932jw9mpy/branch/master?svg=true)](https://ci.appveyor.com/project/githubuser0xFFFF/qt-advanced-docking-system/branch/master)
Windows 10 / 11
[![windows-builds](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/actions/workflows/windows-cmake.yml/badge.svg?branch=master)](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/actions/workflows/windows-cmake.yml)
The library was developed on and for Windows. It is used in a commercial Windows application and is therefore constantly tested.
### macOS
macOS [![Build Status](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System.svg?branch=master)](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System)
The application can be compiled for macOS. A user reported, that the library works on macOS. If have not tested it.
![Advanced Docking on macOS](doc/macos.png)
### Linux
[![Build Status](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System.svg?branch=master)](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System)
[![Build status](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/workflows/linux-builds/badge.svg)](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/actions?query=workflow%3Alinux-builds)
Unfortunately, there is no such thing as a Linux operating system. Linux is a heterogeneous environment with a variety of different distributions. So it is not possible to support "Linux" like it is possible for Windows. It is only possible to support and test a small subset of Linux distributions. The library can be compiled for and has been developed and tested with some Linux distributions. Depending on the used window manager or compositor, dock widgets
@@ -462,7 +496,7 @@ MainWindow::MainWindow(QWidget *parent) :
// Create the dock manager after the ui is setup. Because the
// parent parameter is a QMainWindow the dock manager registers
// itself as the central widget as such the ui must be set up first.
m_DockManager = new ads::CDockManager(this);
DockManager = new ads::CDockManager(this);
// Create example content label - this can be any application specific
// widget
@@ -473,7 +507,7 @@ MainWindow::MainWindow(QWidget *parent) :
// Create a dock widget with the title Label 1 and set the created label
// as the dock widget content
ads::CDockWidget* DockWidget = new ads::CDockWidget("Label 1");
ads::CDockWidget* DockWidget = DockManager->createDockWidget("Label 1");
DockWidget->setWidget(l);
// Add the toggleViewAction of the dock widget to the menu to give
@@ -481,7 +515,7 @@ MainWindow::MainWindow(QWidget *parent) :
ui->menuView->addAction(DockWidget->toggleViewAction());
// Add the dock widget to the top dock widget area
m_DockManager->addDockWidget(ads::TopDockWidgetArea, DockWidget);
DockManager->addDockWidget(ads::TopDockWidgetArea, DockWidget);
}
MainWindow::~MainWindow()
@@ -582,7 +616,7 @@ highlights are:
- Simple Drag & Drop user interface.
- Load data from file.
- Connect to live streaming of data.
- Save the visualization layout and configurations to re-use them later.
- Save the visualization layout and configurations to reuse them later.
- Fast OpenGL visualization.
- Can handle thousands of timeseries and millions of data points.
- Transform your data using a simple editor: derivative, moving average, integral, etc…
@@ -667,15 +701,17 @@ says about the switch to Qt Advanced Docking:
![ADTF](doc/showcase_adtf.png)
### [DREAM.3D NX](https://github.com/BlueQuartzSoftware/DREAM3D)
### [DREAM3D-NX](https://www.dream3d.io)
DREAM.3D *(Digital Representation Environment for Analysis of Materials in 3D)* is an open source, cross-platform and modular, software suite that allows users to prepare, reconstruct, quantify, instantiate, and mesh, multidimensional, multimodal microstructural data, as well as many other applications.
DREAM3D-NX *(Digital Representation Environment for Analysis of Materials in 3D)* is a cross-platform and modular, software suite that allows users to prepare, reconstruct, quantify, instantiate, and mesh, multidimensional, multimodal microstructural data, as well as many other applications.
[BlueQuartz Software](http://www.bluequartz.net/) is currently completely rewriting the DREAM.3D application. For the upcoming version **[DREAM3D NX](http://www.dream3d.io/)** they improved the UI by using the Advanced Docking System. An [early version](http://www.dream3d.io/) of **DREAM3D NX** with ADS is already available to any user who would like to take the brand new version out for a spin.
[BlueQuartz Software](http://www.bluequartz.net/) has completely rewritten the old DREAM.3D version 6.5 application
taking advantage of the Advanced Docking System to present a highly customizable user interface
for DREAM3D-NX Version 7.
![DREAM.3D NX](doc/showcase_dream3d_nx.png)
[read more...](http://dream3d.bluequartz.net/)
[read more...](http://www.dream3d.io/)
### [LabPlot](https://labplot.kde.org/)
@@ -687,6 +723,36 @@ The LabPlot project recently switched to the Qt Advanced Docking System for thei
[read more...](https://labplot.kde.org/)
### [Scrutiny Debugger](https://scrutinydebugger.com/)
Scrutiny is an [open source](https://github.com/scrutinydebugger/) non-intrusive, real-time debugger for embedded systems, built for fast introspection, memory access, and signal visualization—without stopping your application. It uses the Qt Advanced Docking System (ADS) to provide fully customizable dashboards for monitoring and control.
Some of the highlights are:
- **Debug without interfering** — Inspect C++ memory live without disrupting execution flow.
- **HIL testing made easy** — Write to variables through the GUI or SDK to simulate conditions.
- **Configure during production** — Access and tweak variables anytime via GUI or Python.
- **Catch fast events** — Embedded graphs sample at task-level frequency, even with multithreading.
- **Build your dashboard** — Use ADS to create and save custom layouts for your debug sessions.
- **No JTAG needed** — Communicates over serial, CAN, or network interfaces.
- **Compact C++11 library** — Lightweight and easy to integrate into your firmware.
- **Live graphs and runtime values** — Visualize variables, RPVs, and aliases in real time.
ADS powers Scrutinys flexible interface, letting users organize views and data panels to suit their workflow — ideal for real-time monitoring, testing, and debugging.
[read more...](https://scrutinydebugger.com/)
[![Scrutiny Debugger UI](doc/showcase_scrutiny-dark.png)](https://www.youtube.com/watch?v=Dd3osxW-Clo)
### [PiSoWorks](https://pypi.org/project/pisoworks/)
PiSoWorks is an application for controlling the piezo amplifiers, such as the [NV200/D](https://www.piezosystem.com/product/nv-200-d-compact-amplifier/), from [piezosystem jena](https://www.piezosystem.com/) GmbH.
![LabPlot](doc/showcase_pysoworks.png)
[read more...](https://piezosystemjena.github.io/PiSoWorks/)
## Alternative Docking System Implementations
If this Qt Advanced Docking System does not fit to your needs you may consider some of the alternative docking system solutions for Qt.

View File

@@ -0,0 +1,29 @@
#include <windows.h>
VS_VERSION_INFO VERSIONINFO
FILEVERSION @PROJECT_VERSION_MAJOR@,@PROJECT_VERSION_MINOR@,@PROJECT_VERSION_PATCH@,0
PRODUCTVERSION @PROJECT_VERSION_MAJOR@,@PROJECT_VERSION_MINOR@,@PROJECT_VERSION_PATCH@,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP
FILESUBTYPE 0
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "My Company\0"
VALUE "FileDescription", "@PROJECT_NAME@\0"
VALUE "FileVersion", "@PROJECT_VERSION_STRING@\0"
VALUE "ProductVersion", "@PROJECT_VERSION_STRING@\0"
VALUE "GitCommitFull", "@PROJECT_GIT_HASH@\0"
VALUE "GitCommitShort", "@PROJECT_GIT_HASH_SHORT@\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0409, 1200
END
END

View File

@@ -0,0 +1,100 @@
# ============================================================
# Versioning.cmake (Reusable Version + Resource Generator)
# ============================================================
# Freeze the directory where this module lives
# This is critical — it prevents paths from breaking when the
# function is invoked from other CMakeLists.txt files.
set(_VERSIONING_MODULE_DIR "${CMAKE_CURRENT_LIST_DIR}" CACHE INTERNAL "Versioning module directory")
# ------------------------------------------------------------
# Extract version information from Git or use predefined version
# ------------------------------------------------------------
if(NOT DEFINED PROJECT_VERSION_MAJOR OR NOT DEFINED PROJECT_VERSION_MINOR OR NOT DEFINED PROJECT_VERSION_PATCH)
# Get tag (expected: v1.2.3 or 1.2.3 or 1.2.3-12-gHASH)
execute_process(
COMMAND git describe --tags --dirty
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE GIT_DESC_RAW
OUTPUT_STRIP_TRAILING_WHITESPACE
)
# Remove leading "v" if present
string(REGEX REPLACE "^v" "" GIT_DESC "${GIT_DESC_RAW}")
# Extract major.minor.patch
string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.([0-9]+)" _ "${GIT_DESC}")
set(PROJECT_VERSION_MAJOR "${CMAKE_MATCH_1}")
set(PROJECT_VERSION_MINOR "${CMAKE_MATCH_2}")
set(PROJECT_VERSION_PATCH "${CMAKE_MATCH_3}")
# Commit hash (full + short)
execute_process(
COMMAND git rev-parse HEAD
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE PROJECT_GIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
COMMAND git rev-parse --short HEAD
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE PROJECT_GIT_HASH_SHORT
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif()
set(PROJECT_VERSION_STRING
"${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}"
)
# Export variables to parent scope
set(PROJECT_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}" PARENT_SCOPE)
set(PROJECT_VERSION_MINOR "${PROJECT_VERSION_MINOR}" PARENT_SCOPE)
set(PROJECT_VERSION_PATCH "${PROJECT_VERSION_PATCH}" PARENT_SCOPE)
set(PROJECT_VERSION_STRING "${PROJECT_VERSION_STRING}" PARENT_SCOPE)
set(PROJECT_GIT_HASH "${PROJECT_GIT_HASH}" PARENT_SCOPE)
set(PROJECT_GIT_HASH_SHORT "${PROJECT_GIT_HASH_SHORT}" PARENT_SCOPE)
# Public variable for users
set(PROJECT_AUTO_VERSION "${PROJECT_VERSION_STRING}" PARENT_SCOPE)
# ------------------------------------------------------------
# Reusable function: Attach Windows version resources to target
# ------------------------------------------------------------
function(add_windows_version_resources target)
if(NOT WIN32)
return()
endif()
if(NOT TARGET "${target}")
message(FATAL_ERROR "add_windows_version_resources: target '${target}' not found.")
endif()
# Absolute path to the template (never changes)
get_filename_component(_rc_in
"${_VERSIONING_MODULE_DIR}/FileVersionInfo.rc.in"
ABSOLUTE
)
if(NOT EXISTS "${_rc_in}")
message(FATAL_ERROR
"FileVersionInfo.rc.in missing at: ${_rc_in}"
)
endif()
# Output in the caller's binary dir
set(_rc_out "${CMAKE_CURRENT_BINARY_DIR}/${target}_version.rc")
get_filename_component(_rc_out "${_rc_out}" ABSOLUTE)
# Ensure directory exists
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
# Configure the template
configure_file("${_rc_in}" "${_rc_out}" @ONLY)
# Add to the target
target_sources(${target} PRIVATE "${_rc_out}")
endfunction()

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.16)
project(ads_demo VERSION ${VERSION_SHORT})
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
@@ -27,7 +27,7 @@ target_link_libraries(AdvancedDockingSystemDemo PUBLIC Qt${QT_VERSION_MAJOR}::Co
if(WIN32 AND QT_VERSION_MAJOR LESS 6)
target_link_libraries(AdvancedDockingSystemDemo PUBLIC Qt${QT_VERSION_MAJOR}::AxContainer)
endif()
target_link_libraries(AdvancedDockingSystemDemo PRIVATE qt${QT_VERSION_MAJOR}advanceddocking)
target_link_libraries(AdvancedDockingSystemDemo PRIVATE qtadvanceddocking-qt${QT_VERSION_MAJOR})
set_target_properties(AdvancedDockingSystemDemo PROPERTIES
AUTOMOC ON
AUTORCC ON

View File

@@ -75,18 +75,17 @@
#endif
#endif
#include "DockManager.h"
#include "DockWidget.h"
#include "DockAreaWidget.h"
#include "DockAreaTitleBar.h"
#include "DockAreaTabBar.h"
#include "FloatingDockContainer.h"
#include "DockAreaTitleBar.h"
#include "DockAreaWidget.h"
#include "DockComponentsFactory.h"
#include "StatusDialog.h"
#include "DockManager.h"
#include "DockSplitter.h"
#include "DockWidget.h"
#include "FloatingDockContainer.h"
#include "ImageViewer.h"
#include "MyDockAreaTitleBar.h"
#include "StatusDialog.h"
/**
* Returns a random number from 0 to highest - 1
@@ -147,7 +146,7 @@ public:
using Super = ads::CDockComponentsFactory;
ads::CDockAreaTitleBar* createDockAreaTitleBar(ads::CDockAreaWidget* DockArea) const override
{
auto TitleBar = new ads::CDockAreaTitleBar(DockArea);
auto TitleBar = new MyDockAreaTitleBar(DockArea);
auto CustomButton = new QToolButton(DockArea);
CustomButton->setToolTip(QObject::tr("Help"));
CustomButton->setIcon(svgIcon(":/adsdemo/images/help_outline.svg"));
@@ -237,7 +236,7 @@ struct MainWindowPrivate
m->setRootPath(QDir::currentPath());
w->setModel(m);
w->setRootIndex(m->index(QDir::currentPath()));
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Filesystem %1")
ads::CDockWidget* DockWidget = DockManager->createDockWidget(QString("Filesystem %1")
.arg(FileSystemCount++));
DockWidget->setWidget(w);
DockWidget->setIcon(svgIcon(":/adsdemo/images/folder_open.svg"));
@@ -258,7 +257,7 @@ struct MainWindowPrivate
{
static int CalendarCount = 0;
QCalendarWidget* w = new QCalendarWidget();
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Calendar %1").arg(CalendarCount++));
ads::CDockWidget* DockWidget = DockManager->createDockWidget(QString("Calendar %1").arg(CalendarCount++));
// The following lines are for testing the setWidget() and takeWidget()
// functionality
DockWidget->setWidget(w);
@@ -303,7 +302,7 @@ struct MainWindowPrivate
.arg(LabelCount)
.arg(QTime::currentTime().toString("hh:mm:ss:zzz")));
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Label %1").arg(LabelCount++));
ads::CDockWidget* DockWidget = DockManager->createDockWidget(QString("Label %1").arg(LabelCount++));
DockWidget->setWidget(l);
DockWidget->setIcon(svgIcon(":/adsdemo/images/font_download.svg"));
ui.menuView->addAction(DockWidget->toggleViewAction());
@@ -321,7 +320,7 @@ struct MainWindowPrivate
w->setPlaceholderText("This is an editor. If you close the editor, it will be "
"deleted. Enter your text here.");
w->setStyleSheet("border: none");
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Editor %1").arg(EditorCount++));
ads::CDockWidget* DockWidget = DockManager->createDockWidget(QString("Editor %1").arg(EditorCount++));
DockWidget->setWidget(w);
DockWidget->setIcon(svgIcon(":/adsdemo/images/edit.svg"));
DockWidget->setFeature(ads::CDockWidget::CustomCloseHandling, true);
@@ -364,7 +363,7 @@ struct MainWindowPrivate
auto Result = w->loadFile(FileName);
qDebug() << "loadFile result: " << Result;
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Image Viewer %1").arg(ImageViewerCount++));
ads::CDockWidget* DockWidget = DockManager->createDockWidget(QString("Image Viewer %1").arg(ImageViewerCount++));
DockWidget->setIcon(svgIcon(":/adsdemo/images/photo.svg"));
DockWidget->setWidget(w,ads:: CDockWidget::ForceNoScrollArea);
auto ToolBar = DockWidget->createDefaultToolBar();
@@ -379,7 +378,7 @@ struct MainWindowPrivate
{
static int TableCount = 0;
auto w = new CMinSizeTableWidget();
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Table %1").arg(TableCount++));
ads::CDockWidget* DockWidget = DockManager->createDockWidget(QString("Table %1").arg(TableCount++));
static int colCount = 5;
static int rowCount = 30;
w->setColumnCount(colCount);
@@ -397,7 +396,7 @@ struct MainWindowPrivate
DockWidget->setMinimumSizeHintMode(ads::CDockWidget::MinimumSizeHintFromContent);
auto ToolBar = DockWidget->createDefaultToolBar();
auto Action = ToolBar->addAction(svgIcon(":/adsdemo/images/fullscreen.svg"), "Toggle Fullscreen");
QObject::connect(Action, &QAction::triggered, [=]()
QObject::connect(Action, &QAction::triggered, [DockWidget]()
{
if (DockWidget->isFullScreen())
{
@@ -418,7 +417,7 @@ struct MainWindowPrivate
ads::CDockWidget *createQQuickWidget()
{
QQuickWidget *widget = new QQuickWidget();
ads::CDockWidget *dockWidget = new ads::CDockWidget("Quick");
ads::CDockWidget *dockWidget = DockManager->createDockWidget("Quick");
dockWidget->setWidget(widget);
return dockWidget;
}
@@ -433,7 +432,7 @@ struct MainWindowPrivate
{
static int ActiveXCount = 0;
QAxWidget* w = new QAxWidget("{6bf52a52-394a-11d3-b153-00c04f79faa6}", parent);
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Active X %1").arg(ActiveXCount++));
ads::CDockWidget* DockWidget = DockManager->createDockWidget(QString("Active X %1").arg(ActiveXCount++));
DockWidget->setWidget(w);
ui.menuView->addAction(DockWidget->toggleViewAction());
return DockWidget;
@@ -471,12 +470,12 @@ void MainWindowPrivate::createContent()
appendFeaturStringToWindowTitle(FileSystemWidget);
// Test custom factory - we inject a help button into the title bar
ads::CDockComponentsFactory::setFactory(new CCustomComponentsFactory());
DockManager->setComponentsFactory(new CCustomComponentsFactory());
auto TopDockArea = DockManager->addDockWidget(ads::TopDockWidgetArea, FileSystemWidget);
// Uncomment the next line if you would like to test the
// HideSingleWidgetTitleBar functionality
// TopDockArea->setDockAreaFlag(ads::CDockAreaWidget::HideSingleWidgetTitleBar, true);
ads::CDockComponentsFactory::resetDefaultFactory();
DockManager->setComponentsFactory(ads::CDockComponentsFactory::factory());
// We create a calendar widget and clear all flags to prevent the dock area
// from closing
@@ -511,7 +510,7 @@ void MainWindowPrivate::createContent()
auto TitleBar = DockArea->titleBar();
int Index = TitleBar->indexOf(TitleBar->tabBar());
TitleBar->insertWidget(Index + 1, CustomButton);
QObject::connect(CustomButton, &QToolButton::clicked, [=]()
QObject::connect(CustomButton, &QToolButton::clicked, [DockArea, this]()
{
auto DockWidget = createEditorWidget();
DockWidget->setFeature(ads::CDockWidget::DockWidgetDeleteOnClose, true);
@@ -770,6 +769,9 @@ CMainWindow::CMainWindow(QWidget *parent) :
// uncomment if you would like to enable dock widget auto hiding
CDockManager::setAutoHideConfigFlags({CDockManager::DefaultAutoHideConfig});
// uncomment if you would like to disable closing auto hide widget with mouse click outside of auto hide container
//CDockManager::setAutoHideConfigFlag(CDockManager::AutoHideCloseOnOutsideMouseClick, false);
// uncomment if you would like to enable an equal distribution of the
// available size of a splitter to all contained dock widgets
// CDockManager::setConfigFlag(CDockManager::EqualSplitOnInsertion, true);
@@ -777,6 +779,9 @@ CMainWindow::CMainWindow(QWidget *parent) :
// uncomment if you would like to close tabs with the middle mouse button, web browser style
// CDockManager::setConfigFlag(CDockManager::MiddleMouseButtonClosesTab, true);
// uncomment if you would like to avoid using the built-in QSS stylesheet
// CDockManager::setConfigFlag(CDockManager::DisableStylesheet, true);
// Now create the dock manager and its content
d->DockManager = new CDockManager(this);
d->DockManager->setDockWidgetToolBarStyle(Qt::ToolButtonIconOnly, ads::CDockWidget::StateFloating);

58
demo/MyDockAreaTitleBar.h Normal file
View File

@@ -0,0 +1,58 @@
#ifndef QTADS_MYDOCKAREATITLEBAR_H
#define QTADS_MYDOCKAREATITLEBAR_H
/*******************************************************************************
** Qt Advanced Docking System
** Copyright (C) 2017 Uwe Kindler
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with this library; If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
//============================================================================
// INCLUDES
//============================================================================
#include <DockAreaTitleBar.h>
/**
* Custom DockAreaTitleBar that adds a custom context menu
*/
class MyDockAreaTitleBar : public ads::CDockAreaTitleBar
{
public:
explicit MyDockAreaTitleBar(ads::CDockAreaWidget *parent) :
CDockAreaTitleBar(parent)
{
}
QMenu* buildContextMenu(QMenu*) override
{
auto menu = ads::CDockAreaTitleBar::buildContextMenu(nullptr);
menu->addSeparator();
auto action = menu->addAction(tr("Format HardDrive"));
connect(action, &QAction::triggered, this, [this]()
{
QMessageBox msgBox;
msgBox.setText("No, just kidding");
msgBox.setStandardButtons(QMessageBox::Abort);
msgBox.setDefaultButton(QMessageBox::Abort);
msgBox.exec();
});
return menu;
}
};
#endif // QTADS_MYDOCKAREATITLEBAR_H

View File

@@ -41,6 +41,7 @@ int main(int argc, char *argv[])
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
#endif
QApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
std::shared_ptr<int> b;
QApplication a(argc, argv);
a.setApplicationName("Advanced Docking System Demo");

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 364 KiB

After

Width:  |  Height:  |  Size: 382 KiB

BIN
doc/showcase_pysoworks.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

View File

@@ -1,5 +1,6 @@
# User Guide
- [User Guide](#user-guide)
- [Configuration Flags](#configuration-flags)
- [Setting Configuration Flags](#setting-configuration-flags)
- [`ActiveTabHasCloseButton`](#activetabhasclosebutton)
@@ -29,7 +30,8 @@
- [`MiddleMouseButtonClosesTab`](#middlemousebuttonclosestab)
- [`DisableTabTextEliding`](#disabletabtexteliding)
- [`ShowTabTextOnlyForActiveTab`](#showtabtextonlyforactivetab)
- [Auto-Hide Configuration Flags](#auto-hide-configuration-flags)
- [`DoubleClickUndocksWidget`](#doubleclickundockswidget)
- [`TabsAtBottom`](#tabsatbottom)
- [Auto Hide Dock Widgets](#auto-hide-dock-widgets)
- [Pinning Auto-Hide Widgets to a certain border](#pinning-auto-hide-widgets-to-a-certain-border)
- [Show / Hide Auto-Hide Widgets via Mouse Over](#show--hide-auto-hide-widgets-via-mouse-over)
@@ -39,6 +41,7 @@
- [Auto-Hide Drag to Float / Dock](#auto-hide-drag-to-float--dock)
- [Auto-Hide Context Menu](#auto-hide-context-menu)
- [Adding Auto Hide Widgets](#adding-auto-hide-widgets)
- [Auto-Hide Configuration Flags](#auto-hide-configuration-flags)
- [Setting Auto-Hide Flags](#setting-auto-hide-flags)
- [`AutoHideFeatureEnabled`](#autohidefeatureenabled)
- [`DockAreaHasAutoHideButton`](#dockareahasautohidebutton)
@@ -49,6 +52,8 @@
- [`AutoHideCloseButtonCollapsesDock`](#autohideclosebuttoncollapsesdock)
- [`AutoHideHasCloseButton`](#autohidehasclosebutton)
- [`AutoHideHasMinimizeButton`](#autohidehasminimizebutton)
- [`AutoHideOpenOnDragHover`](#autohideopenondraghover)
- [`AutoHideCloseOnOutsideMouseClick`](#autohidecloseonoutsidemouseclick)
- [DockWidget Feature Flags](#dockwidget-feature-flags)
- [`DockWidgetClosable`](#dockwidgetclosable)
- [`DockWidgetMovable`](#dockwidgetmovable)
@@ -62,8 +67,15 @@
- [Central Widget](#central-widget)
- [Empty Dock Area](#empty-dock-area)
- [Custom Close Handling](#custom-close-handling)
- [Globally Lock Docking Features](#globally-lock-docking-features)
- [Dock Widget Size / Minimum Size Handling](#dock-widget-size--minimum-size-handling)
- [Styling](#styling)
- [Disabling the Internal Style Sheet](#disabling-the-internal-style-sheet)
- [Using ADS on Linux](#using-ads-on-linux)
- [Supported Distributions](#supported-distributions)
- [Requirements](#requirements)
- [Manjaro xfce 25.0.1 and Xubuntu 24.04.2 issues](#manjaro-xfce-2501-and-xubuntu-24042-issues)
- [OpenGl + ADS](#opengl--ads)
## Configuration Flags
@@ -495,9 +507,18 @@ for active tabs. Inactive tabs only show their icon:
![MShowTabTextOnlyForActiveTab true](cfg_flag_ShowTabTextOnlyForActiveTab_true.png)
## Auto-Hide Configuration Flags
### `DoubleClickUndocksWidget`
### Auto Hide Dock Widgets
If the flag is set (default), a double click on a tab undocks the dock widget.
If you would like to disable undocking, just clear this flag.
### `TabsAtBottom`
If the flag is set, tabs will be shown at the bottom instead of in the title bar.
![TabsAtBottom true](cfg_flag_TabsAtBottom_true.png)
## Auto Hide Dock Widgets
The Advanced Docking System supports "Auto-Hide" functionality for **all**
dock containers. The "Auto Hide" feature allows to display more information
@@ -598,6 +619,8 @@ DockManager->addAutoHideDockWidget(SideBarLeft, TableDockWidget);
See `autohide` example or the demo application to learn how it works.
## Auto-Hide Configuration Flags
### Setting Auto-Hide Flags
The Advanced Docking System has a number of global configuration flags to
@@ -704,6 +727,20 @@ If this flag is set (disabled by default), then each auto hide widget has a mini
![AutoHideHasMinimizeButton](cfg_flag_AutoHideHasMinimizeButton.png)
### `AutoHideOpenOnDragHover`
If this flag is set (disabled by default), then holding a dragging cursor hover an auto-hide collapsed dock's tab will open said dock:
![AutoHideOpenOnDragHover](cfg_flag_AutoHideOpenOnDragHover.gif)
Said dock must be set to accept drops to hide when cursor leaves its scope. See `AutoHideDragNDropExample` for more details.
### `AutoHideCloseOnOutsideMouseClick`
If this flag is set (default), the auto hide dock container will collapse if the
user clicks outside of the container. If not set, the auto hide container can be
closed only via click on auto hide sidebar tab.
## DockWidget Feature Flags
### `DockWidgetClosable`
@@ -825,6 +862,93 @@ Normally clicking the close button of a dock widget will just hide the widget an
When an entire area is closed, the default behavior is to hide the dock widgets it contains regardless of the `DockWidgetDeleteOnClose` flag except if there is only one dock widget. In this special case, the `DockWidgetDeleteOnClose` flag is followed. This behavior can be changed by setting the `DockWidgetForceCloseWithArea` flag to all the dock widgets that needs to be closed with their area.
## Globally Lock Docking Features
It is possible to globally lock features of all dock widgets to "freeze" the
current workspace layout. That means, you can now lock your workspace
to avoid accidentally dragging a docked view. When locking wasn't possible,
users had to manually dock it back to the desired place after each accidental
undock.
You can use a combination of the following feature flags to define which features
shall get locked:
- `CDockWidget::DockWidgetClosable`
- `CDockWidget::DockWidgetMovable`
- `CDockWidget::DockWidgetFloatable`
- `CDockWidget::DockWidgetPinable`
To clear the locked features, you can use `CDockWidget::NoDockWidgetFeatures`
The following code shows how to lock and unlock all dock widget features
globally.
```c++
DockManager->lockDockWidgetFeaturesGlobally();
DockManager->lockDockWidgetFeaturesGlobally(CDockWidget::NoDockWidgetFeatures);
```
## Dock Widget Size / Minimum Size Handling
There are several `CDockWidget` mode enums to control how a `CDockWidget` is
resized and how the docking system handles the minimum size of a dockwidget.
The first one is the `eInsertMode` enum:
```c++
enum eInsertMode
{
AutoScrollArea,
ForceScrollArea,
ForceNoScrollArea
};
```
The InsertMode defines how the widget is inserted into the dock widget, when you
call the `CDockWidget::setWidget` method:
```c++
DockWidget->setWidget(widget, CDockWidget::AutoScrollArea);
```
The content of a dock widget should be resizable do a very small size to
prevent the dock widget from blocking the resizing. To ensure, that a
dock widget can be resized very well, it is better to insert the content
widget into a scroll area or to provide a widget that is already a scroll
area or that contains a scroll area (such as an `QAbstractItemView`)
If the InsertMode is `AutoScrollArea`, the DockWidget tries to automatically
detect how to insert the given widget. If the widget is derived from
`QScrollArea` (i.e. an `QAbstractItemView`), then the widget is inserted
directly. If the given widget is not a scroll area, the widget will be
inserted into a scroll area.
To force insertion into a scroll area, you can also provide the InsertMode
`ForceScrollArea`. In this case a scroll area will also be created for content
widgets that are derived from `QScrollArea` To prevent insertion into a scroll
area, you can provide the InsertMode `ForceNoScrollArea`. In this case, the
content widget is always inserted directly.
A second enum, the `eMinimumSizeHintMode` defines, which value will be returned
from the `CDockWidget::minimumSizeHint()` function:
```c++
enum eMinimumSizeHintMode
{
MinimumSizeHintFromDockWidget,
MinimumSizeHintFromContent,
MinimumSizeHintFromDockWidgetMinimumSize,
MinimumSizeHintFromContentMinimumSize,
};
```
To ensure, that a dock widget does not block resizing, the dock widget
reimplements `minimumSizeHint()` function to return a very small minimum
size hint. If you would like to adhere the `minimumSizeHint()` from the
content widget, then set the `minimumSizeHintMode()` to
`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.
## Styling
The Advanced Docking System supports styling via [Qt Style Sheets](https://doc.qt.io/qt-5/stylesheet.html). All components like splitters, tabs, buttons, titlebar and
@@ -842,3 +966,51 @@ just call the function for settings the stylesheet with an empty string.
DockManager->setStyleSheet("");
```
## Using ADS on Linux
### Supported Distributions
Unfortunately, there is no such thing as a Linux operating system. Linux is a heterogeneous environment with a variety of different distributions. So it is not possible to support "Linux" like it is possible for Windows. It is only possible to support and test a small subset of Linux distributions. The library can be compiled for and has been developed and tested with some Linux distributions. Depending on the used window manager or compositor, dock widgets
with native title bars are supported or not. If native title bars are not supported,
the library switches to `QWidget` based title bars.
- **Kubuntu 18.04 and 19.10** - uses KWin - no native title bars
- **Ubuntu 18.04, 19.10 and 20.04** - native title bars are supported
- **Ubuntu 22.04** - uses Wayland -> no native title bars
### Requirements
There are some requirements for the Linux distribution that have to be met:
- an X server that supports ARGB visuals and a compositing window manager. This is required to display the translucent dock overlays ([https://doc.qt.io/qt-5/qwidget.html#creating-translucent-windows](https://doc.qt.io/qt-5/qwidget.html#creating-translucent-windows)). If your Linux distribution does not support this, or if you disable this feature, you will very likely see issue [#95](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/95).
- Wayland is not properly supported by Qt yet. If you use Wayland, then you should set the session type to x11: `XDG_SESSION_TYPE=x11 ./AdvancedDockingSystemDemo`. You will find more details about this in issue [#288](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/288).
Screenshot Kubuntu:
![Advanced Docking on Kubuntu Linux](linux_kubuntu_1804.png)
Screenshot Ubuntu:
![Advanced Docking on Ubuntu Linux](linux_ubuntu_1910.png)
### Manjaro xfce 25.0.1 and Xubuntu 24.04.2 issues
There is a known focus stealing issue with the xfce4 compositor reported in issue [#734]. This issue
can be solved by enabling the setting **Activate focus stealing prevention**. `Settings > Window Manager Tweaks` has a tab called `Focus`.
Selecting `Activate focus stealing prevention` and `Do nothing` for `When a window raises itself`, seems to mitigate the issue. Deselecting `Enable display compositing` on the `Compositor` tab, also works.
![Window Manager Tweaks](xfce4_focus_stealing_issue.png)
## OpenGl + ADS
If you would like to use OpenGL widgets with ADS such as `GLWidget`, QML or `QWebEngineView`, then you need
to set `QApplication::setAttribute(Qt::AA_ShareOpenGLContexts)` before creating your application and your
widgets (see issue [#732])
```c++
int main(int argc, char *argv[])
{
QApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
QApplication application(argc, argv);
...
}
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.16)
project(QtADSExamples LANGUAGES CXX VERSION ${VERSION_SHORT})
add_subdirectory(simple)
add_subdirectory(hideshow)
@@ -6,5 +6,7 @@ add_subdirectory(sidebar)
add_subdirectory(deleteonclose)
add_subdirectory(centralwidget)
add_subdirectory(autohide)
add_subdirectory(autohidedragndrop)
add_subdirectory(emptydockarea)
add_subdirectory(dockindock)
add_subdirectory(configflags)

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.16)
project(ads_example_autohide 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)
@@ -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 qt${QT_VERSION_MAJOR}advanceddocking)
target_link_libraries(AutoHideExample PRIVATE qtadvanceddocking-qt${QT_VERSION_MAJOR})
target_link_libraries(AutoHideExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)

View File

@@ -33,7 +33,7 @@ CMainWindow::CMainWindow(QWidget *parent)
// Set central widget
QPlainTextEdit* w = new QPlainTextEdit();
w->setPlaceholderText("This is the central editor. Enter your text here.");
CDockWidget* CentralDockWidget = new CDockWidget("CentralWidget");
CDockWidget* CentralDockWidget = DockManager->createDockWidget("CentralWidget");
CentralDockWidget->setWidget(w);
auto* CentralDockArea = DockManager->setCentralWidget(CentralDockWidget);
CentralDockArea->setAllowedAreas(DockWidgetArea::OuterDockAreas);
@@ -42,7 +42,7 @@ CMainWindow::CMainWindow(QWidget *parent)
QTableWidget* table = new QTableWidget();
table->setColumnCount(3);
table->setRowCount(10);
CDockWidget* TableDockWidget = new CDockWidget("Table 1");
CDockWidget* TableDockWidget = DockManager->createDockWidget("Table 1");
TableDockWidget->setWidget(table);
TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
TableDockWidget->setMinimumSize(200,150);
@@ -53,7 +53,7 @@ CMainWindow::CMainWindow(QWidget *parent)
table = new QTableWidget();
table->setColumnCount(5);
table->setRowCount(1020);
TableDockWidget = new CDockWidget("Table 2");
TableDockWidget = DockManager->createDockWidget("Table 2");
TableDockWidget->setWidget(table);
TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
TableDockWidget->resize(250, 150);
@@ -64,7 +64,7 @@ CMainWindow::CMainWindow(QWidget *parent)
QTableWidget* propertiesTable = new QTableWidget();
propertiesTable->setColumnCount(3);
propertiesTable->setRowCount(10);
CDockWidget* PropertiesDockWidget = new CDockWidget("Properties");
CDockWidget* PropertiesDockWidget = DockManager->createDockWidget("Properties");
PropertiesDockWidget->setWidget(propertiesTable);
PropertiesDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
PropertiesDockWidget->resize(250, 150);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.16)
project(ads_example_centralwidget VERSION ${VERSION_SHORT})
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
@@ -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 qt${QT_VERSION_MAJOR}advanceddocking)
target_link_libraries(CentralWidgetExample PRIVATE qtadvanceddocking-qt${QT_VERSION_MAJOR})
target_link_libraries(CentralWidgetExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)

View File

@@ -40,7 +40,7 @@ CMainWindow::CMainWindow(QWidget *parent)
// Set central widget
QPlainTextEdit* w = new QPlainTextEdit();
w->setPlaceholderText("This is the central editor. Enter your text here.");
CDockWidget* CentralDockWidget = new CDockWidget("CentralWidget");
CDockWidget* CentralDockWidget = DockManager->createDockWidget("CentralWidget");
CentralDockWidget->setWidget(w);
auto* CentralDockArea = DockManager->setCentralWidget(CentralDockWidget);
CentralDockArea->setAllowedAreas(DockWidgetArea::OuterDockAreas);
@@ -49,7 +49,7 @@ CMainWindow::CMainWindow(QWidget *parent)
QTableWidget* table = new QTableWidget();
table->setColumnCount(3);
table->setRowCount(10);
CDockWidget* TableDockWidget = new CDockWidget("Table 1");
CDockWidget* TableDockWidget = DockManager->createDockWidget("Table 1");
TableDockWidget->setWidget(table);
TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
TableDockWidget->resize(250, 150);
@@ -60,7 +60,7 @@ CMainWindow::CMainWindow(QWidget *parent)
table = new QTableWidget();
table->setColumnCount(5);
table->setRowCount(1020);
TableDockWidget = new CDockWidget("Table 2");
TableDockWidget = DockManager->createDockWidget("Table 2");
TableDockWidget->setWidget(table);
TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
TableDockWidget->resize(250, 150);
@@ -71,7 +71,7 @@ CMainWindow::CMainWindow(QWidget *parent)
QTableWidget* propertiesTable = new QTableWidget();
propertiesTable->setColumnCount(3);
propertiesTable->setRowCount(10);
CDockWidget* PropertiesDockWidget = new CDockWidget("Properties");
CDockWidget* PropertiesDockWidget = DockManager->createDockWidget("Properties");
PropertiesDockWidget->setWidget(propertiesTable);
PropertiesDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
PropertiesDockWidget->resize(250, 150);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.16)
project(ads_example_deleteonclose 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)
@@ -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 qt${QT_VERSION_MAJOR}advanceddocking)
target_link_libraries(DeleteOnCloseTest PRIVATE qtadvanceddocking-qt${QT_VERSION_MAJOR})
target_link_libraries(DeleteOnCloseTest PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)

View File

@@ -46,7 +46,7 @@ int main(int argc, char *argv[])
int i = 0;
QObject::connect(action, &QAction::triggered, [&]() {
auto dw = new ads::CDockWidget(QStringLiteral("test %1 [DockWidgetDeleteOnClose]").arg(i++), &w);
auto dw = dockManager->createDockWidget(QStringLiteral("test %1 [DockWidgetDeleteOnClose]").arg(i++), &w);
auto editor = new QTextEdit(QStringLiteral("lorem ipsum..."), dw);
dw->setWidget(editor);
dw->setFeature(ads::CDockWidget::DockWidgetDeleteOnClose, true);
@@ -54,7 +54,7 @@ int main(int argc, char *argv[])
qDebug() << "doc dock widget created!" << dw << area;
});
auto dw = new ads::CDockWidget(QStringLiteral("test %1 [DeleteContentOnClose]").arg(i++), &w);
auto dw = dockManager->createDockWidget(QStringLiteral("test %1 [DeleteContentOnClose]").arg(i++), &w);
auto editor = new QTextEdit(QStringLiteral("recreated lorem ipsum......"), dw);
dw->setWidget(editor);
dw->setFeature(ads::CDockWidget::DeleteContentOnClose, true);
@@ -77,7 +77,7 @@ int main(int argc, char *argv[])
action = new QAction("New", &w);
w.menuBar()->addAction(action);
QObject::connect(action, &QAction::triggered, [&]() {
auto dw = new ads::CDockWidget(QStringLiteral("test %1").arg(i++), &w);
auto dw = dockManager->createDockWidget(QStringLiteral("test %1").arg(i++), &w);
auto editor = new QTextEdit(QStringLiteral("lorem ipsum..."), dw);
dw->setWidget(editor);
auto area = dockManager->addDockWidgetTab(ads::CenterDockWidgetArea, dw);

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.16)
project(ads_example_dockindock 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)
@@ -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 qt${QT_VERSION_MAJOR}advanceddocking)
target_link_libraries(DockInDockExample PRIVATE qtadvanceddocking-qt${QT_VERSION_MAJOR})
target_link_libraries(DockInDockExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)

View File

@@ -54,7 +54,7 @@ ads::CDockAreaWidget* DockInDockWidget::addTabWidget( QWidget* widget, const QSt
}
}
ads::CDockWidget* DockWidget = new ads::CDockWidget(name);
ads::CDockWidget* DockWidget = m_mgr->createDockWidget(name);
DockWidget->setWidget(widget);
DockWidget->setIcon( icon );
@@ -101,7 +101,7 @@ DockInDockWidget* DockInDockWidget::createGroup( const QString& groupName, QIcon
DockInDockWidget* child = new DockInDockWidget( this, m_topLevelDockWidget, m_perspectivesManager );
child->setObjectName( groupName );
ads::CDockWidget* DockWidget = new ads::CDockWidget(groupName);
ads::CDockWidget* DockWidget = m_mgr->createDockWidget(groupName);
DockWidget->setWidget(child);
DockWidget->setIcon(icon);

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.16)
project(ads_example_centralwidget VERSION ${VERSION_SHORT})
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
@@ -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 qt${QT_VERSION_MAJOR}advanceddocking)
target_link_libraries(EmptyDockAreaExample PRIVATE qtadvanceddocking-qt${QT_VERSION_MAJOR})
target_link_libraries(EmptyDockAreaExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)

View File

@@ -19,8 +19,6 @@
#include <QToolBar>
#include "DockAreaWidget.h"
#include "DockAreaTitleBar.h"
#include "DockAreaTabBar.h"
#include "FloatingDockContainer.h"
#include "DockComponentsFactory.h"
@@ -32,16 +30,19 @@ CMainWindow::CMainWindow(QWidget *parent)
, ui(new Ui::CMainWindow)
{
ui->setupUi(this);
CDockManager::setConfigFlag(CDockManager::OpaqueSplitterResize, true);
CDockManager::setConfigFlag(CDockManager::XmlCompressionEnabled, false);
CDockManager::setConfigFlag(CDockManager::FocusHighlighting, true);
ads::CDockManager::setConfigFlag( ads::CDockManager::DockAreaHasCloseButton, false );
ads::CDockManager::setConfigFlag( ads::CDockManager::AllTabsHaveCloseButton, true );
ads::CDockManager::setConfigFlag( ads::CDockManager::DockAreaHasUndockButton, false );
ads::CDockManager::setConfigFlag( ads::CDockManager::DockAreaDynamicTabsMenuButtonVisibility, true );
ads::CDockManager::setConfigFlag( ads::CDockManager::DisableTabTextEliding, true );
ads::CDockManager::setConfigFlag( ads::CDockManager::DoubleClickUndocksWidget, false );
DockManager = new CDockManager(this);
// Set central widget
QLabel* label = new QLabel();
label->setText("This is a DockArea which is always visible, even if it does not contain any DockWidgets.");
label->setAlignment(Qt::AlignCenter);
CDockWidget* CentralDockWidget = new CDockWidget("CentralWidget");
CDockWidget* CentralDockWidget = DockManager->createDockWidget("CentralWidget");
CentralDockWidget->setWidget(label);
CentralDockWidget->setFeature(ads::CDockWidget::NoTab, true);
auto* CentralDockArea = DockManager->setCentralWidget(CentralDockWidget);
@@ -50,7 +51,7 @@ CMainWindow::CMainWindow(QWidget *parent)
QTableWidget* table = new QTableWidget();
table->setColumnCount(3);
table->setRowCount(10);
CDockWidget* TableDockWidget = new CDockWidget("Table 1");
CDockWidget* TableDockWidget = DockManager->createDockWidget("Table 1");
TableDockWidget->setWidget(table);
TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
TableDockWidget->resize(250, 150);
@@ -62,7 +63,7 @@ CMainWindow::CMainWindow(QWidget *parent)
table = new QTableWidget();
table->setColumnCount(5);
table->setRowCount(1020);
TableDockWidget = new CDockWidget("Table 2");
TableDockWidget = DockManager->createDockWidget("Table 2");
TableDockWidget->setWidget(table);
TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
TableDockWidget->resize(250, 150);
@@ -73,7 +74,7 @@ CMainWindow::CMainWindow(QWidget *parent)
QTableWidget* propertiesTable = new QTableWidget();
propertiesTable->setColumnCount(3);
propertiesTable->setRowCount(10);
CDockWidget* PropertiesDockWidget = new CDockWidget("Properties");
CDockWidget* PropertiesDockWidget = DockManager->createDockWidget("Properties");
PropertiesDockWidget->setWidget(propertiesTable);
PropertiesDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
PropertiesDockWidget->resize(250, 150);
@@ -98,8 +99,13 @@ void CMainWindow::createPerspectiveUi()
PerspectiveComboBox = new QComboBox(this);
PerspectiveComboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
PerspectiveComboBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
connect(PerspectiveComboBox, &QComboBox::textActivated,
DockManager, &CDockManager::openPerspective);
#else
connect(PerspectiveComboBox, SIGNAL(activated(const QString&)),
DockManager, SLOT(openPerspective(const QString&)));
#endif
PerspectiveListAction->setDefaultWidget(PerspectiveComboBox);
ui->toolBar->addSeparator();
ui->toolBar->addAction(PerspectiveListAction);

View File

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

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.16)
project(ads_example_hideshow 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)
@@ -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 qt${QT_VERSION_MAJOR}advanceddocking)
target_link_libraries(HideShowExample PRIVATE qtadvanceddocking-qt${QT_VERSION_MAJOR})
target_link_libraries(HideShowExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)

View File

@@ -35,7 +35,7 @@ MainWindow::MainWindow(QWidget *parent) :
// Create a dock widget with the title Label 1 and set the created label
// as the dock widget content
ads::CDockWidget* DockWidget = new ads::CDockWidget("Label 1");
ads::CDockWidget* DockWidget = m_DockManager->createDockWidget("Label 1");
DockWidget->setWidget(l);
// Add the toggleViewAction of the dock widget to the menu to give

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.16)
project(ads_example_sidebar 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)
@@ -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 qt${QT_VERSION_MAJOR}advanceddocking)
target_link_libraries(SidebarExample PRIVATE qtadvanceddocking-qt${QT_VERSION_MAJOR})
target_link_libraries(SidebarExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)

View File

@@ -28,7 +28,7 @@ MainWindow::MainWindow(QWidget *parent) :
// Create a dock widget with the title Label 1 and set the created label
// as the dock widget content
ads::CDockWidget* DockWidget = new ads::CDockWidget("Label 1");
ads::CDockWidget* DockWidget = m_DockManager->createDockWidget("Label 1");
DockWidget->setWidget(l);
// Add the toggleViewAction of the dock widget to the menu to give
@@ -42,7 +42,7 @@ MainWindow::MainWindow(QWidget *parent) :
// Create an example editor
QPlainTextEdit* te = new QPlainTextEdit();
te->setPlaceholderText("Please enter your text here into this QPlainTextEdit...");
DockWidget = new ads::CDockWidget("Editor 1");
DockWidget = m_DockManager->createDockWidget("Editor 1");
DockWidget->setWidget(te);
ui->menuView->addAction(DockWidget->toggleViewAction());
m_DockManager->addDockWidget(ads::BottomDockWidgetArea, DockWidget);

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.16)
project(ads_example_simple 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)
@@ -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 qt${QT_VERSION_MAJOR}advanceddocking)
target_link_libraries(SimpleExample PRIVATE qtadvanceddocking-qt${QT_VERSION_MAJOR})
target_link_libraries(SimpleExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)

View File

@@ -24,7 +24,7 @@ MainWindow::MainWindow(QWidget *parent) :
// Create a dock widget with the title Label 1 and set the created label
// as the dock widget content
ads::CDockWidget* DockWidget = new ads::CDockWidget("Label 1");
ads::CDockWidget* DockWidget = m_DockManager->createDockWidget("Label 1");
DockWidget->setWidget(l);
// Add the toggleViewAction of the dock widget to the menu to give

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -124,6 +124,21 @@ struct AutoHideDockContainerPrivate
*/
AutoHideDockContainerPrivate(CAutoHideDockContainer *_public);
/**
* Convenience function to ease access to dock manager components factory
*/
QSharedPointer<ads::CDockComponentsFactory> componentsFactory() const
{
if (!DockWidget || !DockWidget->dockManager())
{
return CDockComponentsFactory::factory();
}
else
{
return DockWidget->dockManager()->componentsFactory();
}
}
/**
* Convenience function to get a dock widget area
*/
@@ -199,7 +214,7 @@ CAutoHideDockContainer::CAutoHideDockContainer(CDockWidget* DockWidget, SideBarL
{
hide(); // auto hide dock container is initially always hidden
d->SideTabBarArea = area;
d->SideTab = componentsFactory()->createDockWidgetSideTab(nullptr);
d->SideTab = d->componentsFactory()->createDockWidgetSideTab(nullptr);
connect(d->SideTab, &CAutoHideTab::pressed, this, &CAutoHideDockContainer::toggleCollapseState);
d->DockArea = new CDockAreaWidget(DockWidget->dockManager(), parent);
d->DockArea->setObjectName("autoHideDockArea");
@@ -400,7 +415,31 @@ void CAutoHideDockContainer::moveContentsToParent()
// to the user and he does not have to search where the widget was inserted.
d->DockWidget->setDockArea(nullptr);
auto DockContainer = dockContainer();
DockContainer->addDockWidget(d->getDockWidgetArea(d->SideTabBarArea), d->DockWidget);
auto targetArea = d->getDockWidgetArea(d->SideTabBarArea);
// If the widget has a preferred auto-hide location, try to find an existing
// opened dock area that contains a widget with the same preferred location
// and merge as a tab instead of creating a new split.
auto preferred = d->DockWidget->preferredAutoHideSideBarLocation();
if (preferred != SideBarNone)
{
for (auto area : DockContainer->openedDockAreas())
{
if (!area || area->isAutoHide()) continue;
// Check if any widget in this area has the same preferred location
for (auto dw : area->dockWidgets())
{
if (dw && dw->preferredAutoHideSideBarLocation() == preferred)
{
DockContainer->addDockWidget(CenterDockWidgetArea,
d->DockWidget, area);
return;
}
}
}
}
DockContainer->addDockWidget(targetArea, d->DockWidget);
}
@@ -410,8 +449,8 @@ void CAutoHideDockContainer::cleanupAndDelete()
const auto dockWidget = d->DockWidget;
if (dockWidget)
{
auto SideTab = d->SideTab;
dockWidget->setSideTabWidget(nullptr);
SideTab->removeFromSideBar();
SideTab->setParent(nullptr);
SideTab->hide();
@@ -467,6 +506,17 @@ void CAutoHideDockContainer::collapseView(bool Enable)
{
updateSize();
d->updateResizeHandleSizeLimitMax();
// If the parent dock container has native child windows (e.g. because
// an OpenGL or VTK content widget called winId()), this panel is an
// alien (non-native) widget and will always be obscured by those native
// sibling windows regardless of Qt's paint order. Native OS windows are
// rendered above the parent's painted (alien) content by the windowing
// system. To allow raise() to use OS-level Z-order and appear on top,
// this panel must first be promoted to a native window itself.
if (parentWidget() && parentWidget()->internalWinId() && !internalWinId())
{
winId();
}
raise();
show();
d->DockWidget->dockManager()->setDockWidgetFocused(d->DockWidget);
@@ -587,9 +637,13 @@ bool CAutoHideDockContainer::eventFilter(QObject* watched, QEvent* event)
return Super::eventFilter(watched, event);
}
// user clicked into container - collapse the auto hide widget
// user clicked outside of autohide container - collapse the auto hide widget
if (CDockManager::testAutoHideConfigFlag(
CDockManager::AutoHideCloseOnOutsideMouseClick))
{
collapseView(true);
}
}
else if (event->type() == internal::FloatingWidgetDragStartEvent)
{
// If we are dragging our own floating widget, the we do not need to
@@ -657,6 +711,14 @@ bool CAutoHideDockContainer::event(QEvent* event)
return Super::event(event);
}
//============================================================================
void CAutoHideDockContainer::dragLeaveEvent(QDragLeaveEvent*)
{
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideOpenOnDragHover))
{
collapseView(true);
}
}
//============================================================================
Qt::Orientation CAutoHideDockContainer::orientation() const
@@ -709,4 +771,3 @@ int CAutoHideDockContainer::tabIndex() const
}
}

View File

@@ -65,6 +65,7 @@ protected:
virtual void resizeEvent(QResizeEvent* event) override;
virtual void leaveEvent(QEvent *event) override;
virtual bool event(QEvent* event) override;
virtual void dragLeaveEvent(QDragLeaveEvent* ev) override;
/**
* Updates the size considering the size limits and the resize margins

View File

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

View File

@@ -33,6 +33,8 @@
#include <QApplication>
#include <QElapsedTimer>
#include <QMenu>
#include <QEvent>
#include <QTimer>
#include "AutoHideDockContainer.h"
#include "AutoHideSideBar.h"
@@ -41,6 +43,7 @@
#include "DockWidget.h"
#include "FloatingDragPreview.h"
#include "DockOverlay.h"
#include "ads_globals.h"
namespace ads
{
@@ -55,6 +58,7 @@ struct AutoHideTabPrivate
CAutoHideSideBar* SideBar = nullptr;
Qt::Orientation Orientation{Qt::Vertical};
QElapsedTimer TimeSinceHoverMousePress;
QTimer DragOverTimer;
bool MousePressed = false;
eDragState DragState = DraggingInactive;
QPoint GlobalDragStartMousePosition;
@@ -135,7 +139,7 @@ struct AutoHideTabPrivate
IFloatingWidget* createFloatingWidget(T* Widget)
{
auto w = new CFloatingDragPreview(Widget);
_this->connect(w, &CFloatingDragPreview::draggingCanceled, [=]()
_this->connect(w, &CFloatingDragPreview::draggingCanceled, [this]()
{
DragState = DraggingInactive;
});
@@ -252,6 +256,14 @@ CAutoHideTab::CAutoHideTab(QWidget* parent) :
{
setAttribute(Qt::WA_NoMousePropagation);
setFocusPolicy(Qt::NoFocus);
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideOpenOnDragHover)) {
setAcceptDrops(true);
}
d->DragOverTimer.setInterval(CDockManager::configParam(
CDockManager::AutoHideOpenOnDragHoverDelay_ms, 500).toInt());
d->DragOverTimer.setSingleShot(true);
connect(&d->DragOverTimer, &QTimer::timeout, this, &CAutoHideTab::onDragHoverDelayExpired);
}
@@ -355,7 +367,6 @@ bool CAutoHideTab::event(QEvent* event)
case QEvent::Leave:
d->forwardEventToDockContainer(event);
break;
default:
break;
}
@@ -495,7 +506,8 @@ void CAutoHideTab::mouseReleaseEvent(QMouseEvent* ev)
//============================================================================
void CAutoHideTab::mouseMoveEvent(QMouseEvent *ev)
{
if (!(ev->buttons() & Qt::LeftButton) || d->isDraggingState(DraggingInactive))
if (!(ev->buttons() & Qt::LeftButton)
|| d->isDraggingState(DraggingInactive))
{
d->DragState = DraggingInactive;
Super::mouseMoveEvent(ev);
@@ -519,15 +531,19 @@ void CAutoHideTab::mouseMoveEvent(QMouseEvent* ev)
}
auto MappedPos = mapToParent(ev->pos());
bool MouseOutsideBar = (MappedPos.x() < 0) || (MappedPos.x() > parentWidget()->rect().right());
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());
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)))
if (Features.testFlag(CDockWidget::DockWidgetFloatable)
|| (Features.testFlag(CDockWidget::DockWidgetMovable)))
{
d->startFloating();
}
@@ -537,6 +553,27 @@ void CAutoHideTab::mouseMoveEvent(QMouseEvent* ev)
Super::mouseMoveEvent(ev);
}
//============================================================================
void CAutoHideTab::dragEnterEvent(QDragEnterEvent *ev)
{
Q_UNUSED(ev);
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideOpenOnDragHover))
{
d->DragOverTimer.start();
ev->accept();
}
}
//============================================================================
void CAutoHideTab::dragLeaveEvent(QDragLeaveEvent *ev)
{
Q_UNUSED(ev);
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideOpenOnDragHover))
{
d->DragOverTimer.stop();
}
}
//============================================================================
void CAutoHideTab::requestCloseDockWidget()
@@ -544,7 +581,6 @@ void CAutoHideTab::requestCloseDockWidget()
d->DockWidget->requestCloseDockWidget();
}
//============================================================================
int CAutoHideTab::tabIndex() const
{
@@ -557,4 +593,28 @@ int CAutoHideTab::tabIndex() const
}
//============================================================================
void CAutoHideTab::onDragHoverDelayExpired()
{
static const char* const PropertyId = "ActiveDragOverAutoHideContainer";
// First we check if there is an active auto hide container that is visible
// In this case, we collapse it before we open the new one
auto v = d->DockWidget->dockManager()->property(PropertyId);
if (v.isValid())
{
auto ActiveAutoHideContainer = v.value<QPointer<CAutoHideDockContainer>>();
if (ActiveAutoHideContainer)
{
ActiveAutoHideContainer->collapseView(true);
}
}
auto AutoHideContainer = d->DockWidget->autoHideDockContainer();
AutoHideContainer->collapseView(false);
d->DockWidget->dockManager()->setProperty(PropertyId,
QVariant::fromValue(QPointer<CAutoHideDockContainer>(AutoHideContainer)));
}
}

View File

@@ -67,6 +67,7 @@ private:
private Q_SLOTS:
void onAutoHideToActionClicked();
void onDragHoverDelayExpired();
protected:
void setSideBar(CAutoHideSideBar *SideTabBar);
@@ -76,6 +77,8 @@ protected:
virtual void mousePressEvent(QMouseEvent* ev) override;
virtual void mouseReleaseEvent(QMouseEvent* ev) override;
virtual void mouseMoveEvent(QMouseEvent* ev) override;
virtual void dragEnterEvent(QDragEnterEvent* ev) override;
virtual void dragLeaveEvent(QDragLeaveEvent* ev) override;
public:
using Super = CPushButton;
@@ -90,7 +93,7 @@ public:
/**
* Virtual Destructor
*/
virtual ~CAutoHideTab();
~CAutoHideTab() override;
/**
* Update stylesheet style if a property changes

View File

@@ -1,15 +1,23 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.16)
project(QtAdvancedDockingSystem LANGUAGES CXX VERSION ${VERSION_SHORT})
include(GNUInstallDirs)
include(Versioning)
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)
set(ads_DEP_LIBS Core Gui Widgets)
if (UNIX AND NOT APPLE AND QT_VERSION_MAJOR STREQUAL "6" AND QT_VERSION_MINOR GREATER 8)
set(ads_DEP_LIBS Core Gui GuiPrivate Widgets)
endif()
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS ${ads_DEP_LIBS} REQUIRED)
if (UNIX AND NOT APPLE AND ((QT_VERSION_MAJOR STREQUAL "6" AND QT_VERSION_MINOR GREATER 8) OR QT_VERSION_MAJOR STREQUAL "5"))
include_directories(${Qt${QT_VERSION_MAJOR}Gui_PRIVATE_INCLUDE_DIRS})
endif()
set(CMAKE_INCLUDE_CURRENT_DIR ON)
if(BUILD_STATIC)
set(CMAKE_STATIC_LIBRARY_SUFFIX "_static${CMAKE_STATIC_LIBRARY_SUFFIX}")
@@ -70,12 +78,15 @@ if (UNIX AND NOT APPLE)
set(ads_HEADERS linux/FloatingWidgetTitleBar.h ${ads_HEADERS})
endif()
set(library_name "qt${QT_VERSION_MAJOR}advanceddocking")
set(library_name "qtadvanceddocking-qt${QT_VERSION_MAJOR}")
if(BUILD_STATIC)
add_library(${library_name} STATIC ${ads_SRCS} ${ads_HEADERS})
target_compile_definitions( ${library_name} PUBLIC ADS_STATIC)
else()
add_library( ${library_name} SHARED ${ads_SRCS} ${ads_HEADERS})
if(WIN32)
add_windows_version_resources(${library_name})
endif()
target_compile_definitions( ${library_name} PRIVATE ADS_SHARED_EXPORT)
endif()
@@ -84,6 +95,11 @@ add_library(ads::${library_name} ALIAS ${library_name})
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 AND QT_VERSION_MAJOR STREQUAL "6")
target_link_libraries(${library_name} PRIVATE Qt6::GuiPrivate) #needed for <qpa/qplatformnativeinterface.h>
endif()
if (UNIX AND NOT APPLE)
if (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
find_package(X11 REQUIRED)
@@ -97,6 +113,7 @@ set_target_properties(${library_name} PROPERTIES
AUTORCC ON
CXX_EXTENSIONS OFF
VERSION ${VERSION_SHORT}
SOVERSION ${VERSION_SONAME}
EXPORT_NAME ${library_name}
DEBUG_POSTFIX "d"
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
@@ -126,7 +143,7 @@ install(FILES ${ads_HEADERS}
install(FILES
"${CMAKE_CURRENT_SOURCE_DIR}/../LICENSE"
"${CMAKE_CURRENT_SOURCE_DIR}/../gnu-lgpl-v2.1.md"
DESTINATION license/ads
DESTINATION share/ads/license
COMPONENT license
)
install(TARGETS ${library_name}

View File

@@ -111,7 +111,7 @@ void DockAreaTabBarPrivate::updateTabs()
// Sometimes the synchronous calculation of the rectangular area fails
// Therefore we use QTimer::singleShot here to execute the call
// within the event loop - see #520
QTimer::singleShot(0, TabWidget, [&, TabWidget]
QTimer::singleShot(0, _this, [&, TabWidget]
{
_this->ensureWidgetVisible(TabWidget);
});
@@ -160,18 +160,8 @@ CDockAreaTabBar::~CDockAreaTabBar()
//============================================================================
void CDockAreaTabBar::wheelEvent(QWheelEvent* Event)
{
Event->accept();
const int direction = Event->angleDelta().y();
if (direction < 0)
{
horizontalScrollBar()->setValue(horizontalScrollBar()->value() + 20);
QCoreApplication::sendEvent(horizontalScrollBar(), Event);
}
else
{
horizontalScrollBar()->setValue(horizontalScrollBar()->value() - 20);
}
}
//============================================================================
void CDockAreaTabBar::setCurrentIndex(int index)
@@ -344,25 +334,11 @@ void CDockAreaTabBar::onTabCloseRequested()
void CDockAreaTabBar::onCloseOtherTabsRequested()
{
auto Sender = qobject_cast<CDockWidgetTab*>(sender());
for (int i = 0; i < count(); ++i)
{
auto Tab = tab(i);
if (Tab->isClosable() && !Tab->isHidden() && Tab != Sender)
{
// If the dock widget is deleted with the closeTab() call, its tab
// it will no longer be in the layout, and thus the index needs to
// be updated to not skip any tabs
int Offset = Tab->dockWidget()->features().testFlag(
CDockWidget::DockWidgetDeleteOnClose) ? 1 : 0;
closeTab(i);
// If the the dock widget blocks closing, i.e. if the flag
// CustomCloseHandling is set, and the dock widget is still open,
// then we do not need to correct the index
if (Tab->dockWidget()->isClosed())
{
i -= Offset;
}
for (int i = count() - 1; i >= 0; --i) {
auto Tab = tab(i);
if (Tab->isClosable() && !Tab->isHidden() && Tab != Sender) {
closeTab(i);
}
}
}
@@ -390,15 +366,18 @@ void CDockAreaTabBar::onTabWidgetMoved(const QPoint& GlobalPos)
int fromIndex = d->TabsLayout->indexOf(MovingTab);
auto MousePos = mapFromGlobal(GlobalPos);
MousePos.rx() = qMax(d->firstTab()->geometry().left(), MousePos.x());
MousePos.rx() = qMin(d->lastTab()->geometry().right(), MousePos.x());
MousePos.rx() = qMax(0, MousePos.x());
MousePos.rx() = qMin(width(), MousePos.x());
int toIndex = -1;
// Find tab under mouse
for (int i = 0; i < count(); ++i)
{
CDockWidgetTab* DropTab = tab(i);
auto TabGeometry = DropTab->geometry();
TabGeometry.setTopLeft(d->TabsContainerWidget->mapToParent(TabGeometry.topLeft()));
TabGeometry.setBottomRight(d->TabsContainerWidget->mapToParent(TabGeometry.bottomRight()));
if (DropTab == MovingTab || !DropTab->isVisibleTo(this)
|| !DropTab->geometry().contains(MousePos))
|| !TabGeometry.contains(MousePos))
{
continue;
}
@@ -470,6 +449,15 @@ bool CDockAreaTabBar::eventFilter(QObject *watched, QEvent *event)
updateGeometry();
break;
// Manage wheel event
case QEvent::Wheel:
// Ignore wheel events if tab is currently dragged
if (Tab->dragState() == DraggingInactive)
{
wheelEvent((QWheelEvent* )event);
}
break;
default:
break;
}
@@ -545,6 +533,13 @@ int CDockAreaTabBar::tabInsertIndexAt(const QPoint& Pos) const
}
}
//===========================================================================
bool CDockAreaTabBar::areTabsOverflowing() const
{
return d->TabsContainerWidget->width() > width();
}
} // namespace ads

View File

@@ -67,7 +67,6 @@ private Q_SLOTS:
protected:
virtual void wheelEvent(QWheelEvent* Event) override;
public:
using Super = QScrollArea;
@@ -153,6 +152,12 @@ public:
*/
virtual QSize sizeHint() const override;
/**
* This function returns true, if the tabs need more space than the size
* of the tab bar.
*/
bool areTabsOverflowing() const;
public Q_SLOTS:
/**
* This property sets the index of the tab bar's visible tab

View File

@@ -114,6 +114,14 @@ struct DockAreaTitleBarPrivate
return DockArea->dockManager();
}
/**
* Convenience function for access to dock manager components factory
*/
QSharedPointer<ads::CDockComponentsFactory> componentsFactory() const
{
return dockManager()->componentsFactory();
}
/**
* Returns true if the given config flag is set
* Convenience function to ease config flag testing
@@ -252,10 +260,10 @@ void DockAreaTitleBarPrivate::createAutoHideTitleLabel()
{
AutoHideTitleLabel = new CElidingLabel("");
AutoHideTitleLabel->setObjectName("autoHideTitleLabel");
// At position 0 is the tab bar - insert behind tab bar
Layout->insertWidget(1, AutoHideTitleLabel);
AutoHideTitleLabel->setVisible(false); // Default hidden
Layout->insertWidget(2 ,new CSpacerWidget(_this));
// When the tabs are at the top, they will be at position 0, insert the label behind them, and hide it.
Layout->addWidget(AutoHideTitleLabel);
AutoHideTitleLabel->setVisible(CDockManager::testConfigFlag(CDockManager::TabsAtBottom));
Layout->addWidget(new CSpacerWidget(_this));
}
@@ -264,7 +272,9 @@ void DockAreaTitleBarPrivate::createTabBar()
{
TabBar = componentsFactory()->createDockAreaTabBar(DockArea);
TabBar->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
if (!CDockManager::testConfigFlag(CDockManager::TabsAtBottom))
Layout->addWidget(TabBar);
_this->connect(TabBar, SIGNAL(tabClosed(int)), SLOT(markTabsMenuOutdated()));
_this->connect(TabBar, SIGNAL(tabOpened(int)), SLOT(markTabsMenuOutdated()));
_this->connect(TabBar, SIGNAL(tabInserted(int)), SLOT(markTabsMenuOutdated()));
@@ -295,7 +305,7 @@ IFloatingWidget* DockAreaTitleBarPrivate::makeAreaFloating(const QPoint& Offset,
else
{
auto w = new CFloatingDragPreview(DockArea);
QObject::connect(w, &CFloatingDragPreview::draggingCanceled, [=]()
QObject::connect(w, &CFloatingDragPreview::draggingCanceled, [this]()
{
this->DragState = DraggingInactive;
});
@@ -343,8 +353,8 @@ CDockAreaTitleBar::CDockAreaTitleBar(CDockAreaWidget* parent) :
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
d->createTabBar();
d->createButtons();
d->createAutoHideTitleLabel();
d->createButtons();
setFocusPolicy(Qt::NoFocus);
}
@@ -377,10 +387,33 @@ CDockAreaTabBar* CDockAreaTitleBar::tabBar() const
return d->TabBar;
}
//============================================================================
void CDockAreaTitleBar::resizeEvent(QResizeEvent *event)
{
Super::resizeEvent(event);
if (CDockManager::testConfigFlag(CDockManager::DockAreaDynamicTabsMenuButtonVisibility)
&& CDockManager::testConfigFlag(CDockManager::DisableTabTextEliding))
{
// Use queued connection to ensure that the resizing and relayouting has
// finished to ensure that the d->TabBar->areTabsOverflowing() function
// returns the correct value
QMetaObject::invokeMethod(this, "markTabsMenuOutdated", Qt::QueuedConnection);
}
}
//============================================================================
void CDockAreaTitleBar::markTabsMenuOutdated()
{
if(DockAreaTitleBarPrivate::testConfigFlag(CDockManager::DockAreaDynamicTabsMenuButtonVisibility))
if (CDockManager::testConfigFlag(CDockManager::DockAreaDynamicTabsMenuButtonVisibility))
{
bool TabsMenuButtonVisible = false;
if (CDockManager::testConfigFlag(CDockManager::DisableTabTextEliding))
{
TabsMenuButtonVisible = d->TabBar->areTabsOverflowing();
}
else
{
bool hasElidedTabTitle = false;
for (int i = 0; i < d->TabBar->count(); ++i)
@@ -396,8 +429,9 @@ void CDockAreaTitleBar::markTabsMenuOutdated()
break;
}
}
bool visible = (hasElidedTabTitle && (d->TabBar->count() > 1));
QMetaObject::invokeMethod(d->TabsMenuButton, "setVisible", Qt::QueuedConnection, Q_ARG(bool, visible));
TabsMenuButtonVisible = (hasElidedTabTitle && (d->TabBar->count() > 1));
}
QMetaObject::invokeMethod(d->TabsMenuButton, "setVisible", Qt::QueuedConnection, Q_ARG(bool, TabsMenuButtonVisible));
}
d->MenuOutdated = true;
}
@@ -709,6 +743,11 @@ void CDockAreaTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
return;
}
if (!CDockManager::testConfigFlag(CDockManager::DoubleClickUndocksWidget))
{
return;
}
d->makeAreaFloating(event->pos(), DraggingInactive);
}
@@ -744,24 +783,35 @@ void CDockAreaTitleBar::contextMenuEvent(QContextMenuEvent* ev)
return;
}
auto Menu = buildContextMenu(nullptr);
Menu->exec(ev->globalPos());
delete Menu;
}
QMenu* CDockAreaTitleBar::buildContextMenu(QMenu *Menu)
{
const bool isAutoHide = d->DockArea->isAutoHide();
const bool isTopLevelArea = d->DockArea->isTopLevelArea();
QAction* Action;
QMenu Menu(this);
if (Menu == nullptr)
{
Menu = new QMenu(this);
}
if (!isTopLevelArea)
{
Action = Menu.addAction(isAutoHide ? tr("Detach") : tr("Detach Group"),
Action = Menu->addAction(isAutoHide ? tr("Detach") : tr("Detach Group"),
this, SLOT(onUndockButtonClicked()));
Action->setEnabled(d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable));
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideFeatureEnabled))
{
Action = Menu.addAction(isAutoHide ? tr("Unpin (Dock)") : tr("Pin Group"), this, SLOT(onAutoHideDockAreaActionClicked()));
Action = Menu->addAction(isAutoHide ? tr("Unpin (Dock)") : tr("Pin Group"), this, SLOT(onAutoHideDockAreaActionClicked()));
auto AreaIsPinnable = d->DockArea->features().testFlag(CDockWidget::DockWidgetPinnable);
Action->setEnabled(AreaIsPinnable);
if (!isAutoHide)
{
auto menu = Menu.addMenu(tr("Pin Group To..."));
auto menu = Menu->addMenu(tr("Pin Group To..."));
menu->setEnabled(AreaIsPinnable);
d->createAutoHideToAction(tr("Top"), SideBarTop, menu);
d->createAutoHideToAction(tr("Left"), SideBarLeft, menu);
@@ -769,28 +819,27 @@ void CDockAreaTitleBar::contextMenuEvent(QContextMenuEvent* ev)
d->createAutoHideToAction(tr("Bottom"), SideBarBottom, menu);
}
}
Menu.addSeparator();
Menu->addSeparator();
}
if (isAutoHide)
{
Action = Menu.addAction(tr("Minimize"), this, SLOT(minimizeAutoHideContainer()));
Action = Menu.addAction(tr("Close"), this, SLOT(onAutoHideCloseActionTriggered()));
Action = Menu->addAction(tr("Minimize"), this, SLOT(minimizeAutoHideContainer()));
Action = Menu->addAction(tr("Close"), this, SLOT(onAutoHideCloseActionTriggered()));
}
else
{
Action = Menu.addAction(isAutoHide ? tr("Close") : tr("Close Group"), this, SLOT(onCloseButtonClicked()));
Action = Menu->addAction(isAutoHide ? tr("Close") : tr("Close Group"), this, SLOT(onCloseButtonClicked()));
}
Action->setEnabled(d->DockArea->features().testFlag(CDockWidget::DockWidgetClosable));
if (!isAutoHide && !isTopLevelArea)
{
Action = Menu.addAction(tr("Close Other Groups"), d->DockArea, SLOT(closeOtherAreas()));
Action = Menu->addAction(tr("Close Other Groups"), d->DockArea, SLOT(closeOtherAreas()));
}
Menu.exec(ev->globalPos());
return Menu;
}
//============================================================================
void CDockAreaTitleBar::insertWidget(int index, QWidget *widget)
{
@@ -853,8 +902,11 @@ QString CDockAreaTitleBar::titleBarButtonToolTip(TitleBarButton Button) const
//============================================================================
void CDockAreaTitleBar::showAutoHideControls(bool Show)
{
d->TabBar->setVisible(!Show); // Auto hide toolbar never has tabs
if (Show)
d->TabBar->setVisible(false); // Auto hide toolbar never has tabs
d->MinimizeButton->setVisible(Show);
if (!CDockManager::testConfigFlag(CDockManager::TabsAtBottom))
d->AutoHideTitleLabel->setVisible(Show);
}

View File

@@ -152,6 +152,11 @@ protected:
*/
virtual void contextMenuEvent(QContextMenuEvent *event) override;
/**
* Handle resize events
*/
virtual void resizeEvent(QResizeEvent *event) override;
public Q_SLOTS:
/**
* Call this slot to tell the title bar that it should update the tabs menu
@@ -171,7 +176,7 @@ public:
/**
* Virtual Destructor
*/
virtual ~CDockAreaTitleBar();
~CDockAreaTitleBar() override;
/**
* Returns the pointer to the tabBar()
@@ -244,6 +249,20 @@ public:
*/
bool isAutoHide() const;
/**
* Fills the provided menu with standard entries. If a nullptr is passed, a
* new menu is created and filled with standard entries.
* This function is called from the actual version of contextMenuEvent, but
* can be called from any code. Caller is responsible of deleting the created
* object.
*
* @param menu The QMenu to fill with standard entries. If nullptr, a new
* QMenu will be created.
* @return The filled QMenu, either the provided one or a newly created one if
* nullptr was passed.
*/
virtual QMenu *buildContextMenu(QMenu *);
Q_SIGNALS:
/**
* This signal is emitted if a tab in the tab bar is clicked by the user

View File

@@ -34,7 +34,6 @@
#include <QStackedLayout>
#include <QScrollBar>
#include <QWheelEvent>
#include <QStyle>
#include <QPushButton>
#include <QDebug>
@@ -180,14 +179,17 @@ public:
parent->setUpdatesEnabled(false);
}
if (m_CurrentWidget)
{
auto LayoutItem = m_ParentLayout->takeAt(1);
if (LayoutItem)
{
LayoutItem->widget()->setParent(nullptr);
}
delete LayoutItem;
}
m_ParentLayout->addWidget(next);
m_ParentLayout->insertWidget(1, next);
if (prev)
{
prev->hide();
@@ -270,6 +272,14 @@ struct DockAreaWidgetPrivate
*/
DockAreaWidgetPrivate(CDockAreaWidget* _public);
/**
* Convenience function to ease components factory access
*/
QSharedPointer<ads::CDockComponentsFactory> componentsFactory() const
{
return DockManager->componentsFactory();
}
/**
* Creates the layout for top area with tabs and close button
*/
@@ -355,6 +365,14 @@ void DockAreaWidgetPrivate::createTitleBar()
{
TitleBar = componentsFactory()->createDockAreaTitleBar(_this);
Layout->addWidget(TitleBar);
if (CDockManager::testConfigFlag(CDockManager::TabsAtBottom))
{
// Title bar will be index 0, container widgets will be index 1,
// so tabs will always be at the end of the layout.
Layout->addWidget(tabBar());
tabBar()->setVisible(CDockManager::testConfigFlag(CDockManager::AlwaysShowTabs));
}
QObject::connect(tabBar(), &CDockAreaTabBar::tabCloseRequested, _this, &CDockAreaWidget::onTabCloseRequested);
QObject::connect(TitleBar, &CDockAreaTitleBar::tabBarClicked, _this, &CDockAreaWidget::setCurrentIndex);
QObject::connect(tabBar(), &CDockAreaTabBar::tabMoved, _this, &CDockAreaWidget::reorderDockWidget);
@@ -442,6 +460,12 @@ CDockAreaWidget::CDockAreaWidget(CDockManager* DockManager, CDockContainerWidget
d->createTitleBar();
d->ContentsLayout = new DockAreaLayout(d->Layout);
if (CDockManager::testConfigFlag(CDockManager::UseNativeWindows))
{
winId();
}
if (d->DockManager)
{
Q_EMIT d->DockManager->dockAreaCreated(this);
@@ -585,8 +609,7 @@ void CDockAreaWidget::removeDockWidget(CDockWidget* DockWidget)
{
if(CFloatingDockContainer* FloatingDockContainer = DockContainer->floatingWidget())
{
FloatingDockContainer->hide();
FloatingDockContainer->deleteLater();
FloatingDockContainer->finishDropOperation();
}
}
}
@@ -719,6 +742,7 @@ void CDockAreaWidget::setCurrentIndex(int index)
TabBar->setCurrentIndex(index);
d->ContentsLayout->setCurrentIndex(index);
d->ContentsLayout->currentWidget()->show();
d->TitleBar->autoHideTitleLabel()->setText(d->ContentsLayout->currentWidget()->windowTitle());
Q_EMIT currentChanged(index);
}
@@ -865,11 +889,40 @@ void CDockAreaWidget::updateTitleBarVisibility()
bool IsAutoHide = isAutoHide();
if (!CDockManager::testConfigFlag(CDockManager::AlwaysShowTabs))
{
bool Hidden = Container->hasTopLevelDockWidget() && (Container->isFloating()
|| CDockManager::testConfigFlag(CDockManager::HideSingleCentralWidgetTitleBar));
Hidden |= (d->Flags.testFlag(HideSingleWidgetTitleBar) && openDockWidgetsCount() == 1);
Hidden &= !IsAutoHide; // Titlebar must always be visible when auto hidden so it can be dragged
bool Hidden = false;
if (!IsAutoHide) // Titlebar must always be visible when auto hidden so it can be dragged
{
if (Container->isFloating() || CDockManager::testConfigFlag(CDockManager::HideSingleCentralWidgetTitleBar))
{
// Always show title bar if it contains title bar actions
if (CDockWidget* TopLevelWidget = Container->topLevelDockWidget())
{
Hidden |= TopLevelWidget->titleBarActions().empty();
}
else if (CDockManager::testConfigFlag(CDockManager::TabsAtBottom))
{
Hidden = true;
for (CDockWidget* DockWidget : Container->openedDockWidgets())
{
if (!DockWidget->titleBarActions().empty())
{
Hidden = false;
break;
}
}
}
}
if (!Hidden && d->Flags.testFlag(HideSingleWidgetTitleBar))
{
// Always show title bar if it contains title bar actions
auto DockWidgets = openedDockWidgets();
Hidden |= (DockWidgets.size() == 1) && DockWidgets.front()->titleBarActions().empty();
}
}
d->TitleBar->setVisible(!Hidden);
if (CDockManager::testConfigFlag(CDockManager::TabsAtBottom))
d->TitleBar->tabBar()->setVisible(openDockWidgetsCount() > 1);
}
if (isAutoHideFeatureEnabled())
@@ -880,6 +933,19 @@ void CDockAreaWidget::updateTitleBarVisibility()
}
//============================================================================
void CDockAreaWidget::updateWindowTitle()
{
auto currentWidget = d->ContentsLayout->currentWidget();
if (d->TitleBar && currentWidget)
{
d->TitleBar->autoHideTitleLabel()->setText(currentWidget->windowTitle());
}
markTitleBarMenuOutdated();
}
//============================================================================
void CDockAreaWidget::markTitleBarMenuOutdated()
{
@@ -1433,14 +1499,18 @@ QSize CDockAreaWidget::minimumSizeHint() const
return Super::minimumSizeHint();
}
int extraHeight = 0;
if (d->TitleBar->isVisible())
{
return d->MinSizeHint + QSize(0, d->TitleBar->minimumSizeHint().height());
extraHeight += d->TitleBar->minimumSizeHint().height();
}
else
if (CDockManager::testConfigFlag(CDockManager::TabsAtBottom) && d->tabBar()->isVisible())
{
return d->MinSizeHint;
extraHeight += d->tabBar()->minimumSizeHint().height();
}
return d->MinSizeHint + QSize(0, extraHeight);
}

View File

@@ -38,6 +38,7 @@
QT_FORWARD_DECLARE_CLASS(QXmlStreamWriter)
QT_FORWARD_DECLARE_CLASS(QAbstractButton)
QT_FORWARD_DECLARE_CLASS(QMenu)
namespace ads
{
@@ -164,6 +165,11 @@ protected:
*/
void internalSetCurrentDockWidget(CDockWidget* DockWidget);
/**
* Call this function to update the window title
*/
void updateWindowTitle();
/**
* Marks tabs menu to update
*/
@@ -198,7 +204,7 @@ public:
/**
* Virtual Destructor
*/
virtual ~CDockAreaWidget();
~CDockAreaWidget() override;
/**
* Returns the dock manager object this dock area belongs to

View File

@@ -21,7 +21,8 @@
namespace ads
{
static std::unique_ptr<CDockComponentsFactory> DefaultFactory(new CDockComponentsFactory());
static QSharedPointer<ads::CDockComponentsFactory> DefaultFactory;
//============================================================================
@@ -52,9 +53,13 @@ CDockAreaTitleBar* CDockComponentsFactory::createDockAreaTitleBar(CDockAreaWidge
//============================================================================
const CDockComponentsFactory* CDockComponentsFactory::factory()
QSharedPointer<ads::CDockComponentsFactory> CDockComponentsFactory::factory()
{
return DefaultFactory.get();
if (!DefaultFactory)
{
DefaultFactory.reset(new CDockComponentsFactory());
}
return DefaultFactory;
}
@@ -70,6 +75,7 @@ void CDockComponentsFactory::resetDefaultFactory()
{
DefaultFactory.reset(new CDockComponentsFactory());
}
} // namespace ads
//---------------------------------------------------------------------------

View File

@@ -66,9 +66,11 @@ public:
virtual CDockAreaTitleBar* createDockAreaTitleBar(CDockAreaWidget* DockArea) const;
/**
* Returns the default components factory
* This returns the default dock components factory instance.
* If no components factory is assigned to a specific dock manager, this
* global factory instance will be used.
*/
static const CDockComponentsFactory* factory();
static QSharedPointer<ads::CDockComponentsFactory> factory();
/**
* Sets a new default factory for creation of GUI elements.
@@ -82,15 +84,6 @@ public:
static void resetDefaultFactory();
};
/**
* Convenience function to ease factory instance access
*/
inline const CDockComponentsFactory* componentsFactory()
{
return CDockComponentsFactory::factory();
}
} // namespace ads
//---------------------------------------------------------------------------

View File

@@ -907,6 +907,7 @@ void DockContainerWidgetPrivate::addDockAreasToList(const QList<CDockAreaWidget*
{
DockArea->titleBarButton(TitleBarButtonClose)->setVisible(true);
DockArea->titleBarButton(TitleBarButtonAutoHide)->setVisible(true);
DockArea->titleBarButton(TitleBarButtonUndock)->setVisible(true);
}
// We need to ensure, that the dock area title bar is visible. The title bar
@@ -1572,8 +1573,20 @@ void CDockContainerWidget::removeDockArea(CDockAreaWidget* area)
d->DockAreas.removeAll(area);
auto Splitter = area->parentSplitter();
// Remove are from parent splitter and recursively hide tree of parent
// splitters if it has no visible content
// Remove area from parent splitter and recursively hide tree of parent
// splitters if it has no visible content.
// Use internalWinId() rather than testAttribute(WA_NativeWindow) because
// WA_NativeWindow is only set when a widget is *explicitly* made native
// (e.g. winId() called directly on it). Widgets that became native through
// propagation from a child calling winId() (e.g. a VTK/OpenGL widget) also
// hold a real native window handle but may not have WA_NativeWindow set.
// Setting the parent of such a native window to nullptr would make it an
// invisible top-level OS window, causing drawing artifacts. Reparent to
// the dock manager instead so the window stays off-screen but within the
// application's window hierarchy.
if (area->internalWinId())
area->setParent(d->DockManager);
else
area->setParent(nullptr);
internal::hideEmptyParentSplitters(Splitter);
@@ -2204,6 +2217,17 @@ CDockManager* CDockContainerWidget::dockManager() const
}
//===========================================================================
void CDockContainerWidget::removeFromDockManager()
{
if (d->DockManager)
{
d->DockManager->removeDockContainer(this);
d->DockManager.clear();
}
}
//===========================================================================
void CDockContainerWidget::handleAutoHideWidgetEvent(QEvent* e, QWidget* w)
{

View File

@@ -60,7 +60,7 @@ struct AutoHideDockContainerPrivate;
/**
* Container that manages a number of dock areas with single dock widgets
* or tabyfied dock widgets in each area.
* or tabified dock widgets in each area.
* Each window that support docking has a DockContainerWidget. That means
* the main application window and all floating windows contain a
* DockContainerWidget instance.
@@ -86,6 +86,9 @@ private:
friend AutoHideDockContainerPrivate;
friend CAutoHideSideBar;
private Q_SLOTS:
void removeFromDockManager();
protected:
/**
* Handles activation events to update zOrderIndex
@@ -219,7 +222,7 @@ public:
/**
* Virtual Destructor
*/
virtual ~CDockContainerWidget();
~CDockContainerWidget() override;
/**
* Adds dockwidget into the given area.

View File

@@ -423,6 +423,13 @@ CDockWidget* CDockFocusController::focusedDockWidget() const
}
//==========================================================================
CDockAreaWidget* CDockFocusController::focusedDockArea() const
{
return d->FocusedArea.data();
}
//==========================================================================
void CDockFocusController::setDockWidgetTabPressed(bool Value)
{

View File

@@ -69,6 +69,12 @@ public:
*/
CDockWidget* focusedDockWidget() const;
/**
* Returns the dock area that contains the focusedDockWidget() or nullptr if
* the focused dock widget is not in this area.
*/
CDockAreaWidget* focusedDockArea() const;
/**
* Request focus highlighting for the given dock widget assigned to the tab
* given in Tab parameter

View File

@@ -41,6 +41,7 @@
#include <QVariant>
#include <QDebug>
#include <QFile>
#include <QDialog>
#include <QAction>
#include <QXmlStreamWriter>
#include <QSettings>
@@ -48,6 +49,7 @@
#include <QApplication>
#include <QWindow>
#include <QWindowStateChangeEvent>
#include <QVector>
#include "FloatingDockContainer.h"
#include "DockOverlay.h"
@@ -59,6 +61,8 @@
#include "DockAreaTitleBar.h"
#include "DockFocusController.h"
#include "DockSplitter.h"
#include "DockComponentsFactory.h"
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
#include "linux/FloatingWidgetTitleBar.h"
@@ -94,6 +98,7 @@ enum eStateFileVersion
static CDockManager::ConfigFlags StaticConfigFlags = CDockManager::DefaultNonOpaqueConfig;
static CDockManager::AutoHideFlags StaticAutoHideConfigFlags; // auto hide feature is disabled by default
static QVector<QVariant> StaticConfigParams(CDockManager::ConfigParamCount);
static QString FloatingContainersTitle;
@@ -123,6 +128,7 @@ struct DockManagerPrivate
QSize ToolBarIconSizeDocked = QSize(16, 16);
QSize ToolBarIconSizeFloating = QSize(24, 24);
CDockWidget::DockWidgetFeatures LockedDockWidgetFeatures;
QSharedPointer<ads::CDockComponentsFactory> ComponentFactory {ads::CDockComponentsFactory::factory()};
/**
* Private data constructor
@@ -197,6 +203,10 @@ DockManagerPrivate::DockManagerPrivate(CDockManager* _public) :
//============================================================================
void DockManagerPrivate::loadStylesheet()
{
if (CDockManager::testConfigFlag(CDockManager::DisableStylesheet))
{
return;
}
initResource();
QString Result;
QString FileName = ":ads/stylesheets/";
@@ -525,14 +535,45 @@ CDockManager::CDockManager(QWidget *parent) :
window()->installEventFilter(this);
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
connect(qApp, &QApplication::focusWindowChanged, [](QWindow* focusWindow)
connect(qApp, &QApplication::focusWindowChanged, this, [this](QWindow* focusWindow)
{
// bring modal dialogs to foreground to ensure that they are in front of any
// floating dock widget
if (focusWindow && focusWindow->isModal())
if (!focusWindow)
{
focusWindow->raise();
return;
}
auto widget = QWidget::find(focusWindow->winId());
if (!widget)
{
return;
}
// If the user clicks the main window or drags a floating widget or works with a
// modal dialog, then raise the main window, all floating widgets and the focus window
// itself to bring it into foreground of any other application.
bool raise = qobject_cast<QMainWindow*>(widget)
|| qobject_cast<ads::CFloatingDockContainer*>(widget);
if (auto dialog = qobject_cast<QDialog*>(widget))
{
raise |= dialog->isModal();
}
if (!raise)
{
return;
}
this->raise();
for (auto FloatingWidget : d->FloatingWidgets)
{
if (FloatingWidget)
{
FloatingWidget->raise();
}
}
// ensure that the dragged floating window is in front of the main application window
// and any other floating widget - this will also ensure that modal dialogs come to foreground
focusWindow->raise();
});
#endif
}
@@ -550,7 +591,7 @@ CDockManager::~CDockManager()
{
if (!area || area->dockManager() != this) continue;
// QPointer delete safety - just in case some dock wigdet in destruction
// QPointer delete safety - just in case some dock widget in destruction
// deletes another related/twin or child dock widget.
std::vector<QPointer<QWidget>> deleteWidgets;
for ( auto widget : area->dockWidgets() )
@@ -579,6 +620,35 @@ CDockManager::~CDockManager()
delete d;
}
//============================================================================
CDockWidget* CDockManager::createDockWidget(const QString &title, QWidget* parent)
{
return new CDockWidget(this, title, parent);
}
//============================================================================
QSharedPointer<ads::CDockComponentsFactory> CDockManager::componentsFactory() const
{
return d->ComponentFactory;
}
//============================================================================
void CDockManager::setComponentsFactory(ads::CDockComponentsFactory* factory)
{
setComponentsFactory(QSharedPointer<ads::CDockComponentsFactory>(factory));
}
//============================================================================
void CDockManager::setComponentsFactory(QSharedPointer<ads::CDockComponentsFactory> factory)
{
d->ComponentFactory = factory;
}
//============================================================================
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
bool CDockManager::eventFilter(QObject *obj, QEvent *e)
@@ -702,7 +772,8 @@ void CDockManager::registerFloatingWidget(CFloatingDockContainer* FloatingWidget
//============================================================================
void CDockManager::removeFloatingWidget(CFloatingDockContainer* FloatingWidget)
{
d->FloatingWidgets.removeAll(FloatingWidget);
int removed = d->FloatingWidgets.removeAll(FloatingWidget);
Q_ASSERT(removed == 1);
}
//============================================================================
@@ -717,7 +788,8 @@ void CDockManager::removeDockContainer(CDockContainerWidget* DockContainer)
{
if (this != DockContainer)
{
d->Containers.removeAll(DockContainer);
int removed = d->Containers.removeAll(DockContainer);
Q_ASSERT(removed == 1);
}
}
@@ -1475,6 +1547,30 @@ CDockWidget::DockWidgetFeatures CDockManager::globallyLockedDockWidgetFeatures()
}
//===========================================================================
void CDockManager::setConfigParam(CDockManager::eConfigParam Param, QVariant Value)
{
StaticConfigParams[Param] = Value;
}
//===========================================================================
QVariant CDockManager::configParam(eConfigParam Param, QVariant Default)
{
return StaticConfigParams[Param].isValid() ? StaticConfigParams[Param] : Default;
}
//===========================================================================
void CDockManager::raise()
{
if (parentWidget())
{
parentWidget()->raise();
}
}
} // namespace ads
//---------------------------------------------------------------------------

View File

@@ -64,8 +64,13 @@ struct AutoHideTabPrivate;
* of the docking system. The dock manager uses an internal stylesheet to
* style its components like splitters, tabs and buttons. If you want to
* disable this stylesheet because your application uses its own,
* just call the function for settings the stylesheet with an empty
* string.
* you can either set the DisableStylesheet config flag before creating
* the dock manager:
* \code
* CDockManager::setConfigFlag(CDockManager::DisableStylesheet, true);
* \endcode
* Or call the function for settings the stylesheet with an empty string
* after creating the dock manager:
* \code
* DockManager->setStyleSheet("");
* \endcode
@@ -215,6 +220,11 @@ public:
MiddleMouseButtonClosesTab = 0x2000000, //! If the flag is set, the user can use the mouse middle button to close the tab under the mouse
DisableTabTextEliding = 0x4000000, //! Set this flag to disable eliding of tab texts in dock area tabs
ShowTabTextOnlyForActiveTab =0x8000000, //! Set this flag to show label texts in dock area tabs only for active tabs
DoubleClickUndocksWidget = 0x10000000, //!< If the flag is set, a double click on a tab undocks the widget
TabsAtBottom = 0x20000000, //!< If the flag is set, tabs will be shown at the bottom instead of in the title bar.
UseNativeWindows = 0x40000000, //!< If the flag is set, windows for the dock and area widgets will be native.
DisableStylesheet = 0x80000000, //!< If the flag is set, the dock manager will not apply the default stylesheet
DefaultDockAreaButtons = DockAreaHasCloseButton
| DockAreaHasUndockButton
@@ -223,7 +233,8 @@ public:
DefaultBaseConfig = DefaultDockAreaButtons
| ActiveTabHasCloseButton
| XmlCompressionEnabled
| FloatingContainerHasWidgetTitle, ///< default base configuration settings
| FloatingContainerHasWidgetTitle
| DoubleClickUndocksWidget, ///< default base configuration settings
DefaultOpaqueConfig = DefaultBaseConfig
| OpaqueSplitterResize
@@ -254,14 +265,26 @@ public:
AutoHideCloseButtonCollapsesDock = 0x40, ///< Close button of an auto hide container collapses the dock instead of hiding it completely
AutoHideHasCloseButton = 0x80, //< If the flag is set an auto hide title bar has a close button
AutoHideHasMinimizeButton = 0x100, ///< if this flag is set, the auto hide title bar has a minimize button to collapse the dock widget
AutoHideOpenOnDragHover = 0x200, ///< if this flag is set, dragging hover the tab bar will open the dock
AutoHideCloseOnOutsideMouseClick = 0x400, ///< if this flag is set, the auto hide dock container will collapse if the user clicks outside of the container, if not set, the auto hide container can be closed only via click on sidebar tab
DefaultAutoHideConfig = AutoHideFeatureEnabled
| DockAreaHasAutoHideButton
| AutoHideHasMinimizeButton
| AutoHideCloseOnOutsideMouseClick
};
Q_DECLARE_FLAGS(AutoHideFlags, eAutoHideFlag)
/**
* Global configuration parameters that you can set via setConfigParam()
*/
enum eConfigParam
{
AutoHideOpenOnDragHoverDelay_ms, ///< Delay in ms before the dock opens on drag hover if AutoHideOpenOnDragHover flag is set
ConfigParamCount // just a delimiter to count number of config params
};
/**
* Default Constructor.
@@ -277,6 +300,39 @@ public:
*/
virtual ~CDockManager() override;
/**
* Creates a new dock widget with the specified title and optional parent
* widget.
*
* The new dock widget will be managed by the dock manager, and its lifetime
* will be tied to the dock manager. If a parent widget is provided, the dock
* widget will be created as a child of the parent widget. If no parent widget
* is provided, the dock widget will be created as a top-level widget.
*
* @param title The title of the dock widget.
* @param parent The parent widget, if any. Defaults to nullptr.
* @return Returns a pointer to the created CDockWidget.
*/
CDockWidget *createDockWidget(const QString &title, QWidget* parent = nullptr);
/**
* Returns the dock manager specific factory for creating components of
* fock widgets
*/
QSharedPointer<ads::CDockComponentsFactory> componentsFactory() const;
/**
* Sets a custom factory for creating components of dock widgets.
* The pointer is stored internally into a shared pointer so you should not
* delete the given factory object as long as it is used by the dock manager.
*/
void setComponentsFactory(ads::CDockComponentsFactory* Factory);
/**
* Sets a custom factory for creating components of dock widgets.
*/
void setComponentsFactory(QSharedPointer<ads::CDockComponentsFactory>);
/**
* This function returns the global configuration flags
*/
@@ -323,6 +379,17 @@ public:
*/
static bool testAutoHideConfigFlag(eAutoHideFlag Flag);
/**
* Sets the value for the given config parameter
*/
static void setConfigParam(eConfigParam Param, QVariant Value);
/**
* Returns the value for the given config parameter or the default value
* if the parameter is not set.
*/
static QVariant configParam(eConfigParam Param, QVariant Default);
/**
* Returns the global icon provider.
* The icon provider enables the use of custom icons in case using
@@ -711,6 +778,12 @@ public Q_SLOTS:
*/
void hideManagerAndFloatingWidgets();
/**
* Calls raise() for the widget that hosts this dock manager.
* This will bring the widget in front of any other application that is running
*/
void raise();
Q_SIGNALS:
/**
* This signal is emitted if the list of perspectives changed.

View File

@@ -96,12 +96,21 @@ struct DockWidgetPrivate
WidgetFactory* Factory = nullptr;
QPointer<CAutoHideTab> SideTabWidget;
CDockWidget::eToolBarStyleSource ToolBarStyleSource = CDockWidget::ToolBarStyleFromDockManager;
SideBarLocation PreferredAutoHideSideBarLocation = SideBarNone;
/**
* Private data constructor
*/
DockWidgetPrivate(CDockWidget* _public);
/**
* Convenience function to ease components factory access
*/
QSharedPointer<ads::CDockComponentsFactory> componentsFactory() const
{
return DockManager ? DockManager->componentsFactory() : CDockComponentsFactory::factory();
}
/**
* Show dock widget
*/
@@ -358,9 +367,17 @@ void DockWidgetPrivate::setToolBarStyleFromDockManager()
//============================================================================
CDockWidget::CDockWidget(const QString &title, QWidget *parent) :
QFrame(parent),
CDockWidget(nullptr, title, parent)
{
}
//============================================================================
CDockWidget::CDockWidget(CDockManager *manager, const QString &title, QWidget* parent)
: QFrame(parent),
d(new DockWidgetPrivate(this))
{
d->DockManager = manager;
d->Layout = new QBoxLayout(QBoxLayout::TopToBottom);
d->Layout->setContentsMargins(0, 0, 0, 0);
d->Layout->setSpacing(0);
@@ -368,7 +385,7 @@ CDockWidget::CDockWidget(const QString &title, QWidget *parent) :
setWindowTitle(title);
setObjectName(title);
d->TabWidget = componentsFactory()->createDockWidgetTab(this);
d->TabWidget = d->componentsFactory()->createDockWidgetTab(this);
d->ToggleViewAction = new QAction(title, this);
d->ToggleViewAction->setCheckable(true);
@@ -380,7 +397,13 @@ CDockWidget::CDockWidget(const QString &title, QWidget *parent) :
{
setFocusPolicy(Qt::ClickFocus);
}
if (CDockManager::testConfigFlag(CDockManager::UseNativeWindows))
{
winId();
}
}
//============================================================================
CDockWidget::~CDockWidget()
@@ -632,6 +655,20 @@ SideBarLocation CDockWidget::autoHideLocation() const
}
//============================================================================
void CDockWidget::setPreferredAutoHideSideBarLocation(SideBarLocation Location)
{
d->PreferredAutoHideSideBarLocation = Location;
}
//============================================================================
SideBarLocation CDockWidget::preferredAutoHideSideBarLocation() const
{
return d->PreferredAutoHideSideBarLocation;
}
//============================================================================
bool CDockWidget::isFloating() const
{
@@ -824,9 +861,9 @@ void CDockWidget::saveState(QXmlStreamWriter& s) const
void CDockWidget::flagAsUnassigned()
{
d->Closed = true;
setParent(d->DockManager);
setVisible(false);
setDockArea(nullptr);
setParent(d->DockManager);
tabWidget()->setParent(this);
}
@@ -861,7 +898,7 @@ bool CDockWidget::event(QEvent *e)
}
if (d->DockArea)
{
d->DockArea->markTitleBarMenuOutdated();//update tabs menu
d->DockArea->updateWindowTitle();
}
auto FloatingWidget = floatingDockContainer();
@@ -1315,7 +1352,15 @@ void CDockWidget::setAutoHide(bool Enable, SideBarLocation Location, int TabInde
}
else
{
auto area = (SideBarNone == Location) ? DockArea->calculateSideTabBarArea() : Location;
auto area = Location;
if (SideBarNone == area && d->PreferredAutoHideSideBarLocation != SideBarNone)
{
area = d->PreferredAutoHideSideBarLocation;
}
else if (SideBarNone == area)
{
area = DockArea->calculateSideTabBarArea();
}
dockContainer()->createAndSetupAutoHideContainer(area, this, TabIndex);
}
}

View File

@@ -256,13 +256,40 @@ public:
* during runtime, you need to set a unique object name explicitly
* by calling setObjectName() after construction.
* Use the layoutFlags to configure the layout of the dock widget.
* \note If you would like to use custom TabWidget implementations, you need
* to use the constructor with the CDockManager argument.
*/
CDockWidget(const QString &title, QWidget* parent = nullptr);
Q_DECL_DEPRECATED explicit CDockWidget(const QString &title, QWidget* parent = nullptr);
/**
* This constructor creates a dock widget for the given dock manager with the
* provided title.
*
* @param manager Pointer to the dock manager that owns the dock widget.
* @param title The title is the text that is shown in the window title when
* the dock widget is floating and it is the title that is shown in the
* titlebar or the tab of this dock widget if it is tabified.
* @param parent Pointer to the parent widget, defaults to nullptr.
*
* @note The object name of the dock widget is also set to the title. The
* object name is required by the dock manager to properly save and restore
* the state of the dock widget. That means, the title needs to be unique. If
* the title is not unique or if you would like to change the title during
* runtime, you need to set a unique object name explicitly by calling
* setObjectName() after construction. Use the layoutFlags to configure the
* layout of the dock widget.
*
* @note this constructor is preferred over the two argument version, especially
* when custom factories are in use. Indeed, it will use the Dock Manager factory,
* and not the default factory. For this reason, the original constructor should
* be deprecated in favour of this version.
*/
CDockWidget(CDockManager *manager, const QString &title, QWidget* parent = nullptr);
/**
* Virtual Destructor
*/
virtual ~CDockWidget();
~CDockWidget() override;
/**
* We return a fixed minimum size hint or the size hint of the content
@@ -395,6 +422,22 @@ public:
*/
SideBarLocation autoHideLocation() const;
/**
* Sets the preferred auto-hide sidebar location for this dock widget.
* When set to a value other than SideBarNone, the pin button will place
* this widget in the specified sidebar instead of using geometry-based
* detection. When unpinning, widgets with the same preferred location
* will be merged as tabs in the same dock area.
* Set to SideBarNone (default) to use the original geometry-based behavior.
*/
void setPreferredAutoHideSideBarLocation(SideBarLocation Location);
/**
* Returns the preferred auto-hide sidebar location, or SideBarNone
* if no preference is set (geometry-based detection will be used).
*/
SideBarLocation preferredAutoHideSideBarLocation() 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

View File

@@ -50,7 +50,6 @@
#include "FloatingDockContainer.h"
#include "DockOverlay.h"
#include "DockManager.h"
#include "IconProvider.h"
#include "DockFocusController.h"
@@ -170,7 +169,7 @@ struct DockWidgetTabPrivate
else
{
auto w = new CFloatingDragPreview(Widget);
_this->connect(w, &CFloatingDragPreview::draggingCanceled, [=]()
_this->connect(w, &CFloatingDragPreview::draggingCanceled, [this]()
{
DragState = DraggingInactive;
});
@@ -529,26 +528,35 @@ void CDockWidgetTab::contextMenuEvent(QContextMenuEvent* ev)
return;
}
auto Menu = buildContextMenu(nullptr);
d->saveDragStartMousePosition(ev->globalPos());
Menu->exec(ev->globalPos());
}
const bool isFloatable = d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable);
const bool isNotOnlyTabInContainer = !d->DockArea->dockContainer()->hasTopLevelDockWidget();
const bool isTopLevelArea = d->DockArea->isTopLevelArea();
const bool isDetachable = isFloatable && isNotOnlyTabInContainer;
QAction* Action;
QMenu Menu(this);
if (!isTopLevelArea)
QMenu* CDockWidgetTab::buildContextMenu(QMenu *Menu)
{
Action = Menu.addAction(tr("Detach"), this, SLOT(detachDockWidget()));
if (Menu == nullptr) {
Menu = new QMenu(this);
}
ADS_PRINT("CDockWidgetTab::buildContextMenu");
const bool isFloatable = d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable);
const bool isTopLevelArea = d->DockArea->isTopLevelArea();
const bool isFloating = d->DockWidget->isFloating();
const bool isDetachable = isFloatable && !isFloating;
QAction* Action;
if (!(isTopLevelArea && isFloating))
{
Action = Menu->addAction(tr("Detach"), this, SLOT(detachDockWidget()));
Action->setEnabled(isDetachable);
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideFeatureEnabled))
{
Action = Menu.addAction(tr("Pin"), this, SLOT(autoHideDockWidget()));
Action = Menu->addAction(tr("Pin"), this, SLOT(autoHideDockWidget()));
auto IsPinnable = d->DockWidget->features().testFlag(CDockWidget::DockWidgetPinnable);
Action->setEnabled(IsPinnable);
auto menu = Menu.addMenu(tr("Pin To..."));
auto menu = Menu->addMenu(tr("Pin To..."));
menu->setEnabled(IsPinnable);
d->createAutoHideToAction(tr("Top"), SideBarTop, menu);
d->createAutoHideToAction(tr("Left"), SideBarLeft, menu);
@@ -557,17 +565,16 @@ void CDockWidgetTab::contextMenuEvent(QContextMenuEvent* ev)
}
}
Menu.addSeparator();
Action = Menu.addAction(tr("Close"), this, SIGNAL(closeRequested()));
Menu->addSeparator();
Action = Menu->addAction(tr("Close"), this, SIGNAL(closeRequested()));
Action->setEnabled(isClosable());
if (d->DockArea->openDockWidgetsCount() > 1)
{
Action = Menu.addAction(tr("Close Others"), this, SIGNAL(closeOtherTabsRequested()));
}
Menu.exec(ev->globalPos());
Menu->addAction(tr("Close Others"), this, SIGNAL(closeOtherTabsRequested()));
}
return Menu;
}
//============================================================================
bool CDockWidgetTab::isActiveTab() const
{
@@ -592,9 +599,9 @@ void CDockWidgetTab::setActiveTab(bool active)
if (CDockManager::testConfigFlag(CDockManager::FocusHighlighting) && !d->DockWidget->dockManager()->isRestoringState())
{
bool UpdateFocusStyle = false;
if (active && !hasFocus())
// Update the focus only, if this the dock area of this tab is the focused dock area
if (active && !hasFocus() && (d->focusController()->focusedDockArea() == this->dockAreaWidget()))
{
//setFocus(Qt::OtherFocusReason);
d->focusController()->setDockWidgetTabFocused(this);
UpdateFocusStyle = true;
}
@@ -692,7 +699,7 @@ QString CDockWidgetTab::text() const
//============================================================================
void CDockWidgetTab::mouseDoubleClickEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
if (event->button() == Qt::LeftButton && CDockManager::testConfigFlag(CDockManager::DoubleClickUndocksWidget))
{
// 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
@@ -789,6 +796,13 @@ bool CDockWidgetTab::event(QEvent *e)
}
//============================================================================
eDragState CDockWidgetTab::dragState() const
{
return d->DragState;
}
//============================================================================
void CDockWidgetTab::onDockWidgetFeaturesChanged()
{

View File

@@ -35,6 +35,8 @@
#include "ads_globals.h"
QT_FORWARD_DECLARE_CLASS(QMenu)
namespace ads
{
class CDockWidget;
@@ -89,7 +91,7 @@ public:
/**
* Virtual Destructor
*/
virtual ~CDockWidgetTab();
~CDockWidgetTab() override;
/**
* Returns true, if this is the active tab
@@ -178,6 +180,26 @@ public:
*/
void setIconSize(const QSize& Size);
/**
* Returns the current drag state of this tab.
* Use this function to determine if the tab is currently being dragged
*/
eDragState dragState() const;
/**
* Fills the provided menu with standard entries. If a nullptr is passed, a
* new menu is created and filled with standard entries.
* This function is called from the actual version of contextMenuEvent, but
* can be called from any code. Caller is responsible of deleting the created
* object.
*
* @param menu The QMenu to fill with standard entries. If nullptr, a new
* QMenu will be created.
* @return The filled QMenu, either the provided one or a newly created one if
* nullptr was passed.
*/
virtual QMenu *buildContextMenu(QMenu *);
public Q_SLOTS:
virtual void setVisible(bool visible) override;

View File

@@ -374,6 +374,7 @@ struct FloatingDockContainerPrivate
QPoint DragStartPos;
bool Hiding = false;
bool AutoHideChildren = true;
bool HideContentOnNextHide = false;
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
QWidget* MouseEventHandler = nullptr;
CFloatingWidgetTitleBar* TitleBar = nullptr;
@@ -459,7 +460,7 @@ struct FloatingDockContainerPrivate
}
else
{
_this->setWindowIcon(QApplication::windowIcon());
_this->setWindowIcon(CurrentWidget->windowIcon());
}
}
@@ -499,6 +500,9 @@ void FloatingDockContainerPrivate::titleMouseReleaseEvent()
return;
}
// DockManager will be unlinked from this within DropContainer->dropFloatingWidget
const auto OriginalDockManager = this->DockManager.data();
if (DockManager->dockAreaOverlay()->dropAreaUnderCursor() != InvalidDockWidgetArea
|| DockManager->containerOverlay()->dropAreaUnderCursor() != InvalidDockWidgetArea)
{
@@ -532,8 +536,8 @@ void FloatingDockContainerPrivate::titleMouseReleaseEvent()
DropContainer->dropFloatingWidget(_this, QCursor::pos());
}
DockManager->containerOverlay()->hideOverlay();
DockManager->dockAreaOverlay()->hideOverlay();
OriginalDockManager->containerOverlay()->hideOverlay();
OriginalDockManager->dockAreaOverlay()->hideOverlay();
}
@@ -728,6 +732,11 @@ CFloatingDockContainer::CFloatingDockContainer(CDockManager *DockManager) :
l->addWidget(d->DockContainer);
#endif
if (CDockManager::testConfigFlag(CDockManager::UseNativeWindows))
{
winId();
}
DockManager->registerFloatingWidget(this);
}
@@ -845,6 +854,12 @@ void CFloatingDockContainer::changeEvent(QEvent *event)
this->showMaximized();
}
}
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
if (d->TitleBar)
{
d->TitleBar->setVisible(!(isFloating() && isFullScreen()));
}
#endif
break;
default:
@@ -948,6 +963,15 @@ void CFloatingDockContainer::closeEvent(QCloseEvent *event)
return;
}
// New bug (QWebEngineView reload side effect):
// when a WebEngine-based dock is tabified into a floating container, the
// embedded native/web process can trigger delayed hide/show cycles on the
// floating window. If every non-spontaneous hide propagates to
// DockWidget->toggleView(false), unrelated tabs are marked closed and seem
// to "disappear". We therefore arm HideContentOnNextHide only for the
// explicit close path.
d->HideContentOnNextHide = true;
// In Qt version after 5.9.2 there seems to be a bug that causes the
// QWidget::event() function to not receive any NonClientArea mouse
// events anymore after a close/show cycle. The bug is reported here:
@@ -975,6 +999,15 @@ void CFloatingDockContainer::hideEvent(QHideEvent *event)
return;
}
// Only a close operation should propagate hide->toggleView(false) to
// child dock widgets. Generic hide/show cycles (e.g. from platform or
// embedded native content) must not change dock open/closed state.
if (!d->HideContentOnNextHide)
{
return;
}
d->HideContentOnNextHide = false;
if ( d->AutoHideChildren )
{
d->Hiding = true;
@@ -1190,8 +1223,9 @@ void CFloatingDockContainer::finishDropOperation()
if (d->DockManager)
{
d->DockManager->removeFloatingWidget(this);
d->DockManager->removeDockContainer(this->dockContainer());
d->DockManager.clear();
}
this->dockContainer()->removeFromDockManager();
}
//============================================================================
@@ -1331,7 +1365,8 @@ void CFloatingDockContainer::onMaximizeRequest()
//============================================================================
void CFloatingDockContainer::showNormal(bool fixGeometry)
{
if (windowState() == Qt::WindowMaximized)
if ( (windowState() & Qt::WindowMaximized) != 0 ||
(windowState() & Qt::WindowFullScreen) != 0)
{
QRect oldNormal = normalGeometry();
Super::showNormal();

View File

@@ -131,15 +131,6 @@ protected:
virtual void startFloating(const QPoint& DragStartMousePos, const QSize& Size,
eDragState DragState, QWidget* MouseEventHandler) override;
/**
* Call this function to start dragging the floating widget
*/
void startDragging(const QPoint& DragStartMousePos, const QSize& Size,
QWidget* MouseEventHandler)
{
startFloating(DragStartMousePos, Size, DraggingFloatingWidget, MouseEventHandler);
}
/**
* Call this function if you explicitly want to signal that dragging has
* finished
@@ -229,13 +220,22 @@ public:
/**
* Virtual Destructor
*/
virtual ~CFloatingDockContainer();
~CFloatingDockContainer() override;
/**
* Access function for the internal dock container
*/
CDockContainerWidget* dockContainer() const;
/**
* Call this function to start dragging the floating widget
*/
void startDragging(const QPoint& DragStartMousePos, const QSize& Size,
QWidget* MouseEventHandler)
{
startFloating(DragStartMousePos, Size, DraggingFloatingWidget, MouseEventHandler);
}
/**
* This function returns true, if it can be closed.
* It can be closed, if all dock widgets in all dock areas can be closed

View File

@@ -283,7 +283,7 @@ QString detectWindowManagerX11()
}
if(sup_windows.length() == 0)
{
ADS_PRINT("Failed to get the supporting window on non EWMH comform WM.");
ADS_PRINT("Failed to get the supporting window on non EWMH conform WM.");
return "UNKNOWN";
}
support_win = sup_windows[0];

View File

@@ -158,7 +158,7 @@ enum SideBarLocation
SideBarBottom,
SideBarNone
};
Q_ENUMS(SideBarLocation);
Q_ENUMS(SideBarLocation)
namespace internal
@@ -236,7 +236,7 @@ SideBarLocation toSideBarLocation(DockWidgetArea Area);
/**
* Returns true for the top or bottom side bar ansd false for the
* Returns true for the top or bottom side bar and false for the
* left and right side bar
*/
bool isHorizontalSideBarLocation(SideBarLocation Location);

View File

@@ -238,6 +238,20 @@ void CFloatingWidgetTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
}
}
//============================================================================
QSize CFloatingWidgetTitleBar::sizeHint() const
{
if (isVisible())
{
return QFrame::sizeHint();
}
else
{
// Allow titlebar to collapse when set invisible.
return QSize();
}
}
//============================================================================
void CFloatingWidgetTitleBar::setMaximizedIcon(bool maximized)

View File

@@ -59,6 +59,7 @@ protected:
virtual void mouseReleaseEvent(QMouseEvent *ev) override;
virtual void mouseMoveEvent(QMouseEvent *ev) override;
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
virtual QSize sizeHint() const override;
void setMaximizeIcon(const QIcon& Icon);
QIcon maximizeIcon() const;

View File

@@ -75,13 +75,17 @@ ads--CDockWidgetTab[activeTab="true"] {
}
ads--CDockWidgetTab QLabel {
color: palette(dark);
color: palette(text);
}
ads--CDockWidgetTab[activeTab="true"] QLabel {
color: palette(foreground);
}
#autoHideTitleLabel {
padding-left: 4px;
color: palette(foreground);
}
#tabCloseButton {
margin-top: 2px;
@@ -278,7 +282,7 @@ ads--CAutoHideDockContainer ads--CDockAreaWidget[focused="true"] ads--CDockAreaT
}
#autoHideTitleLabel {
ads--CAutoHideDockContainer #autoHideTitleLabel {
padding-left: 4px;
color: palette(light);
}

View File

@@ -39,6 +39,12 @@ ads--CTitleBarButton {
}
#autoHideTitleLabel {
padding-left: 4px;
color: palette(foreground);
}
#tabsMenuButton {
qproperty-icon: url(:/ads/images/tabs-menu-button.svg);
qproperty-iconSize: 16px;
@@ -79,7 +85,7 @@ ads--CDockWidgetTab[activeTab="true"] {
ads--CDockWidgetTab QLabel {
color: palette(dark);
color: palette(text);
}
@@ -88,6 +94,12 @@ ads--CDockWidgetTab[activeTab="true"] QLabel {
}
#autoHideTitleLabel {
padding-left: 4px;
color: palette(foreground);
}
#tabCloseButton {
margin-top: 2px;
background: none;
@@ -314,7 +326,7 @@ ads--CAutoHideDockContainer ads--CDockAreaWidget[focused="true"] ads--CDockAreaT
}
#autoHideTitleLabel {
ads--CAutoHideDockContainer #autoHideTitleLabel {
padding-left: 4px;
color: palette(light);
}

View File

@@ -88,13 +88,17 @@ ads--CDockWidgetTab[activeTab="true"] {
}
ads--CDockWidgetTab QLabel {
color: palette(dark);
color: palette(text);
}
ads--CDockWidgetTab[activeTab="true"] QLabel {
color: palette(foreground);
}
#autoHideTitleLabel {
padding-left: 4px;
color: palette(foreground);
}
#tabCloseButton {
margin-top: 2px;
@@ -134,7 +138,7 @@ ads--CDockWidgetTab[focused="true"] > #tabCloseButton:pressed {
}
ads--CDockWidgetTab[focused="true"] QLabel {
color: palette(light);
color: palette(highlighted-text);
}
@@ -316,7 +320,7 @@ ads--CAutoHideDockContainer ads--CDockAreaWidget[focused="true"] ads--CDockAreaT
}
#autoHideTitleLabel {
ads--CAutoHideDockContainer #autoHideTitleLabel {
padding-left: 4px;
color: palette(light);
}

View File

@@ -40,6 +40,12 @@ ads--CTitleBarButton {
}
#autoHideTitleLabel {
padding-left: 4px;
color: palette(foreground);
}
#tabsMenuButton {
qproperty-icon: url(:/ads/images/tabs-menu-button.svg);
qproperty-iconSize: 16px;
@@ -95,7 +101,7 @@ ads--CDockWidgetTab[activeTab="true"] {
}
ads--CDockWidgetTab QLabel {
color: palette(dark);
color: palette(text);
}
ads--CDockWidgetTab[activeTab="true"] QLabel {
@@ -142,7 +148,7 @@ ads--CDockWidgetTab[focused="true"] > #tabCloseButton:pressed {
}
ads--CDockWidgetTab[focused="true"] QLabel {
color: palette(light);
color: palette(highlighted-text);
}
@@ -391,7 +397,7 @@ ads--CAutoHideDockContainer ads--CDockAreaWidget[focused="true"] ads--CDockAreaT
}
#autoHideTitleLabel {
ads--CAutoHideDockContainer #autoHideTitleLabel {
padding-left: 4px;
color: palette(light);
}