Merge branch 'master' into feature
68
.cproject
@ -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
@ -1,2 +1,10 @@
|
||||
*.pro.user
|
||||
/ 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
|
||||
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
|
||||
|
7
ads.pro
@ -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
@ -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 "DockWidget.h"
|
||||
#include "DockAreaWidget.h"
|
||||
#include "AnimatedLabel.h"
|
||||
|
||||
|
||||
//============================================================================
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -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.
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
@ -52,7 +52,8 @@ CDockSplitter::CDockSplitter(QWidget *parent)
|
||||
: QSplitter(parent),
|
||||
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 "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
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -137,7 +137,8 @@ public:
|
||||
bool isClosable() const;
|
||||
|
||||
public slots:
|
||||
virtual void setVisible(bool visible);
|
||||
|
||||
virtual void setVisible(bool visible) override;
|
||||
|
||||
|
||||
signals:
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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 += \
|
||||
|