Compare commits

...

17 Commits
3.1.0 ... 3.2.0

Author SHA1 Message Date
Uwe Kindler
3407945f19 Merge branch 'master' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System 2020-02-17 10:42:02 +01:00
Uwe Kindler
ce01e6b4a6 Fixed QT_VESION typo in DockOverlay.cpp 2020-02-17 10:41:13 +01:00
Sanakan8472
3428a4b8b4 Added CDockManager::floatingWidgetCreated event (#121)
This allows to subscribe to events of the newly created window.
A common use case is to show a message box if a dock container with many modified documents in it is closed. This allows for the user to decide whether he wants to save / discard all the changes or cancel the closing of the window.
2020-02-17 08:15:11 +01:00
Uwe Kindler
2b9377b5ee Fixed drag canceling via ESC key 2020-02-17 08:08:25 +01:00
Uwe Kindler
d4a18003d9 Properly implemented handling of DockWidget flag DockWidgetIsMovable for NonOpaque undocking - creating the drag preview is allowed even if the DockWidget is not floatable 2020-02-16 14:37:14 +01:00
Uwe Kindler
2c15d5dacd Fixed regression caused by setDockArea() function removed from DockWidgetTab 2020-02-14 22:56:48 +01:00
Uwe Kindler
f236de3277 Replaced all dynamic_casts with qobject_casts 2020-02-13 18:56:04 +01:00
Uwe Kindler
93394577d0 Merge branch 'master' into custom_titlebar 2020-02-13 13:53:56 +01:00
Uwe Kindler
f387c6aebc Merge branch 'master' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System 2020-02-13 13:51:11 +01:00
Uwe Kindler
41173d067b Switched QScopedPointer to std::unique_ptr in DockComponentsFactory 2020-02-13 13:45:40 +01:00
Uwe Kindler
5b60e39ed3 Removed unneeded functions 2020-02-13 13:04:08 +01:00
Uwe Kindler
1916bd726d Fixed build issue for older Qt versions 2020-02-11 15:46:19 +01:00
Uwe Kindler
3efc5f2ada Added DockComponentsFactory.h documentation, changed DockComponentsFactory showcase in MainWindow after discussion on GitHub 2020-02-11 15:38:49 +01:00
Uwe Kindler
3eba02597c Added missing svg icon 2020-02-11 11:57:53 +01:00
Uwe Kindler
65eeffd5e1 Added showcase for DockComponentsFactory - a help button is injected into a title bar 2020-02-11 09:31:57 +01:00
Uwe Kindler
ff1439c719 Added CDockComponentsFactory for creation of components for the docking framework 2020-02-11 08:32:49 +01:00
mvidelgauz
7ba20f37b7 Icon of floating window (#116)
* FloatingContainerHasWidgetTitle and FloatingContainerHasWidgetIcon config flags
2020-02-10 20:07:36 +01:00
18 changed files with 350 additions and 73 deletions

View File

@@ -42,6 +42,7 @@ set(ads_SRCS
src/FloatingDockContainer.cpp src/FloatingDockContainer.cpp
src/FloatingDragPreview.cpp src/FloatingDragPreview.cpp
src/IconProvider.cpp src/IconProvider.cpp
src/DockComponentsFactory.cpp
src/ads.qrc src/ads.qrc
src/linux/FloatingWidgetTitleBar.cpp src/linux/FloatingWidgetTitleBar.cpp
) )
@@ -61,6 +62,7 @@ set(ads_INSTALL_INCLUDE
src/FloatingDockContainer.h src/FloatingDockContainer.h
src/FloatingDragPreview.h src/FloatingDragPreview.h
src/IconProvider.h src/IconProvider.h
src/DockComponentsFactory.h
src/linux/FloatingWidgetTitleBar.h src/linux/FloatingWidgetTitleBar.h
) )
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4") if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4")

View File

