Merge branch 'master' into feature
68
.cproject
@ -71,6 +71,15 @@
|
|||||||
</storageModule>
|
</storageModule>
|
||||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||||
<storageModule moduleId="refreshScope"/>
|
<storageModule moduleId="refreshScope"/>
|
||||||
|
<storageModule moduleId="scannerConfiguration">
|
||||||
|
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||||
|
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1119687795;cdt.managedbuild.toolchain.gnu.mingw.base.1119687795.1949777584;cdt.managedbuild.tool.gnu.cpp.compiler.mingw.base.1947822681;cdt.managedbuild.tool.gnu.cpp.compiler.input.1318830536">
|
||||||
|
<autodiscovery enabled="false" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile"/>
|
||||||
|
</scannerConfigBuildInfo>
|
||||||
|
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1119687795;cdt.managedbuild.toolchain.gnu.mingw.base.1119687795.1949777584;cdt.managedbuild.tool.gnu.c.compiler.mingw.base.389117097;cdt.managedbuild.tool.gnu.c.compiler.input.1568363924">
|
||||||
|
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||||
|
</scannerConfigBuildInfo>
|
||||||
|
</storageModule>
|
||||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
|
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
|
||||||
<buildTargets>
|
<buildTargets>
|
||||||
<target name="Build all" path=" build" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
<target name="Build all" path=" build" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
@ -83,6 +92,7 @@
|
|||||||
</target>
|
</target>
|
||||||
<target name="Clean" path=" build" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
<target name="Clean" path=" build" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
<buildCommand>make</buildCommand>
|
<buildCommand>make</buildCommand>
|
||||||
|
<buildArguments/>
|
||||||
<buildTarget>clean</buildTarget>
|
<buildTarget>clean</buildTarget>
|
||||||
<stopOnError>false</stopOnError>
|
<stopOnError>false</stopOnError>
|
||||||
<useDefaultCommand>true</useDefaultCommand>
|
<useDefaultCommand>true</useDefaultCommand>
|
||||||
@ -99,7 +109,6 @@
|
|||||||
<target name="qmake" path=" build" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
<target name="qmake" path=" build" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
<buildCommand>qmake</buildCommand>
|
<buildCommand>qmake</buildCommand>
|
||||||
<buildArguments>-recursive ../ads.pro</buildArguments>
|
<buildArguments>-recursive ../ads.pro</buildArguments>
|
||||||
<buildTarget/>
|
|
||||||
<stopOnError>true</stopOnError>
|
<stopOnError>true</stopOnError>
|
||||||
<useDefaultCommand>false</useDefaultCommand>
|
<useDefaultCommand>false</useDefaultCommand>
|
||||||
<runAllBuilders>false</runAllBuilders>
|
<runAllBuilders>false</runAllBuilders>
|
||||||
@ -122,7 +131,6 @@
|
|||||||
</target>
|
</target>
|
||||||
<target name="Clean" path=" build/src" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
<target name="Clean" path=" build/src" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
<buildCommand>make</buildCommand>
|
<buildCommand>make</buildCommand>
|
||||||
<buildArguments/>
|
|
||||||
<buildTarget>clean</buildTarget>
|
<buildTarget>clean</buildTarget>
|
||||||
<stopOnError>false</stopOnError>
|
<stopOnError>false</stopOnError>
|
||||||
<useDefaultCommand>true</useDefaultCommand>
|
<useDefaultCommand>true</useDefaultCommand>
|
||||||
@ -139,7 +147,6 @@
|
|||||||
<target name="qmake" path=" build/src" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
<target name="qmake" path=" build/src" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
<buildCommand>qmake</buildCommand>
|
<buildCommand>qmake</buildCommand>
|
||||||
<buildArguments>-recursive ../../src/src.pro</buildArguments>
|
<buildArguments>-recursive ../../src/src.pro</buildArguments>
|
||||||
<buildTarget/>
|
|
||||||
<stopOnError>true</stopOnError>
|
<stopOnError>true</stopOnError>
|
||||||
<useDefaultCommand>false</useDefaultCommand>
|
<useDefaultCommand>false</useDefaultCommand>
|
||||||
<runAllBuilders>false</runAllBuilders>
|
<runAllBuilders>false</runAllBuilders>
|
||||||
@ -152,6 +159,46 @@
|
|||||||
<useDefaultCommand>false</useDefaultCommand>
|
<useDefaultCommand>false</useDefaultCommand>
|
||||||
<runAllBuilders>false</runAllBuilders>
|
<runAllBuilders>false</runAllBuilders>
|
||||||
</target>
|
</target>
|
||||||
|
<target name="Build all" path=" build/example" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
|
<buildCommand>mingw32-make</buildCommand>
|
||||||
|
<buildArguments>-j</buildArguments>
|
||||||
|
<buildTarget>all</buildTarget>
|
||||||
|
<stopOnError>false</stopOnError>
|
||||||
|
<useDefaultCommand>false</useDefaultCommand>
|
||||||
|
<runAllBuilders>false</runAllBuilders>
|
||||||
|
</target>
|
||||||
|
<target name="Clean" path=" build/example" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
|
<buildCommand>make</buildCommand>
|
||||||
|
<buildArguments/>
|
||||||
|
<buildTarget>clean</buildTarget>
|
||||||
|
<stopOnError>false</stopOnError>
|
||||||
|
<useDefaultCommand>true</useDefaultCommand>
|
||||||
|
<runAllBuilders>false</runAllBuilders>
|
||||||
|
</target>
|
||||||
|
<target name="Debug Build" path=" build/example" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
|
<buildCommand>mingw32-make</buildCommand>
|
||||||
|
<buildArguments>-j6</buildArguments>
|
||||||
|
<buildTarget>debug</buildTarget>
|
||||||
|
<stopOnError>false</stopOnError>
|
||||||
|
<useDefaultCommand>false</useDefaultCommand>
|
||||||
|
<runAllBuilders>false</runAllBuilders>
|
||||||
|
</target>
|
||||||
|
<target name="qmake" path=" build/example" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
|
<buildCommand>qmake</buildCommand>
|
||||||
|
<buildArguments>-recursive ../../example/example.pro</buildArguments>
|
||||||
|
<buildTarget/>
|
||||||
|
<stopOnError>true</stopOnError>
|
||||||
|
<useDefaultCommand>false</useDefaultCommand>
|
||||||
|
<runAllBuilders>false</runAllBuilders>
|
||||||
|
</target>
|
||||||
|
<target name="Release Build" path=" build/example" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
|
<buildCommand>mingw32-make</buildCommand>
|
||||||
|
<buildArguments>-j4</buildArguments>
|
||||||
|
<buildTarget>release</buildTarget>
|
||||||
|
<stopOnError>false</stopOnError>
|
||||||
|
<useDefaultCommand>false</useDefaultCommand>
|
||||||
|
<runAllBuilders>false</runAllBuilders>
|
||||||
|
</target>
|
||||||
<target name="Build all" path=" build/demo" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
<target name="Build all" path=" build/demo" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
<buildCommand>mingw32-make</buildCommand>
|
<buildCommand>mingw32-make</buildCommand>
|
||||||
<buildArguments>-j</buildArguments>
|
<buildArguments>-j</buildArguments>
|
||||||
@ -162,7 +209,6 @@
|
|||||||
</target>
|
</target>
|
||||||
<target name="Clean" path=" build/demo" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
<target name="Clean" path=" build/demo" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
<buildCommand>make</buildCommand>
|
<buildCommand>make</buildCommand>
|
||||||
<buildArguments/>
|
|
||||||
<buildTarget>clean</buildTarget>
|
<buildTarget>clean</buildTarget>
|
||||||
<stopOnError>false</stopOnError>
|
<stopOnError>false</stopOnError>
|
||||||
<useDefaultCommand>true</useDefaultCommand>
|
<useDefaultCommand>true</useDefaultCommand>
|
||||||
@ -179,7 +225,6 @@
|
|||||||
<target name="qmake" path=" build/demo" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
<target name="qmake" path=" build/demo" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
<buildCommand>qmake</buildCommand>
|
<buildCommand>qmake</buildCommand>
|
||||||
<buildArguments>-recursive ../../demo/demo.pro</buildArguments>
|
<buildArguments>-recursive ../../demo/demo.pro</buildArguments>
|
||||||
<buildTarget/>
|
|
||||||
<stopOnError>true</stopOnError>
|
<stopOnError>true</stopOnError>
|
||||||
<useDefaultCommand>false</useDefaultCommand>
|
<useDefaultCommand>false</useDefaultCommand>
|
||||||
<runAllBuilders>false</runAllBuilders>
|
<runAllBuilders>false</runAllBuilders>
|
||||||
@ -202,6 +247,7 @@
|
|||||||
</target>
|
</target>
|
||||||
<target name="Clean" path=" build/AdvancedDockingSystemDemo" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
<target name="Clean" path=" build/AdvancedDockingSystemDemo" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
<buildCommand>make</buildCommand>
|
<buildCommand>make</buildCommand>
|
||||||
|
<buildArguments/>
|
||||||
<buildTarget>clean</buildTarget>
|
<buildTarget>clean</buildTarget>
|
||||||
<stopOnError>false</stopOnError>
|
<stopOnError>false</stopOnError>
|
||||||
<useDefaultCommand>true</useDefaultCommand>
|
<useDefaultCommand>true</useDefaultCommand>
|
||||||
@ -240,6 +286,7 @@
|
|||||||
</target>
|
</target>
|
||||||
<target name="Clean" path=" build/AdvancedDockingSystemDemo_v2" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
<target name="Clean" path=" build/AdvancedDockingSystemDemo_v2" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
<buildCommand>make</buildCommand>
|
<buildCommand>make</buildCommand>
|
||||||
|
<buildArguments/>
|
||||||
<buildTarget>clean</buildTarget>
|
<buildTarget>clean</buildTarget>
|
||||||
<stopOnError>false</stopOnError>
|
<stopOnError>false</stopOnError>
|
||||||
<useDefaultCommand>true</useDefaultCommand>
|
<useDefaultCommand>true</useDefaultCommand>
|
||||||
@ -278,6 +325,7 @@
|
|||||||
</target>
|
</target>
|
||||||
<target name="Clean" path=" build/AdvancedDockingSystem" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
<target name="Clean" path=" build/AdvancedDockingSystem" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
<buildCommand>make</buildCommand>
|
<buildCommand>make</buildCommand>
|
||||||
|
<buildArguments/>
|
||||||
<buildTarget>clean</buildTarget>
|
<buildTarget>clean</buildTarget>
|
||||||
<stopOnError>false</stopOnError>
|
<stopOnError>false</stopOnError>
|
||||||
<useDefaultCommand>true</useDefaultCommand>
|
<useDefaultCommand>true</useDefaultCommand>
|
||||||
@ -294,7 +342,6 @@
|
|||||||
<target name="qmake" path=" build/AdvancedDockingSystem" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
<target name="qmake" path=" build/AdvancedDockingSystem" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
<buildCommand>qmake</buildCommand>
|
<buildCommand>qmake</buildCommand>
|
||||||
<buildArguments>-recursive ../../AdvancedDockingSystem/src.pro</buildArguments>
|
<buildArguments>-recursive ../../AdvancedDockingSystem/src.pro</buildArguments>
|
||||||
<buildTarget/>
|
|
||||||
<stopOnError>true</stopOnError>
|
<stopOnError>true</stopOnError>
|
||||||
<useDefaultCommand>false</useDefaultCommand>
|
<useDefaultCommand>false</useDefaultCommand>
|
||||||
<runAllBuilders>false</runAllBuilders>
|
<runAllBuilders>false</runAllBuilders>
|
||||||
@ -309,13 +356,4 @@
|
|||||||
</target>
|
</target>
|
||||||
</buildTargets>
|
</buildTargets>
|
||||||
</storageModule>
|
</storageModule>
|
||||||
<storageModule moduleId="scannerConfiguration">
|
|
||||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
|
||||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1119687795;cdt.managedbuild.toolchain.gnu.mingw.base.1119687795.1949777584;cdt.managedbuild.tool.gnu.cpp.compiler.mingw.base.1947822681;cdt.managedbuild.tool.gnu.cpp.compiler.input.1318830536">
|
|
||||||
<autodiscovery enabled="false" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile"/>
|
|
||||||
</scannerConfigBuildInfo>
|
|
||||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1119687795;cdt.managedbuild.toolchain.gnu.mingw.base.1119687795.1949777584;cdt.managedbuild.tool.gnu.c.compiler.mingw.base.389117097;cdt.managedbuild.tool.gnu.c.compiler.input.1568363924">
|
|
||||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
|
||||||
</scannerConfigBuildInfo>
|
|
||||||
</storageModule>
|
|
||||||
</cproject>
|
</cproject>
|
||||||
|
8
.gitignore
vendored
@ -1,2 +1,10 @@
|
|||||||
*.pro.user
|
*.pro.user
|
||||||
/ build
|
/ build
|
||||||
|
*.o
|
||||||
|
*.dylib
|
||||||
|
*.app
|
||||||
|
qrc_*
|
||||||
|
moc_*
|
||||||
|
ui_*
|
||||||
|
Makefile
|
||||||
|
|
||||||
|
103
CMakeLists.txt
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.3)
|
||||||
|
set(ads_VERSION "2.3.2")
|
||||||
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
set(CMAKE_AUTORCC ON)
|
||||||
|
project(QtAdvancedDockingSystem VERSION ${ads_VERSION})
|
||||||
|
option(BUILD_STATIC "Build the static library" OFF)
|
||||||
|
option(BUILD_EXAMPLES "Build the examples" ON)
|
||||||
|
set(REQUIRED_QT_VERSION 5.0.0)
|
||||||
|
find_package(Qt5Core ${REQUIRED_QT_VERSION} REQUIRED)
|
||||||
|
find_package(Qt5Gui ${REQUIRED_QT_VERSION} REQUIRED)
|
||||||
|
find_package(Qt5Widgets ${REQUIRED_QT_VERSION} REQUIRED)
|
||||||
|
message(STATUS "Found Qt ${Qt5Core_VERSION}")
|
||||||
|
set(ads_INCLUDE ${ads_INCLUDE} ${Qt5Core_INCLUDE_DIRS})
|
||||||
|
set(ads_INCLUDE ${ads_INCLUDE} "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||||
|
set(ads_LIBS ${ads_LIBS} ${Qt5Core_LIBRARIES})
|
||||||
|
set(ads_COMPILE_DEFINE ${ads_COMPILE_DEFINE} ${Qt5Core_COMPILE_DEFINITIONS})
|
||||||
|
set(ads_LIBS ${ads_LIBS} ${Qt5Gui_LIBRARIES})
|
||||||
|
set(ads_INCLUDE ${ads_INCLUDE} ${Qt5Gui_INCLUDE_DIRS})
|
||||||
|
set(ads_COMPILE_DEFINE ${ads_COMPILE_DEFINE} ${Qt5Gui_COMPILE_DEFINITIONS})
|
||||||
|
set(ads_LIBS ${ads_LIBS} ${Qt5Widgets_LIBRARIES})
|
||||||
|
set(ads_INCLUDE ${ads_INCLUDE} ${Qt5Widgets_INCLUDE_DIRS})
|
||||||
|
set(ads_COMPILE_DEFINE ${ads_COMPILE_DEFINE} ${Qt5Widgets_COMPILE_DEFINITIONS})
|
||||||
|
if(BUILD_STATIC)
|
||||||
|
set(CMAKE_STATIC_LIBRARY_SUFFIX "_static${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||||
|
endif()
|
||||||
|
set(ads_SRCS
|
||||||
|
src/ads_globals.cpp
|
||||||
|
src/DockAreaTabBar.cpp
|
||||||
|
src/DockAreaTitleBar.cpp
|
||||||
|
src/DockAreaWidget.cpp
|
||||||
|
src/DockContainerWidget.cpp
|
||||||
|
src/DockManager.cpp
|
||||||
|
src/DockOverlay.cpp
|
||||||
|
src/DockSplitter.cpp
|
||||||
|
src/DockWidget.cpp
|
||||||
|
src/DockWidgetTab.cpp
|
||||||
|
src/ElidingLabel.cpp
|
||||||
|
src/FloatingDockContainer.cpp
|
||||||
|
src/ads.qrc
|
||||||
|
)
|
||||||
|
set(ads_INSTALL_INCLUDE
|
||||||
|
src/ads_globals.h
|
||||||
|
src/DockAreaTabBar.h
|
||||||
|
src/DockAreaTitleBar.h
|
||||||
|
src/DockAreaWidget.h
|
||||||
|
src/DockContainerWidget.h
|
||||||
|
src/DockManager.h
|
||||||
|
src/DockOverlay.h
|
||||||
|
src/DockSplitter.h
|
||||||
|
src/DockWidget.h
|
||||||
|
src/DockWidgetTab.h
|
||||||
|
src/ElidingLabel.h
|
||||||
|
src/FloatingDockContainer.h
|
||||||
|
)
|
||||||
|
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4")
|
||||||
|
set(ads_PlatformDir "x64")
|
||||||
|
else()
|
||||||
|
set(ads_PlatformDir "x86")
|
||||||
|
endif()
|
||||||
|
if(BUILD_STATIC)
|
||||||
|
add_library(ads STATIC ${ads_SRCS})
|
||||||
|
set(ads_COMPILE_DEFINE ${ads_COMPILE_DEFINE} ADS_STATIC)
|
||||||
|
else()
|
||||||
|
add_library(ads SHARED ${ads_SRCS})
|
||||||
|
set(ads_COMPILE_DEFINE ${ads_COMPILE_DEFINE} ADS_SHARED_EXPORT)
|
||||||
|
endif()
|
||||||
|
install(FILES ${ads_INSTALL_INCLUDE}
|
||||||
|
DESTINATION include
|
||||||
|
COMPONENT headers
|
||||||
|
)
|
||||||
|
install(FILES
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.md"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/gnu-lgpl-v2.1.md"
|
||||||
|
DESTINATION license
|
||||||
|
COMPONENT license
|
||||||
|
)
|
||||||
|
install(TARGETS ads
|
||||||
|
EXPORT adsBinary
|
||||||
|
RUNTIME DESTINATION bin COMPONENT library
|
||||||
|
LIBRARY DESTINATION lib COMPONENT library
|
||||||
|
ARCHIVE DESTINATION lib COMPONENT library
|
||||||
|
)
|
||||||
|
target_include_directories(ads PUBLIC
|
||||||
|
$<BUILD_INTERFACE:${ads_INCLUDE}>
|
||||||
|
$<INSTALL_INTERFACE:include>
|
||||||
|
)
|
||||||
|
target_link_libraries(ads PUBLIC ${ads_LIBS})
|
||||||
|
target_compile_definitions(ads PRIVATE ${ads_COMPILE_DEFINE})
|
||||||
|
set_target_properties(ads PROPERTIES
|
||||||
|
VERSION ${ads_VERSION}
|
||||||
|
EXPORT_NAME "Qt Advanced Docking System"
|
||||||
|
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(BUILD_EXAMPLES)
|
||||||
|
add_subdirectory(example)
|
||||||
|
add_subdirectory(demo)
|
||||||
|
endif()
|
||||||
|
|
93
README.md
@ -13,28 +13,36 @@ from Manuel Freiholz. I did an almost complete rewrite of his code to improve
|
|||||||
code quality, readibility and to fix all issues from the issue tracker
|
code quality, readibility and to fix all issues from the issue tracker
|
||||||
of his docking system project.
|
of his docking system project.
|
||||||
|
|
||||||
|
The following video gives a first impression what is possible with the Advanced Docking System for Qt.
|
||||||
|
|
||||||
|
[![Video Advanced Docking](doc/advanced-docking_video.png)](https://www.youtube.com/watch?v=7pdNfafg3Qc)
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
### Docking everywhere - no central widget
|
### Docking everywhere - no central widget
|
||||||
There is no central widget like in the Qt docking system. You can dock on every
|
There is no central widget like in the Qt docking system. You can dock on every
|
||||||
border of the main window or you can dock into each dock area - so you are
|
border of the main window or you can dock into each dock area - so you are
|
||||||
free to dock almost everywhere.
|
free to dock almost everywhere.
|
||||||
|
|
||||||
![Layout of widgets](preview.png)
|
![Dropping widgets](doc/preview-dragndrop.png)\
|
||||||
|
\
|
||||||
![Dropping widgets](preview-dragndrop.png)
|
![Dropping widgets](doc/preview-dragndrop_dark.png)
|
||||||
|
|
||||||
### Docking inside floating windows
|
### Docking inside floating windows
|
||||||
There is no difference between the main window and a floating window. Docking
|
There is no difference between the main window and a floating window. Docking
|
||||||
into floating windows is supported.
|
into floating windows is supported.
|
||||||
|
|
||||||
![Docking inside floating windows](floating-widget-dragndrop.png)
|
![Docking inside floating windows](doc/floating-widget-dragndrop.png)\
|
||||||
|
\
|
||||||
|
![Docking inside floating windows](doc/floating-widget-dragndrop_dark.png)
|
||||||
|
|
||||||
### Grouped dragging
|
### Grouped dragging
|
||||||
When dragging the titlebar of a dock, all the tabs that are tabbed with it are
|
When dragging the titlebar of a dock, all the tabs that are tabbed with it are
|
||||||
going to be dragged. So you can move complete groups of tabbed widgets into
|
going to be dragged. So you can move complete groups of tabbed widgets into
|
||||||
a floating widget or from one dock area to another one.
|
a floating widget or from one dock area to another one.
|
||||||
|
|
||||||
![Grouped dragging](grouped-dragging.png)
|
![Grouped dragging](doc/grouped-dragging.png)\
|
||||||
|
\
|
||||||
|
![Grouped dragging](doc/grouped-dragging_dark.png)
|
||||||
|
|
||||||
### Perspectives for fast switching of the complete main window layout
|
### Perspectives for fast switching of the complete main window layout
|
||||||
A perspective defines the set and layout of dock windows in the main
|
A perspective defines the set and layout of dock windows in the main
|
||||||
@ -43,7 +51,9 @@ perspective to make your own custom perspective. Later you can simply
|
|||||||
select a perspective from the perspective list to quickly switch the complete
|
select a perspective from the perspective list to quickly switch the complete
|
||||||
main window layout.
|
main window layout.
|
||||||
|
|
||||||
![Perspective](perspectives.png)
|
![Perspective](doc/perspectives.png)\
|
||||||
|
\
|
||||||
|
![Perspective](doc/perspectives_dark.png)
|
||||||
|
|
||||||
## Tested Compatible Environments
|
## Tested Compatible Environments
|
||||||
- Windows 10
|
- Windows 10
|
||||||
@ -52,6 +62,77 @@ main window layout.
|
|||||||
Open the `ads.pro` with QtCreator and start the build, that's it.
|
Open the `ads.pro` with QtCreator and start the build, that's it.
|
||||||
You can run the demo project and test it yourself.
|
You can run the demo project and test it yourself.
|
||||||
|
|
||||||
|
## Getting started / Example
|
||||||
|
The following example shows the minimum code required to use the advanced Qt docking system.
|
||||||
|
|
||||||
|
*MainWindow.h*
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include "DockManager.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class MainWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MainWindow : public QMainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MainWindow(QWidget *parent = 0);
|
||||||
|
~MainWindow();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::MainWindow *ui;
|
||||||
|
|
||||||
|
// The main container for docking
|
||||||
|
ads::CDockManager* m_DockManager;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
*MainWindow.cpp*
|
||||||
|
```cpp
|
||||||
|
#include "MainWindow.h"
|
||||||
|
#include "ui_MainWindow.h"
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
MainWindow::MainWindow(QWidget *parent) :
|
||||||
|
QMainWindow(parent),
|
||||||
|
ui(new Ui::MainWindow)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
// Create the dock manager. Because the parent parameter is a QMainWindow
|
||||||
|
// the dock manager registers itself as the central widget.
|
||||||
|
m_DockManager = new ads::CDockManager(this);
|
||||||
|
|
||||||
|
// Create example content label - this can be any application specific
|
||||||
|
// widget
|
||||||
|
QLabel* l = new QLabel();
|
||||||
|
l->setWordWrap(true);
|
||||||
|
l->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||||
|
l->setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ");
|
||||||
|
|
||||||
|
// Create a dock widget with the title Label 1 and set the created label
|
||||||
|
// as the dock widget content
|
||||||
|
ads::CDockWidget* DockWidget = new ads::CDockWidget("Label 1");
|
||||||
|
DockWidget->setWidget(l);
|
||||||
|
|
||||||
|
// Add the toggleViewAction of the dock widget to the menu to give
|
||||||
|
// the user the possibility to show the dock widget if it has been closed
|
||||||
|
ui->menuView->addAction(DockWidget->toggleViewAction());
|
||||||
|
|
||||||
|
// Add the dock widget to the top dock widget area
|
||||||
|
m_DockManager->addDockWidget(ads::TopDockWidgetArea, DockWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindow::~MainWindow()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Developers
|
## Developers
|
||||||
- Uwe Kindler, Project Maintainer
|
- Uwe Kindler, Project Maintainer
|
||||||
- Manuel Freiholz
|
- Manuel Freiholz
|
||||||
|
7
ads.pro
@ -1,6 +1,9 @@
|
|||||||
TEMPLATE = subdirs
|
TEMPLATE = subdirs
|
||||||
CONFIG += ordered
|
|
||||||
|
|
||||||
SUBDIRS = \
|
SUBDIRS = \
|
||||||
src \
|
src \
|
||||||
demo
|
demo \
|
||||||
|
example
|
||||||
|
|
||||||
|
demo.depends = src
|
||||||
|
example.depends = src
|
||||||
|
48
demo/CMakeLists.txt
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.3)
|
||||||
|
set (CMAKE_CXX_STANDARD 11)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
set(CMAKE_AUTOUIC ON)
|
||||||
|
set(CMAKE_AUTORCC ON)
|
||||||
|
project(ads_demo VERSION "1.0")
|
||||||
|
set(REQUIRED_QT_VERSION 5.0.0)
|
||||||
|
find_package(Qt5Core ${REQUIRED_QT_VERSION} REQUIRED)
|
||||||
|
find_package(Qt5Gui ${REQUIRED_QT_VERSION} REQUIRED)
|
||||||
|
find_package(Qt5Widgets ${REQUIRED_QT_VERSION} REQUIRED)
|
||||||
|
set(ads_demo_LIBS ${ads_demo_LIBS} ${Qt5Core_LIBRARIES})
|
||||||
|
set(ads_demo_INCLUDE ${ads_demo_INCLUDE} ${Qt5Core_INCLUDE_DIRS})
|
||||||
|
set(ads_demo_COMPILE_DEFINE ${ads_demo_COMPILE_DEFINE} ${Qt5Core_COMPILE_DEFINITIONS} )
|
||||||
|
set(ads_demo_LIBS ${ads_demo_LIBS} ${Qt5Gui_LIBRARIES})
|
||||||
|
set(ads_demo_INCLUDE ${ads_demo_INCLUDE} ${Qt5Gui_INCLUDE_DIRS})
|
||||||
|
set(ads_demo_COMPILE_DEFINE ${ads_demo_COMPILE_DEFINE} ${Qt5Gui_COMPILE_DEFINITIONS})
|
||||||
|
set(ads_demo_LIBS ${ads_demo_LIBS} ${Qt5Widgets_LIBRARIES})
|
||||||
|
set(ads_demo_INCLUDE ${ads_demo_INCLUDE} ${Qt5Widgets_INCLUDE_DIRS})
|
||||||
|
set(ads_demo_COMPILE_DEFINE ${ads_demo_COMPILE_DEFINE} ${Qt5Widgets_COMPILE_DEFINITIONS})
|
||||||
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
set(ads_demo_SRCS
|
||||||
|
main.cpp
|
||||||
|
MainWindow.cpp
|
||||||
|
MainWindow.ui
|
||||||
|
main.qrc
|
||||||
|
)
|
||||||
|
add_executable(ads_demo WIN32 ${ads_demo_SRCS})
|
||||||
|
if(BUILD_STATIC)
|
||||||
|
set(ads_demo_DEFINE ${ads_demo_DEFINE} ADS_STATIC)
|
||||||
|
endif()
|
||||||
|
add_dependencies(ads_demo ads)
|
||||||
|
target_include_directories(ads_demo PUBLIC
|
||||||
|
$<BUILD_INTERFACE:${ads_demo_INCLUDE}>
|
||||||
|
$<INSTALL_INTERFACE:include>
|
||||||
|
)
|
||||||
|
target_include_directories(ads_demo PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../src" ${ads_demo_INCLUDE})
|
||||||
|
target_link_libraries(ads_demo PRIVATE ads ${ads_demo_LIBS})
|
||||||
|
target_compile_definitions(ads_demo PRIVATE ${ads_demo_DEFINE})
|
||||||
|
set_target_properties(ads_demo PROPERTIES
|
||||||
|
VERSION "1.0"
|
||||||
|
SOVERSION 1
|
||||||
|
EXPORT_NAME "Qt Advanced Docking System Demo"
|
||||||
|
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib/demo"
|
||||||
|
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib/demo"
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/bin/demo"
|
||||||
|
)
|
@ -57,7 +57,6 @@
|
|||||||
#include "DockManager.h"
|
#include "DockManager.h"
|
||||||
#include "DockWidget.h"
|
#include "DockWidget.h"
|
||||||
#include "DockAreaWidget.h"
|
#include "DockAreaWidget.h"
|
||||||
#include "AnimatedLabel.h"
|
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
@ -9,15 +9,11 @@ CONFIG *= c++14
|
|||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
MainWindow.cpp \
|
MainWindow.cpp
|
||||||
mhtabbar.cpp \
|
|
||||||
mhtabwidget.cpp
|
|
||||||
|
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
MainWindow.h \
|
MainWindow.h
|
||||||
mhtabbar.h \
|
|
||||||
mhtabwidget.h
|
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
mainwindow.ui
|
mainwindow.ui
|
||||||
@ -27,9 +23,9 @@ RESOURCES += main.qrc
|
|||||||
LIBS += -L$${ADS_OUT_ROOT}/lib
|
LIBS += -L$${ADS_OUT_ROOT}/lib
|
||||||
|
|
||||||
# Dependency: AdvancedDockingSystem (shared)
|
# Dependency: AdvancedDockingSystem (shared)
|
||||||
win32:CONFIG(release, debug|release): LIBS += -lAdvancedDockingSystem
|
win32:CONFIG(release, debug|release): LIBS += -lqtadvanceddocking
|
||||||
else:win32:CONFIG(debug, debug|release): LIBS += -lAdvancedDockingSystemd
|
else:win32:CONFIG(debug, debug|release): LIBS += -lqtadvanceddockingd
|
||||||
else:unix: LIBS += -lAdvancedDockingSystem
|
else:unix: LIBS += -lqtadvanceddocking
|
||||||
|
|
||||||
INCLUDEPATH += ../src
|
INCLUDEPATH += ../src
|
||||||
DEPENDPATH += ../src
|
DEPENDPATH += ../src
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <MainWindow.h>
|
#include <MainWindow.h>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
@ -38,7 +36,9 @@ void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QS
|
|||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||||
|
#if QT_VERSION >= 0x050600
|
||||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||||
|
#endif
|
||||||
std::shared_ptr<int> b;
|
std::shared_ptr<int> b;
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
a.setQuitOnLastWindowClosed(true);
|
a.setQuitOnLastWindowClosed(true);
|
||||||
|
@ -1,7 +1,3 @@
|
|||||||
<RCC>
|
<RCC>
|
||||||
<qresource prefix="/main">
|
<qresource prefix="/main"/>
|
||||||
<file>bricks.gif</file>
|
|
||||||
<file>bricks_orange.gif</file>
|
|
||||||
<file>bricks.apng</file>
|
|
||||||
</qresource>
|
|
||||||
</RCC>
|
</RCC>
|
||||||
|
BIN
doc/TabMenu.png
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
doc/TabMenu_dark.png
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
doc/advanced-docking_video.png
Normal file
After Width: | Height: | Size: 276 KiB |
BIN
doc/floating-widget-dragndrop.png
Normal file
After Width: | Height: | Size: 103 KiB |
BIN
doc/floating-widget-dragndrop_dark.png
Normal file
After Width: | Height: | Size: 123 KiB |
BIN
doc/grouped-dragging.png
Normal file
After Width: | Height: | Size: 68 KiB |
BIN
doc/grouped-dragging_dark.png
Normal file
After Width: | Height: | Size: 53 KiB |
BIN
doc/perspectives.png
Normal file
After Width: | Height: | Size: 61 KiB |
BIN
doc/perspectives_dark.png
Normal file
After Width: | Height: | Size: 42 KiB |
BIN
doc/preview-dragndrop.png
Normal file
After Width: | Height: | Size: 92 KiB |
BIN
doc/preview-dragndrop_dark.png
Normal file
After Width: | Height: | Size: 194 KiB |
BIN
doc/preview_dark.png
Normal file
After Width: | Height: | Size: 136 KiB |
46
example/CMakeLists.txt
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.3)
|
||||||
|
set (CMAKE_CXX_STANDARD 11)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
set(CMAKE_AUTOUIC ON)
|
||||||
|
project(ads_example VERSION "1.0")
|
||||||
|
set(REQUIRED_QT_VERSION 5.0.0)
|
||||||
|
find_package(Qt5Core ${REQUIRED_QT_VERSION} REQUIRED)
|
||||||
|
find_package(Qt5Gui ${REQUIRED_QT_VERSION} REQUIRED)
|
||||||
|
find_package(Qt5Widgets ${REQUIRED_QT_VERSION} REQUIRED)
|
||||||
|
set(ads_example_LIBS ${ads_example_LIBS} ${Qt5Core_LIBRARIES})
|
||||||
|
set(ads_example_INCLUDE ${ads_example_INCLUDE} ${Qt5Core_INCLUDE_DIRS})
|
||||||
|
set(ads_example_COMPILE_DEFINE ${ads_example_COMPILE_DEFINE} ${Qt5Core_COMPILE_DEFINITIONS} )
|
||||||
|
set(ads_example_LIBS ${ads_example_LIBS} ${Qt5Gui_LIBRARIES})
|
||||||
|
set(ads_example_INCLUDE ${ads_example_INCLUDE} ${Qt5Gui_INCLUDE_DIRS})
|
||||||
|
set(ads_example_COMPILE_DEFINE ${ads_example_COMPILE_DEFINE} ${Qt5Gui_COMPILE_DEFINITIONS})
|
||||||
|
set(ads_example_LIBS ${ads_example_LIBS} ${Qt5Widgets_LIBRARIES})
|
||||||
|
set(ads_example_INCLUDE ${ads_example_INCLUDE} ${Qt5Widgets_INCLUDE_DIRS})
|
||||||
|
set(ads_example_COMPILE_DEFINE ${ads_example_COMPILE_DEFINE} ${Qt5Widgets_COMPILE_DEFINITIONS})
|
||||||
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
set(ads_example_SRCS
|
||||||
|
main.cpp
|
||||||
|
MainWindow.cpp
|
||||||
|
MainWindow.ui
|
||||||
|
)
|
||||||
|
add_executable(ads_example WIN32 ${ads_example_SRCS})
|
||||||
|
if(BUILD_STATIC)
|
||||||
|
set(ads_example_DEFINE ${ads_example_DEFINE} ADS_STATIC)
|
||||||
|
endif()
|
||||||
|
add_dependencies(ads_example ads)
|
||||||
|
target_include_directories(ads_example PUBLIC
|
||||||
|
$<BUILD_INTERFACE:${ads_example_INCLUDE}>
|
||||||
|
$<INSTALL_INTERFACE:include>
|
||||||
|
)
|
||||||
|
target_include_directories(ads_example PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../src" ${ads_example_INCLUDE})
|
||||||
|
target_link_libraries(ads_example PRIVATE ads ${ads_example_LIBS})
|
||||||
|
target_compile_definitions(ads_example PRIVATE ${ads_example_DEFINE})
|
||||||
|
set_target_properties(ads_example PROPERTIES
|
||||||
|
VERSION "1.0"
|
||||||
|
SOVERSION 1
|
||||||
|
EXPORT_NAME "Qt Advanced Docking System Example"
|
||||||
|
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib/example"
|
||||||
|
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib/example"
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/bin/example"
|
||||||
|
)
|
39
example/MainWindow.cpp
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#include "MainWindow.h"
|
||||||
|
#include "ui_MainWindow.h"
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
MainWindow::MainWindow(QWidget *parent) :
|
||||||
|
QMainWindow(parent),
|
||||||
|
ui(new Ui::MainWindow)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
// Create the dock manager. Because the parent parameter is a QMainWindow
|
||||||
|
// the dock manager registers itself as the central widget.
|
||||||
|
m_DockManager = new ads::CDockManager(this);
|
||||||
|
|
||||||
|
// Create example content label - this can be any application specific
|
||||||
|
// widget
|
||||||
|
QLabel* l = new QLabel();
|
||||||
|
l->setWordWrap(true);
|
||||||
|
l->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||||
|
l->setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ");
|
||||||
|
|
||||||
|
// Create a dock widget with the title Label 1 and set the created label
|
||||||
|
// as the dock widget content
|
||||||
|
ads::CDockWidget* DockWidget = new ads::CDockWidget("Label 1");
|
||||||
|
DockWidget->setWidget(l);
|
||||||
|
|
||||||
|
// Add the toggleViewAction of the dock widget to the menu to give
|
||||||
|
// the user the possibility to show the dock widget if it has been closed
|
||||||
|
ui->menuView->addAction(DockWidget->toggleViewAction());
|
||||||
|
|
||||||
|
// Add the dock widget to the top dock widget area
|
||||||
|
m_DockManager->addDockWidget(ads::TopDockWidgetArea, DockWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindow::~MainWindow()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
24
example/MainWindow.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef MAINWINDOW_H
|
||||||
|
#define MAINWINDOW_H
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include "DockManager.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class MainWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MainWindow : public QMainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MainWindow(QWidget *parent = 0);
|
||||||
|
~MainWindow();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::MainWindow *ui;
|
||||||
|
ads::CDockManager* m_DockManager;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MAINWINDOW_H
|
38
example/MainWindow.ui
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MainWindow</class>
|
||||||
|
<widget class="QMainWindow" name="MainWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>MainWindow</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralWidget"/>
|
||||||
|
<widget class="QMenuBar" name="menuBar">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>21</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<widget class="QMenu" name="menuView">
|
||||||
|
<property name="title">
|
||||||
|
<string>View</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<addaction name="menuView"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QStatusBar" name="statusBar"/>
|
||||||
|
</widget>
|
||||||
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
51
example/example.pro
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#-------------------------------------------------
|
||||||
|
#
|
||||||
|
# Project created by QtCreator 2018-12-14T22:42:14
|
||||||
|
#
|
||||||
|
#-------------------------------------------------
|
||||||
|
ADS_ROOT = $${PWD}/..
|
||||||
|
ADS_OUT_ROOT = $${OUT_PWD}/..
|
||||||
|
|
||||||
|
QT += core gui widgets
|
||||||
|
|
||||||
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
|
|
||||||
|
TARGET = Example1
|
||||||
|
DESTDIR = $${ADS_OUT_ROOT}/lib
|
||||||
|
TEMPLATE = app
|
||||||
|
CONFIG *= c++14
|
||||||
|
|
||||||
|
# The following define makes your compiler emit warnings if you use
|
||||||
|
# any feature of Qt which has been marked as deprecated (the exact warnings
|
||||||
|
# depend on your compiler). Please consult the documentation of the
|
||||||
|
# deprecated API in order to know how to port your code away from it.
|
||||||
|
DEFINES += QT_DEPRECATED_WARNINGS
|
||||||
|
|
||||||
|
# You can also make your code fail to compile if you use deprecated APIs.
|
||||||
|
# In order to do so, uncomment the following line.
|
||||||
|
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||||
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
|
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
main.cpp \
|
||||||
|
MainWindow.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
MainWindow.h
|
||||||
|
|
||||||
|
FORMS += \
|
||||||
|
MainWindow.ui
|
||||||
|
|
||||||
|
#RESOURCES += main.qrc
|
||||||
|
|
||||||
|
LIBS += -L$${ADS_OUT_ROOT}/lib
|
||||||
|
|
||||||
|
# Dependency: AdvancedDockingSystem (shared)
|
||||||
|
win32:CONFIG(release, debug|release): LIBS += -lqtadvanceddocking
|
||||||
|
else:win32:CONFIG(debug, debug|release): LIBS += -lqtadvanceddockingd
|
||||||
|
else:unix: LIBS += -lqtadvanceddocking
|
||||||
|
|
||||||
|
INCLUDEPATH += ../src
|
||||||
|
DEPENDPATH += ../src
|
||||||
|
|
11
example/main.cpp
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#include "MainWindow.h"
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QApplication a(argc, argv);
|
||||||
|
MainWindow w;
|
||||||
|
w.show();
|
||||||
|
|
||||||
|
return a.exec();
|
||||||
|
}
|
Before Width: | Height: | Size: 222 KiB |
Before Width: | Height: | Size: 41 KiB |
BIN
perspectives.png
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 82 KiB |
BIN
preview.png
Before Width: | Height: | Size: 57 KiB |
@ -228,16 +228,17 @@ void CDockAreaTabBar::mouseDoubleClickEvent(QMouseEvent *event)
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
startFloating(event->pos());
|
makeAreaFloating(event->pos(), DraggingInactive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
CFloatingDockContainer* CDockAreaTabBar::makeAreaFloating(const QPoint& Pos)
|
CFloatingDockContainer* CDockAreaTabBar::makeAreaFloating(const QPoint& Offset,
|
||||||
|
eDragState DragState)
|
||||||
{
|
{
|
||||||
QSize Size = d->DockArea->size();
|
QSize Size = d->DockArea->size();
|
||||||
CFloatingDockContainer* FloatingWidget = new CFloatingDockContainer(d->DockArea);
|
CFloatingDockContainer* FloatingWidget = new CFloatingDockContainer(d->DockArea);
|
||||||
FloatingWidget->startFloating(Pos, Size);
|
FloatingWidget->startFloating(Offset, Size, DragState);
|
||||||
auto TopLevelDockWidget = FloatingWidget->topLevelDockWidget();
|
auto TopLevelDockWidget = FloatingWidget->topLevelDockWidget();
|
||||||
if (TopLevelDockWidget)
|
if (TopLevelDockWidget)
|
||||||
{
|
{
|
||||||
@ -249,9 +250,9 @@ CFloatingDockContainer* CDockAreaTabBar::makeAreaFloating(const QPoint& Pos)
|
|||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
void CDockAreaTabBar::startFloating(const QPoint& Pos)
|
void CDockAreaTabBar::startFloating(const QPoint& Offset)
|
||||||
{
|
{
|
||||||
d->FloatingWidget = makeAreaFloating(Pos);
|
d->FloatingWidget = makeAreaFloating(Offset, DraggingFloatingWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
// INCLUDES
|
// INCLUDES
|
||||||
//============================================================================
|
//============================================================================
|
||||||
#include <QScrollArea>
|
#include <QScrollArea>
|
||||||
|
#include "ads_globals.h"
|
||||||
|
|
||||||
namespace ads
|
namespace ads
|
||||||
{
|
{
|
||||||
@ -49,7 +50,7 @@ class CDockAreaTabBar : public QScrollArea
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
DockAreaTabBarPrivate* d; ///< private data (pimpl)
|
DockAreaTabBarPrivate* d; ///< private data (pimpl)
|
||||||
friend class DockAreaTabBarPrivate;
|
friend struct DockAreaTabBarPrivate;
|
||||||
friend class CDockAreaTitleBar;
|
friend class CDockAreaTitleBar;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
@ -84,12 +85,13 @@ protected:
|
|||||||
/**
|
/**
|
||||||
* Starts floating
|
* Starts floating
|
||||||
*/
|
*/
|
||||||
void startFloating(const QPoint& Pos);
|
void startFloating(const QPoint& Offset);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes the dock area loating
|
* Makes the dock area floating
|
||||||
*/
|
*/
|
||||||
CFloatingDockContainer* makeAreaFloating(const QPoint& Pos);
|
CFloatingDockContainer* makeAreaFloating(const QPoint& Offset,
|
||||||
|
eDragState DragState);
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#include "DockWidgetTab.h"
|
#include "DockWidgetTab.h"
|
||||||
#include "DockAreaTabBar.h"
|
#include "DockAreaTabBar.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace ads
|
namespace ads
|
||||||
{
|
{
|
||||||
@ -173,6 +174,10 @@ void DockAreaTitleBarPrivate::createTabBar()
|
|||||||
_this->connect(TabBar, SIGNAL(tabMoved(int, int)), SLOT(markTabsMenuOutdated()));
|
_this->connect(TabBar, SIGNAL(tabMoved(int, int)), SLOT(markTabsMenuOutdated()));
|
||||||
_this->connect(TabBar, SIGNAL(currentChanged(int)), SLOT(onCurrentTabChanged(int)));
|
_this->connect(TabBar, SIGNAL(currentChanged(int)), SLOT(onCurrentTabChanged(int)));
|
||||||
_this->connect(TabBar, SIGNAL(tabBarClicked(int)), SIGNAL(tabBarClicked(int)));
|
_this->connect(TabBar, SIGNAL(tabBarClicked(int)), SIGNAL(tabBarClicked(int)));
|
||||||
|
|
||||||
|
TabBar->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
_this->connect(TabBar, SIGNAL(customContextMenuRequested(const QPoint&)),
|
||||||
|
SLOT(showContextMenu(const QPoint&)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -260,7 +265,7 @@ void CDockAreaTitleBar::onCloseButtonClicked()
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
void CDockAreaTitleBar::onUndockButtonClicked()
|
void CDockAreaTitleBar::onUndockButtonClicked()
|
||||||
{
|
{
|
||||||
d->TabBar->makeAreaFloating(mapFromGlobal(QCursor::pos()));
|
d->TabBar->makeAreaFloating(mapFromGlobal(QCursor::pos()), DraggingInactive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -310,6 +315,19 @@ void CDockAreaTitleBar::setVisible(bool Visible)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void CDockAreaTitleBar::showContextMenu(const QPoint& pos)
|
||||||
|
{
|
||||||
|
QMenu Menu(this);
|
||||||
|
Menu.addAction(tr("Detach Area"), this, SLOT(onUndockButtonClicked()));
|
||||||
|
Menu.addSeparator();
|
||||||
|
auto Action = Menu.addAction(tr("Close Area"), this, SLOT(onCloseButtonClicked()));
|
||||||
|
Action->setEnabled(d->DockArea->features().testFlag(CDockWidget::DockWidgetClosable));
|
||||||
|
Menu.addAction(tr("Close Other Areas"), d->DockArea, SLOT(closeOtherAreas()));
|
||||||
|
Menu.exec(mapToGlobal(pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace ads
|
} // namespace ads
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -50,7 +50,7 @@ class CDockAreaTitleBar : public QFrame
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
DockAreaTitleBarPrivate* d; ///< private data (pimpl)
|
DockAreaTitleBarPrivate* d; ///< private data (pimpl)
|
||||||
friend class DockAreaTitleBarPrivate;
|
friend struct DockAreaTitleBarPrivate;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void markTabsMenuOutdated();
|
void markTabsMenuOutdated();
|
||||||
@ -59,6 +59,7 @@ private slots:
|
|||||||
void onUndockButtonClicked();
|
void onUndockButtonClicked();
|
||||||
void onTabsMenuActionTriggered(QAction* Action);
|
void onTabsMenuActionTriggered(QAction* Action);
|
||||||
void onCurrentTabChanged(int Index);
|
void onCurrentTabChanged(int Index);
|
||||||
|
void showContextMenu(const QPoint& pos);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using Super = QFrame;
|
using Super = QFrame;
|
||||||
|
@ -61,9 +61,6 @@ namespace ads
|
|||||||
{
|
{
|
||||||
static const char* const INDEX_PROPERTY = "index";
|
static const char* const INDEX_PROPERTY = "index";
|
||||||
static const char* const ACTION_PROPERTY = "action";
|
static const char* const ACTION_PROPERTY = "action";
|
||||||
static const char* const DOCKWIDGET_PROPERTY = "dockwidget";
|
|
||||||
static const int APPEND = -1;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* New dock area layout mimics stack layout but only inserts the current
|
* New dock area layout mimics stack layout but only inserts the current
|
||||||
@ -690,13 +687,13 @@ void CDockAreaWidget::updateTitleBarVisibility()
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
void CDockAreaWidget::saveState(QXmlStreamWriter& s) const
|
void CDockAreaWidget::saveState(QXmlStreamWriter& s) const
|
||||||
{
|
{
|
||||||
s.writeStartElement("DockAreaWidget");
|
s.writeStartElement("Area");
|
||||||
s.writeAttribute("Tabs", QString::number(d->ContentsLayout->count()));
|
s.writeAttribute("Tabs", QString::number(d->ContentsLayout->count()));
|
||||||
auto CurrentDockWidget = currentDockWidget();
|
auto CurrentDockWidget = currentDockWidget();
|
||||||
QString Name = CurrentDockWidget ? CurrentDockWidget->objectName() : "";
|
QString Name = CurrentDockWidget ? CurrentDockWidget->objectName() : "";
|
||||||
s.writeAttribute("CurrentDockWidget", Name);
|
s.writeAttribute("Current", Name);
|
||||||
qDebug() << "CDockAreaWidget::saveState TabCount: " << d->ContentsLayout->count()
|
qDebug() << "CDockAreaWidget::saveState TabCount: " << d->ContentsLayout->count()
|
||||||
<< " CurrentDockWidge: " << Name;
|
<< " Current: " << Name;
|
||||||
for (int i = 0; i < d->ContentsLayout->count(); ++i)
|
for (int i = 0; i < d->ContentsLayout->count(); ++i)
|
||||||
{
|
{
|
||||||
dockWidget(i)->saveState(s);
|
dockWidget(i)->saveState(s);
|
||||||
@ -779,6 +776,13 @@ void CDockAreaWidget::closeArea()
|
|||||||
DockWidget->toggleView(false);
|
DockWidget->toggleView(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void CDockAreaWidget::closeOtherAreas()
|
||||||
|
{
|
||||||
|
dockContainer()->closeOtherAreas(this);
|
||||||
|
}
|
||||||
} // namespace ads
|
} // namespace ads
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -43,7 +43,7 @@ namespace ads
|
|||||||
struct DockAreaWidgetPrivate;
|
struct DockAreaWidgetPrivate;
|
||||||
class CDockManager;
|
class CDockManager;
|
||||||
class CDockContainerWidget;
|
class CDockContainerWidget;
|
||||||
struct DockContainerWidgetPrivate;
|
class DockContainerWidgetPrivate;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -259,6 +259,11 @@ public slots:
|
|||||||
*/
|
*/
|
||||||
void closeArea();
|
void closeArea();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function closes all other areas except of this area
|
||||||
|
*/
|
||||||
|
void closeOtherAreas();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/**
|
/**
|
||||||
* This signal is emitted when user clicks on a tab at an index.
|
* This signal is emitted when user clicks on a tab at an index.
|
||||||
|
@ -44,12 +44,37 @@
|
|||||||
#include "DockWidget.h"
|
#include "DockWidget.h"
|
||||||
#include "FloatingDockContainer.h"
|
#include "FloatingDockContainer.h"
|
||||||
#include "DockOverlay.h"
|
#include "DockOverlay.h"
|
||||||
#include "DockStateSerialization.h"
|
|
||||||
#include "ads_globals.h"
|
#include "ads_globals.h"
|
||||||
#include "DockSplitter.h"
|
#include "DockSplitter.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#if QT_VERSION < 0x050900
|
||||||
|
|
||||||
|
inline char toHexLower(uint value)
|
||||||
|
{
|
||||||
|
return "0123456789abcdef"[value & 0xF];
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray qByteArrayToHex(const QByteArray& src, char separator)
|
||||||
|
{
|
||||||
|
if(src.size() == 0)
|
||||||
|
return QByteArray();
|
||||||
|
|
||||||
|
const int length = separator ? (src.size() * 3 - 1) : (src.size() * 2);
|
||||||
|
QByteArray hex(length, Qt::Uninitialized);
|
||||||
|
char *hexData = hex.data();
|
||||||
|
const uchar *data = (const uchar *)src.data();
|
||||||
|
for (int i = 0, o = 0; i < src.size(); ++i) {
|
||||||
|
hexData[o++] = toHexLower(data[i] >> 4);
|
||||||
|
hexData[o++] = toHexLower(data[i] & 0xf);
|
||||||
|
|
||||||
|
if ((separator) && (o < length))
|
||||||
|
hexData[o++] = separator;
|
||||||
|
}
|
||||||
|
return hex;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ads
|
namespace ads
|
||||||
{
|
{
|
||||||
@ -101,7 +126,7 @@ public:
|
|||||||
unsigned int zOrderIndex = 0;
|
unsigned int zOrderIndex = 0;
|
||||||
QList<CDockAreaWidget*> DockAreas;
|
QList<CDockAreaWidget*> DockAreas;
|
||||||
QGridLayout* Layout = nullptr;
|
QGridLayout* Layout = nullptr;
|
||||||
QSplitter* RootSplitter;
|
QSplitter* RootSplitter = nullptr;
|
||||||
bool isFloating = false;
|
bool isFloating = false;
|
||||||
CDockAreaWidget* LastAddedAreaCache[5]{0, 0, 0, 0, 0};
|
CDockAreaWidget* LastAddedAreaCache[5]{0, 0, 0, 0, 0};
|
||||||
int VisibleDockAreaCount = -1;
|
int VisibleDockAreaCount = -1;
|
||||||
@ -140,6 +165,12 @@ public:
|
|||||||
void dropIntoSection(CFloatingDockContainer* FloatingWidget,
|
void dropIntoSection(CFloatingDockContainer* FloatingWidget,
|
||||||
CDockAreaWidget* TargetArea, DockWidgetArea area);
|
CDockAreaWidget* TargetArea, DockWidgetArea area);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new tab for a widget dropped into the center of a section
|
||||||
|
*/
|
||||||
|
void dropIntoCenterOfSection(CFloatingDockContainer* FloatingWidget,
|
||||||
|
CDockAreaWidget* TargetArea);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds new dock areas to the internal dock area list
|
* Adds new dock areas to the internal dock area list
|
||||||
*/
|
*/
|
||||||
@ -233,6 +264,18 @@ public:
|
|||||||
emit _this->dockAreasAdded();
|
emit _this->dockAreasAdded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function for creation of new splitter
|
||||||
|
*/
|
||||||
|
CDockSplitter* newSplitter(Qt::Orientation orientation, QWidget* parent = 0)
|
||||||
|
{
|
||||||
|
CDockSplitter* s = new CDockSplitter(orientation, parent);
|
||||||
|
s->setOpaqueResize(DockManager->configFlags().testFlag(CDockManager::OpaqueSplitterResize));
|
||||||
|
s->setChildrenCollapsible(false);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// private slots: ------------------------------------------------------------
|
// private slots: ------------------------------------------------------------
|
||||||
void onDockAreaViewToggled(bool Visible)
|
void onDockAreaViewToggled(bool Visible)
|
||||||
{
|
{
|
||||||
@ -290,7 +333,7 @@ void DockContainerWidgetPrivate::dropIntoContainer(CFloatingDockContainer* Float
|
|||||||
}
|
}
|
||||||
else if (Splitter->orientation() != InsertParam.orientation())
|
else if (Splitter->orientation() != InsertParam.orientation())
|
||||||
{
|
{
|
||||||
QSplitter* NewSplitter = internal::newSplitter(InsertParam.orientation());
|
QSplitter* NewSplitter = newSplitter(InsertParam.orientation());
|
||||||
QLayoutItem* li = Layout->replaceWidget(Splitter, NewSplitter);
|
QLayoutItem* li = Layout->replaceWidget(Splitter, NewSplitter);
|
||||||
NewSplitter->addWidget(Splitter);
|
NewSplitter->addWidget(Splitter);
|
||||||
Splitter = NewSplitter;
|
Splitter = NewSplitter;
|
||||||
@ -332,21 +375,51 @@ void DockContainerWidgetPrivate::dropIntoContainer(CFloatingDockContainer* Float
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void DockContainerWidgetPrivate::dropIntoCenterOfSection(
|
||||||
|
CFloatingDockContainer* FloatingWidget, CDockAreaWidget* TargetArea)
|
||||||
|
{
|
||||||
|
CDockContainerWidget* FloatingContainer = FloatingWidget->dockContainer();
|
||||||
|
auto NewDockWidgets = FloatingContainer->dockWidgets();
|
||||||
|
auto TopLevelDockArea = FloatingContainer->topLevelDockArea();
|
||||||
|
int NewCurrentIndex = -1;
|
||||||
|
|
||||||
|
// If the floating widget contains only one single dock are, then the
|
||||||
|
// current dock widget of the dock area will also be the future current
|
||||||
|
// dock widget in the drop area.
|
||||||
|
if (TopLevelDockArea)
|
||||||
|
{
|
||||||
|
NewCurrentIndex = TopLevelDockArea->currentIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < NewDockWidgets.count(); ++i)
|
||||||
|
{
|
||||||
|
CDockWidget* DockWidget = NewDockWidgets[i];
|
||||||
|
TargetArea->insertDockWidget(i, DockWidget, false);
|
||||||
|
// If the floating widget contains multiple visible dock areas, then we
|
||||||
|
// simply pick the first visible open dock widget and make it
|
||||||
|
// the current one.
|
||||||
|
if (NewCurrentIndex < 0 && !DockWidget->isClosed())
|
||||||
|
{
|
||||||
|
NewCurrentIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TargetArea->setCurrentIndex(NewCurrentIndex);
|
||||||
|
FloatingWidget->deleteLater();
|
||||||
|
TargetArea->updateTitleBarVisibility();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
void DockContainerWidgetPrivate::dropIntoSection(CFloatingDockContainer* FloatingWidget,
|
void DockContainerWidgetPrivate::dropIntoSection(CFloatingDockContainer* FloatingWidget,
|
||||||
CDockAreaWidget* TargetArea, DockWidgetArea area)
|
CDockAreaWidget* TargetArea, DockWidgetArea area)
|
||||||
{
|
{
|
||||||
CDockContainerWidget* FloatingContainer = FloatingWidget->dockContainer();
|
// Dropping into center means all dock widgets in the dropped floating
|
||||||
if (area == CenterDockWidgetArea)
|
// widget will become tabs of the drop area
|
||||||
|
if (CenterDockWidgetArea == area)
|
||||||
{
|
{
|
||||||
auto NewDockWidgets = FloatingContainer->dockWidgets();
|
dropIntoCenterOfSection(FloatingWidget, TargetArea);
|
||||||
for (int i = 0; i < NewDockWidgets.count(); ++i)
|
|
||||||
{
|
|
||||||
TargetArea->insertDockWidget(i, NewDockWidgets[i], false);
|
|
||||||
}
|
|
||||||
TargetArea->setCurrentIndex(0); // make the topmost widget active
|
|
||||||
FloatingWidget->deleteLater();
|
|
||||||
TargetArea->updateTitleBarVisibility();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,47 +430,72 @@ void DockContainerWidgetPrivate::dropIntoSection(CFloatingDockContainer* Floatin
|
|||||||
|
|
||||||
if (!TargetAreaSplitter)
|
if (!TargetAreaSplitter)
|
||||||
{
|
{
|
||||||
QSplitter* Splitter = internal::newSplitter(InsertParam.orientation());
|
QSplitter* Splitter = newSplitter(InsertParam.orientation());
|
||||||
Layout->replaceWidget(TargetArea, Splitter);
|
Layout->replaceWidget(TargetArea, Splitter);
|
||||||
Splitter->addWidget(TargetArea);
|
Splitter->addWidget(TargetArea);
|
||||||
TargetAreaSplitter = Splitter;
|
TargetAreaSplitter = Splitter;
|
||||||
}
|
}
|
||||||
int AreaIndex = TargetAreaSplitter->indexOf(TargetArea);
|
int AreaIndex = TargetAreaSplitter->indexOf(TargetArea);
|
||||||
auto Widget = FloatingWidget->dockContainer()->findChild<QWidget*>(QString(), Qt::FindDirectChildrenOnly);
|
auto Widget = FloatingWidget->dockContainer()->findChild<QWidget*>(QString(), Qt::FindDirectChildrenOnly);
|
||||||
auto FloatingSplitter = dynamic_cast<QSplitter*>(Widget);
|
auto FloatingSplitter = qobject_cast<QSplitter*>(Widget);
|
||||||
|
|
||||||
if (TargetAreaSplitter->orientation() == InsertParam.orientation())
|
if (TargetAreaSplitter->orientation() == InsertParam.orientation())
|
||||||
{
|
{
|
||||||
|
auto Sizes = TargetAreaSplitter->sizes();
|
||||||
|
int TargetAreaSize = (InsertParam.orientation() == Qt::Horizontal) ? TargetArea->width() : TargetArea->height();
|
||||||
|
bool AdjustSplitterSizes = true;
|
||||||
if ((FloatingSplitter->orientation() != InsertParam.orientation()) && FloatingSplitter->count() > 1)
|
if ((FloatingSplitter->orientation() != InsertParam.orientation()) && FloatingSplitter->count() > 1)
|
||||||
{
|
{
|
||||||
TargetAreaSplitter->insertWidget(AreaIndex + InsertParam.insertOffset(), Widget);
|
TargetAreaSplitter->insertWidget(AreaIndex + InsertParam.insertOffset(), Widget);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
AdjustSplitterSizes = (FloatingSplitter->count() == 1);
|
||||||
int InsertIndex = AreaIndex + InsertParam.insertOffset();
|
int InsertIndex = AreaIndex + InsertParam.insertOffset();
|
||||||
while (FloatingSplitter->count())
|
while (FloatingSplitter->count())
|
||||||
{
|
{
|
||||||
TargetAreaSplitter->insertWidget(InsertIndex++, FloatingSplitter->widget(0));
|
TargetAreaSplitter->insertWidget(InsertIndex++, FloatingSplitter->widget(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (AdjustSplitterSizes)
|
||||||
|
{
|
||||||
|
int Size = (TargetAreaSize - TargetAreaSplitter->handleWidth()) / 2;
|
||||||
|
Sizes[AreaIndex] = Size;
|
||||||
|
Sizes.insert(AreaIndex, Size);
|
||||||
|
TargetAreaSplitter->setSizes(Sizes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QSplitter* NewSplitter = internal::newSplitter(InsertParam.orientation());
|
QList<int> NewSplitterSizes;
|
||||||
|
QSplitter* NewSplitter = newSplitter(InsertParam.orientation());
|
||||||
|
int TargetAreaSize = (InsertParam.orientation() == Qt::Horizontal) ? TargetArea->width() : TargetArea->height();
|
||||||
|
bool AdjustSplitterSizes = true;
|
||||||
if ((FloatingSplitter->orientation() != InsertParam.orientation()) && FloatingSplitter->count() > 1)
|
if ((FloatingSplitter->orientation() != InsertParam.orientation()) && FloatingSplitter->count() > 1)
|
||||||
{
|
{
|
||||||
NewSplitter->addWidget(Widget);
|
NewSplitter->addWidget(Widget);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
AdjustSplitterSizes = (FloatingSplitter->count() == 1);
|
||||||
while (FloatingSplitter->count())
|
while (FloatingSplitter->count())
|
||||||
{
|
{
|
||||||
NewSplitter->addWidget(FloatingSplitter->widget(0));
|
NewSplitter->addWidget(FloatingSplitter->widget(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetAreaSplitter->insertWidget(AreaIndex, NewSplitter);
|
// Save the sizes before insertion and restore it later to prevent
|
||||||
|
// shrinking of existing area
|
||||||
|
auto Sizes = TargetAreaSplitter->sizes();
|
||||||
insertWidgetIntoSplitter(NewSplitter, TargetArea, !InsertParam.append());
|
insertWidgetIntoSplitter(NewSplitter, TargetArea, !InsertParam.append());
|
||||||
|
if (AdjustSplitterSizes)
|
||||||
|
{
|
||||||
|
int Size = TargetAreaSize / 2;
|
||||||
|
NewSplitter->setSizes({Size, Size});
|
||||||
|
}
|
||||||
|
TargetAreaSplitter->insertWidget(AreaIndex, NewSplitter);
|
||||||
|
TargetAreaSplitter->setSizes(Sizes);
|
||||||
}
|
}
|
||||||
|
|
||||||
FloatingWidget->deleteLater();
|
FloatingWidget->deleteLater();
|
||||||
@ -455,7 +553,7 @@ void DockContainerWidgetPrivate::saveChildNodesState(QXmlStreamWriter& s, QWidge
|
|||||||
if (Splitter)
|
if (Splitter)
|
||||||
{
|
{
|
||||||
s.writeStartElement("Splitter");
|
s.writeStartElement("Splitter");
|
||||||
s.writeAttribute("Orientation", QString::number(Splitter->orientation()));
|
s.writeAttribute("Orientation", (Splitter->orientation() == Qt::Horizontal) ? "-" : "|");
|
||||||
s.writeAttribute("Count", QString::number(Splitter->count()));
|
s.writeAttribute("Count", QString::number(Splitter->count()));
|
||||||
qDebug() << "NodeSplitter orient: " << Splitter->orientation()
|
qDebug() << "NodeSplitter orient: " << Splitter->orientation()
|
||||||
<< " WidgetCont: " << Splitter->count();
|
<< " WidgetCont: " << Splitter->count();
|
||||||
@ -488,8 +586,17 @@ bool DockContainerWidgetPrivate::restoreSplitter(QXmlStreamReader& s,
|
|||||||
QWidget*& CreatedWidget, bool Testing)
|
QWidget*& CreatedWidget, bool Testing)
|
||||||
{
|
{
|
||||||
bool Ok;
|
bool Ok;
|
||||||
int Orientation = s.attributes().value("Orientation").toInt(&Ok);
|
QString OrientationStr = s.attributes().value("Orientation").toString();
|
||||||
if (!Ok)
|
int Orientation;
|
||||||
|
if (OrientationStr.startsWith("-"))
|
||||||
|
{
|
||||||
|
Orientation = Qt::Horizontal;
|
||||||
|
}
|
||||||
|
else if (OrientationStr.startsWith("|"))
|
||||||
|
{
|
||||||
|
Orientation = Qt::Vertical;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -504,7 +611,7 @@ bool DockContainerWidgetPrivate::restoreSplitter(QXmlStreamReader& s,
|
|||||||
QSplitter* Splitter = nullptr;
|
QSplitter* Splitter = nullptr;
|
||||||
if (!Testing)
|
if (!Testing)
|
||||||
{
|
{
|
||||||
Splitter = internal::newSplitter((Qt::Orientation)Orientation);
|
Splitter = newSplitter((Qt::Orientation)Orientation);
|
||||||
}
|
}
|
||||||
bool Visible = false;
|
bool Visible = false;
|
||||||
QList<int> Sizes;
|
QList<int> Sizes;
|
||||||
@ -516,7 +623,7 @@ bool DockContainerWidgetPrivate::restoreSplitter(QXmlStreamReader& s,
|
|||||||
{
|
{
|
||||||
Result = restoreSplitter(s, ChildNode, Testing);
|
Result = restoreSplitter(s, ChildNode, Testing);
|
||||||
}
|
}
|
||||||
else if (s.name() == "DockAreaWidget")
|
else if (s.name() == "Area")
|
||||||
{
|
{
|
||||||
Result = restoreDockArea(s, ChildNode, Testing);
|
Result = restoreDockArea(s, ChildNode, Testing);
|
||||||
}
|
}
|
||||||
@ -593,8 +700,8 @@ bool DockContainerWidgetPrivate::restoreDockArea(QXmlStreamReader& s,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QString CurrentDockWidget = s.attributes().value("CurrentDockWidget").toString();
|
QString CurrentDockWidget = s.attributes().value("Current").toString();
|
||||||
qDebug() << "Restore NodeDockArea Tabs: " << Tabs << " CurrentDockWidget: "
|
qDebug() << "Restore NodeDockArea Tabs: " << Tabs << " Current: "
|
||||||
<< CurrentDockWidget;
|
<< CurrentDockWidget;
|
||||||
|
|
||||||
CDockAreaWidget* DockArea = nullptr;
|
CDockAreaWidget* DockArea = nullptr;
|
||||||
@ -605,12 +712,12 @@ bool DockContainerWidgetPrivate::restoreDockArea(QXmlStreamReader& s,
|
|||||||
|
|
||||||
while (s.readNextStartElement())
|
while (s.readNextStartElement())
|
||||||
{
|
{
|
||||||
if (s.name() != "DockWidget")
|
if (s.name() != "Widget")
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ObjectName = s.attributes().value("ObjectName");
|
auto ObjectName = s.attributes().value("Name");
|
||||||
if (ObjectName.isEmpty())
|
if (ObjectName.isEmpty())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -673,7 +780,7 @@ bool DockContainerWidgetPrivate::restoreChildNodes(QXmlStreamReader& s,
|
|||||||
Result = restoreSplitter(s, CreatedWidget, Testing);
|
Result = restoreSplitter(s, CreatedWidget, Testing);
|
||||||
qDebug() << "Splitter";
|
qDebug() << "Splitter";
|
||||||
}
|
}
|
||||||
else if (s.name() == "DockAreaWidget")
|
else if (s.name() == "Area")
|
||||||
{
|
{
|
||||||
Result = restoreDockArea(s, CreatedWidget, Testing);
|
Result = restoreDockArea(s, CreatedWidget, Testing);
|
||||||
qDebug() << "DockAreaWidget";
|
qDebug() << "DockAreaWidget";
|
||||||
@ -720,7 +827,7 @@ void DockContainerWidgetPrivate::addDockArea(CDockAreaWidget* NewDockArea, DockW
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QSplitter* NewSplitter = internal::newSplitter(InsertParam.orientation());
|
QSplitter* NewSplitter = newSplitter(InsertParam.orientation());
|
||||||
if (InsertParam.append())
|
if (InsertParam.append())
|
||||||
{
|
{
|
||||||
QLayoutItem* li = Layout->replaceWidget(Splitter, NewSplitter);
|
QLayoutItem* li = Layout->replaceWidget(Splitter, NewSplitter);
|
||||||
@ -820,7 +927,7 @@ CDockAreaWidget* DockContainerWidgetPrivate::dockWidgetIntoDockArea(DockWidgetAr
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
qDebug() << "TargetAreaSplitter->orientation() != InsertParam.orientation()";
|
qDebug() << "TargetAreaSplitter->orientation() != InsertParam.orientation()";
|
||||||
QSplitter* NewSplitter = internal::newSplitter(InsertParam.orientation());
|
QSplitter* NewSplitter = newSplitter(InsertParam.orientation());
|
||||||
NewSplitter->addWidget(TargetDockArea);
|
NewSplitter->addWidget(TargetDockArea);
|
||||||
insertWidgetIntoSplitter(NewSplitter, NewDockArea, InsertParam.append());
|
insertWidgetIntoSplitter(NewSplitter, NewDockArea, InsertParam.append());
|
||||||
TargetAreaSplitter->insertWidget(index, NewSplitter);
|
TargetAreaSplitter->insertWidget(index, NewSplitter);
|
||||||
@ -837,20 +944,24 @@ CDockContainerWidget::CDockContainerWidget(CDockManager* DockManager, QWidget *p
|
|||||||
QFrame(parent),
|
QFrame(parent),
|
||||||
d(new DockContainerWidgetPrivate(this))
|
d(new DockContainerWidgetPrivate(this))
|
||||||
{
|
{
|
||||||
d->isFloating = floatingWidget() != nullptr;
|
|
||||||
d->DockManager = DockManager;
|
d->DockManager = DockManager;
|
||||||
if (DockManager != this)
|
d->isFloating = floatingWidget() != nullptr;
|
||||||
{
|
|
||||||
d->DockManager->registerDockContainer(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
d->Layout = new QGridLayout();
|
d->Layout = new QGridLayout();
|
||||||
d->Layout->setContentsMargins(0, 1, 0, 1);
|
d->Layout->setContentsMargins(0, 1, 0, 1);
|
||||||
d->Layout->setSpacing(0);
|
d->Layout->setSpacing(0);
|
||||||
setLayout(d->Layout);
|
setLayout(d->Layout);
|
||||||
|
|
||||||
d->RootSplitter = internal::newSplitter(Qt::Horizontal);
|
// The function d->newSplitter() accesses the config flags from dock
|
||||||
d->Layout->addWidget(d->RootSplitter);
|
// manager which in turn requires a properly constructed dock manager.
|
||||||
|
// If this dock container is the dock manager, then it is not properly
|
||||||
|
// constructed yet because this base class constructor is called before
|
||||||
|
// the constructor of the DockManager private class
|
||||||
|
if (DockManager != this)
|
||||||
|
{
|
||||||
|
d->DockManager->registerDockContainer(this);
|
||||||
|
createRootSplitter();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
@ -981,10 +1092,12 @@ void CDockContainerWidget::removeDockArea(CDockAreaWidget* area)
|
|||||||
else if (Splitter->count() == 1)
|
else if (Splitter->count() == 1)
|
||||||
{
|
{
|
||||||
qDebug() << "Replacing splitter with content";
|
qDebug() << "Replacing splitter with content";
|
||||||
|
QSplitter* ParentSplitter = internal::findParent<QSplitter*>(Splitter);
|
||||||
|
auto Sizes = ParentSplitter->sizes();
|
||||||
QWidget* widget = Splitter->widget(0);
|
QWidget* widget = Splitter->widget(0);
|
||||||
widget->setParent(this);
|
widget->setParent(this);
|
||||||
QSplitter* ParentSplitter = internal::findParent<QSplitter*>(Splitter);
|
|
||||||
internal::replaceSplitterWidget(ParentSplitter, Splitter, widget);
|
internal::replaceSplitterWidget(ParentSplitter, Splitter, widget);
|
||||||
|
ParentSplitter->setSizes(Sizes);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete Splitter;
|
delete Splitter;
|
||||||
@ -1131,13 +1244,17 @@ void CDockContainerWidget::saveState(QXmlStreamWriter& s) const
|
|||||||
qDebug() << "CDockContainerWidget::saveState isFloating "
|
qDebug() << "CDockContainerWidget::saveState isFloating "
|
||||||
<< isFloating();
|
<< isFloating();
|
||||||
|
|
||||||
s.writeStartElement("DockContainerWidget");
|
s.writeStartElement("Container");
|
||||||
s.writeAttribute("Floating", QString::number(isFloating() ? 1 : 0));
|
s.writeAttribute("Floating", QString::number(isFloating() ? 1 : 0));
|
||||||
if (isFloating())
|
if (isFloating())
|
||||||
{
|
{
|
||||||
CFloatingDockContainer* FloatingWidget = floatingWidget();
|
CFloatingDockContainer* FloatingWidget = floatingWidget();
|
||||||
QByteArray Geometry = FloatingWidget->saveGeometry();
|
QByteArray Geometry = FloatingWidget->saveGeometry();
|
||||||
|
#if QT_VERSION < 0x050900
|
||||||
|
s.writeTextElement("Geometry", qByteArrayToHex(Geometry, ' '));
|
||||||
|
#else
|
||||||
s.writeTextElement("Geometry", Geometry.toHex(' '));
|
s.writeTextElement("Geometry", Geometry.toHex(' '));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
d->saveChildNodesState(s, d->RootSplitter);
|
d->saveChildNodesState(s, d->RootSplitter);
|
||||||
s.writeEndElement();
|
s.writeEndElement();
|
||||||
@ -1193,7 +1310,7 @@ bool CDockContainerWidget::restoreState(QXmlStreamReader& s, bool Testing)
|
|||||||
// and we need to create a new empty root splitter
|
// and we need to create a new empty root splitter
|
||||||
if (!NewRootSplitter)
|
if (!NewRootSplitter)
|
||||||
{
|
{
|
||||||
NewRootSplitter = internal::newSplitter(Qt::Horizontal);
|
NewRootSplitter = d->newSplitter(Qt::Horizontal);
|
||||||
}
|
}
|
||||||
|
|
||||||
d->Layout->replaceWidget(d->RootSplitter, NewRootSplitter);
|
d->Layout->replaceWidget(d->RootSplitter, NewRootSplitter);
|
||||||
@ -1212,6 +1329,18 @@ QSplitter* CDockContainerWidget::rootSplitter() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void CDockContainerWidget::createRootSplitter()
|
||||||
|
{
|
||||||
|
if (d->RootSplitter)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
d->RootSplitter = d->newSplitter(Qt::Horizontal);
|
||||||
|
d->Layout->addWidget(d->RootSplitter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
void CDockContainerWidget::dumpLayout()
|
void CDockContainerWidget::dumpLayout()
|
||||||
{
|
{
|
||||||
@ -1321,6 +1450,19 @@ CFloatingDockContainer* CDockContainerWidget::floatingWidget() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void CDockContainerWidget::closeOtherAreas(CDockAreaWidget* KeepOpenArea)
|
||||||
|
{
|
||||||
|
for (const auto DockArea : d->DockAreas)
|
||||||
|
{
|
||||||
|
if (DockArea != KeepOpenArea && DockArea->features().testFlag(CDockWidget::DockWidgetClosable))
|
||||||
|
{
|
||||||
|
DockArea->closeArea();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace ads
|
} // namespace ads
|
||||||
|
|
||||||
#include "moc_DockContainerWidget.cpp"
|
#include "moc_DockContainerWidget.cpp"
|
||||||
|
@ -57,7 +57,7 @@ class ADS_EXPORT CDockContainerWidget : public QFrame
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
DockContainerWidgetPrivate* d; ///< private data (pimpl)
|
DockContainerWidgetPrivate* d; ///< private data (pimpl)
|
||||||
friend struct DockContainerWidgetPrivate;
|
friend class DockContainerWidgetPrivate;
|
||||||
friend class CDockManager;
|
friend class CDockManager;
|
||||||
friend struct DockManagerPrivate;
|
friend struct DockManagerPrivate;
|
||||||
friend class CDockAreaWidget;
|
friend class CDockAreaWidget;
|
||||||
@ -78,6 +78,11 @@ protected:
|
|||||||
*/
|
*/
|
||||||
QSplitter* rootSplitter() const;
|
QSplitter* rootSplitter() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function for creation of the root splitter
|
||||||
|
*/
|
||||||
|
void createRootSplitter();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Drop floating widget into the container
|
* Drop floating widget into the container
|
||||||
*/
|
*/
|
||||||
@ -228,6 +233,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
CFloatingDockContainer* floatingWidget() const;
|
CFloatingDockContainer* floatingWidget() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call this function to close all dock areas except the KeepOpenArea
|
||||||
|
*/
|
||||||
|
void closeOtherAreas(CDockAreaWidget* KeepOpenArea);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/**
|
/**
|
||||||
* This signal is emitted if one or multiple dock areas has been added to
|
* This signal is emitted if one or multiple dock areas has been added to
|
||||||
|
@ -51,7 +51,6 @@
|
|||||||
#include "DockOverlay.h"
|
#include "DockOverlay.h"
|
||||||
#include "DockWidget.h"
|
#include "DockWidget.h"
|
||||||
#include "ads_globals.h"
|
#include "ads_globals.h"
|
||||||
#include "DockStateSerialization.h"
|
|
||||||
#include "DockAreaWidget.h"
|
#include "DockAreaWidget.h"
|
||||||
|
|
||||||
|
|
||||||
@ -217,12 +216,12 @@ bool DockManagerPrivate::restoreStateFromXml(const QByteArray &state, int versi
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Result = true;
|
bool Result = true;
|
||||||
int DockContainers = s.attributes().value("DockContainers").toInt();
|
int DockContainers = s.attributes().value("Containers").toInt();
|
||||||
qDebug() << DockContainers;
|
qDebug() << DockContainers;
|
||||||
int DockContainerCount = 0;
|
int DockContainerCount = 0;
|
||||||
while (s.readNextStartElement())
|
while (s.readNextStartElement())
|
||||||
{
|
{
|
||||||
if (s.name() == "DockContainerWidget")
|
if (s.name() == "Container")
|
||||||
{
|
{
|
||||||
Result = restoreContainer(DockContainerCount, s, Testing);
|
Result = restoreContainer(DockContainerCount, s, Testing);
|
||||||
if (!Result)
|
if (!Result)
|
||||||
@ -391,12 +390,12 @@ void DockManagerPrivate::addActionToMenu(QAction* Action, QMenu* Menu, bool Inse
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
CDockManager::CDockManager(QWidget *parent) :
|
CDockManager::CDockManager(QWidget *parent) :
|
||||||
CDockContainerWidget(this, parent),
|
CDockContainerWidget(this, parent),
|
||||||
d(new DockManagerPrivate(this))
|
d(new DockManagerPrivate(this))
|
||||||
{
|
{
|
||||||
|
createRootSplitter();
|
||||||
QMainWindow* MainWindow = dynamic_cast<QMainWindow*>(parent);
|
QMainWindow* MainWindow = dynamic_cast<QMainWindow*>(parent);
|
||||||
if (MainWindow)
|
if (MainWindow)
|
||||||
{
|
{
|
||||||
@ -498,7 +497,7 @@ QByteArray CDockManager::saveState(eXmlMode XmlMode, int version) const
|
|||||||
s.writeStartDocument();
|
s.writeStartDocument();
|
||||||
s.writeStartElement("QtAdvancedDockingSystem");
|
s.writeStartElement("QtAdvancedDockingSystem");
|
||||||
s.writeAttribute("Version", QString::number(version));
|
s.writeAttribute("Version", QString::number(version));
|
||||||
s.writeAttribute("DockContainers", QString::number(d->Containers.count()));
|
s.writeAttribute("Containers", QString::number(d->Containers.count()));
|
||||||
for (auto Container : d->Containers)
|
for (auto Container : d->Containers)
|
||||||
{
|
{
|
||||||
Container->saveState(s);
|
Container->saveState(s);
|
||||||
@ -606,10 +605,7 @@ void CDockManager::addPerspective(const QString& UniquePrespectiveName)
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
void CDockManager::removePerspective(const QString& Name)
|
void CDockManager::removePerspective(const QString& Name)
|
||||||
{
|
{
|
||||||
if (d->Perspectives.remove(Name))
|
removePerspectives({Name});
|
||||||
{
|
|
||||||
emit perspectiveListChanged();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -624,6 +620,7 @@ void CDockManager::removePerspectives(const QStringList& Names)
|
|||||||
|
|
||||||
if (Count)
|
if (Count)
|
||||||
{
|
{
|
||||||
|
emit perspectivesRemoved();
|
||||||
emit perspectiveListChanged();
|
emit perspectiveListChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -762,6 +759,7 @@ void CDockManager::setConfigFlags(const ConfigFlags Flags)
|
|||||||
d->ConfigFlags = Flags;
|
d->ConfigFlags = Flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace ads
|
} // namespace ads
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -123,7 +123,8 @@ public:
|
|||||||
ActiveTabHasCloseButton = 0x01, //!< If this flag is set, the active tab in a tab area has a close button
|
ActiveTabHasCloseButton = 0x01, //!< If this flag is set, the active tab in a tab area has a close button
|
||||||
DockAreaHasCloseButton = 0x02, //!< If the flag is set each dock area has a close button
|
DockAreaHasCloseButton = 0x02, //!< If the flag is set each dock area has a close button
|
||||||
DockAreaCloseButtonClosesTab = 0x04,//!< If the flag is set, the dock area close button closes the active tab, if not set, it closes the complete cock area
|
DockAreaCloseButtonClosesTab = 0x04,//!< If the flag is set, the dock area close button closes the active tab, if not set, it closes the complete cock area
|
||||||
DefaultConfig = ActiveTabHasCloseButton | DockAreaHasCloseButton, ///< the default configuration
|
OpaqueSplitterResize = 0x08, //!< See QSplitter::setOpaqueResize() documentation
|
||||||
|
DefaultConfig = ActiveTabHasCloseButton | DockAreaHasCloseButton | OpaqueSplitterResize, ///< the default configuration
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(ConfigFlags, eConfigFlag)
|
Q_DECLARE_FLAGS(ConfigFlags, eConfigFlag)
|
||||||
|
|
||||||
@ -330,6 +331,11 @@ signals:
|
|||||||
*/
|
*/
|
||||||
void perspectiveListChanged();
|
void perspectiveListChanged();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This signal is emitted if perspectives have been removed
|
||||||
|
*/
|
||||||
|
void perspectivesRemoved();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This signal is emitted, if the restore function is called, just before
|
* This signal is emitted, if the restore function is called, just before
|
||||||
* the dock manager starts restoring the state.
|
* the dock manager starts restoring the state.
|
||||||
|
@ -168,7 +168,11 @@ struct DockOverlayCrossPrivate
|
|||||||
QColor borderColor = iconColor(CDockOverlayCross::FrameColor);
|
QColor borderColor = iconColor(CDockOverlayCross::FrameColor);
|
||||||
QColor backgroundColor = iconColor(CDockOverlayCross::WindowBackgroundColor);
|
QColor backgroundColor = iconColor(CDockOverlayCross::WindowBackgroundColor);
|
||||||
|
|
||||||
|
#if QT_VERSION >= 0x050600
|
||||||
double DevicePixelRatio = _this->window()->devicePixelRatioF();
|
double DevicePixelRatio = _this->window()->devicePixelRatioF();
|
||||||
|
#else
|
||||||
|
double DevicePixelRatio = _this->window()->devicePixelRatio();
|
||||||
|
#endif
|
||||||
QSizeF PixmapSize = size * DevicePixelRatio;
|
QSizeF PixmapSize = size * DevicePixelRatio;
|
||||||
QPixmap pm(PixmapSize.toSize());
|
QPixmap pm(PixmapSize.toSize());
|
||||||
pm.fill(QColor(0, 0, 0, 0));
|
pm.fill(QColor(0, 0, 0, 0));
|
||||||
@ -577,8 +581,11 @@ void CDockOverlayCross::setupOverlayCross(CDockOverlay::eMode Mode)
|
|||||||
areaWidgets.insert(BottomDockWidgetArea, d->createDropIndicatorWidget(BottomDockWidgetArea, Mode));
|
areaWidgets.insert(BottomDockWidgetArea, d->createDropIndicatorWidget(BottomDockWidgetArea, Mode));
|
||||||
areaWidgets.insert(LeftDockWidgetArea, d->createDropIndicatorWidget(LeftDockWidgetArea, Mode));
|
areaWidgets.insert(LeftDockWidgetArea, d->createDropIndicatorWidget(LeftDockWidgetArea, Mode));
|
||||||
areaWidgets.insert(CenterDockWidgetArea, d->createDropIndicatorWidget(CenterDockWidgetArea, Mode));
|
areaWidgets.insert(CenterDockWidgetArea, d->createDropIndicatorWidget(CenterDockWidgetArea, Mode));
|
||||||
|
#if QT_VERSION >= 0x050600
|
||||||
d->LastDevicePixelRatio = devicePixelRatioF();
|
d->LastDevicePixelRatio = devicePixelRatioF();
|
||||||
|
#else
|
||||||
|
d->LastDevicePixelRatio = devicePixelRatio();
|
||||||
|
#endif
|
||||||
setAreaWidgets(areaWidgets);
|
setAreaWidgets(areaWidgets);
|
||||||
d->UpdateRequired = false;
|
d->UpdateRequired = false;
|
||||||
}
|
}
|
||||||
@ -596,7 +603,11 @@ void CDockOverlayCross::updateOverlayIcons()
|
|||||||
{
|
{
|
||||||
d->updateDropIndicatorIcon(Widget);
|
d->updateDropIndicatorIcon(Widget);
|
||||||
}
|
}
|
||||||
|
#if QT_VESION >= 0x050600
|
||||||
d->LastDevicePixelRatio = devicePixelRatioF();
|
d->LastDevicePixelRatio = devicePixelRatioF();
|
||||||
|
#else
|
||||||
|
d->LastDevicePixelRatio = devicePixelRatio();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,7 +52,8 @@ CDockSplitter::CDockSplitter(QWidget *parent)
|
|||||||
: QSplitter(parent),
|
: QSplitter(parent),
|
||||||
d(new DockSplitterPrivate(this))
|
d(new DockSplitterPrivate(this))
|
||||||
{
|
{
|
||||||
|
setProperty("ads-splitter", true);
|
||||||
|
setChildrenCollapsible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
** Qt Advanced Docking System
|
|
||||||
** Copyright (C) 2017 Uwe Kindler
|
|
||||||
**
|
|
||||||
** This library is free software; you can redistribute it and/or
|
|
||||||
** modify it under the terms of the GNU Lesser General Public
|
|
||||||
** License as published by the Free Software Foundation; either
|
|
||||||
** version 2.1 of the License, or (at your option) any later version.
|
|
||||||
**
|
|
||||||
** This library is distributed in the hope that it will be useful,
|
|
||||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
** Lesser General Public License for more details.
|
|
||||||
**
|
|
||||||
** You should have received a copy of the GNU Lesser General Public
|
|
||||||
** License along with this library; If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
/// \file DockStateSerialization.cpp
|
|
||||||
/// \author Uwe Kindler
|
|
||||||
/// \date 26.02.2017
|
|
||||||
/// \brief Serialization related data, constants and stuff
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
// INCLUDES
|
|
||||||
//============================================================================
|
|
||||||
#include "DockStateSerialization.h"
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
|||||||
#ifndef DockStateSerializationH
|
|
||||||
#define DockStateSerializationH
|
|
||||||
/*******************************************************************************
|
|
||||||
** Qt Advanced Docking System
|
|
||||||
** Copyright (C) 2017 Uwe Kindler
|
|
||||||
**
|
|
||||||
** This library is free software; you can redistribute it and/or
|
|
||||||
** modify it under the terms of the GNU Lesser General Public
|
|
||||||
** License as published by the Free Software Foundation; either
|
|
||||||
** version 2.1 of the License, or (at your option) any later version.
|
|
||||||
**
|
|
||||||
** This library is distributed in the hope that it will be useful,
|
|
||||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
** Lesser General Public License for more details.
|
|
||||||
**
|
|
||||||
** You should have received a copy of the GNU Lesser General Public
|
|
||||||
** License along with this library; If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
/// \file DockStateSerialization.h
|
|
||||||
/// \author Uwe Kindler
|
|
||||||
/// \date 26.02.2017
|
|
||||||
/// \brief Declaration of serialization related data, constants and stuff
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
// INCLUDES
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
|
|
||||||
namespace ads
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace internal
|
|
||||||
{
|
|
||||||
// sentinel values used to validate state data
|
|
||||||
enum VersionMarkers
|
|
||||||
{
|
|
||||||
VersionMarker = 0xff,
|
|
||||||
ContainerMarker = 0xfe,
|
|
||||||
SplitterMarker = 0xfd,
|
|
||||||
DockAreaMarker = 0xfc,
|
|
||||||
DockWidgetMarker = 0xfb
|
|
||||||
};
|
|
||||||
|
|
||||||
static const bool RestoreTesting = true;
|
|
||||||
static const bool Restore = false;
|
|
||||||
} // internal
|
|
||||||
} // namespace ads
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
#endif // DockManagerH
|
|
@ -47,7 +47,6 @@
|
|||||||
#include "DockAreaWidget.h"
|
#include "DockAreaWidget.h"
|
||||||
#include "DockManager.h"
|
#include "DockManager.h"
|
||||||
#include "FloatingDockContainer.h"
|
#include "FloatingDockContainer.h"
|
||||||
#include "DockStateSerialization.h"
|
|
||||||
#include "DockSplitter.h"
|
#include "DockSplitter.h"
|
||||||
#include "ads_globals.h"
|
#include "ads_globals.h"
|
||||||
|
|
||||||
@ -183,7 +182,7 @@ void DockWidgetPrivate::setupToolBar()
|
|||||||
{
|
{
|
||||||
ToolBar = new QToolBar(_this);
|
ToolBar = new QToolBar(_this);
|
||||||
ToolBar->setObjectName("dockWidgetToolBar");
|
ToolBar->setObjectName("dockWidgetToolBar");
|
||||||
Layout->addWidget(ToolBar);
|
Layout->insertWidget(0, ToolBar);
|
||||||
ToolBar->setIconSize(QSize(16, 16));
|
ToolBar->setIconSize(QSize(16, 16));
|
||||||
ToolBar->toggleViewAction()->setEnabled(false);
|
ToolBar->toggleViewAction()->setEnabled(false);
|
||||||
ToolBar->toggleViewAction()->setVisible(false);
|
ToolBar->toggleViewAction()->setVisible(false);
|
||||||
@ -215,7 +214,7 @@ CDockWidget::CDockWidget(const QString &title, QWidget *parent) :
|
|||||||
setObjectName(title);
|
setObjectName(title);
|
||||||
|
|
||||||
d->TabWidget = new CDockWidgetTab(this);
|
d->TabWidget = new CDockWidgetTab(this);
|
||||||
d->ToggleViewAction = new QAction(title);
|
d->ToggleViewAction = new QAction(title, nullptr);
|
||||||
d->ToggleViewAction->setCheckable(true);
|
d->ToggleViewAction->setCheckable(true);
|
||||||
connect(d->ToggleViewAction, SIGNAL(triggered(bool)), this,
|
connect(d->ToggleViewAction, SIGNAL(triggered(bool)), this,
|
||||||
SLOT(toggleView(bool)));
|
SLOT(toggleView(bool)));
|
||||||
@ -283,7 +282,18 @@ void CDockWidget::setFeatures(DockWidgetFeatures features)
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
void CDockWidget::setFeature(DockWidgetFeature flag, bool on)
|
void CDockWidget::setFeature(DockWidgetFeature flag, bool on)
|
||||||
{
|
{
|
||||||
|
#if QT_VERSION >= 0x050700
|
||||||
d->Features.setFlag(flag, on);
|
d->Features.setFlag(flag, on);
|
||||||
|
#else
|
||||||
|
if(on)
|
||||||
|
{
|
||||||
|
d->Features |= flag;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d->Features &= ~flag;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -474,8 +484,8 @@ void CDockWidget::setDockArea(CDockAreaWidget* DockArea)
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
void CDockWidget::saveState(QXmlStreamWriter& s) const
|
void CDockWidget::saveState(QXmlStreamWriter& s) const
|
||||||
{
|
{
|
||||||
s.writeStartElement("DockWidget");
|
s.writeStartElement("Widget");
|
||||||
s.writeAttribute("ObjectName", objectName());
|
s.writeAttribute("Name", objectName());
|
||||||
s.writeAttribute("Closed", QString::number(d->Closed ? 1 : 0));
|
s.writeAttribute("Closed", QString::number(d->Closed ? 1 : 0));
|
||||||
s.writeEndElement();
|
s.writeEndElement();
|
||||||
}
|
}
|
||||||
@ -681,6 +691,7 @@ QSize CDockWidget::minimumSizeHint() const
|
|||||||
return QSize(60, 40);
|
return QSize(60, 40);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace ads
|
} // namespace ads
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -44,7 +44,8 @@ class CDockWidgetTab;
|
|||||||
class CDockManager;
|
class CDockManager;
|
||||||
class CDockContainerWidget;
|
class CDockContainerWidget;
|
||||||
class CDockAreaWidget;
|
class CDockAreaWidget;
|
||||||
struct DockContainerWidgetPrivate;
|
class DockContainerWidgetPrivate;
|
||||||
|
class CFloatingDockContainer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The QDockWidget class provides a widget that can be docked inside a
|
* The QDockWidget class provides a widget that can be docked inside a
|
||||||
@ -69,7 +70,7 @@ protected:
|
|||||||
friend class CFloatingDockContainer;
|
friend class CFloatingDockContainer;
|
||||||
friend class CDockManager;
|
friend class CDockManager;
|
||||||
friend struct DockManagerPrivate;
|
friend struct DockManagerPrivate;
|
||||||
friend struct DockContainerWidgetPrivate;
|
friend class DockContainerWidgetPrivate;
|
||||||
friend class CDockAreaTabBar;
|
friend class CDockAreaTabBar;
|
||||||
friend class CDockWidgetTab;
|
friend class CDockWidgetTab;
|
||||||
friend struct DockWidgetTabPrivate;
|
friend struct DockWidgetTabPrivate;
|
||||||
|
@ -53,16 +53,6 @@
|
|||||||
|
|
||||||
namespace ads
|
namespace ads
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* The different dragging states
|
|
||||||
*/
|
|
||||||
enum eDragState
|
|
||||||
{
|
|
||||||
DraggingInactive, //!< DraggingInactive
|
|
||||||
DraggingMousePressed, //!< DraggingMousePressed
|
|
||||||
DraggingTab, //!< DraggingTab
|
|
||||||
DraggingFloatingWidget//!< DraggingFloatingWidget
|
|
||||||
};
|
|
||||||
|
|
||||||
using tTabLabel = CElidingLabel;
|
using tTabLabel = CElidingLabel;
|
||||||
using tCloseButton = QPushButton;
|
using tCloseButton = QPushButton;
|
||||||
@ -74,7 +64,7 @@ struct DockWidgetTabPrivate
|
|||||||
{
|
{
|
||||||
CDockWidgetTab* _this;
|
CDockWidgetTab* _this;
|
||||||
CDockWidget* DockWidget;
|
CDockWidget* DockWidget;
|
||||||
QLabel* IconLabel;
|
QLabel* IconLabel = nullptr;
|
||||||
tTabLabel* TitleLabel;
|
tTabLabel* TitleLabel;
|
||||||
QPoint DragStartMousePosition;
|
QPoint DragStartMousePosition;
|
||||||
bool IsActiveTab = false;
|
bool IsActiveTab = false;
|
||||||
@ -123,7 +113,7 @@ struct DockWidgetTabPrivate
|
|||||||
* Returns true, if floating has been started and false if floating
|
* Returns true, if floating has been started and false if floating
|
||||||
* is not possible for any reason
|
* is not possible for any reason
|
||||||
*/
|
*/
|
||||||
bool startFloating();
|
bool startFloating(eDragState DraggingState = DraggingFloatingWidget);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the given config flag is set
|
* Returns true if the given config flag is set
|
||||||
@ -197,7 +187,7 @@ void DockWidgetTabPrivate::moveTab(QMouseEvent* ev)
|
|||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
bool DockWidgetTabPrivate::startFloating()
|
bool DockWidgetTabPrivate::startFloating(eDragState DraggingState)
|
||||||
{
|
{
|
||||||
auto dockContainer = DockWidget->dockContainer();
|
auto dockContainer = DockWidget->dockContainer();
|
||||||
qDebug() << "isFloating " << dockContainer->isFloating();
|
qDebug() << "isFloating " << dockContainer->isFloating();
|
||||||
@ -214,7 +204,7 @@ bool DockWidgetTabPrivate::startFloating()
|
|||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "startFloating";
|
qDebug() << "startFloating";
|
||||||
DragState = DraggingFloatingWidget;
|
DragState = DraggingState;
|
||||||
QSize Size = DockArea->size();
|
QSize Size = DockArea->size();
|
||||||
CFloatingDockContainer* FloatingWidget = nullptr;
|
CFloatingDockContainer* FloatingWidget = nullptr;
|
||||||
if (DockArea->dockWidgetsCount() > 1)
|
if (DockArea->dockWidgetsCount() > 1)
|
||||||
@ -229,11 +219,18 @@ bool DockWidgetTabPrivate::startFloating()
|
|||||||
FloatingWidget = new CFloatingDockContainer(DockArea);
|
FloatingWidget = new CFloatingDockContainer(DockArea);
|
||||||
}
|
}
|
||||||
|
|
||||||
FloatingWidget->startFloating(DragStartMousePosition, Size);
|
if (DraggingFloatingWidget == DraggingState)
|
||||||
auto Overlay = DockWidget->dockManager()->containerOverlay();
|
{
|
||||||
Overlay->setAllowedAreas(OuterDockAreas);
|
FloatingWidget->startDragging(DragStartMousePosition, Size);
|
||||||
this->FloatingWidget = FloatingWidget;
|
auto Overlay = DockWidget->dockManager()->containerOverlay();
|
||||||
DockWidget->emitTopLevelChanged(true);
|
Overlay->setAllowedAreas(OuterDockAreas);
|
||||||
|
this->FloatingWidget = FloatingWidget;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FloatingWidget->initFloatingGeometry(DragStartMousePosition, Size);
|
||||||
|
}
|
||||||
|
DockWidget->emitTopLevelChanged(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,7 +346,6 @@ void CDockWidgetTab::mouseMoveEvent(QMouseEvent* ev)
|
|||||||
void CDockWidgetTab::contextMenuEvent(QContextMenuEvent* ev)
|
void CDockWidgetTab::contextMenuEvent(QContextMenuEvent* ev)
|
||||||
{
|
{
|
||||||
ev->accept();
|
ev->accept();
|
||||||
std::cout << "CDockAreaTabBar::onTabContextMenuRequested" << std::endl;
|
|
||||||
|
|
||||||
d->DragStartMousePosition = ev->pos();
|
d->DragStartMousePosition = ev->pos();
|
||||||
QMenu Menu(this);
|
QMenu Menu(this);
|
||||||
@ -416,15 +412,35 @@ CDockAreaWidget* CDockWidgetTab::dockAreaWidget() const
|
|||||||
void CDockWidgetTab::setIcon(const QIcon& Icon)
|
void CDockWidgetTab::setIcon(const QIcon& Icon)
|
||||||
{
|
{
|
||||||
QBoxLayout* Layout = qobject_cast<QBoxLayout*>(layout());
|
QBoxLayout* Layout = qobject_cast<QBoxLayout*>(layout());
|
||||||
|
if (!d->IconLabel && Icon.isNull())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!d->IconLabel)
|
||||||
|
{
|
||||||
|
d->IconLabel = new QLabel();
|
||||||
|
d->IconLabel->setAlignment(Qt::AlignVCenter);
|
||||||
|
d->IconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
|
||||||
|
d->IconLabel->setToolTip(d->TitleLabel->toolTip());
|
||||||
|
Layout->insertWidget(0, d->IconLabel, Qt::AlignVCenter);
|
||||||
|
Layout->insertSpacing(1, qRound(1.5 * Layout->contentsMargins().left() / 2.0));
|
||||||
|
}
|
||||||
|
else if (Icon.isNull())
|
||||||
|
{
|
||||||
|
// Remove icon label and spacer item
|
||||||
|
Layout->removeWidget(d->IconLabel);
|
||||||
|
Layout->removeItem(Layout->itemAt(0));
|
||||||
|
delete d->IconLabel;
|
||||||
|
d->IconLabel = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
d->Icon = Icon;
|
d->Icon = Icon;
|
||||||
d->IconLabel = new QLabel();
|
if (d->IconLabel)
|
||||||
d->IconLabel->setAlignment(Qt::AlignVCenter);
|
{
|
||||||
d->IconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
|
d->IconLabel->setPixmap(Icon.pixmap(this->windowHandle(), QSize(16, 16)));
|
||||||
d->IconLabel->setToolTip(d->TitleLabel->toolTip());
|
d->IconLabel->setVisible(true);
|
||||||
d->IconLabel->setPixmap(Icon.pixmap(this->windowHandle(), QSize(16, 16)));
|
}
|
||||||
Layout->insertWidget(0, d->IconLabel, Qt::AlignVCenter);
|
|
||||||
Layout->insertSpacing(1, qRound(1.5 * Layout->contentsMargins().left() / 2.0));
|
|
||||||
d->IconLabel->setVisible(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -451,7 +467,7 @@ void CDockWidgetTab::mouseDoubleClickEvent(QMouseEvent *event)
|
|||||||
if (!d->DockArea->dockContainer()->isFloating() || d->DockArea->dockWidgetsCount() > 1)
|
if (!d->DockArea->dockContainer()->isFloating() || d->DockArea->dockWidgetsCount() > 1)
|
||||||
{
|
{
|
||||||
d->DragStartMousePosition = event->pos();
|
d->DragStartMousePosition = event->pos();
|
||||||
d->startFloating();
|
d->startFloating(DraggingInactive);
|
||||||
}
|
}
|
||||||
|
|
||||||
Super::mouseDoubleClickEvent(event);
|
Super::mouseDoubleClickEvent(event);
|
||||||
@ -485,7 +501,7 @@ bool CDockWidgetTab::isClosable() const
|
|||||||
void CDockWidgetTab::onDetachActionTriggered()
|
void CDockWidgetTab::onDetachActionTriggered()
|
||||||
{
|
{
|
||||||
d->DragStartMousePosition = mapFromGlobal(QCursor::pos());
|
d->DragStartMousePosition = mapFromGlobal(QCursor::pos());
|
||||||
d->startFloating();
|
d->startFloating(DraggingInactive);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ads
|
} // namespace ads
|
||||||
|
@ -137,7 +137,8 @@ public:
|
|||||||
bool isClosable() const;
|
bool isClosable() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
virtual void setVisible(bool visible);
|
|
||||||
|
virtual void setVisible(bool visible) override;
|
||||||
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@ -46,7 +46,7 @@ class CElidingLabel : public QLabel
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
ElidingLabelPrivate* d;
|
ElidingLabelPrivate* d;
|
||||||
friend class ElidingLabelPrivate;
|
friend struct ElidingLabelPrivate;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void mouseReleaseEvent(QMouseEvent* event) override;
|
virtual void mouseReleaseEvent(QMouseEvent* event) override;
|
||||||
|
@ -50,16 +50,6 @@
|
|||||||
namespace ads
|
namespace ads
|
||||||
{
|
{
|
||||||
static unsigned int zOrderCounter = 0;
|
static unsigned int zOrderCounter = 0;
|
||||||
/**
|
|
||||||
* The different dragging states
|
|
||||||
*/
|
|
||||||
enum eDragState
|
|
||||||
{
|
|
||||||
StateInactive, //!< DraggingInactive
|
|
||||||
StateMousePressed, //!< DraggingMousePressed
|
|
||||||
StateDraggingActive//!< DraggingFloatingWidget
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private data class of CFloatingDockContainer class (pimpl)
|
* Private data class of CFloatingDockContainer class (pimpl)
|
||||||
*/
|
*/
|
||||||
@ -69,7 +59,7 @@ struct FloatingDockContainerPrivate
|
|||||||
CDockContainerWidget* DockContainer;
|
CDockContainerWidget* DockContainer;
|
||||||
unsigned int zOrderIndex = ++zOrderCounter;
|
unsigned int zOrderIndex = ++zOrderCounter;
|
||||||
QPointer<CDockManager> DockManager;
|
QPointer<CDockManager> DockManager;
|
||||||
eDragState DraggingState = StateInactive;
|
eDragState DraggingState = DraggingInactive;
|
||||||
QPoint DragStartMousePosition;
|
QPoint DragStartMousePosition;
|
||||||
CDockContainerWidget* DropContainer = nullptr;
|
CDockContainerWidget* DropContainer = nullptr;
|
||||||
CDockAreaWidget* SingleDockArea = nullptr;
|
CDockAreaWidget* SingleDockArea = nullptr;
|
||||||
@ -111,7 +101,7 @@ FloatingDockContainerPrivate::FloatingDockContainerPrivate(CFloatingDockContaine
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
void FloatingDockContainerPrivate::titleMouseReleaseEvent()
|
void FloatingDockContainerPrivate::titleMouseReleaseEvent()
|
||||||
{
|
{
|
||||||
setState(StateInactive);
|
setState(DraggingInactive);
|
||||||
if (!DropContainer)
|
if (!DropContainer)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -301,12 +291,12 @@ void CFloatingDockContainer::moveEvent(QMoveEvent *event)
|
|||||||
QWidget::moveEvent(event);
|
QWidget::moveEvent(event);
|
||||||
switch (d->DraggingState)
|
switch (d->DraggingState)
|
||||||
{
|
{
|
||||||
case StateMousePressed:
|
case DraggingMousePressed:
|
||||||
d->setState(StateDraggingActive);
|
d->setState(DraggingFloatingWidget);
|
||||||
d->updateDropOverlays(QCursor::pos());
|
d->updateDropOverlays(QCursor::pos());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case StateDraggingActive:
|
case DraggingFloatingWidget:
|
||||||
d->updateDropOverlays(QCursor::pos());
|
d->updateDropOverlays(QCursor::pos());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -319,7 +309,7 @@ void CFloatingDockContainer::moveEvent(QMoveEvent *event)
|
|||||||
void CFloatingDockContainer::closeEvent(QCloseEvent *event)
|
void CFloatingDockContainer::closeEvent(QCloseEvent *event)
|
||||||
{
|
{
|
||||||
qDebug() << "CFloatingDockContainer closeEvent";
|
qDebug() << "CFloatingDockContainer closeEvent";
|
||||||
d->setState(StateInactive);
|
d->setState(DraggingInactive);
|
||||||
|
|
||||||
if (isClosable())
|
if (isClosable())
|
||||||
{
|
{
|
||||||
@ -365,20 +355,20 @@ bool CFloatingDockContainer::event(QEvent *e)
|
|||||||
{
|
{
|
||||||
switch (d->DraggingState)
|
switch (d->DraggingState)
|
||||||
{
|
{
|
||||||
case StateInactive:
|
case DraggingInactive:
|
||||||
if (e->type() == QEvent::NonClientAreaMouseButtonPress && QGuiApplication::mouseButtons() == Qt::LeftButton)
|
if (e->type() == QEvent::NonClientAreaMouseButtonPress && QGuiApplication::mouseButtons() == Qt::LeftButton)
|
||||||
{
|
{
|
||||||
qDebug() << "FloatingWidget::event Event::NonClientAreaMouseButtonPress" << e->type();
|
qDebug() << "FloatingWidget::event Event::NonClientAreaMouseButtonPress" << e->type();
|
||||||
d->setState(StateMousePressed);
|
d->setState(DraggingMousePressed);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case StateMousePressed:
|
case DraggingMousePressed:
|
||||||
switch (e->type())
|
switch (e->type())
|
||||||
{
|
{
|
||||||
case QEvent::NonClientAreaMouseButtonDblClick:
|
case QEvent::NonClientAreaMouseButtonDblClick:
|
||||||
qDebug() << "FloatingWidget::event QEvent::NonClientAreaMouseButtonDblClick";
|
qDebug() << "FloatingWidget::event QEvent::NonClientAreaMouseButtonDblClick";
|
||||||
d->setState(StateInactive);
|
d->setState(DraggingInactive);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QEvent::Resize:
|
case QEvent::Resize:
|
||||||
@ -392,7 +382,7 @@ bool CFloatingDockContainer::event(QEvent *e)
|
|||||||
// change, we check, if we are not in maximized state.
|
// change, we check, if we are not in maximized state.
|
||||||
if (!isMaximized())
|
if (!isMaximized())
|
||||||
{
|
{
|
||||||
d->setState(StateInactive);
|
d->setState(DraggingInactive);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -401,7 +391,7 @@ bool CFloatingDockContainer::event(QEvent *e)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case StateDraggingActive:
|
case DraggingFloatingWidget:
|
||||||
if (e->type() == QEvent::NonClientAreaMouseButtonRelease)
|
if (e->type() == QEvent::NonClientAreaMouseButtonRelease)
|
||||||
{
|
{
|
||||||
qDebug() << "FloatingWidget::event QEvent::NonClientAreaMouseButtonRelease";
|
qDebug() << "FloatingWidget::event QEvent::NonClientAreaMouseButtonRelease";
|
||||||
@ -424,7 +414,7 @@ bool CFloatingDockContainer::event(QEvent *e)
|
|||||||
bool CFloatingDockContainer::eventFilter(QObject *watched, QEvent *event)
|
bool CFloatingDockContainer::eventFilter(QObject *watched, QEvent *event)
|
||||||
{
|
{
|
||||||
Q_UNUSED(watched);
|
Q_UNUSED(watched);
|
||||||
if (event->type() == QEvent::MouseButtonRelease && d->isState(StateDraggingActive))
|
if (event->type() == QEvent::MouseButtonRelease && d->isState(DraggingFloatingWidget))
|
||||||
{
|
{
|
||||||
qDebug() << "FloatingWidget::eventFilter QEvent::MouseButtonRelease";
|
qDebug() << "FloatingWidget::eventFilter QEvent::MouseButtonRelease";
|
||||||
d->titleMouseReleaseEvent();
|
d->titleMouseReleaseEvent();
|
||||||
@ -435,14 +425,15 @@ bool CFloatingDockContainer::eventFilter(QObject *watched, QEvent *event)
|
|||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
void CFloatingDockContainer::startFloating(const QPoint& Pos, const QSize& Size)
|
void CFloatingDockContainer::startFloating(const QPoint& DragStartMousePos, const QSize& Size,
|
||||||
|
eDragState DragState)
|
||||||
{
|
{
|
||||||
resize(Size);
|
resize(Size);
|
||||||
d->setState(StateDraggingActive);
|
d->setState(DragState);
|
||||||
QPoint TargetPos = QCursor::pos() - Pos;
|
d->DragStartMousePosition = DragStartMousePos;
|
||||||
move(TargetPos);
|
moveFloating();
|
||||||
show();
|
show();
|
||||||
d->DragStartMousePosition = Pos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,7 +81,25 @@ protected:
|
|||||||
* Use moveToGlobalPos() to move the widget to a new position
|
* Use moveToGlobalPos() to move the widget to a new position
|
||||||
* depending on the start position given in Pos parameter
|
* depending on the start position given in Pos parameter
|
||||||
*/
|
*/
|
||||||
void startFloating(const QPoint& Pos, const QSize& Size = QSize());
|
void startFloating(const QPoint& DragStartMousePos, const QSize& Size,
|
||||||
|
eDragState DragState);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call this function to start dragging the floating widget
|
||||||
|
*/
|
||||||
|
void startDragging(const QPoint& DragStartMousePos, const QSize& Size)
|
||||||
|
{
|
||||||
|
startFloating(DragStartMousePos, Size, DraggingFloatingWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call this function if you just want to initialize the position
|
||||||
|
* and size of the floating widget
|
||||||
|
*/
|
||||||
|
void initFloatingGeometry(const QPoint& DragStartMousePos, const QSize& Size)
|
||||||
|
{
|
||||||
|
startFloating(DragStartMousePos, Size, DraggingInactive);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves the widget to a new position relative to the position given when
|
* Moves the widget to a new position relative to the position given when
|
||||||
|
@ -40,16 +40,6 @@ namespace ads
|
|||||||
|
|
||||||
namespace internal
|
namespace internal
|
||||||
{
|
{
|
||||||
//============================================================================
|
|
||||||
QSplitter* newSplitter(Qt::Orientation orientation, QWidget* parent)
|
|
||||||
{
|
|
||||||
QSplitter* s = new CDockSplitter(orientation, parent);
|
|
||||||
s->setProperty("ads-splitter", QVariant(true));
|
|
||||||
s->setChildrenCollapsible(false);
|
|
||||||
s->setOpaqueResize(false);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
void replaceSplitterWidget(QSplitter* Splitter, QWidget* From, QWidget* To)
|
void replaceSplitterWidget(QSplitter* Splitter, QWidget* From, QWidget* To)
|
||||||
{
|
{
|
||||||
|
@ -33,12 +33,17 @@
|
|||||||
#include <QPair>
|
#include <QPair>
|
||||||
#include <QtCore/QtGlobal>
|
#include <QtCore/QtGlobal>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
#ifndef ADS_STATIC
|
||||||
#ifdef ADS_SHARED_EXPORT
|
#ifdef ADS_SHARED_EXPORT
|
||||||
#define ADS_EXPORT Q_DECL_EXPORT
|
#define ADS_EXPORT Q_DECL_EXPORT
|
||||||
#else
|
#else
|
||||||
#define ADS_EXPORT Q_DECL_IMPORT
|
#define ADS_EXPORT Q_DECL_IMPORT
|
||||||
#endif
|
#endif
|
||||||
|
#else
|
||||||
|
#define ADS_EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ADS_DEBUG_LEVEL 0
|
#define ADS_DEBUG_LEVEL 0
|
||||||
|
|
||||||
@ -71,14 +76,21 @@ enum TitleBarButton
|
|||||||
TitleBarButtonClose
|
TitleBarButtonClose
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The different dragging states
|
||||||
|
*/
|
||||||
|
enum eDragState
|
||||||
|
{
|
||||||
|
DraggingInactive, //!< DraggingInactive
|
||||||
|
DraggingMousePressed, //!< DraggingMousePressed
|
||||||
|
DraggingTab, //!< DraggingTab
|
||||||
|
DraggingFloatingWidget//!< DraggingFloatingWidget
|
||||||
|
};
|
||||||
|
|
||||||
namespace internal
|
namespace internal
|
||||||
{
|
{
|
||||||
|
static const bool RestoreTesting = true;
|
||||||
|
static const bool Restore = false;
|
||||||
/**
|
|
||||||
* Helper function to create new splitter widgets
|
|
||||||
*/
|
|
||||||
QSplitter* newSplitter(Qt::Orientation orientation, QWidget* parent = 0);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replace the from widget in the given splitter with the To widget
|
* Replace the from widget in the given splitter with the To widget
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
ADS_ROOT = $${PWD}/..
|
ADS_ROOT = $${PWD}/..
|
||||||
ADS_OUT_ROOT = $${OUT_PWD}/..
|
ADS_OUT_ROOT = $${OUT_PWD}/..
|
||||||
|
|
||||||
TARGET = $$qtLibraryTarget(AdvancedDockingSystem)
|
TARGET = $$qtLibraryTarget(qtadvanceddocking)
|
||||||
TEMPLATE = lib
|
TEMPLATE = lib
|
||||||
DESTDIR = $${ADS_OUT_ROOT}/lib
|
DESTDIR = $${ADS_OUT_ROOT}/lib
|
||||||
QT += core gui widgets
|
QT += core gui widgets
|
||||||
@ -28,6 +28,10 @@ windows {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unix {
|
||||||
|
CONFIG += c++11
|
||||||
|
}
|
||||||
|
|
||||||
RESOURCES += ads.qrc
|
RESOURCES += ads.qrc
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
|