Merge branch 'master' into feature

This commit is contained in:
Andreev Alexander 2019-01-16 18:28:09 +05:00 committed by GitHub
commit 1078387f5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
57 changed files with 923 additions and 286 deletions

View File

@ -71,6 +71,15 @@
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<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">
<buildTargets>
<target name="Build all" path=" build" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
@ -83,6 +92,7 @@
</target>
<target name="Clean" path=" build" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>clean</buildTarget>
<stopOnError>false</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
@ -99,7 +109,6 @@
<target name="qmake" path=" build" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>qmake</buildCommand>
<buildArguments>-recursive ../ads.pro</buildArguments>
<buildTarget/>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>false</runAllBuilders>
@ -122,7 +131,6 @@
</target>
<target name="Clean" path=" build/src" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>clean</buildTarget>
<stopOnError>false</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
@ -139,7 +147,6 @@
<target name="qmake" path=" build/src" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>qmake</buildCommand>
<buildArguments>-recursive ../../src/src.pro</buildArguments>
<buildTarget/>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>false</runAllBuilders>
@ -152,6 +159,46 @@
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>false</runAllBuilders>
</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">
<buildCommand>mingw32-make</buildCommand>
<buildArguments>-j</buildArguments>
@ -162,7 +209,6 @@
</target>
<target name="Clean" path=" build/demo" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>clean</buildTarget>
<stopOnError>false</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
@ -179,7 +225,6 @@
<target name="qmake" path=" build/demo" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>qmake</buildCommand>
<buildArguments>-recursive ../../demo/demo.pro</buildArguments>
<buildTarget/>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>false</runAllBuilders>
@ -202,6 +247,7 @@
</target>
<target name="Clean" path=" build/AdvancedDockingSystemDemo" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>clean</buildTarget>
<stopOnError>false</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
@ -240,6 +286,7 @@
</target>
<target name="Clean" path=" build/AdvancedDockingSystemDemo_v2" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>clean</buildTarget>
<stopOnError>false</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
@ -278,6 +325,7 @@
</target>
<target name="Clean" path=" build/AdvancedDockingSystem" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>clean</buildTarget>
<stopOnError>false</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
@ -294,7 +342,6 @@
<target name="qmake" path=" build/AdvancedDockingSystem" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>qmake</buildCommand>
<buildArguments>-recursive ../../AdvancedDockingSystem/src.pro</buildArguments>
<buildTarget/>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>false</runAllBuilders>
@ -309,13 +356,4 @@
</target>
</buildTargets>
</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>

8
.gitignore vendored
View File

@ -1,2 +1,10 @@
*.pro.user
/ build
*.o
*.dylib
*.app
qrc_*
moc_*
ui_*
Makefile

103
CMakeLists.txt Normal file
View 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()

View File

@ -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
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
### Docking everywhere - no central widget
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
free to dock almost everywhere.
![Layout of widgets](preview.png)
![Dropping widgets](preview-dragndrop.png)
![Dropping widgets](doc/preview-dragndrop.png)\
\
![Dropping widgets](doc/preview-dragndrop_dark.png)
### Docking inside floating windows
There is no difference between the main window and a floating window. Docking
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
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
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
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
main window layout.
![Perspective](perspectives.png)
![Perspective](doc/perspectives.png)\
\
![Perspective](doc/perspectives_dark.png)
## Tested Compatible Environments
- Windows 10
@ -52,6 +62,77 @@ main window layout.
Open the `ads.pro` with QtCreator and start the build, that's it.
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
- Uwe Kindler, Project Maintainer
- Manuel Freiholz

View File

@ -1,6 +1,9 @@
TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS = \
src \
demo
demo \
example
demo.depends = src
example.depends = src

48
demo/CMakeLists.txt Normal file
View 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"
)

View File

@ -57,7 +57,6 @@
#include "DockManager.h"
#include "DockWidget.h"
#include "DockAreaWidget.h"
#include "AnimatedLabel.h"
//============================================================================

View File

@ -9,15 +9,11 @@ CONFIG *= c++14
SOURCES += \
main.cpp \
MainWindow.cpp \
mhtabbar.cpp \
mhtabwidget.cpp
MainWindow.cpp
HEADERS += \
MainWindow.h \
mhtabbar.h \
mhtabwidget.h
MainWindow.h
FORMS += \
mainwindow.ui
@ -27,9 +23,9 @@ RESOURCES += main.qrc
LIBS += -L$${ADS_OUT_ROOT}/lib
# Dependency: AdvancedDockingSystem (shared)
win32:CONFIG(release, debug|release): LIBS += -lAdvancedDockingSystem
else:win32:CONFIG(debug, debug|release): LIBS += -lAdvancedDockingSystemd
else:unix: LIBS += -lAdvancedDockingSystem
win32:CONFIG(release, debug|release): LIBS += -lqtadvanceddocking
else:win32:CONFIG(debug, debug|release): LIBS += -lqtadvanceddockingd
else:unix: LIBS += -lqtadvanceddocking
INCLUDEPATH += ../src
DEPENDPATH += ../src