@@ -73,6 +73,8 @@
#include "DockAreaTitleBar.h" #include "DockAreaTitleBar.h"
#include "DockAreaTabBar.h" #include "DockAreaTabBar.h"
#include "FloatingDockContainer.h" #include "FloatingDockContainer.h"
#include "DockComponentsFactory.h"
//============================================================================ //============================================================================
@@ -142,6 +144,25 @@ static QIcon svgIcon(const QString& File)
} }
//============================================================================
class CCustomComponentsFactory : public ads::CDockComponentsFactory
{
public:
using Super = ads::CDockComponentsFactory;
ads::CDockAreaTitleBar* createDockAreaTitleBar(ads::CDockAreaWidget* DockArea) const override
{
auto TitleBar = new ads::CDockAreaTitleBar(DockArea);
auto CustomButton = new QToolButton(DockArea);
CustomButton->setToolTip(QObject::tr("Help"));
CustomButton->setIcon(svgIcon(":/adsdemo/images/help_outline.svg"));
CustomButton->setAutoRaise(true);
int Index = TitleBar->indexOf(TitleBar->button(ads::TitleBarButtonTabsMenu));
TitleBar->insertWidget(Index + 1, CustomButton);
return TitleBar;
}
};
//============================================================================ //============================================================================
static ads::CDockWidget* createCalendarDockWidget(QMenu* ViewMenu) static ads::CDockWidget* createCalendarDockWidget(QMenu* ViewMenu)
{ {
@@ -202,28 +223,29 @@ static ads::CDockWidget* createEditorWidget(QMenu* ViewMenu)
return DockWidget; return DockWidget;
} }
//============================================================================ //============================================================================
static ads::CDockWidget* createTableWidget(QMenu* ViewMenu) static ads::CDockWidget* createTableWidget(QMenu* ViewMenu)
{ {
static int TableCount = 0; static int TableCount = 0;
QTableWidget* w = new QTableWidget(); QTableWidget* w = new QTableWidget();
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Table %1").arg(TableCount++)); ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Table %1").arg(TableCount++));
static int colCount = 5; static int colCount = 5;
static int rowCount = 30; static int rowCount = 30;
w->setColumnCount(colCount); w->setColumnCount(colCount);
w->setRowCount(rowCount); w->setRowCount(rowCount);
for (int col = 0; col < colCount; ++col) for (int col = 0; col < colCount; ++col)
{ {
w->setHorizontalHeaderItem(col, new QTableWidgetItem(QString("Col %1").arg(col+1))); w->setHorizontalHeaderItem(col, new QTableWidgetItem(QString("Col %1").arg(col+1)));
for (int row = 0; row < rowCount; ++row) for (int row = 0; row < rowCount; ++row)
{ {
w->setItem(row, col, new QTableWidgetItem(QString("T %1-%2").arg(row + 1).arg(col+1))); w->setItem(row, col, new QTableWidgetItem(QString("T %1-%2").arg(row + 1).arg(col+1)));
} }
} }
DockWidget->setWidget(w); DockWidget->setWidget(w);
DockWidget->setIcon(svgIcon(":/adsdemo/images/grid_on.svg")); DockWidget->setIcon(svgIcon(":/adsdemo/images/grid_on.svg"));
ViewMenu->addAction(DockWidget->toggleViewAction()); ViewMenu->addAction(DockWidget->toggleViewAction());
return DockWidget; return DockWidget;
} }
@@ -309,6 +331,8 @@ void MainWindowPrivate::createContent()
auto ToolBar = FileSystemWidget->createDefaultToolBar(); auto ToolBar = FileSystemWidget->createDefaultToolBar();
ToolBar->addAction(ui.actionSaveState); ToolBar->addAction(ui.actionSaveState);
ToolBar->addAction(ui.actionRestoreState); ToolBar->addAction(ui.actionRestoreState);
FileSystemWidget->setFeature(ads::CDockWidget::DockWidgetFloatable, false);
appendFeaturStringToWindowTitle(FileSystemWidget);
DockManager->addDockWidget(ads::BottomDockWidgetArea, FileSystemWidget); DockManager->addDockWidget(ads::BottomDockWidgetArea, FileSystemWidget);
FileSystemWidget = createFileSystemTreeDockWidget(ViewMenu); FileSystemWidget = createFileSystemTreeDockWidget(ViewMenu);
@@ -318,9 +342,13 @@ void MainWindowPrivate::createContent()
FileSystemWidget->setFeature(ads::CDockWidget::DockWidgetMovable, false); FileSystemWidget->setFeature(ads::CDockWidget::DockWidgetMovable, false);
FileSystemWidget->setFeature(ads::CDockWidget::DockWidgetFloatable, false); FileSystemWidget->setFeature(ads::CDockWidget::DockWidgetFloatable, false);
appendFeaturStringToWindowTitle(FileSystemWidget); appendFeaturStringToWindowTitle(FileSystemWidget);
auto TopDockArea = DockManager->addDockWidget(ads::TopDockWidgetArea, FileSystemWidget);
// We create a calender widget and clear all flags to prevent the dock area // Test custom factory - we inject a help button into the title bar
ads::CDockComponentsFactory::setFactory(new CCustomComponentsFactory());
auto TopDockArea = DockManager->addDockWidget(ads::TopDockWidgetArea, FileSystemWidget);
ads::CDockComponentsFactory::resetDefaultFactory();
// We create a calendar widget and clear all flags to prevent the dock area
// from closing // from closing
DockWidget = createCalendarDockWidget(ViewMenu); DockWidget = createCalendarDockWidget(ViewMenu);
DockWidget->setFeature(ads::CDockWidget::DockWidgetClosable, false); DockWidget->setFeature(ads::CDockWidget::DockWidgetClosable, false);
@@ -458,9 +486,9 @@ CMainWindow::CMainWindow(QWidget *parent) :
// a QToolButton instead of a QPushButton // a QToolButton instead of a QPushButton
// CDockManager::setConfigFlags(CDockManager::configFlags() | CDockManager::TabCloseButtonIsToolButton); // CDockManager::setConfigFlags(CDockManager::configFlags() | CDockManager::TabCloseButtonIsToolButton);
// comment the following line if you want to use opaque undocking and // uncomment the following line if you want to use opaque undocking and
// opaque splitter resizing // opaque splitter resizing
CDockManager::setConfigFlags(CDockManager::DefaultNonOpaqueConfig); // CDockManager::setConfigFlags(CDockManager::DefaultOpaqueConfig);
// uncomment the following line if you want a fixed tab width that does // uncomment the following line if you want a fixed tab width that does
// not change if the visibility of the close button changes // not change if the visibility of the close button changes
@@ -481,6 +509,12 @@ CMainWindow::CMainWindow(QWidget *parent) :
// uncomment the following line if you want to show tabs menu button on DockArea's title bar only when there are more than one tab and at least of them has elided title // uncomment the following line if you want to show tabs menu button on DockArea's title bar only when there are more than one tab and at least of them has elided title
//CDockManager::setConfigFlag(CDockManager::DockAreaDynamicTabsMenuButtonVisibility, true); //CDockManager::setConfigFlag(CDockManager::DockAreaDynamicTabsMenuButtonVisibility, true);
// uncomment the following line if you want floating container to always show application title instead of active dock widget's title
//CDockManager::setConfigFlag(CDockManager::FloatingContainerHasWidgetTitle, false);
// uncomment the following line if you want floating container to show active dock widget's icon instead of always showing application icon
//CDockManager::setConfigFlag(CDockManager::FloatingContainerHasWidgetIcon, true);
// Now create the dock manager and its content // Now create the dock manager and its content
d->DockManager = new CDockManager(this); d->DockManager = new CDockManager(this);

