Compare commits

...

99 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
66 changed files with 1002 additions and 655 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 name: linux-builds
on: [push] on:
push:
workflow_dispatch:
jobs: jobs:
build: build_ubuntu_2204_cmake:
strategy: runs-on: ubuntu-22.04
matrix:
os: [ubuntu-20.04]
runs-on: ${{ matrix.os }} env:
QT_VERSION: 6.4.2
QT_DIR: ${{ github.workspace }}/Qt
steps: steps:
- uses: actions/checkout@v1 - name: Checkout source
- name: install qt uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch full history and tags
- name: Install dependencies
run: | run: |
sudo apt-get update --fix-missing sudo apt-get update
sudo apt-get install qt5-default sudo apt-get install -y build-essential cmake ninja-build libgl1-mesa-dev libxkbcommon-x11-0 libx11-dev
sudo apt-get install qtbase5-private-dev qtdeclarative5-dev
- name: qmake - name: Install Qt
run: qmake uses: jurplel/install-qt-action@v3
- name: make with:
run: make -j4 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: build_ubuntu_2204:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
@@ -28,7 +53,7 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Cache Qt - name: Cache Qt
id: cache-qt-6-4 id: cache-qt-6-4
uses: actions/cache@v1 # not v2! uses: actions/cache@v3
with: with:
path: ../Qt/6.4.2 path: ../Qt/6.4.2
key: ${{ runner.os }}-QtCache-Qt6-4 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

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) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
if (POLICY CMP0091) if (POLICY CMP0091)
cmake_policy(SET CMP0091 NEW) cmake_policy(SET CMP0091 NEW)
endif (POLICY CMP0091) 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, # By default, the version information is extracted from the git index. However,
# we can override this behavior by explicitly setting ADS_VERSION and # 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 # 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) # used independently of its original git repo (e.g. vendored in another project)
if(NOT ADS_VERSION) if(NOT ADS_VERSION)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules ${CMAKE_MODULE_PATH})
include(GetGitRevisionDescription) include(GetGitRevisionDescription)
git_describe(GitTagVersion --tags) git_describe(GitTagVersion --tags)
string(REGEX REPLACE "^([0-9]+)\\..*" "\\1" VERSION_MAJOR "${GitTagVersion}") 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]+).*" "\\1" VERSION_MINOR "${GitTagVersion}")
string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" VERSION_PATCH "${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_SHORT "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
set(VERSION_SONAME "${VERSION_MAJOR}")
else() else()
string(REGEX MATCHALL "[\.]" VERSION_DOT_MATCHES ${ADS_VERSION}) string(REGEX MATCHALL "[\.]" VERSION_DOT_MATCHES ${ADS_VERSION})
list(LENGTH VERSION_DOT_MATCHES VERSION_DOT_COUNT) list(LENGTH VERSION_DOT_MATCHES VERSION_DOT_COUNT)
if(VERSION_DOT_COUNT EQUAL 2) if(VERSION_DOT_COUNT EQUAL 2)
set(VERSION_SHORT ${ADS_VERSION}) 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() else()
message(FATAL_ERROR "ADS_VERSION must be in major.minor.patch format, e.g. 3.8.1. Got ${ADS_VERSION}") message(FATAL_ERROR "ADS_VERSION must be in major.minor.patch format, e.g. 3.8.1. Got ${ADS_VERSION}")
endif() endif()
@@ -32,10 +41,15 @@ project(QtADS LANGUAGES CXX VERSION ${VERSION_SHORT})
option(BUILD_STATIC "Build the static library" OFF) option(BUILD_STATIC "Build the static library" OFF)
option(BUILD_EXAMPLES "Build the examples" ON) option(BUILD_EXAMPLES "Build the examples" ON)
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4") # Platform directory: auto-detected based on pointer size, or manually set
set(ads_PlatformDir "x86") if(NOT ADS_PLATFORM_DIR)
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4")
set(ads_PlatformDir "x86")
else()
set(ads_PlatformDir "x64")
endif()
else() else()
set(ads_PlatformDir "x64") set(ads_PlatformDir "${ADS_PLATFORM_DIR}")
endif() endif()
add_subdirectory(src) add_subdirectory(src)

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) [![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://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) [![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 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. integrated development environments (IDEs) such as Visual Studio.
- [What's new...](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/releases/latest) - [What's new...](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/releases/latest)
- [Documentation](doc/user-guide.md) - [Documentation](https://githubuser0xffff.github.io/Qt-Advanced-Docking-System/doc/user-guide.html)
- Original Repository: https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System - 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) [![Video Advanced Docking](doc/advanced-docking_video.png)](https://www.youtube.com/watch?v=7pdNfafg3Qc)
## New and Noteworthy ## 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 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: 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 ### Overview
- [New and Noteworthy](#new-and-noteworthy) - [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) - [Drag \& Drop to Auto-Hide](#drag--drop-to-auto-hide)
- [Auto-Hide Tab Insertion Order](#auto-hide-tab-insertion-order) - [Auto-Hide Tab Insertion Order](#auto-hide-tab-insertion-order)
- [Auto-Hide Tab Sorting](#auto-hide-tab-sorting) - [Auto-Hide Tab Sorting](#auto-hide-tab-sorting)
@@ -161,6 +176,7 @@ know it from Visual Studio.
- [Auto-Hide Functionality](#auto-hide-functionality) - [Auto-Hide Functionality](#auto-hide-functionality)
- [Python Bindings](#python-bindings) - [Python Bindings](#python-bindings)
- [PySide6](#pyside6) - [PySide6](#pyside6)
- [PyQt6](#pyqt6)
- [PyQt5](#pyqt5) - [PyQt5](#pyqt5)
- [Tested Compatible Environments](#tested-compatible-environments) - [Tested Compatible Environments](#tested-compatible-environments)
- [Supported Qt Versions](#supported-qt-versions) - [Supported Qt Versions](#supported-qt-versions)
@@ -189,8 +205,10 @@ know it from Visual Studio.
- [RDE Robox Development Environment](#rde--robox-development-environment) - [RDE Robox Development Environment](#rde--robox-development-environment)
- [ResInsight](#resinsight) - [ResInsight](#resinsight)
- [ADTF 3](#adtf-3) - [ADTF 3](#adtf-3)
- [DREAM.3D NX](#dream3d-nx) - [DREAM3D-NX](#dream3d-nx)
- [LabPlot](#labplot) - [LabPlot](#labplot)
- [Scrutiny Debugger](#scrutiny-debugger)
- [PiSoWorks](#pisoworks)
- [Alternative Docking System Implementations](#alternative-docking-system-implementations) - [Alternative Docking System Implementations](#alternative-docking-system-implementations)
- [KDDockWidgets](#kddockwidgets) - [KDDockWidgets](#kddockwidgets)
- [QtitanDocking](#qtitandocking) - [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. 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: 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 - `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 - `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 - `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) ![Python Logo](doc/python_logo.png)
Thanks to the contribution of several users, the Advanced Docking System comes 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**.
### 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 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: The PySide6 bindings were contributed by:
- [mborgerson](https://github.com/mborgerson) - [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. 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 ### PyQt5
A package is available via [conda-forge](https://github.com/conda-forge/pyqtads-feedstock). 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
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. The library was developed on and for Windows. It is used in a commercial Windows application and is therefore constantly tested.
### macOS ### 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. 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) ![Advanced Docking on macOS](doc/macos.png)
### Linux ### 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) [![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 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
@@ -667,15 +701,17 @@ says about the switch to Qt Advanced Docking:
![ADTF](doc/showcase_adtf.png) ![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) ![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/) ### [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/) [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 ## 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. 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}) project(ads_demo VERSION ${VERSION_SHORT})
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)

View File

@@ -396,7 +396,7 @@ struct MainWindowPrivate
DockWidget->setMinimumSizeHintMode(ads::CDockWidget::MinimumSizeHintFromContent); DockWidget->setMinimumSizeHintMode(ads::CDockWidget::MinimumSizeHintFromContent);
auto ToolBar = DockWidget->createDefaultToolBar(); auto ToolBar = DockWidget->createDefaultToolBar();
auto Action = ToolBar->addAction(svgIcon(":/adsdemo/images/fullscreen.svg"), "Toggle Fullscreen"); 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()) if (DockWidget->isFullScreen())
{ {
@@ -510,7 +510,7 @@ void MainWindowPrivate::createContent()
auto TitleBar = DockArea->titleBar(); auto TitleBar = DockArea->titleBar();
int Index = TitleBar->indexOf(TitleBar->tabBar()); int Index = TitleBar->indexOf(TitleBar->tabBar());
TitleBar->insertWidget(Index + 1, CustomButton); TitleBar->insertWidget(Index + 1, CustomButton);
QObject::connect(CustomButton, &QToolButton::clicked, [=]() QObject::connect(CustomButton, &QToolButton::clicked, [DockArea, this]()
{ {
auto DockWidget = createEditorWidget(); auto DockWidget = createEditorWidget();
DockWidget->setFeature(ads::CDockWidget::DockWidgetDeleteOnClose, true); DockWidget->setFeature(ads::CDockWidget::DockWidgetDeleteOnClose, true);
@@ -779,6 +779,9 @@ CMainWindow::CMainWindow(QWidget *parent) :
// uncomment if you would like to close tabs with the middle mouse button, web browser style // uncomment if you would like to close tabs with the middle mouse button, web browser style
// CDockManager::setConfigFlag(CDockManager::MiddleMouseButtonClosesTab, true); // 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 // Now create the dock manager and its content
d->DockManager = new CDockManager(this); d->DockManager = new CDockManager(this);
d->DockManager->setDockWidgetToolBarStyle(Qt::ToolButtonIconOnly, ads::CDockWidget::StateFloating); d->DockManager->setDockWidgetToolBarStyle(Qt::ToolButtonIconOnly, ads::CDockWidget::StateFloating);

View File

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

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,74 +1,81 @@
# User Guide # User Guide
- [Configuration Flags](#configuration-flags) - [User Guide](#user-guide)
- [Setting Configuration Flags](#setting-configuration-flags) - [Configuration Flags](#configuration-flags)
- [`ActiveTabHasCloseButton`](#activetabhasclosebutton) - [Setting Configuration Flags](#setting-configuration-flags)
- [`DockAreaHasCloseButton`](#dockareahasclosebutton) - [`ActiveTabHasCloseButton`](#activetabhasclosebutton)
- [`DockAreaCloseButtonClosesTab`](#dockareaclosebuttonclosestab) - [`DockAreaHasCloseButton`](#dockareahasclosebutton)
- [`OpaqueSplitterResize`](#opaquesplitterresize) - [`DockAreaCloseButtonClosesTab`](#dockareaclosebuttonclosestab)
- [`XmlAutoFormattingEnabled`](#xmlautoformattingenabled) - [`OpaqueSplitterResize`](#opaquesplitterresize)
- [`XmlCompressionEnabled`](#xmlcompressionenabled) - [`XmlAutoFormattingEnabled`](#xmlautoformattingenabled)
- [`TabCloseButtonIsToolButton`](#tabclosebuttonistoolbutton) - [`XmlCompressionEnabled`](#xmlcompressionenabled)
- [`AllTabsHaveCloseButton`](#alltabshaveclosebutton) - [`TabCloseButtonIsToolButton`](#tabclosebuttonistoolbutton)
- [`RetainTabSizeWhenCloseButtonHidden`](#retaintabsizewhenclosebuttonhidden) - [`AllTabsHaveCloseButton`](#alltabshaveclosebutton)
- [`DragPreviewIsDynamic`](#dragpreviewisdynamic) - [`RetainTabSizeWhenCloseButtonHidden`](#retaintabsizewhenclosebuttonhidden)
- [`DragPreviewShowsContentPixmap`](#dragpreviewshowscontentpixmap) - [`DragPreviewIsDynamic`](#dragpreviewisdynamic)
- [`DragPreviewHasWindowFrame`](#dragpreviewhaswindowframe) - [`DragPreviewShowsContentPixmap`](#dragpreviewshowscontentpixmap)
- [`AlwaysShowTabs`](#alwaysshowtabs) - [`DragPreviewHasWindowFrame`](#dragpreviewhaswindowframe)
- [`DockAreaHasUndockButton`](#dockareahasundockbutton) - [`AlwaysShowTabs`](#alwaysshowtabs)
- [`DockAreaHasTabsMenuButton`](#dockareahastabsmenubutton) - [`DockAreaHasUndockButton`](#dockareahasundockbutton)
- [`DockAreaHideDisabledButtons`](#dockareahidedisabledbuttons) - [`DockAreaHasTabsMenuButton`](#dockareahastabsmenubutton)
- [`DockAreaDynamicTabsMenuButtonVisibility`](#dockareadynamictabsmenubuttonvisibility) - [`DockAreaHideDisabledButtons`](#dockareahidedisabledbuttons)
- [`FloatingContainerHasWidgetTitle`](#floatingcontainerhaswidgettitle) - [`DockAreaDynamicTabsMenuButtonVisibility`](#dockareadynamictabsmenubuttonvisibility)
- [`FloatingContainerHasWidgetIcon`](#floatingcontainerhaswidgeticon) - [`FloatingContainerHasWidgetTitle`](#floatingcontainerhaswidgettitle)
- [`HideSingleCentralWidgetTitleBar`](#hidesinglecentralwidgettitlebar) - [`FloatingContainerHasWidgetIcon`](#floatingcontainerhaswidgeticon)
- [`FocusHighlighting`](#focushighlighting) - [`HideSingleCentralWidgetTitleBar`](#hidesinglecentralwidgettitlebar)
- [`EqualSplitOnInsertion`](#equalsplitoninsertion) - [`FocusHighlighting`](#focushighlighting)
- [`FloatingContainerForceNativeTitleBar` (Linux only)](#floatingcontainerforcenativetitlebar-linux-only) - [`EqualSplitOnInsertion`](#equalsplitoninsertion)
- [`FloatingContainerForceQWidgetTitleBar` (Linux only)](#floatingcontainerforceqwidgettitlebar-linux-only) - [`FloatingContainerForceNativeTitleBar` (Linux only)](#floatingcontainerforcenativetitlebar-linux-only)
- [`MiddleMouseButtonClosesTab`](#middlemousebuttonclosestab) - [`FloatingContainerForceQWidgetTitleBar` (Linux only)](#floatingcontainerforceqwidgettitlebar-linux-only)
- [`DisableTabTextEliding`](#disabletabtexteliding) - [`MiddleMouseButtonClosesTab`](#middlemousebuttonclosestab)
- [`ShowTabTextOnlyForActiveTab`](#showtabtextonlyforactivetab) - [`DisableTabTextEliding`](#disabletabtexteliding)
- [`DoubleClickUndocksWidget`](#doubleclickundockswidget) - [`ShowTabTextOnlyForActiveTab`](#showtabtextonlyforactivetab)
- [Auto Hide Dock Widgets](#auto-hide-dock-widgets) - [`DoubleClickUndocksWidget`](#doubleclickundockswidget)
- [Pinning Auto-Hide Widgets to a certain border](#pinning-auto-hide-widgets-to-a-certain-border) - [`TabsAtBottom`](#tabsatbottom)
- [Show / Hide Auto-Hide Widgets via Mouse Over](#show--hide-auto-hide-widgets-via-mouse-over) - [Auto Hide Dock Widgets](#auto-hide-dock-widgets)
- [Drag \& Drop to Auto-Hide](#drag--drop-to-auto-hide) - [Pinning Auto-Hide Widgets to a certain border](#pinning-auto-hide-widgets-to-a-certain-border)
- [Auto-Hide Tab Insertion Order](#auto-hide-tab-insertion-order) - [Show / Hide Auto-Hide Widgets via Mouse Over](#show--hide-auto-hide-widgets-via-mouse-over)
- [Auto-Hide Tab Sorting](#auto-hide-tab-sorting) - [Drag \& Drop to Auto-Hide](#drag--drop-to-auto-hide)
- [Auto-Hide Drag to Float / Dock](#auto-hide-drag-to-float--dock) - [Auto-Hide Tab Insertion Order](#auto-hide-tab-insertion-order)
- [Auto-Hide Context Menu](#auto-hide-context-menu) - [Auto-Hide Tab Sorting](#auto-hide-tab-sorting)
- [Adding Auto Hide Widgets](#adding-auto-hide-widgets) - [Auto-Hide Drag to Float / Dock](#auto-hide-drag-to-float--dock)
- [Auto-Hide Configuration Flags](#auto-hide-configuration-flags) - [Auto-Hide Context Menu](#auto-hide-context-menu)
- [Setting Auto-Hide Flags](#setting-auto-hide-flags) - [Adding Auto Hide Widgets](#adding-auto-hide-widgets)
- [`AutoHideFeatureEnabled`](#autohidefeatureenabled) - [Auto-Hide Configuration Flags](#auto-hide-configuration-flags)
- [`DockAreaHasAutoHideButton`](#dockareahasautohidebutton) - [Setting Auto-Hide Flags](#setting-auto-hide-flags)
- [`AutoHideButtonTogglesArea`](#autohidebuttontogglesarea) - [`AutoHideFeatureEnabled`](#autohidefeatureenabled)
- [`AutoHideButtonCheckable`](#autohidebuttoncheckable) - [`DockAreaHasAutoHideButton`](#dockareahasautohidebutton)
- [`AutoHideSideBarsIconOnly`](#autohidesidebarsicononly) - [`AutoHideButtonTogglesArea`](#autohidebuttontogglesarea)
- [`AutoHideShowOnMouseOver`](#autohideshowonmouseover) - [`AutoHideButtonCheckable`](#autohidebuttoncheckable)
- [`AutoHideCloseButtonCollapsesDock`](#autohideclosebuttoncollapsesdock) - [`AutoHideSideBarsIconOnly`](#autohidesidebarsicononly)
- [`AutoHideHasCloseButton`](#autohidehasclosebutton) - [`AutoHideShowOnMouseOver`](#autohideshowonmouseover)
- [`AutoHideHasMinimizeButton`](#autohidehasminimizebutton) - [`AutoHideCloseButtonCollapsesDock`](#autohideclosebuttoncollapsesdock)
- [`AutoHideOpenOnDragHover`](#autohideopenondraghover) - [`AutoHideHasCloseButton`](#autohidehasclosebutton)
- [`AutoHideCloseOnOutsideMouseClick`](#autohidecloseonoutsidemouseclick) - [`AutoHideHasMinimizeButton`](#autohidehasminimizebutton)
- [DockWidget Feature Flags](#dockwidget-feature-flags) - [`AutoHideOpenOnDragHover`](#autohideopenondraghover)
- [`DockWidgetClosable`](#dockwidgetclosable) - [`AutoHideCloseOnOutsideMouseClick`](#autohidecloseonoutsidemouseclick)
- [`DockWidgetMovable`](#dockwidgetmovable) - [DockWidget Feature Flags](#dockwidget-feature-flags)
- [`DockWidgetFloatable`](#dockwidgetfloatable) - [`DockWidgetClosable`](#dockwidgetclosable)
- [`DockWidgetDeleteOnClose`](#dockwidgetdeleteonclose) - [`DockWidgetMovable`](#dockwidgetmovable)
- [`CustomCloseHandling`](#customclosehandling) - [`DockWidgetFloatable`](#dockwidgetfloatable)
- [`DockWidgetFocusable`](#dockwidgetfocusable) - [`DockWidgetDeleteOnClose`](#dockwidgetdeleteonclose)
- [`DockWidgetForceCloseWithArea`](#dockwidgetforceclosewitharea) - [`CustomCloseHandling`](#customclosehandling)
- [`NoTab`](#notab) - [`DockWidgetFocusable`](#dockwidgetfocusable)
- [`DeleteContentOnClose`](#deletecontentonclose) - [`DockWidgetForceCloseWithArea`](#dockwidgetforceclosewitharea)
- [Central Widget](#central-widget) - [`NoTab`](#notab)
- [Empty Dock Area](#empty-dock-area) - [`DeleteContentOnClose`](#deletecontentonclose)
- [Custom Close Handling](#custom-close-handling) - [Central Widget](#central-widget)
- [Globally Lock Docking Features](#globally-lock-docking-features) - [Empty Dock Area](#empty-dock-area)
- [Dock Widget Size / Minimum Size Handling](#dock-widget-size--minimum-size-handling) - [Custom Close Handling](#custom-close-handling)
- [Styling](#styling) - [Globally Lock Docking Features](#globally-lock-docking-features)
- [Disabling the Internal Style Sheet](#disabling-the-internal-style-sheet) - [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 ## Configuration Flags
@@ -505,6 +512,12 @@ for active tabs. Inactive tabs only show their icon:
If the flag is set (default), a double click on a tab undocks the dock widget. 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. 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 ## Auto Hide Dock Widgets
The Advanced Docking System supports "Auto-Hide" functionality for **all** The Advanced Docking System supports "Auto-Hide" functionality for **all**
@@ -860,12 +873,12 @@ undock.
You can use a combination of the following feature flags to define which features You can use a combination of the following feature flags to define which features
shall get locked: shall get locked:
- CDockWidget::DockWidgetClosable - `CDockWidget::DockWidgetClosable`
- CDockWidget::DockWidgetMovable - `CDockWidget::DockWidgetMovable`
- CDockWidget::DockWidgetFloatable - `CDockWidget::DockWidgetFloatable`
- CDockWidget::DockWidgetPinable - `CDockWidget::DockWidgetPinable`
To clear the locked features, you can use CDockWidget::NoDockWidgetFeatures To clear the locked features, you can use `CDockWidget::NoDockWidgetFeatures`
The following code shows how to lock and unlock all dock widget features The following code shows how to lock and unlock all dock widget features
globally. globally.
@@ -953,3 +966,51 @@ just call the function for settings the stylesheet with an empty string.
DockManager->setStyleSheet(""); 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}) project(QtADSExamples LANGUAGES CXX VERSION ${VERSION_SHORT})
add_subdirectory(simple) add_subdirectory(simple)
add_subdirectory(hideshow) add_subdirectory(hideshow)
@@ -9,3 +9,4 @@ add_subdirectory(autohide)
add_subdirectory(autohidedragndrop) add_subdirectory(autohidedragndrop)
add_subdirectory(emptydockarea) add_subdirectory(emptydockarea)
add_subdirectory(dockindock) 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}) project(ads_example_autohide VERSION ${VERSION_SHORT})
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED) find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)

View File

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

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.16)
project(ads_example_autohide_dragndrop VERSION ${VERSION_SHORT}) project(ads_example_autohide_dragndrop VERSION ${VERSION_SHORT})
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED) find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)

View File

@@ -27,6 +27,7 @@ CMainWindow::CMainWindow(QWidget *parent)
CDockManager::setConfigFlag(CDockManager::OpaqueSplitterResize, true); CDockManager::setConfigFlag(CDockManager::OpaqueSplitterResize, true);
CDockManager::setConfigFlag(CDockManager::XmlCompressionEnabled, false); CDockManager::setConfigFlag(CDockManager::XmlCompressionEnabled, false);
CDockManager::setConfigFlag(CDockManager::FocusHighlighting, true); CDockManager::setConfigFlag(CDockManager::FocusHighlighting, true);
CDockManager::setConfigFlag(CDockManager::TabsAtBottom, true);
CDockManager::setAutoHideConfigFlags(CDockManager::DefaultAutoHideConfig); CDockManager::setAutoHideConfigFlags(CDockManager::DefaultAutoHideConfig);
CDockManager::setAutoHideConfigFlag(CDockManager::AutoHideOpenOnDragHover, true); CDockManager::setAutoHideConfigFlag(CDockManager::AutoHideOpenOnDragHover, true);
CDockManager::setConfigParam(CDockManager::AutoHideOpenOnDragHoverDelay_ms, 500); CDockManager::setConfigParam(CDockManager::AutoHideOpenOnDragHoverDelay_ms, 500);
@@ -35,14 +36,14 @@ CMainWindow::CMainWindow(QWidget *parent)
// Set central widget // Set central widget
QPlainTextEdit* w = new QPlainTextEdit(); QPlainTextEdit* w = new QPlainTextEdit();
w->setPlaceholderText("This is the central editor. Enter your text here."); w->setPlaceholderText("This is the central editor. Enter your text here.");
CDockWidget* CentralDockWidget = new CDockWidget("CentralWidget"); CDockWidget* CentralDockWidget = DockManager->createDockWidget("CentralWidget");
CentralDockWidget->setWidget(w); CentralDockWidget->setWidget(w);
auto* CentralDockArea = DockManager->setCentralWidget(CentralDockWidget); auto* CentralDockArea = DockManager->setCentralWidget(CentralDockWidget);
CentralDockArea->setAllowedAreas(DockWidgetArea::OuterDockAreas); CentralDockArea->setAllowedAreas(DockWidgetArea::OuterDockAreas);
{ {
DroppableItem* droppableItem = new DroppableItem("Drop text here."); DroppableItem* droppableItem = new DroppableItem("Drop text here.");
CDockWidget* dropDockWidget = new CDockWidget("Tab 1"); CDockWidget* dropDockWidget = DockManager->createDockWidget("Tab 1");
dropDockWidget->setWidget(droppableItem); dropDockWidget->setWidget(droppableItem);
dropDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget); dropDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
dropDockWidget->setMinimumSize(200,150); dropDockWidget->setMinimumSize(200,150);
@@ -54,7 +55,7 @@ CMainWindow::CMainWindow(QWidget *parent)
} }
{ {
DroppableItem* droppableItem = new DroppableItem("Drop text here."); DroppableItem* droppableItem = new DroppableItem("Drop text here.");
CDockWidget* dropDockWidget = new CDockWidget("Tab 2"); CDockWidget* dropDockWidget = DockManager->createDockWidget("Tab 2");
dropDockWidget->setWidget(droppableItem); dropDockWidget->setWidget(droppableItem);
dropDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget); dropDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
dropDockWidget->setMinimumSize(200,150); dropDockWidget->setMinimumSize(200,150);
@@ -68,7 +69,7 @@ CMainWindow::CMainWindow(QWidget *parent)
QTableWidget* propertiesTable = new QTableWidget(); QTableWidget* propertiesTable = new QTableWidget();
propertiesTable->setColumnCount(3); propertiesTable->setColumnCount(3);
propertiesTable->setRowCount(10); propertiesTable->setRowCount(10);
CDockWidget* PropertiesDockWidget = new CDockWidget("Properties"); CDockWidget* PropertiesDockWidget = DockManager->createDockWidget("Properties");
PropertiesDockWidget->setWidget(propertiesTable); PropertiesDockWidget->setWidget(propertiesTable);
PropertiesDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget); PropertiesDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
PropertiesDockWidget->resize(250, 150); PropertiesDockWidget->resize(250, 150);

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}) project(ads_example_centralwidget VERSION ${VERSION_SHORT})
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED) find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)

View File

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

View File

@@ -1,19 +1,19 @@
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.16)
project(ads_example_centralwidget VERSION ${VERSION_SHORT}) project(ads_example_configflags VERSION ${VERSION_SHORT})
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED) find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(configFlagsExample WIN32 add_executable(ConfigFlagsExample WIN32
main.cpp main.cpp
mainwindow.cpp mainwindow.cpp
mainwindow.ui mainwindow.ui
) )
target_include_directories(CentralWidgetExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src") target_include_directories(ConfigFlagsExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
target_link_libraries(CentralWidgetExample PRIVATE qtadvanceddocking-qt${QT_VERSION_MAJOR}) target_link_libraries(ConfigFlagsExample PRIVATE qtadvanceddocking-qt${QT_VERSION_MAJOR})
target_link_libraries(CentralWidgetExample PUBLIC Qt${QT_VERSION_MAJOR}::Core target_link_libraries(ConfigFlagsExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets) Qt${QT_VERSION_MAJOR}::Widgets)
set_target_properties(CentralWidgetExample PROPERTIES set_target_properties(ConfigFlagsExample PROPERTIES
AUTOMOC ON AUTOMOC ON
AUTORCC ON AUTORCC ON
AUTOUIC ON AUTOUIC ON
@@ -21,7 +21,7 @@ set_target_properties(CentralWidgetExample PROPERTIES
CXX_STANDARD_REQUIRED ON CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS OFF CXX_EXTENSIONS OFF
VERSION ${VERSION_SHORT} VERSION ${VERSION_SHORT}
EXPORT_NAME "Qt Advanced Docking System Central Widget Example" EXPORT_NAME "Qt Advanced Docking System Config Flags"
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib" ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
LIBRARY_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" RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/bin"

View File

@@ -6,7 +6,6 @@
#include <QToolBar> #include <QToolBar>
#include "DockAreaWidget.h" #include "DockAreaWidget.h"
#include "DockAreaTitleBar.h"
using namespace ads; using namespace ads;
@@ -36,7 +35,7 @@ CMainWindow::CMainWindow(QWidget *parent) :
l1->setWordWrap(true); l1->setWordWrap(true);
l1->setAlignment(Qt::AlignTop | Qt::AlignLeft); l1->setAlignment(Qt::AlignTop | Qt::AlignLeft);
l1->setText("Docking widget 1"); l1->setText("Docking widget 1");
ads::CDockWidget *dockWidget1 = new ads::CDockWidget("Dock 1"); ads::CDockWidget *dockWidget1 = DockManager->createDockWidget("Dock 1");
dockWidget1->setWidget(l1); dockWidget1->setWidget(l1);
DockManager->addDockWidget(ads::LeftDockWidgetArea, dockWidget1); DockManager->addDockWidget(ads::LeftDockWidgetArea, dockWidget1);
@@ -44,7 +43,7 @@ CMainWindow::CMainWindow(QWidget *parent) :
l2->setWordWrap(true); l2->setWordWrap(true);
l2->setAlignment(Qt::AlignTop | Qt::AlignLeft); l2->setAlignment(Qt::AlignTop | Qt::AlignLeft);
l2->setText("Docking widget 2"); l2->setText("Docking widget 2");
ads::CDockWidget *dockWidget2 = new ads::CDockWidget("Dock 2"); ads::CDockWidget *dockWidget2 = DockManager->createDockWidget("Dock 2");
dockWidget2->setWidget(l2); dockWidget2->setWidget(l2);
DockManager->addDockWidget(ads::RightDockWidgetArea, dockWidget2); DockManager->addDockWidget(ads::RightDockWidgetArea, dockWidget2);

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}) project(ads_example_deleteonclose VERSION ${VERSION_SHORT})
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED) find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)

View File

@@ -46,7 +46,7 @@ int main(int argc, char *argv[])
int i = 0; int i = 0;
QObject::connect(action, &QAction::triggered, [&]() { 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); auto editor = new QTextEdit(QStringLiteral("lorem ipsum..."), dw);
dw->setWidget(editor); dw->setWidget(editor);
dw->setFeature(ads::CDockWidget::DockWidgetDeleteOnClose, true); dw->setFeature(ads::CDockWidget::DockWidgetDeleteOnClose, true);
@@ -54,7 +54,7 @@ int main(int argc, char *argv[])
qDebug() << "doc dock widget created!" << dw << area; 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); auto editor = new QTextEdit(QStringLiteral("recreated lorem ipsum......"), dw);
dw->setWidget(editor); dw->setWidget(editor);
dw->setFeature(ads::CDockWidget::DeleteContentOnClose, true); dw->setFeature(ads::CDockWidget::DeleteContentOnClose, true);
@@ -77,7 +77,7 @@ int main(int argc, char *argv[])
action = new QAction("New", &w); action = new QAction("New", &w);
w.menuBar()->addAction(action); w.menuBar()->addAction(action);
QObject::connect(action, &QAction::triggered, [&]() { 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); auto editor = new QTextEdit(QStringLiteral("lorem ipsum..."), dw);
dw->setWidget(editor); dw->setWidget(editor);
auto area = dockManager->addDockWidgetTab(ads::CenterDockWidgetArea, dw); 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}) project(ads_example_dockindock VERSION ${VERSION_SHORT})
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED) find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)

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->setWidget(widget);
DockWidget->setIcon( icon ); DockWidget->setIcon( icon );
@@ -101,7 +101,7 @@ DockInDockWidget* DockInDockWidget::createGroup( const QString& groupName, QIcon
DockInDockWidget* child = new DockInDockWidget( this, m_topLevelDockWidget, m_perspectivesManager ); DockInDockWidget* child = new DockInDockWidget( this, m_topLevelDockWidget, m_perspectivesManager );
child->setObjectName( groupName ); child->setObjectName( groupName );
ads::CDockWidget* DockWidget = new ads::CDockWidget(groupName); ads::CDockWidget* DockWidget = m_mgr->createDockWidget(groupName);
DockWidget->setWidget(child); DockWidget->setWidget(child);
DockWidget->setIcon(icon); 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}) project(ads_example_centralwidget VERSION ${VERSION_SHORT})
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED) find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)

View File

@@ -19,8 +19,6 @@
#include <QToolBar> #include <QToolBar>
#include "DockAreaWidget.h" #include "DockAreaWidget.h"
#include "DockAreaTitleBar.h"
#include "DockAreaTabBar.h"
#include "FloatingDockContainer.h" #include "FloatingDockContainer.h"
#include "DockComponentsFactory.h" #include "DockComponentsFactory.h"
@@ -44,7 +42,7 @@ CMainWindow::CMainWindow(QWidget *parent)
QLabel* label = new QLabel(); QLabel* label = new QLabel();
label->setText("This is a DockArea which is always visible, even if it does not contain any DockWidgets."); label->setText("This is a DockArea which is always visible, even if it does not contain any DockWidgets.");
label->setAlignment(Qt::AlignCenter); label->setAlignment(Qt::AlignCenter);
CDockWidget* CentralDockWidget = new CDockWidget("CentralWidget"); CDockWidget* CentralDockWidget = DockManager->createDockWidget("CentralWidget");
CentralDockWidget->setWidget(label); CentralDockWidget->setWidget(label);
CentralDockWidget->setFeature(ads::CDockWidget::NoTab, true); CentralDockWidget->setFeature(ads::CDockWidget::NoTab, true);
auto* CentralDockArea = DockManager->setCentralWidget(CentralDockWidget); auto* CentralDockArea = DockManager->setCentralWidget(CentralDockWidget);
@@ -53,7 +51,7 @@ CMainWindow::CMainWindow(QWidget *parent)
QTableWidget* table = new QTableWidget(); QTableWidget* table = new QTableWidget();
table->setColumnCount(3); table->setColumnCount(3);
table->setRowCount(10); table->setRowCount(10);
CDockWidget* TableDockWidget = new CDockWidget("Table 1"); CDockWidget* TableDockWidget = DockManager->createDockWidget("Table 1");
TableDockWidget->setWidget(table); TableDockWidget->setWidget(table);
TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget); TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
TableDockWidget->resize(250, 150); TableDockWidget->resize(250, 150);
@@ -65,7 +63,7 @@ CMainWindow::CMainWindow(QWidget *parent)
table = new QTableWidget(); table = new QTableWidget();
table->setColumnCount(5); table->setColumnCount(5);
table->setRowCount(1020); table->setRowCount(1020);
TableDockWidget = new CDockWidget("Table 2"); TableDockWidget = DockManager->createDockWidget("Table 2");
TableDockWidget->setWidget(table); TableDockWidget->setWidget(table);
TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget); TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
TableDockWidget->resize(250, 150); TableDockWidget->resize(250, 150);
@@ -76,7 +74,7 @@ CMainWindow::CMainWindow(QWidget *parent)
QTableWidget* propertiesTable = new QTableWidget(); QTableWidget* propertiesTable = new QTableWidget();
propertiesTable->setColumnCount(3); propertiesTable->setColumnCount(3);
propertiesTable->setRowCount(10); propertiesTable->setRowCount(10);
CDockWidget* PropertiesDockWidget = new CDockWidget("Properties"); CDockWidget* PropertiesDockWidget = DockManager->createDockWidget("Properties");
PropertiesDockWidget->setWidget(propertiesTable); PropertiesDockWidget->setWidget(propertiesTable);
PropertiesDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget); PropertiesDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
PropertiesDockWidget->resize(250, 150); PropertiesDockWidget->resize(250, 150);

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}) project(ads_example_hideshow VERSION ${VERSION_SHORT})
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED) find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)

View File

@@ -35,7 +35,7 @@ MainWindow::MainWindow(QWidget *parent) :
// Create a dock widget with the title Label 1 and set the created label // Create a dock widget with the title Label 1 and set the created label
// as the dock widget content // as the dock widget content
ads::CDockWidget* DockWidget = new ads::CDockWidget("Label 1"); ads::CDockWidget* DockWidget = m_DockManager->createDockWidget("Label 1");
DockWidget->setWidget(l); DockWidget->setWidget(l);
// Add the toggleViewAction of the dock widget to the menu to give // 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}) project(ads_example_sidebar VERSION ${VERSION_SHORT})
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED) find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)

View File

@@ -28,7 +28,7 @@ MainWindow::MainWindow(QWidget *parent) :
// Create a dock widget with the title Label 1 and set the created label // Create a dock widget with the title Label 1 and set the created label
// as the dock widget content // as the dock widget content
ads::CDockWidget* DockWidget = new ads::CDockWidget("Label 1"); ads::CDockWidget* DockWidget = m_DockManager->createDockWidget("Label 1");
DockWidget->setWidget(l); DockWidget->setWidget(l);
// Add the toggleViewAction of the dock widget to the menu to give // Add the toggleViewAction of the dock widget to the menu to give
@@ -42,7 +42,7 @@ MainWindow::MainWindow(QWidget *parent) :
// Create an example editor // Create an example editor
QPlainTextEdit* te = new QPlainTextEdit(); QPlainTextEdit* te = new QPlainTextEdit();
te->setPlaceholderText("Please enter your text here into this 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); DockWidget->setWidget(te);
ui->menuView->addAction(DockWidget->toggleViewAction()); ui->menuView->addAction(DockWidget->toggleViewAction());
m_DockManager->addDockWidget(ads::BottomDockWidgetArea, DockWidget); 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}) project(ads_example_simple VERSION ${VERSION_SHORT})
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED) find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)

View File

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

View File

@@ -415,7 +415,31 @@ void CAutoHideDockContainer::moveContentsToParent()
// to the user and he does not have to search where the widget was inserted. // to the user and he does not have to search where the widget was inserted.
d->DockWidget->setDockArea(nullptr); d->DockWidget->setDockArea(nullptr);
auto DockContainer = dockContainer(); 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);
} }
@@ -425,8 +449,8 @@ void CAutoHideDockContainer::cleanupAndDelete()
const auto dockWidget = d->DockWidget; const auto dockWidget = d->DockWidget;
if (dockWidget) if (dockWidget)
{ {
auto SideTab = d->SideTab; auto SideTab = d->SideTab;
dockWidget->setSideTabWidget(nullptr);
SideTab->removeFromSideBar(); SideTab->removeFromSideBar();
SideTab->setParent(nullptr); SideTab->setParent(nullptr);
SideTab->hide(); SideTab->hide();
@@ -482,6 +506,17 @@ void CAutoHideDockContainer::collapseView(bool Enable)
{ {
updateSize(); updateSize();
d->updateResizeHandleSizeLimitMax(); 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(); raise();
show(); show();
d->DockWidget->dockManager()->setDockWidgetFocused(d->DockWidget); d->DockWidget->dockManager()->setDockWidgetFocused(d->DockWidget);

View File

@@ -139,7 +139,7 @@ struct AutoHideTabPrivate
IFloatingWidget* createFloatingWidget(T* Widget) IFloatingWidget* createFloatingWidget(T* Widget)
{ {
auto w = new CFloatingDragPreview(Widget); auto w = new CFloatingDragPreview(Widget);
_this->connect(w, &CFloatingDragPreview::draggingCanceled, [=]() _this->connect(w, &CFloatingDragPreview::draggingCanceled, [this]()
{ {
DragState = DraggingInactive; DragState = DraggingInactive;
}); });

View File

@@ -93,7 +93,7 @@ public:
/** /**
* Virtual Destructor * Virtual Destructor
*/ */
virtual ~CAutoHideTab(); ~CAutoHideTab() override;
/** /**
* Update stylesheet style if a property changes * Update stylesheet style if a property changes

View File

@@ -1,16 +1,23 @@
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.16)
project(QtAdvancedDockingSystem LANGUAGES CXX VERSION ${VERSION_SHORT}) project(QtAdvancedDockingSystem LANGUAGES CXX VERSION ${VERSION_SHORT})
include(GNUInstallDirs) include(GNUInstallDirs)
include(Versioning)
if (${QT_VERSION_MAJOR}) if (${QT_VERSION_MAJOR})
message(STATUS "Forced to use Qt version ${QT_VERSION_MAJOR}") message(STATUS "Forced to use Qt version ${QT_VERSION_MAJOR}")
find_package(QT NAMES Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED) find_package(QT NAMES Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)
else() else()
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
endif() endif()
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Widgets REQUIRED)
if (UNIX AND NOT APPLE) set(ads_DEP_LIBS Core Gui Widgets)
include_directories(${Qt${QT_VERSION_MAJOR}Gui_PRIVATE_INCLUDE_DIRS}) 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() 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) set(CMAKE_INCLUDE_CURRENT_DIR ON)
if(BUILD_STATIC) if(BUILD_STATIC)
set(CMAKE_STATIC_LIBRARY_SUFFIX "_static${CMAKE_STATIC_LIBRARY_SUFFIX}") set(CMAKE_STATIC_LIBRARY_SUFFIX "_static${CMAKE_STATIC_LIBRARY_SUFFIX}")
@@ -77,6 +84,9 @@ if(BUILD_STATIC)
target_compile_definitions( ${library_name} PUBLIC ADS_STATIC) target_compile_definitions( ${library_name} PUBLIC ADS_STATIC)
else() else()
add_library( ${library_name} SHARED ${ads_SRCS} ${ads_HEADERS}) 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) target_compile_definitions( ${library_name} PRIVATE ADS_SHARED_EXPORT)
endif() endif()
@@ -85,6 +95,11 @@ add_library(ads::${library_name} ALIAS ${library_name})
target_link_libraries(${library_name} PUBLIC Qt${QT_VERSION_MAJOR}::Core target_link_libraries(${library_name} PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets) 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 (UNIX AND NOT APPLE)
if (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") if (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
find_package(X11 REQUIRED) find_package(X11 REQUIRED)
@@ -98,6 +113,7 @@ set_target_properties(${library_name} PROPERTIES
AUTORCC ON AUTORCC ON
CXX_EXTENSIONS OFF CXX_EXTENSIONS OFF
VERSION ${VERSION_SHORT} VERSION ${VERSION_SHORT}
SOVERSION ${VERSION_SONAME}
EXPORT_NAME ${library_name} EXPORT_NAME ${library_name}
DEBUG_POSTFIX "d" DEBUG_POSTFIX "d"
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib" ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
@@ -127,7 +143,7 @@ install(FILES ${ads_HEADERS}
install(FILES install(FILES
"${CMAKE_CURRENT_SOURCE_DIR}/../LICENSE" "${CMAKE_CURRENT_SOURCE_DIR}/../LICENSE"
"${CMAKE_CURRENT_SOURCE_DIR}/../gnu-lgpl-v2.1.md" "${CMAKE_CURRENT_SOURCE_DIR}/../gnu-lgpl-v2.1.md"
DESTINATION license/ads DESTINATION share/ads/license
COMPONENT license COMPONENT license
) )
install(TARGETS ${library_name} install(TARGETS ${library_name}

View File

@@ -334,27 +334,13 @@ void CDockAreaTabBar::onTabCloseRequested()
void CDockAreaTabBar::onCloseOtherTabsRequested() void CDockAreaTabBar::onCloseOtherTabsRequested()
{ {
auto Sender = qobject_cast<CDockWidgetTab*>(sender()); 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 dock widget blocks closing, i.e. if the flag for (int i = count() - 1; i >= 0; --i) {
// CustomCloseHandling is set, and the dock widget is still open, auto Tab = tab(i);
// then we do not need to correct the index if (Tab->isClosable() && !Tab->isHidden() && Tab != Sender) {
if (Tab->dockWidget()->isClosed()) closeTab(i);
{ }
i -= Offset; }
}
}
}
} }

View File

@@ -260,10 +260,10 @@ void DockAreaTitleBarPrivate::createAutoHideTitleLabel()
{ {
AutoHideTitleLabel = new CElidingLabel(""); AutoHideTitleLabel = new CElidingLabel("");
AutoHideTitleLabel->setObjectName("autoHideTitleLabel"); AutoHideTitleLabel->setObjectName("autoHideTitleLabel");
// At position 0 is the tab bar - insert behind tab bar // When the tabs are at the top, they will be at position 0, insert the label behind them, and hide it.
Layout->insertWidget(1, AutoHideTitleLabel); Layout->addWidget(AutoHideTitleLabel);
AutoHideTitleLabel->setVisible(false); // Default hidden AutoHideTitleLabel->setVisible(CDockManager::testConfigFlag(CDockManager::TabsAtBottom));
Layout->insertWidget(2 ,new CSpacerWidget(_this)); Layout->addWidget(new CSpacerWidget(_this));
} }
@@ -272,7 +272,9 @@ void DockAreaTitleBarPrivate::createTabBar()
{ {
TabBar = componentsFactory()->createDockAreaTabBar(DockArea); TabBar = componentsFactory()->createDockAreaTabBar(DockArea);
TabBar->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); TabBar->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
Layout->addWidget(TabBar); if (!CDockManager::testConfigFlag(CDockManager::TabsAtBottom))
Layout->addWidget(TabBar);
_this->connect(TabBar, SIGNAL(tabClosed(int)), SLOT(markTabsMenuOutdated())); _this->connect(TabBar, SIGNAL(tabClosed(int)), SLOT(markTabsMenuOutdated()));
_this->connect(TabBar, SIGNAL(tabOpened(int)), SLOT(markTabsMenuOutdated())); _this->connect(TabBar, SIGNAL(tabOpened(int)), SLOT(markTabsMenuOutdated()));
_this->connect(TabBar, SIGNAL(tabInserted(int)), SLOT(markTabsMenuOutdated())); _this->connect(TabBar, SIGNAL(tabInserted(int)), SLOT(markTabsMenuOutdated()));
@@ -303,7 +305,7 @@ IFloatingWidget* DockAreaTitleBarPrivate::makeAreaFloating(const QPoint& Offset,
else else
{ {
auto w = new CFloatingDragPreview(DockArea); auto w = new CFloatingDragPreview(DockArea);
QObject::connect(w, &CFloatingDragPreview::draggingCanceled, [=]() QObject::connect(w, &CFloatingDragPreview::draggingCanceled, [this]()
{ {
this->DragState = DraggingInactive; this->DragState = DraggingInactive;
}); });
@@ -351,8 +353,8 @@ CDockAreaTitleBar::CDockAreaTitleBar(CDockAreaWidget* parent) :
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
d->createTabBar(); d->createTabBar();
d->createButtons();
d->createAutoHideTitleLabel(); d->createAutoHideTitleLabel();
d->createButtons();
setFocusPolicy(Qt::NoFocus); setFocusPolicy(Qt::NoFocus);
} }
@@ -900,9 +902,12 @@ QString CDockAreaTitleBar::titleBarButtonToolTip(TitleBarButton Button) const
//============================================================================ //============================================================================
void CDockAreaTitleBar::showAutoHideControls(bool Show) 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); d->MinimizeButton->setVisible(Show);
d->AutoHideTitleLabel->setVisible(Show); if (!CDockManager::testConfigFlag(CDockManager::TabsAtBottom))
d->AutoHideTitleLabel->setVisible(Show);
} }

View File

@@ -176,7 +176,7 @@ public:
/** /**
* Virtual Destructor * Virtual Destructor
*/ */
virtual ~CDockAreaTitleBar(); ~CDockAreaTitleBar() override;
/** /**
* Returns the pointer to the tabBar() * Returns the pointer to the tabBar()

View File

@@ -179,14 +179,17 @@ public:
parent->setUpdatesEnabled(false); parent->setUpdatesEnabled(false);
} }
auto LayoutItem = m_ParentLayout->takeAt(1); if (m_CurrentWidget)
if (LayoutItem)
{ {
LayoutItem->widget()->setParent(nullptr); auto LayoutItem = m_ParentLayout->takeAt(1);
if (LayoutItem)
{
LayoutItem->widget()->setParent(nullptr);
}
delete LayoutItem;
} }
delete LayoutItem;
m_ParentLayout->addWidget(next); m_ParentLayout->insertWidget(1, next);
if (prev) if (prev)
{ {
prev->hide(); prev->hide();
@@ -362,6 +365,14 @@ void DockAreaWidgetPrivate::createTitleBar()
{ {
TitleBar = componentsFactory()->createDockAreaTitleBar(_this); TitleBar = componentsFactory()->createDockAreaTitleBar(_this);
Layout->addWidget(TitleBar); 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(tabBar(), &CDockAreaTabBar::tabCloseRequested, _this, &CDockAreaWidget::onTabCloseRequested);
QObject::connect(TitleBar, &CDockAreaTitleBar::tabBarClicked, _this, &CDockAreaWidget::setCurrentIndex); QObject::connect(TitleBar, &CDockAreaTitleBar::tabBarClicked, _this, &CDockAreaWidget::setCurrentIndex);
QObject::connect(tabBar(), &CDockAreaTabBar::tabMoved, _this, &CDockAreaWidget::reorderDockWidget); QObject::connect(tabBar(), &CDockAreaTabBar::tabMoved, _this, &CDockAreaWidget::reorderDockWidget);
@@ -449,6 +460,12 @@ CDockAreaWidget::CDockAreaWidget(CDockManager* DockManager, CDockContainerWidget
d->createTitleBar(); d->createTitleBar();
d->ContentsLayout = new DockAreaLayout(d->Layout); d->ContentsLayout = new DockAreaLayout(d->Layout);
if (CDockManager::testConfigFlag(CDockManager::UseNativeWindows))
{
winId();
}
if (d->DockManager) if (d->DockManager)
{ {
Q_EMIT d->DockManager->dockAreaCreated(this); Q_EMIT d->DockManager->dockAreaCreated(this);
@@ -592,8 +609,7 @@ void CDockAreaWidget::removeDockWidget(CDockWidget* DockWidget)
{ {
if(CFloatingDockContainer* FloatingDockContainer = DockContainer->floatingWidget()) if(CFloatingDockContainer* FloatingDockContainer = DockContainer->floatingWidget())
{ {
FloatingDockContainer->hide(); FloatingDockContainer->finishDropOperation();
FloatingDockContainer->deleteLater();
} }
} }
} }
@@ -726,6 +742,7 @@ void CDockAreaWidget::setCurrentIndex(int index)
TabBar->setCurrentIndex(index); TabBar->setCurrentIndex(index);
d->ContentsLayout->setCurrentIndex(index); d->ContentsLayout->setCurrentIndex(index);
d->ContentsLayout->currentWidget()->show(); d->ContentsLayout->currentWidget()->show();
d->TitleBar->autoHideTitleLabel()->setText(d->ContentsLayout->currentWidget()->windowTitle());
Q_EMIT currentChanged(index); Q_EMIT currentChanged(index);
} }
@@ -872,11 +889,40 @@ void CDockAreaWidget::updateTitleBarVisibility()
bool IsAutoHide = isAutoHide(); bool IsAutoHide = isAutoHide();
if (!CDockManager::testConfigFlag(CDockManager::AlwaysShowTabs)) if (!CDockManager::testConfigFlag(CDockManager::AlwaysShowTabs))
{ {
bool Hidden = Container->hasTopLevelDockWidget() && (Container->isFloating() bool Hidden = false;
|| CDockManager::testConfigFlag(CDockManager::HideSingleCentralWidgetTitleBar)); if (!IsAutoHide) // Titlebar must always be visible when auto hidden so it can be dragged
Hidden |= (d->Flags.testFlag(HideSingleWidgetTitleBar) && openDockWidgetsCount() == 1); {
Hidden &= !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); d->TitleBar->setVisible(!Hidden);
if (CDockManager::testConfigFlag(CDockManager::TabsAtBottom))
d->TitleBar->tabBar()->setVisible(openDockWidgetsCount() > 1);
} }
if (isAutoHideFeatureEnabled()) if (isAutoHideFeatureEnabled())
@@ -887,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() void CDockAreaWidget::markTitleBarMenuOutdated()
{ {
@@ -1440,14 +1499,18 @@ QSize CDockAreaWidget::minimumSizeHint() const
return Super::minimumSizeHint(); return Super::minimumSizeHint();
} }
int extraHeight = 0;
if (d->TitleBar->isVisible()) 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

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

View File

@@ -907,6 +907,7 @@ void DockContainerWidgetPrivate::addDockAreasToList(const QList<CDockAreaWidget*
{ {
DockArea->titleBarButton(TitleBarButtonClose)->setVisible(true); DockArea->titleBarButton(TitleBarButtonClose)->setVisible(true);
DockArea->titleBarButton(TitleBarButtonAutoHide)->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 // We need to ensure, that the dock area title bar is visible. The title bar
@@ -1572,9 +1573,21 @@ void CDockContainerWidget::removeDockArea(CDockAreaWidget* area)
d->DockAreas.removeAll(area); d->DockAreas.removeAll(area);
auto Splitter = area->parentSplitter(); auto Splitter = area->parentSplitter();
// Remove are from parent splitter and recursively hide tree of parent // Remove area from parent splitter and recursively hide tree of parent
// splitters if it has no visible content // splitters if it has no visible content.
area->setParent(nullptr); // 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); internal::hideEmptyParentSplitters(Splitter);
// Remove this area from cached areas // Remove this area from cached areas
@@ -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) 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 * 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 * Each window that support docking has a DockContainerWidget. That means
* the main application window and all floating windows contain a * the main application window and all floating windows contain a
* DockContainerWidget instance. * DockContainerWidget instance.
@@ -86,6 +86,9 @@ private:
friend AutoHideDockContainerPrivate; friend AutoHideDockContainerPrivate;
friend CAutoHideSideBar; friend CAutoHideSideBar;
private Q_SLOTS:
void removeFromDockManager();
protected: protected:
/** /**
* Handles activation events to update zOrderIndex * Handles activation events to update zOrderIndex
@@ -219,7 +222,7 @@ public:
/** /**
* Virtual Destructor * Virtual Destructor
*/ */
virtual ~CDockContainerWidget(); ~CDockContainerWidget() override;
/** /**
* Adds dockwidget into the given area. * 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) void CDockFocusController::setDockWidgetTabPressed(bool Value)
{ {

View File

@@ -69,6 +69,12 @@ public:
*/ */
CDockWidget* focusedDockWidget() const; 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 * Request focus highlighting for the given dock widget assigned to the tab
* given in Tab parameter * given in Tab parameter

View File

@@ -41,6 +41,7 @@
#include <QVariant> #include <QVariant>
#include <QDebug> #include <QDebug>
#include <QFile> #include <QFile>
#include <QDialog>
#include <QAction> #include <QAction>
#include <QXmlStreamWriter> #include <QXmlStreamWriter>
#include <QSettings> #include <QSettings>
@@ -202,6 +203,10 @@ DockManagerPrivate::DockManagerPrivate(CDockManager* _public) :
//============================================================================ //============================================================================
void DockManagerPrivate::loadStylesheet() void DockManagerPrivate::loadStylesheet()
{ {
if (CDockManager::testConfigFlag(CDockManager::DisableStylesheet))
{
return;
}
initResource(); initResource();
QString Result; QString Result;
QString FileName = ":ads/stylesheets/"; QString FileName = ":ads/stylesheets/";
@@ -530,14 +535,45 @@ CDockManager::CDockManager(QWidget *parent) :
window()->installEventFilter(this); window()->installEventFilter(this);
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) #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 if (!focusWindow)
// floating dock widget
if (focusWindow && focusWindow->isModal())
{ {
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 #endif
} }
@@ -736,7 +772,8 @@ void CDockManager::registerFloatingWidget(CFloatingDockContainer* FloatingWidget
//============================================================================ //============================================================================
void CDockManager::removeFloatingWidget(CFloatingDockContainer* FloatingWidget) void CDockManager::removeFloatingWidget(CFloatingDockContainer* FloatingWidget)
{ {
d->FloatingWidgets.removeAll(FloatingWidget); int removed = d->FloatingWidgets.removeAll(FloatingWidget);
Q_ASSERT(removed == 1);
} }
//============================================================================ //============================================================================
@@ -751,7 +788,8 @@ void CDockManager::removeDockContainer(CDockContainerWidget* DockContainer)
{ {
if (this != DockContainer) if (this != DockContainer)
{ {
d->Containers.removeAll(DockContainer); int removed = d->Containers.removeAll(DockContainer);
Q_ASSERT(removed == 1);
} }
} }
@@ -1523,6 +1561,16 @@ QVariant CDockManager::configParam(eConfigParam Param, QVariant Default)
} }
//===========================================================================
void CDockManager::raise()
{
if (parentWidget())
{
parentWidget()->raise();
}
}
} // namespace ads } // namespace ads
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@@ -64,8 +64,13 @@ struct AutoHideTabPrivate;
* of the docking system. The dock manager uses an internal stylesheet to * of the docking system. The dock manager uses an internal stylesheet to
* style its components like splitters, tabs and buttons. If you want to * style its components like splitters, tabs and buttons. If you want to
* disable this stylesheet because your application uses its own, * disable this stylesheet because your application uses its own,
* just call the function for settings the stylesheet with an empty * you can either set the DisableStylesheet config flag before creating
* string. * 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 * \code
* DockManager->setStyleSheet(""); * DockManager->setStyleSheet("");
* \endcode * \endcode
@@ -216,6 +221,9 @@ public:
DisableTabTextEliding = 0x4000000, //! Set this flag to disable eliding of tab texts in dock area tabs 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 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 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 DefaultDockAreaButtons = DockAreaHasCloseButton
@@ -770,6 +778,12 @@ public Q_SLOTS:
*/ */
void hideManagerAndFloatingWidgets(); 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: Q_SIGNALS:
/** /**
* This signal is emitted if the list of perspectives changed. * This signal is emitted if the list of perspectives changed.

View File

@@ -96,6 +96,7 @@ struct DockWidgetPrivate
WidgetFactory* Factory = nullptr; WidgetFactory* Factory = nullptr;
QPointer<CAutoHideTab> SideTabWidget; QPointer<CAutoHideTab> SideTabWidget;
CDockWidget::eToolBarStyleSource ToolBarStyleSource = CDockWidget::ToolBarStyleFromDockManager; CDockWidget::eToolBarStyleSource ToolBarStyleSource = CDockWidget::ToolBarStyleFromDockManager;
SideBarLocation PreferredAutoHideSideBarLocation = SideBarNone;
/** /**
* Private data constructor * Private data constructor
@@ -396,6 +397,11 @@ CDockWidget::CDockWidget(CDockManager *manager, const QString &title, QWidget* p
{ {
setFocusPolicy(Qt::ClickFocus); setFocusPolicy(Qt::ClickFocus);
} }
if (CDockManager::testConfigFlag(CDockManager::UseNativeWindows))
{
winId();
}
} }
@@ -649,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 bool CDockWidget::isFloating() const
{ {
@@ -841,9 +861,9 @@ void CDockWidget::saveState(QXmlStreamWriter& s) const
void CDockWidget::flagAsUnassigned() void CDockWidget::flagAsUnassigned()
{ {
d->Closed = true; d->Closed = true;
setParent(d->DockManager);
setVisible(false); setVisible(false);
setDockArea(nullptr); setDockArea(nullptr);
setParent(d->DockManager);
tabWidget()->setParent(this); tabWidget()->setParent(this);
} }
@@ -878,7 +898,7 @@ bool CDockWidget::event(QEvent *e)
} }
if (d->DockArea) if (d->DockArea)
{ {
d->DockArea->markTitleBarMenuOutdated();//update tabs menu d->DockArea->updateWindowTitle();
} }
auto FloatingWidget = floatingDockContainer(); auto FloatingWidget = floatingDockContainer();
@@ -1332,7 +1352,15 @@ void CDockWidget::setAutoHide(bool Enable, SideBarLocation Location, int TabInde
} }
else 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); dockContainer()->createAndSetupAutoHideContainer(area, this, TabIndex);
} }
} }

View File

@@ -289,7 +289,7 @@ public:
/** /**
* Virtual Destructor * Virtual Destructor
*/ */
virtual ~CDockWidget(); ~CDockWidget() override;
/** /**
* We return a fixed minimum size hint or the size hint of the content * We return a fixed minimum size hint or the size hint of the content
@@ -422,6 +422,22 @@ public:
*/ */
SideBarLocation autoHideLocation() const; 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. * This property holds whether the dock widget is floating.
* A dock widget is only floating, if it is the one and only widget inside * 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 "FloatingDockContainer.h"
#include "DockOverlay.h" #include "DockOverlay.h"
#include "DockManager.h" #include "DockManager.h"
#include "IconProvider.h"
#include "DockFocusController.h" #include "DockFocusController.h"
@@ -170,7 +169,7 @@ struct DockWidgetTabPrivate
else else
{ {
auto w = new CFloatingDragPreview(Widget); auto w = new CFloatingDragPreview(Widget);
_this->connect(w, &CFloatingDragPreview::draggingCanceled, [=]() _this->connect(w, &CFloatingDragPreview::draggingCanceled, [this]()
{ {
DragState = DraggingInactive; DragState = DraggingInactive;
}); });
@@ -540,13 +539,14 @@ QMenu* CDockWidgetTab::buildContextMenu(QMenu *Menu)
Menu = new QMenu(this); Menu = new QMenu(this);
} }
ADS_PRINT("CDockWidgetTab::buildContextMenu");
const bool isFloatable = d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable); const bool isFloatable = d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable);
const bool isNotOnlyTabInContainer = !d->DockArea->dockContainer()->hasTopLevelDockWidget();
const bool isTopLevelArea = d->DockArea->isTopLevelArea(); const bool isTopLevelArea = d->DockArea->isTopLevelArea();
const bool isDetachable = isFloatable && isNotOnlyTabInContainer; const bool isFloating = d->DockWidget->isFloating();
const bool isDetachable = isFloatable && !isFloating;
QAction* Action; QAction* Action;
if (!isTopLevelArea) if (!(isTopLevelArea && isFloating))
{ {
Action = Menu->addAction(tr("Detach"), this, SLOT(detachDockWidget())); Action = Menu->addAction(tr("Detach"), this, SLOT(detachDockWidget()));
Action->setEnabled(isDetachable); Action->setEnabled(isDetachable);
@@ -570,7 +570,7 @@ QMenu* CDockWidgetTab::buildContextMenu(QMenu *Menu)
Action->setEnabled(isClosable()); Action->setEnabled(isClosable());
if (d->DockArea->openDockWidgetsCount() > 1) if (d->DockArea->openDockWidgetsCount() > 1)
{ {
Action = Menu->addAction(tr("Close Others"), this, SIGNAL(closeOtherTabsRequested())); Menu->addAction(tr("Close Others"), this, SIGNAL(closeOtherTabsRequested()));
} }
return Menu; return Menu;
@@ -599,9 +599,9 @@ void CDockWidgetTab::setActiveTab(bool active)
if (CDockManager::testConfigFlag(CDockManager::FocusHighlighting) && !d->DockWidget->dockManager()->isRestoringState()) if (CDockManager::testConfigFlag(CDockManager::FocusHighlighting) && !d->DockWidget->dockManager()->isRestoringState())
{ {
bool UpdateFocusStyle = false; 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); d->focusController()->setDockWidgetTabFocused(this);
UpdateFocusStyle = true; UpdateFocusStyle = true;
} }

View File

@@ -91,7 +91,7 @@ public:
/** /**
* Virtual Destructor * Virtual Destructor
*/ */
virtual ~CDockWidgetTab(); ~CDockWidgetTab() override;
/** /**
* Returns true, if this is the active tab * Returns true, if this is the active tab

View File

@@ -374,6 +374,7 @@ struct FloatingDockContainerPrivate
QPoint DragStartPos; QPoint DragStartPos;
bool Hiding = false; bool Hiding = false;
bool AutoHideChildren = true; bool AutoHideChildren = true;
bool HideContentOnNextHide = false;
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) #if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
QWidget* MouseEventHandler = nullptr; QWidget* MouseEventHandler = nullptr;
CFloatingWidgetTitleBar* TitleBar = nullptr; CFloatingWidgetTitleBar* TitleBar = nullptr;
@@ -459,7 +460,7 @@ struct FloatingDockContainerPrivate
} }
else else
{ {
_this->setWindowIcon(QApplication::windowIcon()); _this->setWindowIcon(CurrentWidget->windowIcon());
} }
} }
@@ -499,6 +500,9 @@ void FloatingDockContainerPrivate::titleMouseReleaseEvent()
return; return;
} }
// DockManager will be unlinked from this within DropContainer->dropFloatingWidget
const auto OriginalDockManager = this->DockManager.data();
if (DockManager->dockAreaOverlay()->dropAreaUnderCursor() != InvalidDockWidgetArea if (DockManager->dockAreaOverlay()->dropAreaUnderCursor() != InvalidDockWidgetArea
|| DockManager->containerOverlay()->dropAreaUnderCursor() != InvalidDockWidgetArea) || DockManager->containerOverlay()->dropAreaUnderCursor() != InvalidDockWidgetArea)
{ {
@@ -532,8 +536,8 @@ void FloatingDockContainerPrivate::titleMouseReleaseEvent()
DropContainer->dropFloatingWidget(_this, QCursor::pos()); DropContainer->dropFloatingWidget(_this, QCursor::pos());
} }
DockManager->containerOverlay()->hideOverlay(); OriginalDockManager->containerOverlay()->hideOverlay();
DockManager->dockAreaOverlay()->hideOverlay(); OriginalDockManager->dockAreaOverlay()->hideOverlay();
} }
@@ -728,6 +732,11 @@ CFloatingDockContainer::CFloatingDockContainer(CDockManager *DockManager) :
l->addWidget(d->DockContainer); l->addWidget(d->DockContainer);
#endif #endif
if (CDockManager::testConfigFlag(CDockManager::UseNativeWindows))
{
winId();
}
DockManager->registerFloatingWidget(this); DockManager->registerFloatingWidget(this);
} }
@@ -845,6 +854,12 @@ void CFloatingDockContainer::changeEvent(QEvent *event)
this->showMaximized(); this->showMaximized();
} }
} }
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
if (d->TitleBar)
{
d->TitleBar->setVisible(!(isFloating() && isFullScreen()));
}
#endif
break; break;
default: default:
@@ -948,6 +963,15 @@ void CFloatingDockContainer::closeEvent(QCloseEvent *event)
return; 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 // 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 // QWidget::event() function to not receive any NonClientArea mouse
// events anymore after a close/show cycle. The bug is reported here: // events anymore after a close/show cycle. The bug is reported here:
@@ -975,6 +999,15 @@ void CFloatingDockContainer::hideEvent(QHideEvent *event)
return; 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 ) if ( d->AutoHideChildren )
{ {
d->Hiding = true; d->Hiding = true;
@@ -1190,8 +1223,9 @@ void CFloatingDockContainer::finishDropOperation()
if (d->DockManager) if (d->DockManager)
{ {
d->DockManager->removeFloatingWidget(this); d->DockManager->removeFloatingWidget(this);
d->DockManager->removeDockContainer(this->dockContainer()); d->DockManager.clear();
} }
this->dockContainer()->removeFromDockManager();
} }
//============================================================================ //============================================================================

View File

@@ -220,7 +220,7 @@ public:
/** /**
* Virtual Destructor * Virtual Destructor
*/ */
virtual ~CFloatingDockContainer(); ~CFloatingDockContainer() override;
/** /**
* Access function for the internal dock container * Access function for the internal dock container

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) void CFloatingWidgetTitleBar::setMaximizedIcon(bool maximized)

View File

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

View File

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

View File

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

View File

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

View File

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