View File

@ -1,5 +1,3 @@
#include <windows.h>
#include <MainWindow.h>
#include <QString>
#include <QFile>
@ -38,7 +36,9 @@ void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QS
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#if QT_VERSION >= 0x050600
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
std::shared_ptr<int> b;
QApplication a(argc, argv);
a.setQuitOnLastWindowClosed(true);

View File

@ -1,7 +1,3 @@
<RCC>
<qresource prefix="/main">
<file>bricks.gif</file>
<file>bricks_orange.gif</file>
<file>bricks.apng</file>
</qresource>
<qresource prefix="/main"/>
</RCC>

BIN
doc/TabMenu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
doc/TabMenu_dark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

BIN
doc/grouped-dragging.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
doc/perspectives.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
doc/perspectives_dark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
doc/preview-dragndrop.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

BIN
doc/preview_dark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

46
example/CMakeLists.txt Normal file
View 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
View 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
View 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
View 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
View 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
View 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();
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

View File

@ -228,16 +228,17 @@ void CDockAreaTabBar::mouseDoubleClickEvent(QMouseEvent *event)
{
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();
CFloatingDockContainer* FloatingWidget = new CFloatingDockContainer(d->DockArea);
FloatingWidget->startFloating(Pos, Size);
FloatingWidget->startFloating(Offset, Size, DragState);
auto TopLevelDockWidget = FloatingWidget->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);
}

View File

