Compare commits

..

32 Commits

Author SHA1 Message Date
Uwe Kindler
df34b0eb2b An additional fix for #496 Nonfloatable hidden window disappears on drop in empty area 2023-03-22 18:22:34 +01:00
Uwe Kindler
db3dc80170 Fixed #496 Nonfloatable hidden window disappears on drop in empty area 2023-03-21 08:31:55 +01:00
Nicolas Elie
db16c5f1b5 Update python bindings to 4.0.2 (#495)
* start adaption of PyQt5 bindings to Qt-ADS 4.0

* Update PyQt bindings

* Fix Python bindings build on Linux

---------

Co-authored-by: Mira Weller <mweller@seemoo.tu-darmstadt.de>
2023-03-21 06:04:19 +01:00
Nicolas Elie
d28ca1e7a1 Add options to project.py to specify include and library directories (#493) 2023-03-11 08:34:23 +01:00
Nicolas Elie
e84b4a8146 Add namespace to default argument for python bindings (#492) 2023-03-06 14:53:43 +01:00
Nicolas Elie
46e0d832f8 Fix wrong include path in CMake install (#491) 2023-03-06 14:52:57 +01:00
Uwe Kindler
7e63919c08 Updated ads icons 2023-03-01 08:54:27 +01:00
Uwe Kindler
1873dde358 Added ADTF to showcase section and added video link for Resinsight to showcase section 2023-03-01 08:49:19 +01:00
Uwe Kindler
6362d14da6 Merge branch 'master' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System 2023-02-27 08:03:08 +01:00
Uwe Kindler
1f48f0f3ad Updated linux-builds.yml to fix broken Ubuntu 22.04 workflow 2023-02-27 07:51:39 +01:00
Nicolas Elie
82695d1b3d Remove setup.py and related files (#490) 2023-02-23 18:42:47 +01:00
Nicolas Elie
08b0f8ad54 Change targets name based on Qt version (#489) 2023-02-23 15:50:50 +01:00
githubuser0xFFFF
54c2bd0c30 Update linux-builds.yml 2023-02-10 14:55:18 +01:00
githubuser0xFFFF
d8784a22b7 Update linux-builds.yml 2023-02-10 14:09:02 +01:00
githubuser0xFFFF
bc9f136f20 Update linux-builds.yml 2023-02-10 13:58:03 +01:00
githubuser0xFFFF
7192a06eb8 Update linux-builds.yml 2023-02-10 13:42:31 +01:00
githubuser0xFFFF
a4c6f1d16c Update linux-builds.yml 2023-02-10 13:30:41 +01:00
githubuser0xFFFF
009af32e61 Update linux-builds.yml
added Ubuntu 22.04 build with Qt6
2023-02-10 13:25:58 +01:00
Uwe Kindler
fab41828ab Updated the build documentation for Ubuntu 22.04 2023-02-10 12:02:42 +01:00
Uwe Kindler
cae42939c8 Disable native windows on Linux if wayland is used 2023-02-10 11:36:40 +01:00
Uwe Kindler
7b30322946 Added ResInsight to showcase section 2023-01-24 16:07:00 +01:00
Uwe Kindler
2730c135ea Removed OpaqueUndocking documentation 2023-01-20 11:58:58 +01:00
Uwe Kindler
9c30169c42 Removed support for opaque undocking 2023-01-20 11:50:34 +01:00
Uwe Kindler
624d21d001 Added RDE to showcase section 2023-01-20 10:25:21 +01:00
Uwe Kindler
378c647952 Fixed #481 issue Undocking an autohide dock widget does not close the AutoHideTab from the sidebar 2023-01-20 09:44:18 +01:00
Uwe Kindler
bbfe99ce7d Added image for showcase section 2023-01-19 13:34:32 +01:00
Uwe Kindler
97d675cb24 Updated README.md 2022-12-27 15:21:51 +01:00
Uwe Kindler
bbfad308e5 Added some pictures to show AutoHide and ImageViewer functionality 2022-12-27 15:19:51 +01:00
Uwe Kindler
858cdb2d66 Added some pictures to show AutoHide and ImageViewer functionality 2022-12-27 15:18:09 +01:00
githubuser0xFFFF
9f5e06ae13 Update linux-builds.yml
Removed ubuntu-latest because there seems to be build issues for ubuntu-22.04
2022-12-09 15:04:03 +01:00
Uwe Kindler
2cd451c53c Added dockContainer() function to AutoHideSideBar.cpp 2022-12-09 08:50:41 +01:00
Uwe Kindler
302ee59d67 Fixed dockContainer() function of AutoHideDockContainer.cpp
Returning the dock container of the internal dock area is wrong, if the dock widget is removed from
the AutoHideDockContainer, then the DockArea container function already returns the new dock container
of the DockArea and not the dock container of the AutoHideDockContainer.cpp
2022-12-09 08:50:12 +01:00
53 changed files with 1113 additions and 3019 deletions

View File

@@ -1,4 +1,4 @@
name: linux-builds
ilds
on: [push]
@@ -6,7 +6,7 @@ jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, ubuntu-20.04, ubuntu-18.04]
os: [ubuntu-20.04, ubuntu-18.04]
runs-on: ${{ matrix.os }}
@@ -21,3 +21,39 @@ jobs:
run: qmake
- name: make
run: make -j4
build_ubuntu_2204:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
- name: Cache Qt
id: cache-qt-6-4
uses: actions/cache@v1 # not v2!
with:
path: ../Qt/6.4.2
key: ${{ runner.os }}-QtCache-Qt6-4
- name: Install Qt
uses: jurplel/install-qt-action@v2
with:
version: '6.4.2'
host: 'linux'
target: 'desktop'
install-deps: true
cached: ${{ steps.cache-qt-6-4.outputs.cache-hit }}
setup-python: true
tools: ''
tools-only: false
- name: Install needed xkbcommon symlink
run: sudo apt-get install libxkbcommon-dev -y
- name: Ubuntu and Qt version
run: |
cat /etc/issue
echo number of processors: $(nproc)
qmake -v
- name: qmake
run: qmake
- name: make
run: make -j$(nproc)

1173
README.md

File diff suppressed because it is too large Load Diff

View File

@@ -25,7 +25,7 @@ target_link_libraries(AdvancedDockingSystemDemo PUBLIC Qt${QT_VERSION_MAJOR}::Co
if(WIN32 AND QT_VERSION_MAJOR LESS 6)
target_link_libraries(AdvancedDockingSystemDemo PUBLIC Qt${QT_VERSION_MAJOR}::AxContainer)
endif()
target_link_libraries(AdvancedDockingSystemDemo PRIVATE qtadvanceddocking)
target_link_libraries(AdvancedDockingSystemDemo PRIVATE qt${QT_VERSION_MAJOR}advanceddocking)
set_target_properties(AdvancedDockingSystemDemo PROPERTIES
AUTOMOC ON
AUTORCC ON

View File

@@ -544,13 +544,7 @@ void MainWindowPrivate::createContent()
#ifdef Q_OS_WIN
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
// If opaque undocking is active, then undocking of widgets while
// active x widget is visible causes jerking while dragging a floating
// widget
if (!ads::CDockManager::testConfigFlag(ads::CDockManager::OpaqueUndocking))
{
DockManager->addDockWidget(ads::CenterDockWidgetArea, createActiveXWidget(), RighDockArea);
}
DockManager->addDockWidget(ads::CenterDockWidgetArea, createActiveXWidget(), RighDockArea);
#endif
#endif

BIN
doc/AutoHide_Animation.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
doc/Feature_ImageViewer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 387 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

BIN
doc/showcase_adtf.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

BIN
doc/showcase_resinsight.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 461 KiB

BIN
doc/showcase_robox_ide.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 KiB

View File

@@ -11,7 +11,6 @@
- [`TabCloseButtonIsToolButton`](#tabclosebuttonistoolbutton)
- [`AllTabsHaveCloseButton`](#alltabshaveclosebutton)
- [`RetainTabSizeWhenCloseButtonHidden`](#retaintabsizewhenclosebuttonhidden)
- [`OpaqueUndocking`](#opaqueundocking)
- [`DragPreviewIsDynamic`](#dragpreviewisdynamic)
- [`DragPreviewShowsContentPixmap`](#dragpreviewshowscontentpixmap)
- [`DragPreviewHasWindowFrame`](#dragpreviewhaswindowframe)
@@ -170,37 +169,6 @@ constant, that means, if enabled, the tabs need more space.
![AllTabsHaveCloseButton false](cfg_flag_RetainTabSizeWhenCloseButtonHidden_true.png)
### `OpaqueUndocking`
If this flag is set, opaque undocking is active. That means, as soon as you drag a dock widget or a dock area with a number of dock widgets it will be undocked and moved into a floating widget and then the floating widget will be dragged around. That means undocking will take place immediately. You can compare this with opaque splitter resizing.
![OpaqueUndocking true](opaque_undocking.gif)
If you would like to test opaque undocking, you should set the predefined config
flags `CDockManager::DefaultOpaqueConfig`.
```c++
CDockManager::setConfigFlags(CDockManager::DefaultOpaqueConfig);
```
If this flag is cleared (default), then non-opaque undocking is active. In this mode, undocking is more like a standard drag and drop operation. That means, the dragged dock widget or dock area is not undocked immediatelly. Instead, a drag preview widget is created and dragged around to indicate the future position of the dock widget or dock area. The actual dock operation is only executed when the mouse button is released. That makes it possible, to cancel an active drag operation with the escape key.
![OpaqueUndocking true](non_opaque_undocking.gif)
The drag preview widget can be configured by a number of global dock manager flags:
- `DragPreviewIsDynamic`
- `DragPreviewShowsContentPixmap`
- `DragPreviewHasWindowFrame`
Non-opaque undocking is enabled by default. If you would like to enable it
explicitely, you can do this by setting the predefined configuration flags
`CDockManager::DefaultNonOpaqueConfig`.
```c++
CDockManager::setConfigFlags(CDockManager::DefaultNonOpaqueConfig);
```
### `DragPreviewIsDynamic`
If non-opaque undocking is enabled, this flag defines the behavior of the drag
@@ -631,10 +599,7 @@ If set, the dock widget will have a close button.
If a dock widget is movable, then it and can be moved to a new position in the
current dock container. Disable this flag to prevent moving of a dock widget
via mouse. If the `OpaqueUndocking` configuration flag is set, then dock widgets
are immediately undocked into floating widgets. That means, moving is only
possible in this case, if the dock widget is also floatable (feature flag
`DockWidgetFloatable` is set).
via mouse.
### `DockWidgetFloatable`

View File

@@ -9,7 +9,7 @@ add_executable(AutoHideExample WIN32
mainwindow.ui
)
target_include_directories(AutoHideExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
target_link_libraries(AutoHideExample PRIVATE qtadvanceddocking)
target_link_libraries(AutoHideExample PRIVATE qt${QT_VERSION_MAJOR}advanceddocking)
target_link_libraries(AutoHideExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)

View File

@@ -9,7 +9,7 @@ add_executable(CentralWidgetExample WIN32
mainwindow.ui
)
target_include_directories(CentralWidgetExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
target_link_libraries(CentralWidgetExample PRIVATE qtadvanceddocking)
target_link_libraries(CentralWidgetExample PRIVATE qt${QT_VERSION_MAJOR}advanceddocking)
target_link_libraries(CentralWidgetExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)

View File

@@ -7,7 +7,7 @@ add_executable(DeleteOnCloseTest WIN32
main.cpp
)
target_include_directories(DeleteOnCloseTest PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
target_link_libraries(DeleteOnCloseTest PRIVATE qtadvanceddocking)
target_link_libraries(DeleteOnCloseTest PRIVATE qt${QT_VERSION_MAJOR}advanceddocking)
target_link_libraries(DeleteOnCloseTest PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)

View File

@@ -12,7 +12,7 @@ add_executable(DockInDockExample WIN32
mainframe.cpp
)
target_include_directories(DockInDockExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
target_link_libraries(DockInDockExample PRIVATE qtadvanceddocking)
target_link_libraries(DockInDockExample PRIVATE qt${QT_VERSION_MAJOR}advanceddocking)
target_link_libraries(DockInDockExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)

View File

@@ -9,7 +9,7 @@ add_executable(EmptyDockAreaExample WIN32
mainwindow.ui
)
target_include_directories(EmptyDockAreaExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
target_link_libraries(EmptyDockAreaExample PRIVATE qtadvanceddocking)
target_link_libraries(EmptyDockAreaExample PRIVATE qt${QT_VERSION_MAJOR}advanceddocking)
target_link_libraries(EmptyDockAreaExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)

View File

@@ -9,7 +9,7 @@ add_executable(HideShowExample WIN32
MainWindow.ui
)
target_include_directories(HideShowExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
target_link_libraries(HideShowExample PRIVATE qtadvanceddocking)
target_link_libraries(HideShowExample PRIVATE qt${QT_VERSION_MAJOR}advanceddocking)
target_link_libraries(HideShowExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)

View File

@@ -9,7 +9,7 @@ add_executable(SidebarExample WIN32
MainWindow.ui
)
target_include_directories(SidebarExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
target_link_libraries(SidebarExample PRIVATE qtadvanceddocking)
target_link_libraries(SidebarExample PRIVATE qt${QT_VERSION_MAJOR}advanceddocking)
target_link_libraries(SidebarExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)

View File

@@ -9,7 +9,7 @@ add_executable(SimpleExample WIN32
MainWindow.ui
)
target_include_directories(SimpleExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
target_link_libraries(SimpleExample PRIVATE qtadvanceddocking)
target_link_libraries(SimpleExample PRIVATE qt${QT_VERSION_MAJOR}advanceddocking)
target_link_libraries(SimpleExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)

View File

@@ -1,4 +1,5 @@
import os
import sys
from pyqtbuild import PyQtBindings, PyQtProject
from sipbuild import Option
@@ -16,12 +17,37 @@ class ads(PyQtBindings):
""" Initialise the bindings. """
super().__init__(project, 'ads')
def get_options(self):
"""Our custom options that a user can pass to sip-build."""
options = super().get_options()
options += [
Option('ads_incdir',
help='the directory containing the ads header file',
metavar='DIR'),
Option('ads_libdir',
help='the directory containing the ads library',
metavar='DIR'),
Option('ads_lib',
help='the ads library',
metavar='LIB'),
]
return options
def apply_user_defaults(self, tool):
""" Set default values for user options that haven't been set yet. """
resource_file = os.path.join(self.project.root_dir,'src','ads.qrc')
print("Adding resource file to qmake project: ", resource_file)
self.builder_settings.append('RESOURCES += '+resource_file)
if self.ads_lib is not None:
self.libraries.append(self.ads_lib)
if self.ads_incdir is not None:
self.include_dirs.append(self.ads_incdir)
if self.ads_libdir is not None:
self.library_dirs.append(self.ads_libdir)
super().apply_user_defaults(tool)

View File

@@ -1,12 +1,12 @@
# Specify the build system.
[build-system]
requires = ["sip >=6.0.2, <6.6", "PyQt-builder >=1.6, <2", "PyQt5>=5.15.4", "PyQt5-sip<13,>=12.8"]
requires = ["sip >=6.0.2, <6.3", "PyQt-builder >=1.6, <2", "PyQt5==5.15.4", "PyQt5-sip<13,>=12.8"]
build-backend = "sipbuild.api"
# Specify the PEP 566 metadata for the project.
[tool.sip.metadata]
name = "PyQtAds"
version = "3.8.2"
version = "4.0.2"
summary = "Python bindings for Qt Advanced Docking System"
home-page = "https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/"
license = "LGPL v2.1"
@@ -21,8 +21,11 @@ tag-prefix = "QtAds"
define-macros = ["ADS_SHARED_EXPORT"]
sip-file = "ads.sip"
include-dirs = ["src"]
qmake-QT = ["widgets"]
qmake-QT = ["widgets", "gui-private; platform_system == 'Linux'"]
headers = [
"src/AutoHideDockContainer.h",
"src/AutoHideSideBar.h",
"src/AutoHideTab.h",
"src/DockAreaTabBar.h",
"src/DockAreaTitleBar.h",
"src/DockAreaTitleBar_p.h",
@@ -40,10 +43,15 @@ headers = [
"src/FloatingDockContainer.h",
"src/FloatingDragPreview.h",
"src/IconProvider.h",
"src/PushButton.h",
"src/ResizeHandle.h",
"src/ads_globals.h",
# "src/linux/FloatingWidgetTitleBar.h",
"src/linux/FloatingWidgetTitleBar.h; platform_system == 'Linux'",
]
sources = [
"src/AutoHideTab.cpp",
"src/AutoHideDockContainer.cpp",
"src/AutoHideSideBar.cpp",
"src/DockAreaTabBar.cpp",
"src/DockAreaTitleBar.cpp",
"src/DockAreaWidget.cpp",
@@ -60,6 +68,8 @@ sources = [
"src/FloatingDockContainer.cpp",
"src/FloatingDragPreview.cpp",
"src/IconProvider.cpp",
"src/PushButton.cpp",
"src/ResizeHandle.cpp",
"src/ads_globals.cpp",
# "src/linux/FloatingWidgetTitleBar.cpp",
"src/linux/FloatingWidgetTitleBar.h; platform_system == 'Linux'",
]

View File

@@ -1,7 +0,0 @@
[versioneer]
VCS = git
style = pep440
versionfile_source = PyQtAds/_version.py
versionfile_build = PyQtAds/_version.py
tag_prefix =

396
setup.py
View File

@@ -1,396 +0,0 @@
import os
import sys
import shlex
import shutil
import subprocess
import glob
import versioneer
from setuptools import setup, find_packages
from setuptools.command.build_py import build_py
from setuptools.extension import Extension
from distutils import sysconfig, dir_util, spawn, log, cmd
from distutils.dep_util import newer
import sipdistutils
import sipconfig
from PyQt5.QtCore import PYQT_CONFIGURATION
from PyQt5.pyrcc_main import processResourceFile
MODULE_NAME = "ads"
SRC_PATH = "PyQtAds"
REQUIRE_PYQT = True
if "--conda-recipe" in sys.argv:
REQUIRE_PYQT = False
sys.argv.remove("--conda-recipe")
class HostPythonConfiguration(object):
def __init__(self):
self.platform = sys.platform
self.version = sys.hexversion>>8
self.inc_dir = sysconfig.get_python_inc()
self.venv_inc_dir = sysconfig.get_python_inc(prefix=sys.prefix)
self.module_dir = sysconfig.get_python_lib(plat_specific=1)
if sys.platform == 'win32':
self.data_dir = sys.prefix
self.lib_dir = sys.prefix +'\\libs'
else:
self.data_dir = sys.prefix + '/share'
self.lib_dir = sys.prefix + '/lib'
class TargetQtConfiguration(object):
def __init__(self, qmake):
pipe = os.popen(' '.join([qmake, '-query']))
for l in pipe:
l = l.strip()
tokens = l.split(':', 1)
if isinstance(tokens, list):
if len(tokens) != 2:
error("Unexpected output from qmake: '%s'\n" % l)
name, value = tokens
else:
name = tokens
value = None
name = name.replace('/', '_')
setattr(self, name, value)
pipe.close()
class build_ext(sipdistutils.build_ext):
description = "Builds the " + MODULE_NAME + " module."
user_options = sipdistutils.build_ext.user_options + [
('qmake-bin=', None, "Path to qmake binary"),
('sip-bin=', None, "Path to sip binary"),
('qt-include-dir=', None, "Path to Qt headers"),
('pyqt-sip-dir=', None, "Path to PyQt's SIP files"),
('pyqt-sip-flags=', None, "SIP flags used to generate PyQt bindings"),
('sip-dir=', None, "Path to module's SIP files"),
('inc-dir=', None, "Path to module's include files")
]
def initialize_options (self):
super().initialize_options()
self.qmake_bin = 'qmake'
self.sip_bin = None
self.qt_include_dir = None
self.qt_libinfix = ''
self.pyqt_sip_dir = None
self.pyqt_sip_flags = None
self.sip_files_dir = None
self.sip_inc_dir = None
self.inc_dir = None
self.pyconfig = HostPythonConfiguration()
self.qtconfig = TargetQtConfiguration(self.qmake_bin)
self.config = sipconfig.Configuration()
self.config.default_mod_dir = ("/usr/local/lib/python%i.%i/dist-packages" %
(sys.version_info.major, sys.version_info.minor))
def finalize_options (self):
super().finalize_options()
if not self.qt_include_dir:
self.qt_include_dir = self.qtconfig.QT_INSTALL_HEADERS
if not self.qt_libinfix:
try:
with open(os.path.join(self.qtconfig.QT_INSTALL_PREFIX, 'mkspecs', 'qconfig.pri'), 'r') as f:
for line in f.readlines():
if line.startswith('QT_LIBINFIX'):
self.qt_libinfix = line.split('=')[1].strip('\n').strip()
except (FileNotFoundError, IndexError):
pass
if not self.pyqt_sip_dir:
self.pyqt_sip_dir = os.path.join(self.pyconfig.data_dir, 'sip', 'PyQt5')
if not self.pyqt_sip_flags:
self.pyqt_sip_flags = PYQT_CONFIGURATION.get('sip_flags', '')
if not self.sip_files_dir:
self.sip_files_dir = os.path.abspath(os.path.join(".", "sip"))
if not self.sip_inc_dir:
self.sip_inc_dir = self.pyconfig.venv_inc_dir
if not self.inc_dir:
self.inc_dir = os.path.abspath(os.path.join(".", "src"))
if not self.qt_include_dir:
raise SystemExit('Could not find Qt5 headers. '
'Please specify via --qt-include-dir=')
if not self.pyqt_sip_dir:
raise SystemExit('Could not find PyQt SIP files. '
'Please specify containing directory via '
'--pyqt-sip-dir=')
if not self.pyqt_sip_flags:
raise SystemExit('Could not find PyQt SIP flags. '
'Please specify via --pyqt-sip-flags=')
def _find_sip(self):
"""override _find_sip to allow for manually speficied sip path."""
# 1. Manually specified sip_bin
if self.sip_bin:
return self.sip_bin
# 2. Path determined from sipconfig.Configuration()
# This may not exist, depending on conda build configuration.
sip_bin = super()._find_sip()
if os.path.exists(sip_bin):
return sip_bin
# 3. Finally, fall back to sip binary found in path
sip_bin = shutil.which('sip')
if sip_bin:
return sip_bin
raise SystemExit('Could not find PyQt SIP binary.')
def _sip_sipfiles_dir(self):
sip_dir = super()._sip_sipfiles_dir()
if os.path.exists(sip_dir):
return sip_dir
return os.path.join(sys.prefix, 'sip', 'PyQt5')
def _sip_compile(self, sip_bin, source, sbf):
target_dir = os.path.dirname(__file__) if self.inplace else self.build_lib
pyi = os.path.join(target_dir, "PyQtAds", "QtAds", "ads.pyi")
if not os.path.exists(os.path.dirname(pyi)):
os.makedirs(os.path.dirname(pyi))
cmd = [sip_bin]
if hasattr(self, 'sip_opts'):
cmd += self.sip_opts
if hasattr(self, '_sip_sipfiles_dir'):
cmd += ['-I', self._sip_sipfiles_dir()]
cmd += [
"-I", self.sip_files_dir,
"-I", self.pyqt_sip_dir,
"-I", self.sip_inc_dir,
"-I", self.inc_dir,
"-c", self._sip_output_dir(),
"-b", sbf,
"-y", pyi,
"-w", "-o"]
cmd += shlex.split(self.pyqt_sip_flags) # use same SIP flags as for PyQt5
cmd.append(source)
self.spawn(cmd)
if os.path.exists(pyi):
with open(pyi) as f:
content = f.readlines()
with open(pyi, "w") as f:
for line in content:
if not line.startswith("class ads"):
f.write(line)
def swig_sources (self, sources, extension=None):
if not self.extensions:
return
# Add the local include directory to the include path
if extension is not None:
extension.extra_compile_args += ['-D', 'QT_CORE_LIB',
'-D', 'QT_GUI_LIB',
'-D', 'QT_WIDGETS_LIB',
'-D', 'ADS_SHARED_EXPORT']
extension.include_dirs += [self.qt_include_dir, self.inc_dir,
os.path.join(self.qt_include_dir, 'QtCore'),
os.path.join(self.qt_include_dir, 'QtGui'),
os.path.join(self.qt_include_dir, 'QtWidgets')]
extension.libraries += ['Qt5Core' + self.qt_libinfix,
'Qt5Gui' + self.qt_libinfix,
'Qt5Widgets' + self.qt_libinfix]
if sys.platform == 'win32':
extension.library_dirs += [self.qtconfig.QT_INSTALL_LIBS,
self.inc_dir, self._sip_output_dir()]
elif sys.platform == 'darwin':
extension.extra_compile_args += ['-F' + self.qtconfig.QT_INSTALL_LIBS,
'-std=c++11', '-stdlib=libc++', '-mmacosx-version-min=10.9']
extension.extra_link_args += ['-F' + self.qtconfig.QT_INSTALL_LIBS,
'-mmacosx-version-min=10.9']
elif sys.platform == 'linux':
extension.extra_compile_args += ['-std=c++11']
return super().swig_sources(sources, extension)
def build_extension(self, ext):
cppsources = [source for source in ext.sources if source.endswith(".cpp")]
headersources = ['src/DockAreaTitleBar_p.h']
dir_util.mkpath(self.build_temp, dry_run=self.dry_run)
def get_moc_args(out_file, source):
if sys.platform.startswith('linux'):
return ["moc", "-D", "Q_OS_LINUX=1", "-o", out_file, source]
if sys.platform.startswith('darwin'):
return ["moc", "-D", "Q_OS_MACOS=1", "-o", out_file, source]
if sys.platform.startswith('win'):
return ["moc", "-D", "Q_OS_WIN=1", "-o", out_file, source]
return ["moc", "-o", out_file, source]
# Run moc on all header files.
for source in cppsources:
# *.cpp -> *.moc
moc_file = os.path.basename(source).replace(".cpp", ".moc")
out_file = os.path.join(self.build_temp, moc_file)
if newer(source, out_file) or self.force:
spawn.spawn(get_moc_args(out_file, source), dry_run=self.dry_run)
header = source.replace(".cpp", ".h")
if os.path.exists(header):
# *.h -> moc_*.cpp
moc_file = "moc_" + os.path.basename(header).replace(".h", ".cpp")
out_file = os.path.join(self.build_temp, moc_file)
if newer(header, out_file) or self.force:
spawn.spawn(get_moc_args(out_file, header), dry_run=self.dry_run)
if os.path.getsize(out_file) > 0:
ext.sources.append(out_file)
# Run moc on all orphan header files.
for source in headersources:
# *.cpp -> *.moc
moc_file = os.path.basename(source).replace(".h", ".moc")
out_file = os.path.join(self.build_temp, moc_file)
if newer(source, out_file) or self.force:
spawn.spawn(get_moc_args(out_file, source),
dry_run=self.dry_run)
header = source
if os.path.exists(header):
# *.h -> moc_*.cpp
moc_file = "moc_" + os.path.basename(header).replace(
".h", ".cpp")
out_file = os.path.join(self.build_temp, moc_file)
if newer(header, out_file) or self.force:
spawn.spawn(get_moc_args(out_file, header),
dry_run=self.dry_run)
if os.path.getsize(out_file) > 0:
ext.sources.append(out_file)
# Add the temp build directory to include path, for compiler to find
# the created .moc files
ext.include_dirs += [self._sip_output_dir()]
# Run rcc on all resource files
resources = [source for source in ext.sources if source.endswith(".qrc")]
for source in resources:
ext.sources.remove(source)
out_file = os.path.join(self.build_temp, "qrc_" + os.path.basename(source).replace(".qrc", ".cpp"))
if newer(header, out_file) or self.force:
spawn.spawn(["rcc", "-name", os.path.splitext(os.path.basename(source))[0], source, "-o", out_file], dry_run=self.dry_run)
if os.path.getsize(out_file) > 0:
ext.sources.append(out_file)
sipdistutils.build_ext.build_extension(self, ext)
import inspect
sys.path.append(os.path.join(self.build_lib, 'PyQtAds', 'QtAds'))
import ads
with open(os.path.join(self.build_lib, 'PyQtAds', 'QtAds', '__init__.py'), 'w') as f:
f.write('from .._version import *\n')
f.write('from .ads import ads\n')
for name, member in sorted(inspect.getmembers(ads.ads)):
if not name.startswith('_'):
f.write('{0} = ads.{0}\n'.format(name))
class ProcessResourceCommand(cmd.Command):
"""A custom command to compile the resource file into a Python file"""
description = "Compile the qrc file into a python file"
def initialize_options(self):
return
def finalize_options(self):
return
def run(self):
processResourceFile([os.path.join('src', 'ads.qrc')],
os.path.join(SRC_PATH, 'rc.py'), False)
class BuildPyCommand(build_py):
"""Custom build command to include ProcessResource command"""
def run(self):
self.run_command("process_resource")
build_py.run(self)
setup_requires = ["PyQt5"] if REQUIRE_PYQT else []
cpp_sources = glob.glob(os.path.join('src', '*.cpp'))
sip_sources = [os.path.join('sip', MODULE_NAME + '.sip')]
resources = [os.path.join('src', MODULE_NAME + '.qrc')]
if sys.platform == 'linux':
cpp_sources += glob.glob(os.path.join('src', 'linux', '*.cpp'))
ext_modules = [Extension('PyQtAds.QtAds.ads', cpp_sources + sip_sources + resources)]
install_requires = ["PyQt5"]
if sys.platform == 'win32':
install_requires.append("pywin32")
with open('README.md', 'r') as f:
LONG_DESCRIPTION = f.read()
setup(
name = SRC_PATH,
author = "Nicolas Elie",
author_email = "nicolas.elie@cnrs.fr",
url = "https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System",
version = versioneer.get_version(),
description = "Advanced Docking System for Qt",
long_description = LONG_DESCRIPTION,
keywords = ["qt"],
license = "LGPLv2+",
classifiers = ["Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)",
"Operating System :: OS Independent",
"Topic :: Software Development :: Libraries :: Python Modules",
"Environment :: Win32 (MS Windows)",
"Environment :: MacOS X",
"Environment :: X11 Applications :: Qt",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.2",
"Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7"],
ext_modules = ext_modules,
cmdclass = versioneer.get_cmdclass({'process_resource': ProcessResourceCommand,
'build_py': BuildPyCommand,
'build_ext': build_ext}),
packages = find_packages(),
setup_requires = setup_requires,
install_requires = install_requires,
zip_safe=False
)

View File

@@ -0,0 +1,46 @@
%Import QtWidgets/QtWidgetsmod.sip
%If (Qt_5_0_0 -)
namespace ads
{
class CAutoHideDockContainer : QFrame
{
%TypeHeaderCode
#include <AutoHideDockContainer.h>
%End
protected:
virtual bool eventFilter(QObject* watched, QEvent* event);
virtual void resizeEvent(QResizeEvent* event);
virtual void leaveEvent(QEvent *event);
virtual bool event(QEvent* event);
void updateSize();
void saveState(QXmlStreamWriter& Stream);
public:
CAutoHideDockContainer(ads::CDockWidget* DockWidget /Transfer/, ads::SideBarLocation area,
ads::CDockContainerWidget* parent /TransferThis/);
virtual ~CAutoHideDockContainer();
ads::CAutoHideSideBar* sideBar() const;
ads::CAutoHideTab* autoHideTab() const;
ads::CDockWidget* dockWidget() const;
void addDockWidget(ads::CDockWidget* DockWidget /Transfer/);
ads::SideBarLocation sideBarLocation() const;
void setSideBarLocation(ads::SideBarLocation SideBarLocation);
ads::CDockAreaWidget* dockAreaWidget() const;
ads::CDockContainerWidget* dockContainer() const;
void moveContentsToParent();
void cleanupAndDelete();
void toggleView(bool Enable);
void collapseView(bool Enable);
void toggleCollapseState();
void setSize(int Size);
};
};
%End

41
sip/AutoHideSideBar.sip Normal file
View File

@@ -0,0 +1,41 @@
%Import QtWidgets/QtWidgetsmod.sip
%If (Qt_5_0_0 -)
namespace ads
{
class CAutoHideSideBar : QScrollArea
{
%TypeHeaderCode
#include <AutoHideSideBar.h>
%End
protected:
virtual bool eventFilter(QObject *watched, QEvent *event);
void saveState(QXmlStreamWriter& Stream) const;
void insertTab(int Index, ads::CAutoHideTab* SideTab /Transfer/);
public:
CAutoHideSideBar(ads::CDockContainerWidget* parent /TransferThis/, SideBarLocation area);
virtual ~CAutoHideSideBar();
void removeTab(ads::CAutoHideTab* SideTab) /TransferBack/;
ads::CAutoHideDockContainer* insertDockWidget(int Index, ads::CDockWidget* DockWidget /Transfer/);
void removeAutoHideWidget(ads::CAutoHideDockContainer* AutoHideWidget) /TransferBack/;
void addAutoHideWidget(ads::CAutoHideDockContainer* AutoHideWidget);
Qt::Orientation orientation() const;
ads::CAutoHideTab* tabAt(int index) const;
int tabCount() const;
ads::SideBarLocation sideBarLocation() const;
virtual QSize minimumSizeHint() const;
virtual QSize sizeHint() const;
int spacing() const;
void setSpacing(int Spacing);
CDockContainerWidget* dockContainer() const;
};
};
%End

36
sip/AutoHideTab.sip Normal file
View File

@@ -0,0 +1,36 @@
%Import QtWidgets/QtWidgetsmod.sip
%If (Qt_5_0_0 -)
namespace ads
{
class CAutoHideTab : CPushButton
{
%TypeHeaderCode
#include <AutoHideTab.h>
%End
protected:
void setSideBar(ads::CAutoHideSideBar *SideTabBar);
void removeFromSideBar();
virtual bool event(QEvent* event);
public:
CAutoHideTab(QWidget* parent /TransferThis/ = 0);
virtual ~CAutoHideTab();
void updateStyle();
ads::SideBarLocation sideBarLocation() const;
void setOrientation(Qt::Orientation Orientation);
Qt::Orientation orientation() const;
bool isActiveTab() const;
ads::CDockWidget* dockWidget() const;
void setDockWidget(ads::CDockWidget* DockWidget);
bool iconOnly() const;
ads::CAutoHideSideBar* sideBar() const;
};
};
%End

View File

@@ -27,10 +27,12 @@ public:
virtual ~CDockAreaTitleBar();
ads::CDockAreaTabBar* tabBar() const;
QAbstractButton* button(ads::TitleBarButton which) const;
ads::CElidingLabel* autoHideTitleLabel() const;
void updateDockWidgetActionsButtons();
virtual void setVisible(bool Visible);
void insertWidget(int index, QWidget *widget /Transfer/ );
int indexOf(QWidget *widget) const;
QString titleBarButtonToolTip(ads::TitleBarButton Button) const;
signals:

View File

@@ -23,6 +23,7 @@ protected:
void updateTitleBarVisibility();
void internalSetCurrentDockWidget(ads::CDockWidget* DockWidget /Transfer/);
void markTitleBarMenuOutdated();
void updateTitleBarButtonVisibility(bool IsTopLevel) const;
protected slots:
void toggleView(bool Open);
@@ -52,6 +53,8 @@ public:
ads::CDockWidget* currentDockWidget() const;
void setCurrentDockWidget(ads::CDockWidget* DockWidget);
void saveState(QXmlStreamWriter& Stream) const;
static bool restoreState(ads::CDockingStateReader& Stream, ads::CDockAreaWidget*& CreatedWidget,
bool Testing, ads::CDockContainerWidget* ParentContainer);
ads::CDockWidget::DockWidgetFeatures features(ads::eBitwiseOperator Mode = ads::BitwiseAnd) const;
QAbstractButton* titleBarButton(ads::TitleBarButton which) const;
virtual void setVisible(bool Visible);
@@ -65,6 +68,8 @@ public:
void setDockAreaFlag(eDockAreaFlag Flag, bool On);
bool isCentralWidgetArea() const;
bool containsCentralWidget() const;
bool isTopLevelArea() const;
public slots:
void setCurrentIndex(int index);

View File

@@ -13,6 +13,7 @@ class CDockComponentsFactory
public:
virtual ~CDockComponentsFactory();
virtual CDockWidgetTab* createDockWidgetTab(CDockWidget* DockWidget /Transfer/ ) const;
virtual CAutoHideTab* createDockWidgetSideTab(CDockWidget* DockWidget /Transfer/) const;
virtual CDockAreaTabBar* createDockAreaTabBar(CDockAreaWidget* DockArea /Transfer/ ) const;
virtual CDockAreaTitleBar* createDockAreaTitleBar(CDockAreaWidget* DockArea /Transfer/ ) const;
static const CDockComponentsFactory* factory();

View File

@@ -21,6 +21,7 @@ class CDockContainerWidget : QFrame
protected:
virtual bool event(QEvent *e);
QSplitter* rootSplitter() const;
ads::CAutoHideDockContainer* createAndSetupAutoHideContainer(ads::SideBarLocation area, ads::CDockWidget* DockWidget /Transfer/);
void createRootSplitter();
void dropFloatingWidget(ads::CFloatingDockContainer* FloatingWidget, const QPoint& TargetPos);
void dropWidget(QWidget* Widget, DockWidgetArea DropArea, CDockAreaWidget* TargetAreaWidget);
@@ -33,124 +34,44 @@ protected:
ads::CDockAreaWidget* topLevelDockArea() const;
QList<ads::CDockWidget*> dockWidgets() const;
void updateSplitterHandles(QSplitter* splitter);
void registerAutoHideWidget(ads::CAutoHideDockContainer* AutoHideWidget /Transfer/);
void removeAutoHideWidget(ads::CAutoHideDockContainer* AutoHideWidget /TransferBack/);
void handleAutoHideWidgetEvent(QEvent* e, QWidget* w);
public:
/**
* Default Constructor
*/
CDockContainerWidget(ads::CDockManager* DockManager /TransferThis/, QWidget* parent /TransferThis/ = 0);
/**
* Virtual Destructor
*/
virtual ~CDockContainerWidget();
/**
* Adds dockwidget into the given area.
* If DockAreaWidget is not null, then the area parameter indicates the area
* into the DockAreaWidget. If DockAreaWidget is null, the Dockwidget will
* be dropped into the container.
* \return Returns the dock area widget that contains the new DockWidget
*/
ads::CDockAreaWidget* addDockWidget(ads::DockWidgetArea area, ads::CDockWidget* Dockwidget /Transfer/,
ads::CDockAreaWidget* DockAreaWidget /Transfer/ = 0);
/**
* Removes dockwidget
*/
ads::CDockAreaWidget* DockAreaWidget /Transfer/ = 0,
int Index = -1);
void removeDockWidget(ads::CDockWidget* Dockwidget) /TransferBack/;
/**
* Returns the current zOrderIndex
*/
virtual unsigned int zOrderIndex() const;
/**
* This function returns true if this container widgets z order index is
* higher than the index of the container widget given in Other parameter
*/
bool isInFrontOf(ads::CDockContainerWidget* Other) const;
/**
* Returns the dock area at teh given global position or 0 if there is no
* dock area at this position
*/
ads::CDockAreaWidget* dockAreaAt(const QPoint& GlobalPos) const;
/**
* Returns the dock area at the given Index or 0 if the index is out of
* range
*/
ads::CDockAreaWidget* dockArea(int Index) const;
/**
* Returns the list of dock areas that are not closed
* If all dock widgets in a dock area are closed, the dock area will be closed
*/
QList<ads::CDockAreaWidget*> openedDockAreas() const;
QList<ads::CDockWidget*> openedDockWidgets() const;
bool hasTopLevelDockWidget() const;
/**
* Returns the number of dock areas in this container
*/
int dockAreaCount() const;
/**
* Returns the number of visible dock areas
*/
int visibleDockAreaCount() const;
/**
* This function returns true, if this container is in a floating widget
*/
bool isFloating() const;
/**
* Dumps the layout for debugging purposes
*/
void dumpLayout();
/**
* This functions returns the dock widget features of all dock widget in
* this container.
* A bitwise and is used to combine the flags of all dock widgets. That
* means, if only dock widget does not support a certain flag, the whole
* dock are does not support the flag.
*/
ads::CDockWidget::DockWidgetFeatures features() const;
/**
* If this dock container is in a floating widget, this function returns
* the floating widget.
* Else, it returns a nullptr.
*/
ads::CFloatingDockContainer* floatingWidget() const;
/**
* Call this function to close all dock areas except the KeepOpenArea
*/
void closeOtherAreas(ads::CDockAreaWidget* KeepOpenArea);
ads::CAutoHideSideBar* sideTabBar(SideBarLocation area) const;
QList<ads::CAutoHideDockContainer*> autoHideWidgets() const;
QRect contentRect() const;
QRect contentRectGlobal() const;
ads::CDockManager* dockManager() const;
signals:
/**
* This signal is emitted if one or multiple dock areas has been added to
* the internal list of dock areas.
* If multiple dock areas are inserted, this signal is emitted only once
*/
void dockAreasAdded();
/**
* This signal is emitted if one or multiple dock areas has been removed
*/
void autoHideWidgetCreated(ads::CAutoHideDockContainer* AutoHideWidget);
void dockAreasRemoved();
/**
* This signal is emitted if a dock area is opened or closed via
* toggleView() function
*/
void dockAreaViewToggled(ads::CDockAreaWidget* DockArea, bool Open);
}; // class DockContainerWidget
};
// namespace ads
};
%End

View File

@@ -22,6 +22,7 @@ public:
void notifyFloatingWidgetDrop(ads::CFloatingDockContainer* FloatingWidget);
ads::CDockWidget* focusedDockWidget() const;
void setDockWidgetTabFocused(ads::CDockWidgetTab* Tab);
void clearDockWidgetFocus(ads::CDockWidget* dockWidget);
public slots:
void setDockWidgetFocused(ads::CDockWidget* focusedNow);

View File

@@ -156,7 +156,6 @@ public:
TabCloseButtonIsToolButton,
AllTabsHaveCloseButton,
RetainTabSizeWhenCloseButtonHidden,
OpaqueUndocking,
DragPreviewIsDynamic,
DragPreviewShowsContentPixmap,
DragPreviewHasWindowFrame,
@@ -180,6 +179,17 @@ public:
NonOpaqueWithWindowFrame,
};
typedef QFlags<ads::CDockManager::eConfigFlag> ConfigFlags;
enum eAutoHideFlag
{
AutoHideFeatureEnabled,
DockAreaHasAutoHideButton,
AutoHideButtonTogglesArea,
AutoHideButtonCheckable,
AutoHideSideBarsIconOnly,
AutoHideShowOnMouseOver,
DefaultAutoHideConfig,
};
typedef QFlags<ads::CDockManager::eAutoHideFlag> AutoHideFlags;
CDockManager(QWidget* parent /TransferThis/ = 0);
virtual ~CDockManager();
@@ -187,13 +197,24 @@ public:
static void setConfigFlags(const ads::CDockManager::ConfigFlags Flags);
static void setConfigFlag(ads::CDockManager::eConfigFlag Flag, bool On = true);
static bool testConfigFlag(eConfigFlag Flag);
static ads::CDockManager::AutoHideFlags autoHideConfigFlags();
static void setAutoHideConfigFlags(const ads::CDockManager::AutoHideFlags Flags);
static void setAutoHideConfigFlag(ads::CDockManager::eAutoHideFlag Flag, bool On = true);
static bool testAutoHideConfigFlag(eAutoHideFlag Flag);
static ads::CIconProvider& iconProvider();
ads::CDockAreaWidget* addDockWidget(ads::DockWidgetArea area, ads::CDockWidget* Dockwidget /Transfer/,
ads::CDockAreaWidget* DockAreaWidget /Transfer/ = 0);
ads::CDockAreaWidget* DockAreaWidget /Transfer/ = 0,
int Index = -1);
ads::CDockAreaWidget* addDockWidgetToContainer(ads::DockWidgetArea area, ads::CDockWidget* Dockwidget /Transfer/,
ads::CDockContainerWidget* DockContainerWidget /Transfer/ = 0);
ads::CAutoHideDockContainer* addAutoHideDockWidget(ads::SideBarLocation Location, ads::CDockWidget* Dockwidget /Transfer/);
ads::CAutoHideDockContainer* addAutoHideDockWidgetToContainer(SideBarLocation Location,
ads::CDockWidget* Dockwidget /Transfer/, ads::CDockContainerWidget* DockContainerWidget);
ads::CDockAreaWidget* addDockWidgetTab(ads::DockWidgetArea area,
ads::CDockWidget* Dockwidget /Transfer/);
ads::CDockAreaWidget* addDockWidgetTabToArea(ads::CDockWidget* Dockwidget /Transfer/,
ads::CDockAreaWidget* DockAreaWidget /Transfer/);
ads::CDockAreaWidget* DockAreaWidget /Transfer/,
int Index = -1);
ads::CFloatingDockContainer* addDockWidgetFloating(ads::CDockWidget* DockWidget /Transfer/);
ads::CDockWidget* findDockWidget(const QString& ObjectName) const;
void removeDockWidget(ads::CDockWidget* Dockwidget) /TransferBack/;
@@ -220,6 +241,8 @@ public:
ads::CDockWidget* focusedDockWidget() const;
QList<int> splitterSizes(ads::CDockAreaWidget *ContainedArea) const;
void setSplitterSizes(ads::CDockAreaWidget *ContainedArea, const QList<int>& sizes);
static void setFloatingContainersTitle(const QString& Title);
static QString floatingContainersTitle();
public slots:
void openPerspective(const QString& PerspectiveName);

View File

@@ -35,6 +35,7 @@ public:
DockWidgetForceCloseWithArea,
NoTab,
DeleteContentOnClose,
DockWidgetPinnable,
DefaultDockWidgetFeatures,
AllDockWidgetFeatures,
DockWidgetAlwaysCloseAndDelete,
@@ -81,7 +82,12 @@ public:
ads::CDockWidget::DockWidgetFeatures features() const;
ads::CDockManager* dockManager() const;
ads::CDockContainerWidget* dockContainer() const;
ads::CFloatingDockContainer* floatingDockContainer() const;
ads::CDockAreaWidget* dockAreaWidget() const;
ads::CAutoHideTab* sideTabWidget() const;
void setSideTabWidget(ads::CAutoHideTab* SideTab /Transfer/) const;
bool isAutoHide() const;
ads::CAutoHideDockContainer* autoHideDockContainer() const;
bool isFloating() const;
bool isInFloatingContainer() const;
bool isClosed() const;
@@ -118,6 +124,8 @@ public slots:
void closeDockWidget();
void showFullScreen();
void showNormal();
void setAutoHide(bool Enable, ads::SideBarLocation Location = ads::SideBarNone);
void toggleAutoHide(ads::SideBarLocation Location = ads::SideBarNone);
signals:
void viewToggled(bool Open);

View File

@@ -64,6 +64,7 @@ protected:
%If (WS_X11)
virtual void moveEvent(QMoveEvent *event);
virtual void resizeEvent(QResizeEvent *event);
virtual bool event(QEvent *e);
%End
%If (WS_WIN)

View File

@@ -27,10 +27,9 @@ public:
public: // implements IFloatingWidget
virtual void startFloating(const QPoint& DragStartMousePos, const QSize& Size,
ads::eDragState DragState, QWidget* MouseEventHandler);
virtual void moveFloating();
virtual void finishDragging();
void cleanupAutoHideContainerWidget();
signals:
void draggingCanceled();

31
sip/PushButton.sip Normal file
View File

@@ -0,0 +1,31 @@
%Import QtWidgets/QtWidgetsmod.sip
%If (Qt_5_0_0 -)
namespace ads
{
class CPushButton : QPushButton
{
%TypeHeaderCode
#include <PushButton.h>
%End
public:
enum Orientation {
Horizontal,
VerticalTopToBottom,
VerticalBottomToTop
};
virtual QSize sizeHint() const;
ads::CPushButton::Orientation buttonOrientation() const;
void setButtonOrientation(ads::CPushButton::Orientation orientation);
};
};
%End

36
sip/ResizeHandle.sip Normal file
View File

@@ -0,0 +1,36 @@
%Import QtWidgets/QtWidgetsmod.sip
%If (Qt_5_0_0 -)
namespace ads
{
class CResizeHandle : QFrame
{
%TypeHeaderCode
#include <ResizeHandle.h>
%End
protected:
void mouseMoveEvent(QMouseEvent *);
void mousePressEvent(QMouseEvent *);
void mouseReleaseEvent(QMouseEvent *);
public:
CResizeHandle(Qt::Edge HandlePosition, QWidget* parent /TransferThis/);
virtual ~CResizeHandle();
void setHandlePosition(Qt::Edge HandlePosition);
Qt::Edge handlePostion() const;
Qt::Orientation orientation() const;
QSize sizeHint() const;
bool isResizing() const;
void setMinResizeSize(int MinSize);
void setMaxResizeSize(int MaxSize);
void setOpaqueResize(bool opaque = true);
bool opaqueResize() const;
};
};
%End

View File

@@ -3,6 +3,9 @@
%DefaultSupertype sip.simplewrapper
%Include ads_globals.sip
%Include AutoHideDockContainer.sip
%Include AutoHideSideBar.sip
%Include AutoHideTab.sip
%Include DockWidget.sip
%Include DockAreaTabBar.sip
%Include DockAreaTitleBar_p.sip
@@ -20,6 +23,8 @@
%Include FloatingDockContainer.sip
%Include FloatingDragPreview.sip
%Include IconProvider.sip
%Include PushButton.sip
%Include ResizeHandle.sip
%If (WS_X11)
%Include linux/FloatingWidgetTitleBar.sip
%End

View File

@@ -50,7 +50,6 @@ namespace ads
TopDockWidgetArea,
BottomDockWidgetArea,
CenterDockWidgetArea,
InvalidDockWidgetArea,
OuterDockAreas,
AllDockAreas
@@ -62,7 +61,8 @@ namespace ads
{
TitleBarButtonTabsMenu,
TitleBarButtonUndock,
TitleBarButtonClose
TitleBarButtonClose,
TitleBarButtonAutoHide
};
enum eDragState
@@ -76,10 +76,10 @@ namespace ads
enum eIcon
{
TabCloseIcon,
AutoHideIcon,
DockAreaMenuIcon,
DockAreaUndockIcon,
DockAreaCloseIcon,
IconCount,
};
@@ -89,6 +89,15 @@ namespace ads
BitwiseOr
};
enum SideBarLocation
{
SideBarTop,
SideBarLeft,
SideBarRight,
SideBarBottom,
SideBarNone
};
namespace internal
{
void replaceSplitterWidget(QSplitter* Splitter, QWidget* From, QWidget* To);
@@ -131,6 +140,7 @@ namespace ads
};
void repolishStyle(QWidget* w, ads::internal::eRepolishChildOptions Options = ads::internal::RepolishIgnoreChildren);
QRect globalGeometry(QWidget* w);
};
};

View File

@@ -187,14 +187,7 @@ AutoHideDockContainerPrivate::AutoHideDockContainerPrivate(
//============================================================================
CDockContainerWidget* CAutoHideDockContainer::dockContainer() const
{
if (d->DockArea)
{
return d->DockArea->dockContainer();
}
else
{
return internal::findParent<CDockContainerWidget*>(this);
}
return internal::findParent<CDockContainerWidget*>(this);
}
@@ -303,8 +296,15 @@ CAutoHideDockContainer::~CAutoHideDockContainer()
//============================================================================
CAutoHideSideBar* CAutoHideDockContainer::sideBar() const
{
auto DockContainer = dockContainer();
return DockContainer ? DockContainer->sideTabBar(d->SideTabBarArea) : nullptr;
if (d->SideTab)
{
return d->SideTab->sideBar();
}
else
{
auto DockContainer = dockContainer();
return DockContainer ? DockContainer->sideTabBar(d->SideTabBarArea) : nullptr;
}
}

View File

@@ -378,11 +378,19 @@ int CAutoHideSideBar::spacing() const
return d->TabsLayout->spacing();
}
//===========================================================================
void CAutoHideSideBar::setSpacing(int Spacing)
{
d->TabsLayout->setSpacing(Spacing);
}
//===========================================================================
CDockContainerWidget* CAutoHideSideBar::dockContainer() const
{
return d->ContainerWidget;
}
} // namespace ads

View File

@@ -163,6 +163,11 @@ public:
* Setter for spacing property - sets the spacing
*/
void setSpacing(int Spacing);
/**
* Returns the dock container that hosts this sideBar()
*/
CDockContainerWidget* dockContainer() const;
};
} // namespace ads
//-----------------------------------------------------------------------------

View File

@@ -64,50 +64,52 @@ if (UNIX AND NOT APPLE)
set(ads_SRCS linux/FloatingWidgetTitleBar.cpp ${ads_SRCS})
set(ads_HEADERS linux/FloatingWidgetTitleBar.h ${ads_HEADERS})
endif()
set(library_name "qt${QT_VERSION_MAJOR}advanceddocking")
if(BUILD_STATIC)
add_library(qtadvanceddocking STATIC ${ads_SRCS} ${ads_HEADERS})
target_compile_definitions(qtadvanceddocking PUBLIC ADS_STATIC)
add_library(${library_name} STATIC ${ads_SRCS} ${ads_HEADERS})
target_compile_definitions( ${library_name} PUBLIC ADS_STATIC)
else()
add_library(qtadvanceddocking SHARED ${ads_SRCS} ${ads_HEADERS})
target_compile_definitions(qtadvanceddocking PRIVATE ADS_SHARED_EXPORT)
add_library( ${library_name} SHARED ${ads_SRCS} ${ads_HEADERS})
target_compile_definitions( ${library_name} PRIVATE ADS_SHARED_EXPORT)
endif()
add_library(ads::qtadvanceddocking ALIAS qtadvanceddocking)
add_library(ads::${library_name} ALIAS ${library_name})
target_link_libraries(qtadvanceddocking PUBLIC Qt${QT_VERSION_MAJOR}::Core
target_link_libraries(${library_name} PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)
if (UNIX AND NOT APPLE)
target_link_libraries(qtadvanceddocking PUBLIC xcb)
target_link_libraries(${library_name} PUBLIC xcb)
endif()
set_target_properties(qtadvanceddocking PROPERTIES
set_target_properties(${library_name} PROPERTIES
AUTOMOC ON
AUTORCC ON
CXX_EXTENSIONS OFF
VERSION ${VERSION_SHORT}
EXPORT_NAME "qtadvanceddocking"
EXPORT_NAME ${library_name}
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/bin"
)
if(QT_VERSION_MAJOR STREQUAL "5")
set_target_properties(qtadvanceddocking PROPERTIES
set_target_properties(${library_name} PROPERTIES
CXX_STANDARD 14
CXX_STANDARD_REQUIRED ON)
elseif(QT_VERSION_MAJOR STREQUAL "6")
set_target_properties(qtadvanceddocking PROPERTIES
set_target_properties(${library_name} PROPERTIES
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON)
endif()
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"qtadvanceddockingConfigVersion.cmake"
"${library_name}ConfigVersion.cmake"
VERSION ${VERSION_SHORT}
COMPATIBILITY SameMajorVersion
)
install(FILES ${ads_HEADERS}
DESTINATION include
DESTINATION include/${library_name}
COMPONENT headers
)
install(FILES
@@ -116,24 +118,27 @@ install(FILES
DESTINATION license/ads
COMPONENT license
)
install(TARGETS qtadvanceddocking
install(TARGETS ${library_name}
EXPORT adsTargets
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
INCLUDES DESTINATION include
INCLUDES DESTINATION include/${library_name}
)
install(EXPORT adsTargets
FILE adsTargets.cmake
NAMESPACE ads::
DESTINATION lib/cmake/qtadvanceddocking
DESTINATION lib/cmake/${library_name}
)
install(FILES qtadvanceddockingConfig.cmake "${CMAKE_CURRENT_BINARY_DIR}/qtadvanceddockingConfigVersion.cmake"
DESTINATION lib/cmake/qtadvanceddocking
install(FILES qtadvanceddockingConfig.cmake RENAME ${library_name}Config.cmake
DESTINATION lib/cmake/${library_name}
)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${library_name}ConfigVersion.cmake"
DESTINATION lib/cmake/${library_name}
)
target_include_directories(qtadvanceddocking PUBLIC
target_include_directories(${library_name} PUBLIC
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
)

View File

@@ -262,12 +262,15 @@ IFloatingWidget* DockAreaTitleBarPrivate::makeAreaFloating(const QPoint& Offset,
{
QSize Size = DockArea->size();
this->DragState = DragState;
bool OpaqueUndocking = CDockManager::testConfigFlag(CDockManager::OpaqueUndocking) ||
(DraggingFloatingWidget != DragState);
bool CreateFloatingDockContainer = (DraggingFloatingWidget != DragState);
CFloatingDockContainer* FloatingDockContainer = nullptr;
IFloatingWidget* FloatingWidget;
if (OpaqueUndocking)
if (CreateFloatingDockContainer)
{
if (DockArea->autoHideDockContainer())
{
DockArea->autoHideDockContainer()->cleanupAndDelete();
}
FloatingWidget = FloatingDockContainer = new CFloatingDockContainer(DockArea);
}
else
@@ -297,7 +300,7 @@ IFloatingWidget* DockAreaTitleBarPrivate::makeAreaFloating(const QPoint& Offset,
//============================================================================
void DockAreaTitleBarPrivate::startFloating(const QPoint& Offset)
{
if (DockArea->autoHideDockContainer() != nullptr)
if (DockArea->autoHideDockContainer())
{
DockArea->autoHideDockContainer()->hide();
}
@@ -428,11 +431,6 @@ void CDockAreaTitleBar::onUndockButtonClicked()
{
if (d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
{
if (d->DockArea->autoHideDockContainer())
{
d->DockArea->autoHideDockContainer()->cleanupAndDelete();
}
d->makeAreaFloating(mapFromGlobal(QCursor::pos()), DraggingInactive);
}
}
@@ -634,11 +632,9 @@ void CDockAreaTitleBar::mouseMoveEvent(QMouseEvent* ev)
// If one single dock widget in this area is not floatable then the whole
// area is not floatable
// If we do non opaque undocking, then we can create the floating drag
// preview if the dock widget is movable
// We can create the floating drag preview if the dock widget is movable
auto Features = d->DockArea->features();
if (!Features.testFlag(CDockWidget::DockWidgetFloatable)
&& !(Features.testFlag(CDockWidget::DockWidgetMovable) && !CDockManager::testConfigFlag(CDockManager::OpaqueUndocking)))
if (!Features.testFlag(CDockWidget::DockWidgetFloatable) && !(Features.testFlag(CDockWidget::DockWidgetMovable)))
{
return;
}
@@ -671,10 +667,6 @@ void CDockAreaTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
{
return;
}
if (d->DockArea->autoHideDockContainer())
{
d->DockArea->autoHideDockContainer()->cleanupAndDelete();
}
d->makeAreaFloating(event->pos(), DraggingInactive);
}

View File

@@ -130,7 +130,7 @@ protected:
/**
* Adds the given dock area to this container widget
*/
void addDockArea(CDockAreaWidget* DockAreaWidget, DockWidgetArea area = CenterDockWidgetArea);
void addDockArea(CDockAreaWidget* DockAreaWidget, DockWidgetArea area = ads::CenterDockWidgetArea);
/**
* Removes the given dock area from this container

View File

@@ -180,7 +180,6 @@ public:
TabCloseButtonIsToolButton = 0x0040,//! If enabled the tab close buttons will be QToolButtons instead of QPushButtons - disabled by default
AllTabsHaveCloseButton = 0x0080, //!< if this flag is set, then all tabs that are closable show a close button
RetainTabSizeWhenCloseButtonHidden = 0x0100, //!< if this flag is set, the space for the close button is reserved even if the close button is not visible
OpaqueUndocking = 0x0200,///< If enabled, the widgets are immediately undocked into floating widgets, if disabled, only a draw preview is undocked and the real undocking is deferred until the mouse is released
DragPreviewIsDynamic = 0x0400,///< If opaque undocking is disabled, this flag defines the behavior of the drag preview window, if this flag is enabled, the preview will be adjusted dynamically to the drop area
DragPreviewShowsContentPixmap = 0x0800,///< If opaque undocking is disabled, the created drag preview window shows a copy of the content of the dock widget / dock are that is dragged
DragPreviewHasWindowFrame = 0x1000,///< If opaque undocking is disabled, then this flag configures if the drag preview is frameless or looks like a real window
@@ -216,7 +215,7 @@ public:
DefaultOpaqueConfig = DefaultBaseConfig
| OpaqueSplitterResize
| OpaqueUndocking, ///< the default configuration with opaque operations - this may cause issues if ActiveX or Qt 3D windows are involved
| DragPreviewShowsContentPixmap, ///< the default configuration for non opaque operations
DefaultNonOpaqueConfig = DefaultBaseConfig
| DragPreviewShowsContentPixmap, ///< the default configuration for non opaque operations

View File

@@ -248,17 +248,31 @@ void DockWidgetPrivate::updateParentDockArea()
//============================================================================
void DockWidgetPrivate::closeAutoHideDockWidgetsIfNeeded()
{
if (_this->dockContainer() && _this->dockContainer()->openedDockWidgets().isEmpty() && !_this->dockManager()->isRestoringState())
auto DockContainer = _this->dockContainer();
if (!DockContainer)
{
for (auto autoHideWidget : _this->dockContainer()->autoHideWidgets())
{
if (autoHideWidget->dockWidget() == _this)
{
continue;
}
return;
}
autoHideWidget->dockWidget()->toggleView(false);
}
if (_this->dockManager()->isRestoringState())
{
return;
}
if (!DockContainer->openedDockWidgets().isEmpty())
{
return;
}
for (auto autoHideWidget : DockContainer->autoHideWidgets())
{
auto DockWidget = autoHideWidget->dockWidget();
if (DockWidget == _this)
{
continue;
}
DockWidget->toggleView(false);
}
}

View File

@@ -162,9 +162,9 @@ struct DockWidgetTabPrivate
}
template <typename T>
IFloatingWidget* createFloatingWidget(T* Widget, bool OpaqueUndocking)
IFloatingWidget* createFloatingWidget(T* Widget, bool CreateContainer)
{
if (OpaqueUndocking)
if (CreateContainer)
{
return new CFloatingDockContainer(Widget);
}
@@ -312,8 +312,7 @@ bool DockWidgetTabPrivate::startFloating(eDragState DraggingState)
ADS_PRINT("startFloating");
DragState = DraggingState;
IFloatingWidget* FloatingWidget = nullptr;
bool OpaqueUndocking = CDockManager::testConfigFlag(CDockManager::OpaqueUndocking) ||
(DraggingFloatingWidget != DraggingState);
bool CreateContainer = (DraggingFloatingWidget != DraggingState);
// If section widget has multiple tabs, we take only one tab
// If it has only one single tab, we can move the complete
@@ -321,12 +320,12 @@ bool DockWidgetTabPrivate::startFloating(eDragState DraggingState)
QSize Size;
if (DockArea->dockWidgetsCount() > 1)
{
FloatingWidget = createFloatingWidget(DockWidget, OpaqueUndocking);
FloatingWidget = createFloatingWidget(DockWidget, CreateContainer);
Size = DockWidget->size();
}
else
{
FloatingWidget = createFloatingWidget(DockArea, OpaqueUndocking);
FloatingWidget = createFloatingWidget(DockArea, CreateContainer);
Size = DockArea->size();
}
@@ -477,15 +476,13 @@ void CDockWidgetTab::mouseMoveEvent(QMouseEvent* ev)
// Floating is only allowed for widgets that are floatable
// If we do non opaque undocking, then can create the drag preview
// if the widget is movable.
// We can create the drag preview if the widget is movable.
auto Features = d->DockWidget->features();
if (Features.testFlag(CDockWidget::DockWidgetFloatable)
|| (Features.testFlag(CDockWidget::DockWidgetMovable) && !CDockManager::testConfigFlag(CDockManager::OpaqueUndocking)))
if (Features.testFlag(CDockWidget::DockWidgetFloatable) || (Features.testFlag(CDockWidget::DockWidgetMovable)))
{
// If we undock, we need to restore the initial position of this
// tab because it looks strange if it remains on its dragged position
if (d->isDraggingState(DraggingTab) && !CDockManager::testConfigFlag(CDockManager::OpaqueUndocking))
if (d->isDraggingState(DraggingTab))
{
parentWidget()->layout()->update();
}

View File

@@ -674,6 +674,17 @@ CFloatingDockContainer::CFloatingDockContainer(CDockManager *DockManager) :
native_window = window_manager != "KWIN";
}
if (native_window)
{
// Native windows do not work if wayland is used. Ubuntu 22.04 uses wayland by default. To use
// native windows, switch to Xorg
QString XdgSessionType = qgetenv("XDG_SESSION_TYPE").toLower();
if ("wayland" == XdgSessionType)
{
native_window = false;
}
}
if (native_window)
{
setTitleBarWidget(new QWidget());

View File

@@ -72,6 +72,26 @@ struct FloatingDragPreviewPrivate
* outside of any drop area
*/
void createFloatingWidget();
/**
* Returns true, if the content is floatable
*/
bool isContentFloatable() const
{
CDockWidget* DockWidget = qobject_cast<CDockWidget*>(Content);
if (DockWidget && DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable))
{
return true;
}
CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(Content);
if (DockArea && DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
{
return true;
}
return false;
}
};
// struct LedArrayPanelPrivate
@@ -328,10 +348,17 @@ void CFloatingDragPreview::finishDragging()
{
ADS_PRINT("CFloatingDragPreview::finishDragging");
cleanupAutoHideContainerWidget();
auto DockDropArea = d->DockManager->dockAreaOverlay()->visibleDropAreaUnderCursor();
auto ContainerDropArea = d->DockManager->containerOverlay()->visibleDropAreaUnderCursor();
bool ValidDropArea = (DockDropArea != InvalidDockWidgetArea) || (ContainerDropArea != InvalidDockWidgetArea);
// Non floatable auto hide widgets should stay in its current auto hide
// state if they are dragged into a floating window
if (ValidDropArea || d->isContentFloatable())
{
cleanupAutoHideContainerWidget();
}
if (!d->DropContainer)
{
d->createFloatingWidget();

View File

@@ -38,6 +38,8 @@
#include <QStyle>
#include <QMouseEvent>
#include <iostream>
#ifdef Q_OS_LINUX
#include <xcb/xcb.h>
#endif

File diff suppressed because it is too large Load Diff