View File

@@ -12,5 +12,6 @@
<file>images/custom-menu-button.svg</file> <file>images/custom-menu-button.svg</file>
<file>app.css</file> <file>app.css</file>
<file>images/plus.svg</file> <file>images/plus.svg</file>
<file>images/help_outline.svg</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@@ -0,0 +1,6 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,1024,1024">
<desc>help_outline icon - Licensed under Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0) - Created with Iconfu.com - Derivative work of Material icons (Copyright Google Inc.)</desc>
<g fill="#03b8e5" fill-rule="nonzero" style="mix-blend-mode: normal">
<path d="M938.67,512c0,235.52 -191.15,426.67 -426.67,426.67c-235.52,0 -426.67,-191.15 -426.67,-426.67c0,-235.52 191.15,-426.67 426.67,-426.67c235.52,0 426.67,191.15 426.67,426.67zM853.33,512c0,-188.16 -153.17,-341.33 -341.33,-341.33c-188.16,0 -341.33,153.17 -341.33,341.33c0,188.16 153.17,341.33 341.33,341.33c188.16,0 341.33,-153.17 341.33,-341.33zM682.67,426.67c0,106.67 -128,117.33 -128,213.33h-85.34c0,-138.67 128,-128 128,-213.33c0,-46.93 -38.4,-85.34 -85.33,-85.34c-46.93,0 -85.33,38.41 -85.33,85.34h-85.34c0,-94.29 76.38,-170.67 170.67,-170.67c94.29,0 170.67,76.38 170.67,170.67zM469.33,682.67h85.34v85.33h-85.34z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -49,6 +49,7 @@
#include "DockWidgetTab.h" #include "DockWidgetTab.h"
#include "DockAreaTabBar.h" #include "DockAreaTabBar.h"
#include "IconProvider.h" #include "IconProvider.h"
#include "DockComponentsFactory.h"
#include <iostream> #include <iostream>
@@ -234,7 +235,7 @@ void DockAreaTitleBarPrivate::createButtons()
#endif #endif
_this->connect(TabsMenu, SIGNAL(aboutToShow()), SLOT(onTabsMenuAboutToShow())); _this->connect(TabsMenu, SIGNAL(aboutToShow()), SLOT(onTabsMenuAboutToShow()));
TabsMenuButton->setMenu(TabsMenu); TabsMenuButton->setMenu(TabsMenu);
internal::setToolTip(TabsMenuButton, QObject::tr("List all tabs")); internal::setToolTip(TabsMenuButton, QObject::tr("List All Tabs"));
TabsMenuButton->setSizePolicy(ButtonSizePolicy); TabsMenuButton->setSizePolicy(ButtonSizePolicy);
Layout->addWidget(TabsMenuButton, 0); Layout->addWidget(TabsMenuButton, 0);
_this->connect(TabsMenuButton->menu(), SIGNAL(triggered(QAction*)), _this->connect(TabsMenuButton->menu(), SIGNAL(triggered(QAction*)),
@@ -273,7 +274,7 @@ void DockAreaTitleBarPrivate::createButtons()
//============================================================================ //============================================================================
void DockAreaTitleBarPrivate::createTabBar() void DockAreaTitleBarPrivate::createTabBar()
{ {
TabBar = new CDockAreaTabBar(DockArea); TabBar = componentsFactory()->createDockAreaTabBar(DockArea);
TabBar->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); TabBar->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
Layout->addWidget(TabBar); Layout->addWidget(TabBar);
_this->connect(TabBar, SIGNAL(tabClosed(int)), SLOT(markTabsMenuOutdated())); _this->connect(TabBar, SIGNAL(tabClosed(int)), SLOT(markTabsMenuOutdated()));
@@ -599,7 +600,11 @@ void CDockAreaTitleBar::mouseMoveEvent(QMouseEvent* ev)
// If one single dock widget in this area is not floatable then the whole // If one single dock widget in this area is not floatable then the whole
// area is not floatable // area is not floatable
if (!d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable)) // If we do non opaque undocking, then we can create the floating drag
// preview if the dock widget is movable
auto Features = d->DockArea->features();
if (!Features.testFlag(CDockWidget::DockWidgetFloatable)
&& !(Features.testFlag(CDockWidget::DockWidgetMovable) && !CDockManager::testConfigFlag(CDockManager::OpaqueUndocking)))
{ {
return; return;
} }

View File

@@ -28,9 +28,10 @@
//============================================================================ //============================================================================
// INCLUDES // INCLUDES
//============================================================================ //============================================================================
#include "DockWidgetTab.h"
#include "DockAreaWidget.h" #include "DockAreaWidget.h"
#include <iostream>
#include <QStackedLayout> #include <QStackedLayout>
#include <QScrollBar> #include <QScrollBar>
#include <QScrollArea> #include <QScrollArea>
@@ -53,8 +54,8 @@
#include "DockAreaTabBar.h" #include "DockAreaTabBar.h"
#include "DockSplitter.h" #include "DockSplitter.h"
#include "DockAreaTitleBar.h" #include "DockAreaTitleBar.h"
#include "DockComponentsFactory.h"
#include <iostream> #include "DockWidgetTab.h"
namespace ads namespace ads
@@ -262,7 +263,7 @@ struct DockAreaWidgetPrivate
*/ */
CDockWidget* dockWidgetAt(int index) CDockWidget* dockWidgetAt(int index)
{ {
return dynamic_cast<CDockWidget*>(ContentsLayout->widget(index)); return qobject_cast<CDockWidget*>(ContentsLayout->widget(index));
} }
/** /**
@@ -317,7 +318,7 @@ DockAreaWidgetPrivate::DockAreaWidgetPrivate(CDockAreaWidget* _public) :
//============================================================================ //============================================================================
void DockAreaWidgetPrivate::createTitleBar() void DockAreaWidgetPrivate::createTitleBar()
{ {
TitleBar = new CDockAreaTitleBar(_this); TitleBar = componentsFactory()->createDockAreaTitleBar(_this);
Layout->addWidget(TitleBar); Layout->addWidget(TitleBar);
QObject::connect(tabBar(), &CDockAreaTabBar::tabCloseRequested, _this, &CDockAreaWidget::onTabCloseRequested); QObject::connect(tabBar(), &CDockAreaTabBar::tabCloseRequested, _this, &CDockAreaWidget::onTabCloseRequested);
QObject::connect(TitleBar, &CDockAreaTitleBar::tabBarClicked, _this, &CDockAreaWidget::setCurrentIndex); QObject::connect(TitleBar, &CDockAreaTitleBar::tabBarClicked, _this, &CDockAreaWidget::setCurrentIndex);

View File

@@ -0,0 +1,69 @@
//============================================================================
/// \file DockComponentsFactory.cpp
/// \author Uwe Kindler
/// \date 10.02.2020
/// \brief Implementation of DockComponentsFactory
//============================================================================
//============================================================================
// INCLUDES
//============================================================================
#include <DockComponentsFactory.h>
#include <memory>
#include "DockWidgetTab.h"
#include "DockAreaTabBar.h"
#include "DockAreaTitleBar.h"
#include "DockWidget.h"
#include "DockAreaWidget.h"
namespace ads
{
static std::unique_ptr<CDockComponentsFactory> DefaultFactory(new CDockComponentsFactory());
//============================================================================
CDockWidgetTab* CDockComponentsFactory::createDockWidgetTab(CDockWidget* DockWidget) const
{
return new CDockWidgetTab(DockWidget);
}
//============================================================================
CDockAreaTabBar* CDockComponentsFactory::createDockAreaTabBar(CDockAreaWidget* DockArea) const
{
return new CDockAreaTabBar(DockArea);
}
//============================================================================
CDockAreaTitleBar* CDockComponentsFactory::createDockAreaTitleBar(CDockAreaWidget* DockArea) const
{
return new CDockAreaTitleBar(DockArea);
}
//============================================================================
const CDockComponentsFactory* CDockComponentsFactory::factory()
{
return DefaultFactory.get();
}
//============================================================================
void CDockComponentsFactory::setFactory(CDockComponentsFactory* Factory)
{
DefaultFactory.reset(Factory);
}
//============================================================================
void CDockComponentsFactory::resetDefaultFactory()
{
DefaultFactory.reset(new CDockComponentsFactory());
}
} // namespace ads
//---------------------------------------------------------------------------
// EOF DockComponentsFactory.cpp

View File

@@ -0,0 +1,90 @@
#ifndef DockComponentsFactoryH
#define DockComponentsFactoryH
//============================================================================
/// \file DockComponentsFactory.h
/// \author Uwe Kindler
/// \date 10.02.2020
/// \brief Declaration of DockComponentsFactory
//============================================================================
//============================================================================
// INCLUDES
//============================================================================
#include "ads_globals.h"
namespace ads
{
class CDockWidgetTab;
class CDockAreaTitleBar;
class CDockAreaTabBar;
class CDockAreaWidget;
class CDockWidget;
/**
* Factory for creation of certain GUI elements for the docking framework.
* A default unique instance provided by CDockComponentsFactory is used for
* creation of all supported components. To inject your custom components,
* you can create your own derived dock components factory and register
* it via setDefaultFactory() function.
* \code
* CDockComponentsFactory::setDefaultFactory(new MyComponentsFactory()));
* \endcode
*/
class ADS_EXPORT CDockComponentsFactory
{
public:
/**
* Force virtual destructor
*/
virtual ~CDockComponentsFactory() {}
/**
* This default implementation just creates a dock widget tab with
* new CDockWidgetTab(DockWIdget).
*/
virtual CDockWidgetTab* createDockWidgetTab(CDockWidget* DockWidget) const;
/**
* This default implementation just creates a dock area tab bar with
* new CDockAreaTabBar(DockArea).
*/
virtual CDockAreaTabBar* createDockAreaTabBar(CDockAreaWidget* DockArea) const;
/**
* This default implementation just creates a dock area title bar with
* new CDockAreaTitleBar(DockArea).
*/
virtual CDockAreaTitleBar* createDockAreaTitleBar(CDockAreaWidget* DockArea) const;
/**
* Returns the default components factory
*/
static const CDockComponentsFactory* factory();
/**
* Sets a new default factory for creation of GUI elements.
* This function takes ownership of the given Factory.
*/
static void setFactory(CDockComponentsFactory* Factory);
/**
* Resets the current factory to the
*/
static void resetDefaultFactory();
};
/**
* Convenience function to ease factory instance access
*/
inline const CDockComponentsFactory* componentsFactory()
{
return CDockComponentsFactory::factory();
}
} // namespace ads
//---------------------------------------------------------------------------
#endif // DockComponentsFactoryH

View File

@@ -736,7 +736,7 @@ void DockContainerWidgetPrivate::appendDockAreas(const QList<CDockAreaWidget*> N
//============================================================================ //============================================================================
void DockContainerWidgetPrivate::saveChildNodesState(QXmlStreamWriter& s, QWidget* Widget) void DockContainerWidgetPrivate::saveChildNodesState(QXmlStreamWriter& s, QWidget* Widget)
{ {
QSplitter* Splitter = dynamic_cast<QSplitter*>(Widget); QSplitter* Splitter = qobject_cast<QSplitter*>(Widget);
if (Splitter) if (Splitter)
{ {
s.writeStartElement("Splitter"); s.writeStartElement("Splitter");
@@ -759,7 +759,7 @@ void DockContainerWidgetPrivate::saveChildNodesState(QXmlStreamWriter& s, QWidge
} }
else else
{ {
CDockAreaWidget* DockArea = dynamic_cast<CDockAreaWidget*>(Widget); CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(Widget);
if (DockArea) if (DockArea)
{ {
DockArea->saveState(s); DockArea->saveState(s);
@@ -1046,7 +1046,7 @@ void DockContainerWidgetPrivate::addDockArea(CDockAreaWidget* NewDockArea, DockW
void DockContainerWidgetPrivate::dumpRecursive(int level, QWidget* widget) void DockContainerWidgetPrivate::dumpRecursive(int level, QWidget* widget)
{ {
#if defined(QT_DEBUG) #if defined(QT_DEBUG)
QSplitter* Splitter = dynamic_cast<QSplitter*>(widget); QSplitter* Splitter = qobject_cast<QSplitter*>(widget);
QByteArray buf; QByteArray buf;
buf.fill(' ', level * 4); buf.fill(' ', level * 4);
if (Splitter) if (Splitter)
@@ -1069,7 +1069,7 @@ void DockContainerWidgetPrivate::dumpRecursive(int level, QWidget* widget)
} }
else else
{ {
CDockAreaWidget* DockArea = dynamic_cast<CDockAreaWidget*>(widget); CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(widget);
if (!DockArea) if (!DockArea)
{ {
return; return;
@@ -1285,7 +1285,7 @@ void CDockContainerWidget::removeDockArea(CDockAreaWidget* area)
} }
QWidget* widget = Splitter->widget(0); QWidget* widget = Splitter->widget(0);
QSplitter* ChildSplitter = dynamic_cast<QSplitter*>(widget); QSplitter* ChildSplitter = qobject_cast<QSplitter*>(widget);
// If the one and only content widget of the splitter is not a splitter // If the one and only content widget of the splitter is not a splitter
// then we are finished // then we are finished
if (!ChildSplitter) if (!ChildSplitter)
@@ -1573,7 +1573,7 @@ bool CDockContainerWidget::restoreState(CDockingStateReader& s, bool Testing)
d->Layout->replaceWidget(d->RootSplitter, NewRootSplitter); d->Layout->replaceWidget(d->RootSplitter, NewRootSplitter);
QSplitter* OldRoot = d->RootSplitter; QSplitter* OldRoot = d->RootSplitter;
d->RootSplitter = dynamic_cast<QSplitter*>(NewRootSplitter); d->RootSplitter = qobject_cast<QSplitter*>(NewRootSplitter);
OldRoot->deleteLater(); OldRoot->deleteLater();
return true; return true;

View File

@@ -58,7 +58,7 @@
namespace ads namespace ads
{ {
static CDockManager::ConfigFlags StaticConfigFlags = CDockManager::DefaultOpaqueConfig; static CDockManager::ConfigFlags StaticConfigFlags = CDockManager::DefaultNonOpaqueConfig;
/** /**
* Private data class of CDockManager class (pimpl) * Private data class of CDockManager class (pimpl)
@@ -411,7 +411,7 @@ CDockManager::CDockManager(QWidget *parent) :
d(new DockManagerPrivate(this)) d(new DockManagerPrivate(this))
{ {
createRootSplitter(); createRootSplitter();
QMainWindow* MainWindow = dynamic_cast<QMainWindow*>(parent); QMainWindow* MainWindow = qobject_cast<QMainWindow*>(parent);
if (MainWindow) if (MainWindow)
{ {
MainWindow->setCentralWidget(this); MainWindow->setCentralWidget(this);
@@ -440,6 +440,7 @@ CDockManager::~CDockManager()
void CDockManager::registerFloatingWidget(CFloatingDockContainer* FloatingWidget) void CDockManager::registerFloatingWidget(CFloatingDockContainer* FloatingWidget)
{ {
d->FloatingWidgets.append(FloatingWidget); d->FloatingWidgets.append(FloatingWidget);
emit floatingWidgetCreated(FloatingWidget);
ADS_PRINT("d->FloatingWidgets.count() " << d->FloatingWidgets.count()); ADS_PRINT("d->FloatingWidgets.count() " << d->FloatingWidgets.count());
} }

View File

@@ -59,6 +59,7 @@ class CDockWidgetTab;
struct DockWidgetTabPrivate; struct DockWidgetTabPrivate;
struct DockAreaWidgetPrivate; struct DockAreaWidgetPrivate;
class CIconProvider; class CIconProvider;
class CDockComponentsFactory;
/** /**
* The central dock manager that maintains the complete docking system. * The central dock manager that maintains the complete docking system.
@@ -162,6 +163,8 @@ public:
DockAreaHasTabsMenuButton = 0x8000, //!< If the flag is set each dock area has a tabs menu button DockAreaHasTabsMenuButton = 0x8000, //!< If the flag is set each dock area has a tabs menu button
DockAreaHideDisabledButtons = 0x10000, //!< If the flag is set disabled dock area buttons will not appear on the tollbar at all (enabling them will bring them back) DockAreaHideDisabledButtons = 0x10000, //!< If the flag is set disabled dock area buttons will not appear on the tollbar at all (enabling them will bring them back)
DockAreaDynamicTabsMenuButtonVisibility = 0x20000, //!< If the flag is set dock area will disable a tabs menu button when there is only one tab in the area DockAreaDynamicTabsMenuButtonVisibility = 0x20000, //!< If the flag is set dock area will disable a tabs menu button when there is only one tab in the area
FloatingContainerHasWidgetTitle = 0x40000,
FloatingContainerHasWidgetIcon = 0x80000,
DefaultDockAreaButtons = DockAreaHasCloseButton DefaultDockAreaButtons = DockAreaHasCloseButton
@@ -170,7 +173,8 @@ public:
DefaultBaseConfig = DefaultDockAreaButtons DefaultBaseConfig = DefaultDockAreaButtons
| ActiveTabHasCloseButton | ActiveTabHasCloseButton
| XmlCompressionEnabled,///< default base configuration settings | XmlCompressionEnabled
| FloatingContainerHasWidgetTitle,///< default base configuration settings
DefaultOpaqueConfig = DefaultBaseConfig DefaultOpaqueConfig = DefaultBaseConfig
| OpaqueSplitterResize | OpaqueSplitterResize
@@ -446,10 +450,17 @@ signals:
/** /**
* This signal is emitted if the dock manager finished opening a * This signal is emitted if the dock manager finished opening a
* perspective * perspective.
*/ */
void perspectiveOpened(const QString& PerspectiveName); void perspectiveOpened(const QString& PerspectiveName);
/**
* This signal is emitted, if a new floating widget has been created.
* An application can use this signal to e.g. subscribe to events of
* the newly created window.
*/
void floatingWidgetCreated(CFloatingDockContainer* FloatingWidget);
/** /**
* This signal is emitted, if a new DockArea has been created. * This signal is emitted, if a new DockArea has been created.
* An application can use this signal to set custom icons or custom * An application can use this signal to set custom icons or custom

View File

@@ -380,7 +380,7 @@ DockWidgetArea CDockOverlay::dropAreaUnderCursor() const
return Result; return Result;
} }
CDockAreaWidget* DockArea = dynamic_cast<CDockAreaWidget*>(d->TargetWidget.data()); CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(d->TargetWidget.data());
if (!DockArea) if (!DockArea)
{ {
return Result; return Result;
@@ -632,7 +632,7 @@ void CDockOverlayCross::updateOverlayIcons()
{ {
d->updateDropIndicatorIcon(Widget); d->updateDropIndicatorIcon(Widget);
} }
#if QT_VESION >= 0x050600 #if QT_VERSION >= 0x050600
d->LastDevicePixelRatio = devicePixelRatioF(); d->LastDevicePixelRatio = devicePixelRatioF();
#else #else
d->LastDevicePixelRatio = devicePixelRatio(); d->LastDevicePixelRatio = devicePixelRatio();

View File

@@ -54,6 +54,7 @@
#include "DockManager.h" #include "DockManager.h"
#include "FloatingDockContainer.h" #include "FloatingDockContainer.h"
#include "DockSplitter.h" #include "DockSplitter.h"
#include "DockComponentsFactory.h"
#include "ads_globals.h" #include "ads_globals.h"
@@ -220,7 +221,7 @@ CDockWidget::CDockWidget(const QString &title, QWidget *parent) :
setWindowTitle(title); setWindowTitle(title);
setObjectName(title); setObjectName(title);
d->TabWidget = new CDockWidgetTab(this); d->TabWidget = componentsFactory()->createDockWidgetTab(this);
d->ToggleViewAction = new QAction(title, this); d->ToggleViewAction = new QAction(title, this);
d->ToggleViewAction->setCheckable(true); d->ToggleViewAction->setCheckable(true);
connect(d->ToggleViewAction, SIGNAL(triggered(bool)), this, connect(d->ToggleViewAction, SIGNAL(triggered(bool)), this,

View File

@@ -368,8 +368,13 @@ void CDockWidgetTab::mouseMoveEvent(QMouseEvent* ev)
return; return;
} }
// Floating is only allowed for widgets that are movable
if (d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable)) // Floating is only allowed for widgets that are floatable
// If we do non opaque undocking, then can create the drag preview
// if the widget is movable.
auto Features = d->DockWidget->features();
if (Features.testFlag(CDockWidget::DockWidgetFloatable)
|| (Features.testFlag(CDockWidget::DockWidgetMovable) && !CDockManager::testConfigFlag(CDockManager::OpaqueUndocking)))
{ {
// If we undock, we need to restore the initial position of this // If we undock, we need to restore the initial position of this
// tab because it looks strange if it remains on its dragged position // tab because it looks strange if it remains on its dragged position

View File

@@ -94,11 +94,6 @@ public:
*/ */
void setActiveTab(bool active); void setActiveTab(bool active);
/**
* Returns the dock widget this title widget belongs to
*/
CDockWidget* dockWidget() const;
/** /**
* Sets the dock area widget the dockWidget returned by dockWidget() * Sets the dock area widget the dockWidget returned by dockWidget()
* function belongs to. * function belongs to.
@@ -112,6 +107,11 @@ public:
*/ */
CDockAreaWidget* dockAreaWidget() const; CDockAreaWidget* dockAreaWidget() const;
/**
* Returns the dock widget this title widget belongs to
*/
CDockWidget* dockWidget() const;
/** /**
* Sets the icon to show in title bar * Sets the icon to show in title bar
*/ */

View File

@@ -79,6 +79,14 @@ struct FloatingDockContainerPrivate
void titleMouseReleaseEvent(); void titleMouseReleaseEvent();
void updateDropOverlays(const QPoint &GlobalPos); void updateDropOverlays(const QPoint &GlobalPos);
/**
* Returns true if the given config flag is set
*/
static bool testConfigFlag(CDockManager::eConfigFlag Flag)
{
return CDockManager::configFlags().testFlag(Flag);
}
/** /**
* Tests is a certain state is active * Tests is a certain state is active
*/ */
@@ -100,6 +108,31 @@ struct FloatingDockContainerPrivate
_this->setWindowTitle(Text); _this->setWindowTitle(Text);
#endif #endif
} }
void reflectCurrentWidget(CDockWidget* CurrentWidget)
{
// reflect CurrentWidget's title if configured to do so, otherwise display application name as window title
if (testConfigFlag(CDockManager::FloatingContainerHasWidgetTitle))
{
setWindowTitle(CurrentWidget->windowTitle());
}
else
{
setWindowTitle(qApp->applicationDisplayName());
}
// reflect CurrentWidget's icon if configured to do so, otherwise display application icon as window icon
QIcon CurrentWidgetIcon = CurrentWidget->icon();
if (testConfigFlag(CDockManager::FloatingContainerHasWidgetIcon)
&& !CurrentWidgetIcon.isNull())
{
_this->setWindowIcon(CurrentWidget->icon());
}
else
{
_this->setWindowIcon(QApplication::windowIcon());
}
}
}; };
// struct FloatingDockContainerPrivate // struct FloatingDockContainerPrivate
@@ -537,8 +570,8 @@ void CFloatingDockContainer::onDockAreasAddedOrRemoved()
if (TopLevelDockArea) if (TopLevelDockArea)
{ {
d->SingleDockArea = TopLevelDockArea; d->SingleDockArea = TopLevelDockArea;
d->setWindowTitle( CDockWidget* CurrentWidget = d->SingleDockArea->currentDockWidget();
d->SingleDockArea->currentDockWidget()->windowTitle()); d->reflectCurrentWidget(CurrentWidget);
connect(d->SingleDockArea, SIGNAL(currentChanged(int)), this, connect(d->SingleDockArea, SIGNAL(currentChanged(int)), this,
SLOT(onDockAreaCurrentChanged(int))); SLOT(onDockAreaCurrentChanged(int)));
} }
@@ -551,6 +584,7 @@ void CFloatingDockContainer::onDockAreasAddedOrRemoved()
d->SingleDockArea = nullptr; d->SingleDockArea = nullptr;
} }
d->setWindowTitle(qApp->applicationDisplayName()); d->setWindowTitle(qApp->applicationDisplayName());
setWindowIcon(QApplication::windowIcon());
} }
} }
@@ -560,11 +594,13 @@ void CFloatingDockContainer::updateWindowTitle()
auto TopLevelDockArea = d->DockContainer->topLevelDockArea(); auto TopLevelDockArea = d->DockContainer->topLevelDockArea();
if (TopLevelDockArea) if (TopLevelDockArea)
{ {
d->setWindowTitle(TopLevelDockArea->currentDockWidget()->windowTitle()); CDockWidget* CurrentWidget = TopLevelDockArea->currentDockWidget();
d->reflectCurrentWidget(CurrentWidget);
} }
else else
{ {
d->setWindowTitle(qApp->applicationDisplayName()); d->setWindowTitle(qApp->applicationDisplayName());
setWindowIcon(QApplication::windowIcon());
} }
} }
@@ -572,7 +608,8 @@ void CFloatingDockContainer::updateWindowTitle()
void CFloatingDockContainer::onDockAreaCurrentChanged(int Index) void CFloatingDockContainer::onDockAreaCurrentChanged(int Index)
{ {
Q_UNUSED(Index); Q_UNUSED(Index);
d->setWindowTitle(d->SingleDockArea->currentDockWidget()->windowTitle()); CDockWidget* CurrentWidget = d->SingleDockArea->currentDockWidget();
d->reflectCurrentWidget(CurrentWidget);
} }
//============================================================================ //============================================================================

View File

@@ -206,10 +206,6 @@ CFloatingDragPreview::CFloatingDragPreview(QWidget* Content, QWidget* parent) :
connect(qApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)), connect(qApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)),
SLOT(onApplicationStateChanged(Qt::ApplicationState))); SLOT(onApplicationStateChanged(Qt::ApplicationState)));
// We need to install an event filter for the given Content
// widget to receive the escape key press
Content->installEventFilter(this);
} }
@@ -224,6 +220,10 @@ CFloatingDragPreview::CFloatingDragPreview(CDockWidget* Content)
d->ContenSourceContainer = Content->dockContainer(); d->ContenSourceContainer = Content->dockContainer();
} }
setWindowTitle(Content->windowTitle()); setWindowTitle(Content->windowTitle());
// We need to install an event filter for the given Content
// widget to receive the escape key press
Content->dockAreaWidget()->installEventFilter(this);
} }
@@ -235,6 +235,10 @@ CFloatingDragPreview::CFloatingDragPreview(CDockAreaWidget* Content)
d->ContentSourceArea = Content; d->ContentSourceArea = Content;
d->ContenSourceContainer = Content->dockContainer(); d->ContenSourceContainer = Content->dockContainer();
setWindowTitle(Content->currentDockWidget()->windowTitle()); setWindowTitle(Content->currentDockWidget()->windowTitle());
// We need to install an event filter for the given Content
// widget to receive the escape key press
Content->installEventFilter(this);
} }
@@ -291,25 +295,33 @@ void CFloatingDragPreview::finishDragging()
else else
{ {
CDockWidget* DockWidget = qobject_cast<CDockWidget*>(d->Content); CDockWidget* DockWidget = qobject_cast<CDockWidget*>(d->Content);
CFloatingDockContainer* FloatingWidget; CFloatingDockContainer* FloatingWidget = nullptr;
if (DockWidget)
if (DockWidget && DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable))
{ {
FloatingWidget = new CFloatingDockContainer(DockWidget); FloatingWidget = new CFloatingDockContainer(DockWidget);
} }
else else
{ {
CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(d->Content); CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(d->Content);
FloatingWidget = new CFloatingDockContainer(DockArea); if (DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
{
FloatingWidget = new CFloatingDockContainer(DockArea);
}
} }
FloatingWidget->setGeometry(this->geometry());
FloatingWidget->show(); if (FloatingWidget)
if (!CDockManager::configFlags().testFlag(CDockManager::DragPreviewHasWindowFrame))
{ {
QApplication::processEvents(); FloatingWidget->setGeometry(this->geometry());
int FrameHeight = FloatingWidget->frameGeometry().height() - FloatingWidget->geometry().height(); FloatingWidget->show();
QRect FixedGeometry = this->geometry(); if (!CDockManager::configFlags().testFlag(CDockManager::DragPreviewHasWindowFrame))
FixedGeometry.adjust(0, FrameHeight, 0, 0); {
FloatingWidget->setGeometry(FixedGeometry); QApplication::processEvents();
int FrameHeight = FloatingWidget->frameGeometry().height() - FloatingWidget->geometry().height();
QRect FixedGeometry = this->geometry();
FixedGeometry.adjust(0, FrameHeight, 0, 0);
FloatingWidget->setGeometry(FixedGeometry);
}
} }
} }
@@ -373,7 +385,7 @@ bool CFloatingDragPreview::eventFilter(QObject *watched, QEvent *event)
QKeyEvent* e = static_cast<QKeyEvent*>(event); QKeyEvent* e = static_cast<QKeyEvent*>(event);
if (e->key() == Qt::Key_Escape) if (e->key() == Qt::Key_Escape)
{ {
d->Content->removeEventFilter(this); watched->removeEventFilter(this);
d->cancelDragging(); d->cancelDragging();
} }
} }

View File

@@ -43,7 +43,8 @@ HEADERS += \
DockSplitter.h \ DockSplitter.h \
DockAreaTitleBar.h \ DockAreaTitleBar.h \
ElidingLabel.h \ ElidingLabel.h \
IconProvider.h IconProvider.h \
DockComponentsFactory.h
SOURCES += \ SOURCES += \
@@ -61,7 +62,8 @@ SOURCES += \
DockSplitter.cpp \ DockSplitter.cpp \
DockAreaTitleBar.cpp \ DockAreaTitleBar.cpp \
ElidingLabel.cpp \ ElidingLabel.cpp \
IconProvider.cpp IconProvider.cpp \
DockComponentsFactory.cpp
unix { unix {