@ -30,6 +30,7 @@
// INCLUDES
//============================================================================
#include <QScrollArea>
#include "ads_globals.h"
namespace ads
{
@ -49,7 +50,7 @@ class CDockAreaTabBar : public QScrollArea
Q_OBJECT
private:
DockAreaTabBarPrivate* d; ///< private data (pimpl)
friend class DockAreaTabBarPrivate;
friend struct DockAreaTabBarPrivate;
friend class CDockAreaTitleBar;
private slots:
@ -84,12 +85,13 @@ protected:
/**
* 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:

View File

@ -47,6 +47,7 @@
#include "DockWidgetTab.h"
#include "DockAreaTabBar.h"
#include <iostream>
namespace ads
{
@ -173,6 +174,10 @@ void DockAreaTitleBarPrivate::createTabBar()
_this->connect(TabBar, SIGNAL(tabMoved(int, int)), SLOT(markTabsMenuOutdated()));
_this->connect(TabBar, SIGNAL(currentChanged(int)), SLOT(onCurrentTabChanged(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()
{
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
//---------------------------------------------------------------------------

View File

@ -50,7 +50,7 @@ class CDockAreaTitleBar : public QFrame
Q_OBJECT
private:
DockAreaTitleBarPrivate* d; ///< private data (pimpl)
friend class DockAreaTitleBarPrivate;
friend struct DockAreaTitleBarPrivate;
private slots:
void markTabsMenuOutdated();
@ -59,6 +59,7 @@ private slots:
void onUndockButtonClicked();
void onTabsMenuActionTriggered(QAction* Action);
void onCurrentTabChanged(int Index);
void showContextMenu(const QPoint& pos);
public:
using Super = QFrame;

View File

@ -1,17 +1,17 @@
/*******************************************************************************
** 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/>.
******************************************************************************/
@ -61,9 +61,6 @@ namespace ads
{
static const char* const INDEX_PROPERTY = "index";
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
@ -690,13 +687,13 @@ void CDockAreaWidget::updateTitleBarVisibility()
//============================================================================
void CDockAreaWidget::saveState(QXmlStreamWriter& s) const
{
s.writeStartElement("DockAreaWidget");
s.writeStartElement("Area");
s.writeAttribute("Tabs", QString::number(d->ContentsLayout->count()));
auto CurrentDockWidget = currentDockWidget();
QString Name = CurrentDockWidget ? CurrentDockWidget->objectName() : "";
s.writeAttribute("CurrentDockWidget", Name);
s.writeAttribute("Current", Name);
qDebug() << "CDockAreaWidget::saveState TabCount: " << d->ContentsLayout->count()
<< " CurrentDockWidge: " << Name;
<< " Current: " << Name;
for (int i = 0; i < d->ContentsLayout->count(); ++i)
{
dockWidget(i)->saveState(s);
@ -779,6 +776,13 @@ void CDockAreaWidget::closeArea()
DockWidget->toggleView(false);
}
}
//============================================================================
void CDockAreaWidget::closeOtherAreas()
{
dockContainer()->closeOtherAreas(this);
}
} // namespace ads
//---------------------------------------------------------------------------

View File

@ -43,7 +43,7 @@ namespace ads
struct DockAreaWidgetPrivate;
class CDockManager;
class CDockContainerWidget;
struct DockContainerWidgetPrivate;
class DockContainerWidgetPrivate;
/**
@ -259,6 +259,11 @@ public slots:
*/
void closeArea();
/**
* This function closes all other areas except of this area
*/
void closeOtherAreas();
signals:
/**
* This signal is emitted when user clicks on a tab at an index.

View File

@ -44,12 +44,37 @@
#include "DockWidget.h"
#include "FloatingDockContainer.h"
#include "DockOverlay.h"
#include "DockStateSerialization.h"
#include "ads_globals.h"
#include "DockSplitter.h"
#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
{
@ -101,7 +126,7 @@ public:
unsigned int zOrderIndex = 0;
QList<CDockAreaWidget*> DockAreas;
QGridLayout* Layout = nullptr;
QSplitter* RootSplitter;
QSplitter* RootSplitter = nullptr;
bool isFloating = false;
CDockAreaWidget* LastAddedAreaCache[5]{0, 0, 0, 0, 0};
int VisibleDockAreaCount = -1;
@ -140,6 +165,12 @@ public:
void dropIntoSection(CFloatingDockContainer* FloatingWidget,
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
*/
@ -233,6 +264,18 @@ public:
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: ------------------------------------------------------------
void onDockAreaViewToggled(bool Visible)
{
@ -290,7 +333,7 @@ void DockContainerWidgetPrivate::dropIntoContainer(CFloatingDockContainer* Float
}
else if (Splitter->orientation() != InsertParam.orientation())
{
QSplitter* NewSplitter = internal::newSplitter(InsertParam.orientation());
QSplitter* NewSplitter = newSplitter(InsertParam.orientation());
QLayoutItem* li = Layout->replaceWidget(Splitter, NewSplitter);
NewSplitter->addWidget(Splitter);
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,
CDockAreaWidget* TargetArea, DockWidgetArea area)
{
CDockContainerWidget* FloatingContainer = FloatingWidget->dockContainer();
if (area == CenterDockWidgetArea)
// Dropping into center means all dock widgets in the dropped floating
// widget will become tabs of the drop area
if (CenterDockWidgetArea == area)
{
auto NewDockWidgets = FloatingContainer->dockWidgets();
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();
dropIntoCenterOfSection(FloatingWidget, TargetArea);
return;
}
@ -357,47 +430,72 @@ void DockContainerWidgetPrivate::dropIntoSection(CFloatingDockContainer* Floatin
if (!TargetAreaSplitter)
{
QSplitter* Splitter = internal::newSplitter(InsertParam.orientation());
QSplitter* Splitter = newSplitter(InsertParam.orientation());
Layout->replaceWidget(TargetArea, Splitter);
Splitter->addWidget(TargetArea);
TargetAreaSplitter = Splitter;
}
int AreaIndex = TargetAreaSplitter->indexOf(TargetArea);
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())
{
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)
{
TargetAreaSplitter->insertWidget(AreaIndex + InsertParam.insertOffset(), Widget);
}
else
{
AdjustSplitterSizes = (FloatingSplitter->count() == 1);
int InsertIndex = AreaIndex + InsertParam.insertOffset();
while (FloatingSplitter->count())
{
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
{
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)
{
NewSplitter->addWidget(Widget);
}
else
{
AdjustSplitterSizes = (FloatingSplitter->count() == 1);
while (FloatingSplitter->count())
{
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());
if (AdjustSplitterSizes)
{
int Size = TargetAreaSize / 2;
NewSplitter->setSizes({Size, Size});
}
TargetAreaSplitter->insertWidget(AreaIndex, NewSplitter);
TargetAreaSplitter->setSizes(Sizes);
}
FloatingWidget->deleteLater();
@ -455,7 +553,7 @@ void DockContainerWidgetPrivate::saveChildNodesState(QXmlStreamWriter& s, QWidge
if (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()));
qDebug() << "NodeSplitter orient: " << Splitter->orientation()
<< " WidgetCont: " << Splitter->count();
@ -488,8 +586,17 @@ bool DockContainerWidgetPrivate::restoreSplitter(QXmlStreamReader& s,
QWidget*& CreatedWidget, bool Testing)
{
bool Ok;
int Orientation = s.attributes().value("Orientation").toInt(&Ok);
if (!Ok)
QString OrientationStr = s.attributes().value("Orientation").toString();
int Orientation;
if (OrientationStr.startsWith("-"))
{
Orientation = Qt::Horizontal;
}
else if (OrientationStr.startsWith("|"))
{
Orientation = Qt::Vertical;
}
else
{
return false;
}
@ -504,7 +611,7 @@ bool DockContainerWidgetPrivate::restoreSplitter(QXmlStreamReader& s,
QSplitter* Splitter = nullptr;
if (!Testing)
{
Splitter = internal::newSplitter((Qt::Orientation)Orientation);
Splitter = newSplitter((Qt::Orientation)Orientation);
}
bool Visible = false;
QList<int> Sizes;
@ -516,7 +623,7 @@ bool DockContainerWidgetPrivate::restoreSplitter(QXmlStreamReader& s,
{
Result = restoreSplitter(s, ChildNode, Testing);
}
else if (s.name() == "DockAreaWidget")
else if (s.name() == "Area")
{
Result = restoreDockArea(s, ChildNode, Testing);
}
@ -593,8 +700,8 @@ bool DockContainerWidgetPrivate::restoreDockArea(QXmlStreamReader& s,
}
QString CurrentDockWidget = s.attributes().value("CurrentDockWidget").toString();
qDebug() << "Restore NodeDockArea Tabs: " << Tabs << " CurrentDockWidget: "
QString CurrentDockWidget = s.attributes().value("Current").toString();
qDebug() << "Restore NodeDockArea Tabs: " << Tabs << " Current: "
<< CurrentDockWidget;
CDockAreaWidget* DockArea = nullptr;
@ -605,12 +712,12 @@ bool DockContainerWidgetPrivate::restoreDockArea(QXmlStreamReader& s,
while (s.readNextStartElement())
{
if (s.name() != "DockWidget")
if (s.name() != "Widget")
{
continue;
}
auto ObjectName = s.attributes().value("ObjectName");
auto ObjectName = s.attributes().value("Name");
if (ObjectName.isEmpty())
{
return false;
@ -673,7 +780,7 @@ bool DockContainerWidgetPrivate::restoreChildNodes(QXmlStreamReader& s,
Result = restoreSplitter(s, CreatedWidget, Testing);
qDebug() << "Splitter";
}
else if (s.name() == "DockAreaWidget")
else if (s.name() == "Area")
{
Result = restoreDockArea(s, CreatedWidget, Testing);
qDebug() << "DockAreaWidget";
@ -720,7 +827,7 @@ void DockContainerWidgetPrivate::addDockArea(CDockAreaWidget* NewDockArea, DockW
}
else
{
QSplitter* NewSplitter = internal::newSplitter(InsertParam.orientation());
QSplitter* NewSplitter = newSplitter(InsertParam.orientation());
if (InsertParam.append())
{
QLayoutItem* li = Layout->replaceWidget(Splitter, NewSplitter);
@ -820,7 +927,7 @@ CDockAreaWidget* DockContainerWidgetPrivate::dockWidgetIntoDockArea(DockWidgetAr
else
{
qDebug() << "TargetAreaSplitter->orientation() != InsertParam.orientation()";
QSplitter* NewSplitter = internal::newSplitter(InsertParam.orientation());
QSplitter* NewSplitter = newSplitter(InsertParam.orientation());
NewSplitter->addWidget(TargetDockArea);
insertWidgetIntoSplitter(NewSplitter, NewDockArea, InsertParam.append());
TargetAreaSplitter->insertWidget(index, NewSplitter);
@ -837,20 +944,24 @@ CDockContainerWidget::CDockContainerWidget(CDockManager* DockManager, QWidget *p
QFrame(parent),
d(new DockContainerWidgetPrivate(this))
{
d->isFloating = floatingWidget() != nullptr;
d->DockManager = DockManager;
if (DockManager != this)
{
d->DockManager->registerDockContainer(this);
}
d->isFloating = floatingWidget() != nullptr;
d->Layout = new QGridLayout();
d->Layout->setContentsMargins(0, 1, 0, 1);
d->Layout->setSpacing(0);
setLayout(d->Layout);
d->RootSplitter = internal::newSplitter(Qt::Horizontal);
d->Layout->addWidget(d->RootSplitter);
// The function d->newSplitter() accesses the config flags from dock
// 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)
{
qDebug() << "Replacing splitter with content";
QSplitter* ParentSplitter = internal::findParent<QSplitter*>(Splitter);
auto Sizes = ParentSplitter->sizes();
QWidget* widget = Splitter->widget(0);
widget->setParent(this);
QSplitter* ParentSplitter = internal::findParent<QSplitter*>(Splitter);
internal::replaceSplitterWidget(ParentSplitter, Splitter, widget);
ParentSplitter->setSizes(Sizes);
}
delete Splitter;
@ -1131,13 +1244,17 @@ void CDockContainerWidget::saveState(QXmlStreamWriter& s) const
qDebug() << "CDockContainerWidget::saveState isFloating "
<< isFloating();
s.writeStartElement("DockContainerWidget");
s.writeStartElement("Container");
s.writeAttribute("Floating", QString::number(isFloating() ? 1 : 0));
if (isFloating())
{
CFloatingDockContainer* FloatingWidget = floatingWidget();
QByteArray Geometry = FloatingWidget->saveGeometry();
#if QT_VERSION < 0x050900
s.writeTextElement("Geometry", qByteArrayToHex(Geometry, ' '));
#else
s.writeTextElement("Geometry", Geometry.toHex(' '));
#endif
}
d->saveChildNodesState(s, d->RootSplitter);
s.writeEndElement();
@ -1193,7 +1310,7 @@ bool CDockContainerWidget::restoreState(QXmlStreamReader& s, bool Testing)
// and we need to create a new empty root splitter
if (!NewRootSplitter)
{
NewRootSplitter = internal::newSplitter(Qt::Horizontal);
NewRootSplitter = d->newSplitter(Qt::Horizontal);
}
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()
{
@ -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
#include "moc_DockContainerWidget.cpp"

View File

@ -57,7 +57,7 @@ class ADS_EXPORT CDockContainerWidget : public QFrame
Q_OBJECT
private:
DockContainerWidgetPrivate* d; ///< private data (pimpl)
friend struct DockContainerWidgetPrivate;
friend class DockContainerWidgetPrivate;
friend class CDockManager;
friend struct DockManagerPrivate;
friend class CDockAreaWidget;
@ -78,6 +78,11 @@ protected:
*/
QSplitter* rootSplitter() const;
/**
* Helper function for creation of the root splitter
*/
void createRootSplitter();
/**
* Drop floating widget into the container
*/
@ -228,6 +233,11 @@ public:
*/
CFloatingDockContainer* floatingWidget() const;
/**
* Call this function to close all dock areas except the KeepOpenArea
*/
void closeOtherAreas(CDockAreaWidget* KeepOpenArea);
signals:
/**
* This signal is emitted if one or multiple dock areas has been added to

View File

@ -51,7 +51,6 @@
#include "DockOverlay.h"
#include "DockWidget.h"
#include "ads_globals.h"
#include "DockStateSerialization.h"
#include "DockAreaWidget.h"
@ -217,12 +216,12 @@ bool DockManagerPrivate::restoreStateFromXml(const QByteArray &state, int versi
}
bool Result = true;
int DockContainers = s.attributes().value("DockContainers").toInt();
int DockContainers = s.attributes().value("Containers").toInt();
qDebug() << DockContainers;
int DockContainerCount = 0;
while (s.readNextStartElement())
{
if (s.name() == "DockContainerWidget")
if (s.name() == "Container")
{
Result = restoreContainer(DockContainerCount, s, Testing);
if (!Result)
@ -391,12 +390,12 @@ void DockManagerPrivate::addActionToMenu(QAction* Action, QMenu* Menu, bool Inse
}
//============================================================================
CDockManager::CDockManager(QWidget *parent) :
CDockContainerWidget(this, parent),
d(new DockManagerPrivate(this))
{
createRootSplitter();
QMainWindow* MainWindow = dynamic_cast<QMainWindow*>(parent);
if (MainWindow)
{
@ -498,7 +497,7 @@ QByteArray CDockManager::saveState(eXmlMode XmlMode, int version) const
s.writeStartDocument();
s.writeStartElement("QtAdvancedDockingSystem");
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)
{
Container->saveState(s);
@ -606,10 +605,7 @@ void CDockManager::addPerspective(const QString& UniquePrespectiveName)
//============================================================================
void CDockManager::removePerspective(const QString& Name)
{
if (d->Perspectives.remove(Name))
{
emit perspectiveListChanged();
}
removePerspectives({Name});
}
@ -624,6 +620,7 @@ void CDockManager::removePerspectives(const QStringList& Names)
if (Count)
{
emit perspectivesRemoved();
emit perspectiveListChanged();
}
}
@ -762,6 +759,7 @@ void CDockManager::setConfigFlags(const ConfigFlags Flags)
d->ConfigFlags = Flags;
}
} // namespace ads
//---------------------------------------------------------------------------

View File

@ -123,7 +123,8 @@ public:
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
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)
@ -330,6 +331,11 @@ signals:
*/
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
* the dock manager starts restoring the state.

View File

@ -168,7 +168,11 @@ struct DockOverlayCrossPrivate
QColor borderColor = iconColor(CDockOverlayCross::FrameColor);
QColor backgroundColor = iconColor(CDockOverlayCross::WindowBackgroundColor);
#if QT_VERSION >= 0x050600
double DevicePixelRatio = _this->window()->devicePixelRatioF();
#else
double DevicePixelRatio = _this->window()->devicePixelRatio();
#endif
QSizeF PixmapSize = size * DevicePixelRatio;
QPixmap pm(PixmapSize.toSize());
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(LeftDockWidgetArea, d->createDropIndicatorWidget(LeftDockWidgetArea, Mode));
areaWidgets.insert(CenterDockWidgetArea, d->createDropIndicatorWidget(CenterDockWidgetArea, Mode));
#if QT_VERSION >= 0x050600
d->LastDevicePixelRatio = devicePixelRatioF();
#else
d->LastDevicePixelRatio = devicePixelRatio();
#endif
setAreaWidgets(areaWidgets);
d->UpdateRequired = false;
}
@ -596,7 +603,11 @@ void CDockOverlayCross::updateOverlayIcons()
{
d->updateDropIndicatorIcon(Widget);
}
#if QT_VESION >= 0x050600
d->LastDevicePixelRatio = devicePixelRatioF();
#else
d->LastDevicePixelRatio = devicePixelRatio();
#endif
}

View File

@ -52,7 +52,8 @@ CDockSplitter::CDockSplitter(QWidget *parent)
: QSplitter(parent),
d(new DockSplitterPrivate(this))
{
setProperty("ads-splitter", true);
setChildrenCollapsible(false);
}

View File

@ -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"

View File

@ -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

View File

@ -47,7 +47,6 @@
#include "DockAreaWidget.h"
#include "DockManager.h"
#include "FloatingDockContainer.h"
#include "DockStateSerialization.h"
#include "DockSplitter.h"
#include "ads_globals.h"
@ -183,7 +182,7 @@ void DockWidgetPrivate::setupToolBar()
{
ToolBar = new QToolBar(_this);
ToolBar->setObjectName("dockWidgetToolBar");
Layout->addWidget(ToolBar);
Layout->insertWidget(0, ToolBar);
ToolBar->setIconSize(QSize(16, 16));
ToolBar->toggleViewAction()->setEnabled(false);
ToolBar->toggleViewAction()->setVisible(false);
@ -215,7 +214,7 @@ CDockWidget::CDockWidget(const QString &title, QWidget *parent) :
setObjectName(title);
d->TabWidget = new CDockWidgetTab(this);
d->ToggleViewAction = new QAction(title);
d->ToggleViewAction = new QAction(title, nullptr);
d->ToggleViewAction->setCheckable(true);
connect(d->ToggleViewAction, SIGNAL(triggered(bool)), this,
SLOT(toggleView(bool)));
@ -283,7 +282,18 @@ void CDockWidget::setFeatures(DockWidgetFeatures features)
//============================================================================
void CDockWidget::setFeature(DockWidgetFeature flag, bool on)
{
#if QT_VERSION >= 0x050700
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
{
s.writeStartElement("DockWidget");
s.writeAttribute("ObjectName", objectName());
s.writeStartElement("Widget");
s.writeAttribute("Name", objectName());
s.writeAttribute("Closed", QString::number(d->Closed ? 1 : 0));
s.writeEndElement();
}
@ -681,6 +691,7 @@ QSize CDockWidget::minimumSizeHint() const
return QSize(60, 40);
}
} // namespace ads
//---------------------------------------------------------------------------

View File

@ -44,7 +44,8 @@ class CDockWidgetTab;
class CDockManager;
class CDockContainerWidget;
class CDockAreaWidget;
struct DockContainerWidgetPrivate;
class DockContainerWidgetPrivate;
class CFloatingDockContainer;
/**
* The QDockWidget class provides a widget that can be docked inside a
@ -69,7 +70,7 @@ protected:
friend class CFloatingDockContainer;
friend class CDockManager;
friend struct DockManagerPrivate;
friend struct DockContainerWidgetPrivate;
friend class DockContainerWidgetPrivate;
friend class CDockAreaTabBar;
friend class CDockWidgetTab;
friend struct DockWidgetTabPrivate;

View File

@ -53,16 +53,6 @@
namespace ads
{
/**
* The different dragging states
*/
enum eDragState
{
DraggingInactive, //!< DraggingInactive
DraggingMousePressed, //!< DraggingMousePressed
DraggingTab, //!< DraggingTab
DraggingFloatingWidget//!< DraggingFloatingWidget
};
using tTabLabel = CElidingLabel;
using tCloseButton = QPushButton;
@ -74,7 +64,7 @@ struct DockWidgetTabPrivate
{
CDockWidgetTab* _this;
CDockWidget* DockWidget;
QLabel* IconLabel;
QLabel* IconLabel = nullptr;
tTabLabel* TitleLabel;
QPoint DragStartMousePosition;
bool IsActiveTab = false;
@ -123,7 +113,7 @@ struct DockWidgetTabPrivate
* Returns true, if floating has been started and false if floating
* is not possible for any reason
*/
bool startFloating();
bool startFloating(eDragState DraggingState = DraggingFloatingWidget);
/**
* 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();
qDebug() << "isFloating " << dockContainer->isFloating();
@ -214,7 +204,7 @@ bool DockWidgetTabPrivate::startFloating()
}
qDebug() << "startFloating";
DragState = DraggingFloatingWidget;
DragState = DraggingState;
QSize Size = DockArea->size();
CFloatingDockContainer* FloatingWidget = nullptr;
if (DockArea->dockWidgetsCount() > 1)
@ -229,11 +219,18 @@ bool DockWidgetTabPrivate::startFloating()
FloatingWidget = new CFloatingDockContainer(DockArea);
}
FloatingWidget->startFloating(DragStartMousePosition, Size);
auto Overlay = DockWidget->dockManager()->containerOverlay();
Overlay->setAllowedAreas(OuterDockAreas);
this->FloatingWidget = FloatingWidget;
DockWidget->emitTopLevelChanged(true);
if (DraggingFloatingWidget == DraggingState)
{
FloatingWidget->startDragging(DragStartMousePosition, Size);
auto Overlay = DockWidget->dockManager()->containerOverlay();
Overlay->setAllowedAreas(OuterDockAreas);
this->FloatingWidget = FloatingWidget;
}
else
{
FloatingWidget->initFloatingGeometry(DragStartMousePosition, Size);
}
DockWidget->emitTopLevelChanged(true);
return true;
}
@ -349,7 +346,6 @@ void CDockWidgetTab::mouseMoveEvent(QMouseEvent* ev)
void CDockWidgetTab::contextMenuEvent(QContextMenuEvent* ev)
{
ev->accept();
std::cout << "CDockAreaTabBar::onTabContextMenuRequested" << std::endl;
d->DragStartMousePosition = ev->pos();
QMenu Menu(this);
@ -416,15 +412,35 @@ CDockAreaWidget* CDockWidgetTab::dockAreaWidget() const
void CDockWidgetTab::setIcon(const QIcon& Icon)
{
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->IconLabel = new QLabel();
d->IconLabel->setAlignment(Qt::AlignVCenter);
d->IconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
d->IconLabel->setToolTip(d->TitleLabel->toolTip());
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);
if (d->IconLabel)
{
d->IconLabel->setPixmap(Icon.pixmap(this->windowHandle(), QSize(16, 16)));
d->IconLabel->setVisible(true);
}
}
@ -451,7 +467,7 @@ void CDockWidgetTab::mouseDoubleClickEvent(QMouseEvent *event)
if (!d->DockArea->dockContainer()->isFloating() || d->DockArea->dockWidgetsCount() > 1)
{
d->DragStartMousePosition = event->pos();
d->startFloating();
d->startFloating(DraggingInactive);
}
Super::mouseDoubleClickEvent(event);
@ -485,7 +501,7 @@ bool CDockWidgetTab::isClosable() const
void CDockWidgetTab::onDetachActionTriggered()
{
d->DragStartMousePosition = mapFromGlobal(QCursor::pos());
d->startFloating();
d->startFloating(DraggingInactive);
}
} // namespace ads

View File

@ -137,8 +137,9 @@ public:
bool isClosable() const;
public slots:
virtual void setVisible(bool visible);
virtual void setVisible(bool visible) override;
signals:
void activeTabChanged();

View File

@ -46,7 +46,7 @@ class CElidingLabel : public QLabel
Q_OBJECT
private:
ElidingLabelPrivate* d;
friend class ElidingLabelPrivate;
friend struct ElidingLabelPrivate;
protected:
virtual void mouseReleaseEvent(QMouseEvent* event) override;

View File

@ -50,16 +50,6 @@
namespace ads
{
static unsigned int zOrderCounter = 0;
/**
* The different dragging states
*/
enum eDragState
{
StateInactive, //!< DraggingInactive
StateMousePressed, //!< DraggingMousePressed
StateDraggingActive//!< DraggingFloatingWidget
};
/**
* Private data class of CFloatingDockContainer class (pimpl)
*/
@ -69,7 +59,7 @@ struct FloatingDockContainerPrivate
CDockContainerWidget* DockContainer;
unsigned int zOrderIndex = ++zOrderCounter;
QPointer<CDockManager> DockManager;
eDragState DraggingState = StateInactive;
eDragState DraggingState = DraggingInactive;
QPoint DragStartMousePosition;
CDockContainerWidget* DropContainer = nullptr;
CDockAreaWidget* SingleDockArea = nullptr;
@ -111,7 +101,7 @@ FloatingDockContainerPrivate::FloatingDockContainerPrivate(CFloatingDockContaine
//============================================================================
void FloatingDockContainerPrivate::titleMouseReleaseEvent()
{
setState(StateInactive);
setState(DraggingInactive);
if (!DropContainer)
{
return;
@ -301,12 +291,12 @@ void CFloatingDockContainer::moveEvent(QMoveEvent *event)
QWidget::moveEvent(event);
switch (d->DraggingState)
{
case StateMousePressed:
d->setState(StateDraggingActive);
case DraggingMousePressed:
d->setState(DraggingFloatingWidget);
d->updateDropOverlays(QCursor::pos());
break;
case StateDraggingActive:
case DraggingFloatingWidget:
d->updateDropOverlays(QCursor::pos());
break;
default:
@ -319,7 +309,7 @@ void CFloatingDockContainer::moveEvent(QMoveEvent *event)
void CFloatingDockContainer::closeEvent(QCloseEvent *event)
{
qDebug() << "CFloatingDockContainer closeEvent";
d->setState(StateInactive);
d->setState(DraggingInactive);
if (isClosable())
{
@ -365,20 +355,20 @@ bool CFloatingDockContainer::event(QEvent *e)
{
switch (d->DraggingState)
{
case StateInactive:
case DraggingInactive:
if (e->type() == QEvent::NonClientAreaMouseButtonPress && QGuiApplication::mouseButtons() == Qt::LeftButton)
{
qDebug() << "FloatingWidget::event Event::NonClientAreaMouseButtonPress" << e->type();
d->setState(StateMousePressed);
d->setState(DraggingMousePressed);
}
break;
case StateMousePressed:
case DraggingMousePressed:
switch (e->type())
{
case QEvent::NonClientAreaMouseButtonDblClick:
qDebug() << "FloatingWidget::event QEvent::NonClientAreaMouseButtonDblClick";
d->setState(StateInactive);
d->setState(DraggingInactive);
break;
case QEvent::Resize:
@ -392,7 +382,7 @@ bool CFloatingDockContainer::event(QEvent *e)
// change, we check, if we are not in maximized state.
if (!isMaximized())
{
d->setState(StateInactive);
d->setState(DraggingInactive);
}
break;
@ -401,7 +391,7 @@ bool CFloatingDockContainer::event(QEvent *e)
}
break;
case StateDraggingActive:
case DraggingFloatingWidget:
if (e->type() == QEvent::NonClientAreaMouseButtonRelease)
{
qDebug() << "FloatingWidget::event QEvent::NonClientAreaMouseButtonRelease";
@ -424,7 +414,7 @@ bool CFloatingDockContainer::event(QEvent *e)
bool CFloatingDockContainer::eventFilter(QObject *watched, QEvent *event)
{
Q_UNUSED(watched);
if (event->type() == QEvent::MouseButtonRelease && d->isState(StateDraggingActive))
if (event->type() == QEvent::MouseButtonRelease && d->isState(DraggingFloatingWidget))
{
qDebug() << "FloatingWidget::eventFilter QEvent::MouseButtonRelease";
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);
d->setState(StateDraggingActive);
QPoint TargetPos = QCursor::pos() - Pos;
move(TargetPos);
d->setState(DragState);
d->DragStartMousePosition = DragStartMousePos;
moveFloating();
show();
d->DragStartMousePosition = Pos;
}

View File

@ -81,7 +81,25 @@ protected:
* Use moveToGlobalPos() to move the widget to a new position
* 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

View File

@ -40,16 +40,6 @@ namespace ads
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)
{

View File

@ -33,12 +33,17 @@
#include <QPair>
#include <QtCore/QtGlobal>
#include <QPixmap>
#include <QWidget>
#ifndef ADS_STATIC
#ifdef ADS_SHARED_EXPORT
#define ADS_EXPORT Q_DECL_EXPORT
#else
#define ADS_EXPORT Q_DECL_IMPORT
#endif
#else
#define ADS_EXPORT
#endif
#define ADS_DEBUG_LEVEL 0
@ -71,14 +76,21 @@ enum TitleBarButton
TitleBarButtonClose
};
/**
* The different dragging states
*/
enum eDragState
{
DraggingInactive, //!< DraggingInactive
DraggingMousePressed, //!< DraggingMousePressed
DraggingTab, //!< DraggingTab
DraggingFloatingWidget//!< DraggingFloatingWidget
};
namespace internal
{
/**
* Helper function to create new splitter widgets
*/
QSplitter* newSplitter(Qt::Orientation orientation, QWidget* parent = 0);
static const bool RestoreTesting = true;
static const bool Restore = false;
/**
* Replace the from widget in the given splitter with the To widget

View File

@ -1,7 +1,7 @@
ADS_ROOT = $${PWD}/..
ADS_OUT_ROOT = $${OUT_PWD}/..
TARGET = $$qtLibraryTarget(AdvancedDockingSystem)
TARGET = $$qtLibraryTarget(qtadvanceddocking)
TEMPLATE = lib
DESTDIR = $${ADS_OUT_ROOT}/lib
QT += core gui widgets
@ -28,6 +28,10 @@ windows {
}
}
unix {
CONFIG += c++11
}
RESOURCES += ads.qrc
HEADERS += \