mirror of
https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git
synced 2025-01-14 00:52:05 +08:00
Implemented initial support for floating widgets
This commit is contained in:
parent
b31c5f1f3d
commit
2c9ceb8645
@ -229,6 +229,26 @@ void FloatingWidget::onCloseButtonClicked()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FloatingWidget::setDraggingActive(bool Active)
|
||||||
|
{
|
||||||
|
if (m_DraggingActive == Active)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_DraggingActive = Active;
|
||||||
|
if (Active)
|
||||||
|
{
|
||||||
|
std::cout << "FloatingWidget:: InstallEventFilter" << std::endl;
|
||||||
|
qApp->installEventFilter(this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "FloatingWidget:: RemoveEventFilter" << std::endl;
|
||||||
|
qApp->removeEventFilter(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FloatingWidget::changeEvent(QEvent *event)
|
void FloatingWidget::changeEvent(QEvent *event)
|
||||||
{
|
{
|
||||||
QWidget::changeEvent(event);
|
QWidget::changeEvent(event);
|
||||||
@ -251,28 +271,6 @@ void FloatingWidget::moveEvent(QMoveEvent *event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FloatingWidget::setDraggingActive(bool Active)
|
|
||||||
{
|
|
||||||
if (m_DraggingActive == Active)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_DraggingActive = Active;
|
|
||||||
if (Active)
|
|
||||||
{
|
|
||||||
std::cout << "FloatingWidget:: InstallEventFilter" << std::endl;
|
|
||||||
qApp->installEventFilter(this);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << "FloatingWidget:: RemoveEventFilter" << std::endl;
|
|
||||||
qApp->removeEventFilter(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool FloatingWidget::event(QEvent *e)
|
bool FloatingWidget::event(QEvent *e)
|
||||||
{
|
{
|
||||||
if ((e->type() == QEvent::NonClientAreaMouseButtonPress))
|
if ((e->type() == QEvent::NonClientAreaMouseButtonPress))
|
||||||
|
@ -98,6 +98,7 @@ struct DockAreaWidgetPrivate
|
|||||||
QPushButton* TabsMenuButton;
|
QPushButton* TabsMenuButton;
|
||||||
QPushButton* CloseButton;
|
QPushButton* CloseButton;
|
||||||
int TabsLayoutInitCount;
|
int TabsLayoutInitCount;
|
||||||
|
CDockManager* DockManager = nullptr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private data constructor
|
* Private data constructor
|
||||||
@ -127,8 +128,11 @@ struct DockAreaWidgetPrivate
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a tabs menu entry for the given dock widget
|
* Adds a tabs menu entry for the given dock widget
|
||||||
|
* If menu is 0, a menu entry is added to the menu of the TabsMenuButton
|
||||||
|
* member. If menu is a valid menu pointer, the entry will be added to
|
||||||
|
* the given menu
|
||||||
*/
|
*/
|
||||||
void addTabsMenuEntry(CDockWidget* DockWidget);
|
void addTabsMenuEntry(CDockWidget* DockWidget, QMenu* menu = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the tab action of the given dock widget
|
* Returns the tab action of the given dock widget
|
||||||
@ -145,6 +149,12 @@ struct DockAreaWidgetPrivate
|
|||||||
{
|
{
|
||||||
return DockWidget->property(INDEX_PROPERTY).toInt();
|
return DockWidget->property(INDEX_PROPERTY).toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the tabs menu if dock widget order changed or if dock widget has
|
||||||
|
* been removed
|
||||||
|
*/
|
||||||
|
void updateTabsMenu();
|
||||||
};
|
};
|
||||||
// struct DockAreaWidgetPrivate
|
// struct DockAreaWidgetPrivate
|
||||||
|
|
||||||
@ -202,19 +212,35 @@ void DockAreaWidgetPrivate::createTabBar()
|
|||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
void DockAreaWidgetPrivate::addTabsMenuEntry(CDockWidget* DockWidget)
|
void DockAreaWidgetPrivate::addTabsMenuEntry(CDockWidget* DockWidget,
|
||||||
|
QMenu* menu)
|
||||||
{
|
{
|
||||||
auto Action = TabsMenuButton->menu()->addAction(DockWidget->windowTitle());
|
menu = menu ? menu : TabsMenuButton->menu();
|
||||||
|
auto Action = menu->addAction(DockWidget->windowTitle());
|
||||||
QVariant vAction = QVariant::fromValue(Action);
|
QVariant vAction = QVariant::fromValue(Action);
|
||||||
DockWidget->setProperty(ACTION_PROPERTY, vAction);
|
DockWidget->setProperty(ACTION_PROPERTY, vAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void DockAreaWidgetPrivate::updateTabsMenu()
|
||||||
|
{
|
||||||
|
QMenu* menu = TabsMenuButton->menu();
|
||||||
|
menu->clear();
|
||||||
|
for (int i = 0; i < ContentsLayout->count(); ++i)
|
||||||
|
{
|
||||||
|
CDockWidget* DockWidget = dockWidgetAt(i);
|
||||||
|
addTabsMenuEntry(dockWidgetAt(i), menu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
CDockAreaWidget::CDockAreaWidget(CDockManager* DockManager, CDockContainerWidget* parent) :
|
CDockAreaWidget::CDockAreaWidget(CDockManager* DockManager, CDockContainerWidget* parent) :
|
||||||
QFrame(parent),
|
QFrame(parent),
|
||||||
d(new DockAreaWidgetPrivate(this))
|
d(new DockAreaWidgetPrivate(this))
|
||||||
{
|
{
|
||||||
|
d->DockManager = DockManager;
|
||||||
setStyleSheet("ads--CDockAreaWidget {border: 1px solid white;}");
|
setStyleSheet("ads--CDockAreaWidget {border: 1px solid white;}");
|
||||||
d->Layout = new QBoxLayout(QBoxLayout::TopToBottom);
|
d->Layout = new QBoxLayout(QBoxLayout::TopToBottom);
|
||||||
d->Layout->setContentsMargins(0, 0, 0, 0);
|
d->Layout->setContentsMargins(0, 0, 0, 0);
|
||||||
@ -232,12 +258,20 @@ CDockAreaWidget::CDockAreaWidget(CDockManager* DockManager, CDockContainerWidget
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
CDockAreaWidget::~CDockAreaWidget()
|
CDockAreaWidget::~CDockAreaWidget()
|
||||||
{
|
{
|
||||||
|
std::cout << "~CDockAreaWidget()" << std::endl;
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
CDockContainerWidget* CDockAreaWidget::dockContainerWidget() const
|
CDockManager* CDockAreaWidget::dockManager() const
|
||||||
|
{
|
||||||
|
return d->DockManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
CDockContainerWidget* CDockAreaWidget::dockContainer() const
|
||||||
{
|
{
|
||||||
QWidget* Parent = parentWidget();
|
QWidget* Parent = parentWidget();
|
||||||
while (Parent)
|
while (Parent)
|
||||||
@ -274,6 +308,25 @@ void CDockAreaWidget::addDockWidget(CDockWidget* DockWidget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void CDockAreaWidget::removeDockWidget(CDockWidget* DockWidget)
|
||||||
|
{
|
||||||
|
std::cout << "CDockAreaWidget::removeDockWidget" << std::endl;
|
||||||
|
d->ContentsLayout->removeWidget(DockWidget);
|
||||||
|
auto TitleBar = DockWidget->titleBar();
|
||||||
|
d->TabsLayout->removeWidget(TitleBar);
|
||||||
|
disconnect(TitleBar, SIGNAL(clicked()), this, SLOT(onDockWidgetTitleClicked()));
|
||||||
|
d->updateTabsMenu();
|
||||||
|
|
||||||
|
if (d->ContentsLayout->isEmpty())
|
||||||
|
{
|
||||||
|
std::cout << "Dock Area empty" << std::endl;
|
||||||
|
dockContainer()->removeDockArea(this);
|
||||||
|
this->deleteLater();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
void CDockAreaWidget::onDockWidgetTitleClicked()
|
void CDockAreaWidget::onDockWidgetTitleClicked()
|
||||||
{
|
{
|
||||||
|
@ -66,11 +66,16 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual ~CDockAreaWidget();
|
virtual ~CDockAreaWidget();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the dock manager object this dock area belongs to
|
||||||
|
*/
|
||||||
|
CDockManager* dockManager() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the dock container widget this dock area widget belongs to or 0
|
* Returns the dock container widget this dock area widget belongs to or 0
|
||||||
* if there is no
|
* if there is no
|
||||||
*/
|
*/
|
||||||
CDockContainerWidget* dockContainerWidget() const;
|
CDockContainerWidget* dockContainer() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new dock widget to dock area.
|
* Add a new dock widget to dock area.
|
||||||
@ -78,6 +83,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
void addDockWidget(CDockWidget* DockWidget);
|
void addDockWidget(CDockWidget* DockWidget);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the given dock widget from the dock area
|
||||||
|
*/
|
||||||
|
void removeDockWidget(CDockWidget* DockWidget);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the rectangle of the title area
|
* Returns the rectangle of the title area
|
||||||
*/
|
*/
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
|
|
||||||
#include "DockManager.h"
|
#include "DockManager.h"
|
||||||
#include "DockAreaWidget.h"
|
#include "DockAreaWidget.h"
|
||||||
|
#include "DockWidget.h"
|
||||||
#include "ads_globals.h"
|
#include "ads_globals.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -97,6 +98,11 @@ struct DockContainerWidgetPrivate
|
|||||||
*/
|
*/
|
||||||
CDockAreaWidget* dockWidgetIntoDockArea(DockWidgetArea area, CDockWidget* Dockwidget,
|
CDockAreaWidget* dockWidgetIntoDockArea(DockWidgetArea area, CDockWidget* Dockwidget,
|
||||||
CDockAreaWidget* TargetDockArea);
|
CDockAreaWidget* TargetDockArea);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add dock area to this container
|
||||||
|
*/
|
||||||
|
void addDockArea(CDockAreaWidget* NewDockWidget, DockWidgetArea area = CenterDockWidgetArea);
|
||||||
}; // struct DockContainerWidgetPrivate
|
}; // struct DockContainerWidgetPrivate
|
||||||
|
|
||||||
|
|
||||||
@ -114,8 +120,15 @@ CDockAreaWidget* DockContainerWidgetPrivate::dockWidgetIntoContainer(DockWidgetA
|
|||||||
{
|
{
|
||||||
CDockAreaWidget* NewDockArea = new CDockAreaWidget(DockManager, _this);
|
CDockAreaWidget* NewDockArea = new CDockAreaWidget(DockManager, _this);
|
||||||
NewDockArea->addDockWidget(Dockwidget);
|
NewDockArea->addDockWidget(Dockwidget);
|
||||||
auto InsertParam = internal::dockAreaInsertParameters(area);
|
addDockArea(NewDockArea, area);
|
||||||
|
return NewDockArea;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void DockContainerWidgetPrivate::addDockArea(CDockAreaWidget* NewDockArea, DockWidgetArea area)
|
||||||
|
{
|
||||||
|
auto InsertParam = internal::dockAreaInsertParameters(area);
|
||||||
if (DockAreas.isEmpty())
|
if (DockAreas.isEmpty())
|
||||||
{
|
{
|
||||||
Layout->addWidget(NewDockArea, 0, 0);
|
Layout->addWidget(NewDockArea, 0, 0);
|
||||||
@ -156,7 +169,6 @@ CDockAreaWidget* DockContainerWidgetPrivate::dockWidgetIntoContainer(DockWidgetA
|
|||||||
}
|
}
|
||||||
|
|
||||||
DockAreas.append(NewDockArea);
|
DockAreas.append(NewDockArea);
|
||||||
return NewDockArea;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -173,7 +185,7 @@ CDockAreaWidget* DockContainerWidgetPrivate::dockWidgetIntoDockArea(DockWidgetAr
|
|||||||
CDockAreaWidget* NewDockArea = new CDockAreaWidget(DockManager, _this);
|
CDockAreaWidget* NewDockArea = new CDockAreaWidget(DockManager, _this);
|
||||||
NewDockArea->addDockWidget(Dockwidget);
|
NewDockArea->addDockWidget(Dockwidget);
|
||||||
auto InsertParam = internal::dockAreaInsertParameters(area);
|
auto InsertParam = internal::dockAreaInsertParameters(area);
|
||||||
QSplitter* TargetAreaSplitter = internal::findParentSplitter(TargetDockArea);
|
QSplitter* TargetAreaSplitter = internal::findParent<QSplitter*>(TargetDockArea);
|
||||||
int index = TargetAreaSplitter ->indexOf(TargetDockArea);
|
int index = TargetAreaSplitter ->indexOf(TargetDockArea);
|
||||||
if (TargetAreaSplitter->orientation() == InsertParam.orientation())
|
if (TargetAreaSplitter->orientation() == InsertParam.orientation())
|
||||||
{
|
{
|
||||||
@ -219,6 +231,13 @@ CDockContainerWidget::~CDockContainerWidget()
|
|||||||
CDockAreaWidget* CDockContainerWidget::addDockWidget(DockWidgetArea area, CDockWidget* Dockwidget,
|
CDockAreaWidget* CDockContainerWidget::addDockWidget(DockWidgetArea area, CDockWidget* Dockwidget,
|
||||||
CDockAreaWidget* DockAreaWidget)
|
CDockAreaWidget* DockAreaWidget)
|
||||||
{
|
{
|
||||||
|
CDockAreaWidget* OldDockArea = Dockwidget->dockAreaWidget();
|
||||||
|
if (OldDockArea)
|
||||||
|
{
|
||||||
|
OldDockArea->removeDockWidget(Dockwidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
Dockwidget->setDockManager(d->DockManager);
|
||||||
if (DockAreaWidget)
|
if (DockAreaWidget)
|
||||||
{
|
{
|
||||||
return d->dockWidgetIntoDockArea(area, Dockwidget, DockAreaWidget);
|
return d->dockWidgetIntoDockArea(area, Dockwidget, DockAreaWidget);
|
||||||
@ -259,6 +278,49 @@ bool CDockContainerWidget::event(QEvent *e)
|
|||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void CDockContainerWidget::addDockArea(CDockAreaWidget* DockAreaWidget,
|
||||||
|
DockWidgetArea area)
|
||||||
|
{
|
||||||
|
CDockContainerWidget* Container = DockAreaWidget->dockContainer();
|
||||||
|
if (Container && Container != this)
|
||||||
|
{
|
||||||
|
Container->removeDockArea(DockAreaWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
d->addDockArea(DockAreaWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void CDockContainerWidget::removeDockArea(CDockAreaWidget* area)
|
||||||
|
{
|
||||||
|
d->DockAreas.removeAll(area);
|
||||||
|
QSplitter* Splitter = internal::findParent<QSplitter*>(area);
|
||||||
|
area->setParent(0);
|
||||||
|
if (!(Splitter && Splitter->count() == 1))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// It the splitter contains only one single widget, then we do not need
|
||||||
|
// it anymore and can replace it with its content
|
||||||
|
std::cout << "Replacing splitter with content" << std::endl;
|
||||||
|
QWidget* widget = Splitter->widget(0);
|
||||||
|
widget->setParent(this);
|
||||||
|
QSplitter* ParentSplitter = internal::findParent<QSplitter*>(Splitter);
|
||||||
|
if (ParentSplitter)
|
||||||
|
{
|
||||||
|
internal::replaceSplitterWidget(ParentSplitter, Splitter, widget);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d->Layout->replaceWidget(Splitter, widget);
|
||||||
|
}
|
||||||
|
delete Splitter;
|
||||||
|
}
|
||||||
} // namespace ads
|
} // namespace ads
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -78,6 +78,16 @@ public:
|
|||||||
CDockAreaWidget* addDockWidget(DockWidgetArea area, CDockWidget* Dockwidget,
|
CDockAreaWidget* addDockWidget(DockWidgetArea area, CDockWidget* Dockwidget,
|
||||||
CDockAreaWidget* DockAreaWidget = nullptr);
|
CDockAreaWidget* DockAreaWidget = nullptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the given dock area to this container widget
|
||||||
|
*/
|
||||||
|
void addDockArea(CDockAreaWidget* DockAreaWidget, DockWidgetArea area = CenterDockWidgetArea);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the given dock area from this container
|
||||||
|
*/
|
||||||
|
void removeDockArea(CDockAreaWidget* area);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current zOrderIndex
|
* Returns the current zOrderIndex
|
||||||
*/
|
*/
|
||||||
|
@ -31,6 +31,11 @@
|
|||||||
#include "DockManager.h"
|
#include "DockManager.h"
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "FloatingDockContainer.h"
|
||||||
|
|
||||||
namespace ads
|
namespace ads
|
||||||
{
|
{
|
||||||
@ -40,6 +45,7 @@ namespace ads
|
|||||||
struct DockManagerPrivate
|
struct DockManagerPrivate
|
||||||
{
|
{
|
||||||
CDockManager* _this;
|
CDockManager* _this;
|
||||||
|
QList<CFloatingDockContainer*> FloatingWidgets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private data constructor
|
* Private data constructor
|
||||||
@ -73,6 +79,15 @@ CDockManager::~CDockManager()
|
|||||||
{
|
{
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void CDockManager::registerFloatingWidget(CFloatingDockContainer* FloatingWidget)
|
||||||
|
{
|
||||||
|
d->FloatingWidgets.append(FloatingWidget);
|
||||||
|
std::cout << "d->FloatingWidgets.count() " << d->FloatingWidgets.count()
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
} // namespace ads
|
} // namespace ads
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
namespace ads
|
namespace ads
|
||||||
{
|
{
|
||||||
struct DockManagerPrivate;
|
struct DockManagerPrivate;
|
||||||
|
class CFloatingDockContainer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The central dock manager that maintains the complete docking system
|
* The central dock manager that maintains the complete docking system
|
||||||
@ -46,10 +47,11 @@ private:
|
|||||||
DockManagerPrivate* d; ///< private data (pimpl)
|
DockManagerPrivate* d; ///< private data (pimpl)
|
||||||
friend class DockManagerPrivate;
|
friend class DockManagerPrivate;
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Default Constructor.
|
* Default Constructor.
|
||||||
* If the given parent is a QMainWindow, the dck manager sets itself as the
|
* If the given parent is a QMainWindow, the dock manager sets itself as the
|
||||||
* central widget
|
* central widget
|
||||||
*/
|
*/
|
||||||
CDockManager(QWidget* parent = 0);
|
CDockManager(QWidget* parent = 0);
|
||||||
@ -58,6 +60,12 @@ public:
|
|||||||
* Virtual Destructor
|
* Virtual Destructor
|
||||||
*/
|
*/
|
||||||
virtual ~CDockManager();
|
virtual ~CDockManager();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the given floating widget in the internal list of
|
||||||
|
* floating widgets
|
||||||
|
*/
|
||||||
|
void registerFloatingWidget(CFloatingDockContainer* FloatingWidget);
|
||||||
}; // class DockManager
|
}; // class DockManager
|
||||||
} // namespace ads
|
} // namespace ads
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -33,6 +33,9 @@
|
|||||||
#include <QBoxLayout>
|
#include <QBoxLayout>
|
||||||
|
|
||||||
#include "DockWidgetTitleBar.h"
|
#include "DockWidgetTitleBar.h"
|
||||||
|
#include "DockContainerWidget.h"
|
||||||
|
#include "DockAreaWidget.h"
|
||||||
|
#include "ads_globals.h"
|
||||||
|
|
||||||
namespace ads
|
namespace ads
|
||||||
{
|
{
|
||||||
@ -46,6 +49,7 @@ struct DockWidgetPrivate
|
|||||||
QWidget* Widget = nullptr;
|
QWidget* Widget = nullptr;
|
||||||
CDockWidgetTitleBar* TitleWidget;
|
CDockWidgetTitleBar* TitleWidget;
|
||||||
CDockWidget::DockWidgetFeatures Features = CDockWidget::AllDockWidgetFeatures;
|
CDockWidget::DockWidgetFeatures Features = CDockWidget::AllDockWidgetFeatures;
|
||||||
|
CDockManager* DockManager = nullptr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private data constructor
|
* Private data constructor
|
||||||
@ -125,6 +129,34 @@ CDockWidget::DockWidgetFeatures CDockWidget::features() const
|
|||||||
return d->Features;
|
return d->Features;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
CDockManager* CDockWidget::dockManager() const
|
||||||
|
{
|
||||||
|
return d->DockManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void CDockWidget::setDockManager(CDockManager* DockManager)
|
||||||
|
{
|
||||||
|
d->DockManager = DockManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
CDockContainerWidget* CDockWidget::dockContainer() const
|
||||||
|
{
|
||||||
|
return internal::findParent<CDockContainerWidget*>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
CDockAreaWidget* CDockWidget::dockAreaWidget() const
|
||||||
|
{
|
||||||
|
return internal::findParent<CDockAreaWidget*>(this);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ads
|
} // namespace ads
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -36,6 +36,9 @@ namespace ads
|
|||||||
{
|
{
|
||||||
struct DockWidgetPrivate;
|
struct DockWidgetPrivate;
|
||||||
class CDockWidgetTitleBar;
|
class CDockWidgetTitleBar;
|
||||||
|
class CDockManager;
|
||||||
|
class CDockContainerWidget;
|
||||||
|
class CDockAreaWidget;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The QDockWidget class provides a widget that can be docked inside a
|
* The QDockWidget class provides a widget that can be docked inside a
|
||||||
@ -47,7 +50,14 @@ class CDockWidget : public QFrame
|
|||||||
private:
|
private:
|
||||||
DockWidgetPrivate* d; ///< private data (pimpl)
|
DockWidgetPrivate* d; ///< private data (pimpl)
|
||||||
friend class DockWidgetPrivate;
|
friend class DockWidgetPrivate;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
friend class CDockContainerWidget;
|
||||||
|
/**
|
||||||
|
* Assigns the dock manager that manages this dock widget
|
||||||
|
*/
|
||||||
|
void setDockManager(CDockManager* DockManager);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum DockWidgetFeature
|
enum DockWidgetFeature
|
||||||
{
|
{
|
||||||
@ -97,6 +107,24 @@ public:
|
|||||||
* DockWidgetMovable and DockWidgetFloatable.
|
* DockWidgetMovable and DockWidgetFloatable.
|
||||||
*/
|
*/
|
||||||
DockWidgetFeatures features() const;
|
DockWidgetFeatures features() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the dock manager that manages the dock widget or 0 if the widget
|
||||||
|
* has not been assigned to any dock manager yet
|
||||||
|
*/
|
||||||
|
CDockManager* dockManager() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the dock container widget this dock area widget belongs to or 0
|
||||||
|
* if this dock widget has nt been docked yet
|
||||||
|
*/
|
||||||
|
CDockContainerWidget* dockContainer() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the dock area widget this dock widget belongs to or 0
|
||||||
|
* if this dock widget has not been docked yet
|
||||||
|
*/
|
||||||
|
CDockAreaWidget* dockAreaWidget() const;
|
||||||
}; // class DockWidget
|
}; // class DockWidget
|
||||||
}
|
}
|
||||||
// namespace ads
|
// namespace ads
|
||||||
|
@ -35,14 +35,29 @@
|
|||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QStyle>
|
#include <QStyle>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QSplitter>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "ads_globals.h"
|
||||||
#include "DockWidget.h"
|
#include "DockWidget.h"
|
||||||
#include "DockAreaWidget.h"
|
#include "DockAreaWidget.h"
|
||||||
|
#include "FloatingDockContainer.h"
|
||||||
|
|
||||||
namespace ads
|
namespace ads
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* The different dragging states
|
||||||
|
*/
|
||||||
|
enum eDragState
|
||||||
|
{
|
||||||
|
DraggingInactive, //!< DraggingInactive
|
||||||
|
DraggingMousePressed, //!< DraggingMousePressed
|
||||||
|
DraggingTab, //!< DraggingTab
|
||||||
|
DraggingFloatingWidget//!< DraggingFloatingWidget
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private data class of CDockWidgetTitleBar class (pimpl)
|
* Private data class of CDockWidgetTitleBar class (pimpl)
|
||||||
*/
|
*/
|
||||||
@ -54,8 +69,8 @@ struct DockWidgetTitleBarPrivate
|
|||||||
QLabel* TitleLabel;
|
QLabel* TitleLabel;
|
||||||
QPoint DragStartMousePosition;
|
QPoint DragStartMousePosition;
|
||||||
bool IsActiveTab = false;
|
bool IsActiveTab = false;
|
||||||
bool TabMoving = false;
|
|
||||||
CDockAreaWidget* DockArea = nullptr;
|
CDockAreaWidget* DockArea = nullptr;
|
||||||
|
eDragState DragState = DraggingInactive;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private data constructor
|
* Private data constructor
|
||||||
@ -71,6 +86,29 @@ struct DockWidgetTitleBarPrivate
|
|||||||
* Moves the tab depending on the position in the given mouse event
|
* Moves the tab depending on the position in the given mouse event
|
||||||
*/
|
*/
|
||||||
void moveTab(QMouseEvent* ev);
|
void moveTab(QMouseEvent* ev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test function for current drag state
|
||||||
|
*/
|
||||||
|
bool isDraggingState(eDragState dragState)
|
||||||
|
{
|
||||||
|
return this->DragState == dragState;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the given global point is inside the title area geometry
|
||||||
|
* rectangle.
|
||||||
|
* The position is given as global position.
|
||||||
|
*/
|
||||||
|
bool titleAreaGeometryContains(const QPoint& GlobalPos) const
|
||||||
|
{
|
||||||
|
return DockArea->titleAreaGeometry().contains(DockArea->mapFromGlobal(GlobalPos));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts floating of the dock widget that belongs to this title bar
|
||||||
|
*/
|
||||||
|
void startFloating(const QPoint& GlobalPos);
|
||||||
};
|
};
|
||||||
// struct DockWidgetTitleBarPrivate
|
// struct DockWidgetTitleBarPrivate
|
||||||
|
|
||||||
@ -114,6 +152,39 @@ void DockWidgetTitleBarPrivate::moveTab(QMouseEvent* ev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void DockWidgetTitleBarPrivate::startFloating(const QPoint& GlobalPos)
|
||||||
|
{
|
||||||
|
std::cout << "startFloating" << std::endl;
|
||||||
|
DragState = DraggingFloatingWidget;
|
||||||
|
QSize Size = DockArea->size();
|
||||||
|
CFloatingDockContainer* FloatingWidget = nullptr;
|
||||||
|
if (DockArea->count() > 1)
|
||||||
|
{
|
||||||
|
// If section widget has multiple tabs, we take only one tab
|
||||||
|
FloatingWidget = new CFloatingDockContainer(DockWidget);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If section widget has only one content widget, we can move the complete
|
||||||
|
// section widget into floating widget
|
||||||
|
auto splitter = internal::findParent<QSplitter*>(DockArea);
|
||||||
|
FloatingWidget = new CFloatingDockContainer(DockArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
FloatingWidget->resize(Size);
|
||||||
|
FloatingWidget->setObjectName("FloatingWidget");
|
||||||
|
FloatingWidget->startFloating(DragStartMousePosition);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DropOverlay* ContainerDropOverlay = cw->dropOverlay();
|
||||||
|
ContainerDropOverlay->setAllowedAreas(OuterAreas);
|
||||||
|
ContainerDropOverlay->showDropOverlay(this);
|
||||||
|
ContainerDropOverlay->raise();
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
CDockWidgetTitleBar::CDockWidgetTitleBar(CDockWidget* DockWidget, QWidget *parent) :
|
CDockWidgetTitleBar::CDockWidgetTitleBar(CDockWidget* DockWidget, QWidget *parent) :
|
||||||
QFrame(parent),
|
QFrame(parent),
|
||||||
@ -137,6 +208,7 @@ void CDockWidgetTitleBar::mousePressEvent(QMouseEvent* ev)
|
|||||||
{
|
{
|
||||||
ev->accept();
|
ev->accept();
|
||||||
d->DragStartMousePosition = ev->pos();
|
d->DragStartMousePosition = ev->pos();
|
||||||
|
d->DragState = DraggingMousePressed;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QFrame::mousePressEvent(ev);
|
QFrame::mousePressEvent(ev);
|
||||||
@ -148,7 +220,7 @@ void CDockWidgetTitleBar::mousePressEvent(QMouseEvent* ev)
|
|||||||
void CDockWidgetTitleBar::mouseReleaseEvent(QMouseEvent* ev)
|
void CDockWidgetTitleBar::mouseReleaseEvent(QMouseEvent* ev)
|
||||||
{
|
{
|
||||||
// End of tab moving, change order now
|
// End of tab moving, change order now
|
||||||
if (d->TabMoving && d->DockArea)
|
if (d->isDraggingState(DraggingTab) && d->DockArea)
|
||||||
{
|
{
|
||||||
// Find tab under mouse
|
// Find tab under mouse
|
||||||
QPoint pos = d->DockArea->mapFromGlobal(ev->globalPos());
|
QPoint pos = d->DockArea->mapFromGlobal(ev->globalPos());
|
||||||
@ -168,7 +240,7 @@ void CDockWidgetTitleBar::mouseReleaseEvent(QMouseEvent* ev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
d->DragStartMousePosition = QPoint();
|
d->DragStartMousePosition = QPoint();
|
||||||
d->TabMoving = false;
|
d->DragState = DraggingInactive;
|
||||||
//mcw->m_SectionDropOverlay->hideDropOverlay();
|
//mcw->m_SectionDropOverlay->hideDropOverlay();
|
||||||
//mcw->hideContainerOverlay();
|
//mcw->hideContainerOverlay();
|
||||||
QFrame::mouseReleaseEvent(ev);
|
QFrame::mouseReleaseEvent(ev);
|
||||||
@ -178,22 +250,34 @@ void CDockWidgetTitleBar::mouseReleaseEvent(QMouseEvent* ev)
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
void CDockWidgetTitleBar::mouseMoveEvent(QMouseEvent* ev)
|
void CDockWidgetTitleBar::mouseMoveEvent(QMouseEvent* ev)
|
||||||
{
|
{
|
||||||
if (!(ev->buttons() & Qt::LeftButton))
|
if (!(ev->buttons() & Qt::LeftButton) || d->isDraggingState(DraggingInactive))
|
||||||
|
{
|
||||||
|
d->DragState = DraggingInactive;
|
||||||
|
QFrame::mouseMoveEvent(ev);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d->isDraggingState(DraggingFloatingWidget))
|
||||||
{
|
{
|
||||||
QFrame::mouseMoveEvent(ev);
|
QFrame::mouseMoveEvent(ev);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// move tab
|
// move tab
|
||||||
if (d->TabMoving)
|
if (d->isDraggingState(DraggingTab))
|
||||||
{
|
{
|
||||||
d->moveTab(ev);
|
d->moveTab(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ev->pos() - d->DragStartMousePosition).manhattanLength() >= QApplication::startDragDistance() // Wait a few pixels before start moving
|
bool MouseInsideTitleArea = d->titleAreaGeometryContains(ev->globalPos());
|
||||||
&& d->DockArea->titleAreaGeometry().contains(d->DockArea->mapFromGlobal(ev->globalPos())))
|
if (!MouseInsideTitleArea)
|
||||||
{
|
{
|
||||||
d->TabMoving = true;
|
d->startFloating(ev->globalPos());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if ((ev->pos() - d->DragStartMousePosition).manhattanLength() >= QApplication::startDragDistance()) // Wait a few pixels before start moving
|
||||||
|
{
|
||||||
|
d->DragState = DraggingTab;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,6 +323,13 @@ void CDockWidgetTitleBar::setDockAreaWidget(CDockAreaWidget* DockArea)
|
|||||||
{
|
{
|
||||||
d->DockArea = DockArea;
|
d->DockArea = DockArea;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
CDockAreaWidget* CDockWidgetTitleBar::dockAreaWidget() const
|
||||||
|
{
|
||||||
|
return d->DockArea;
|
||||||
|
}
|
||||||
} // namespace ads
|
} // namespace ads
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -89,6 +89,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
void setDockAreaWidget(CDockAreaWidget* DockArea);
|
void setDockAreaWidget(CDockAreaWidget* DockArea);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the dock area widget this title bar belongs to.
|
||||||
|
* \return This function returns 0 if the dock widget that owns this title
|
||||||
|
* bar widget has not been added to any dock area yet.
|
||||||
|
*/
|
||||||
|
CDockAreaWidget* dockAreaWidget() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void activeTabChanged();
|
void activeTabChanged();
|
||||||
void clicked();
|
void clicked();
|
||||||
|
@ -20,8 +20,8 @@
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
/// \file FloatingDockContainer.cpp
|
/// \file FloatingDockContainer.cpp
|
||||||
/// \author Uwe Kindler
|
/// \author Uwe Kindler
|
||||||
/// \date 23.02.2017
|
/// \date 01.03.2017
|
||||||
/// \brief Implementation of CFloatingDockContainer
|
/// \brief Implementation of CFloatingDockContainer class
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
|
|
||||||
@ -30,9 +30,288 @@
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
#include "FloatingDockContainer.h"
|
#include "FloatingDockContainer.h"
|
||||||
|
|
||||||
|
#include <QBoxLayout>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "DockContainerWidget.h"
|
||||||
|
#include "DockAreaWidget.h"
|
||||||
|
#include "DockManager.h"
|
||||||
|
#include "DockWidget.h"
|
||||||
|
|
||||||
namespace ads
|
namespace ads
|
||||||
{
|
{
|
||||||
|
static unsigned int zOrderCounter = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private data class of CFloatingDockContainer class (pimpl)
|
||||||
|
*/
|
||||||
|
struct FloatingDockContainerPrivate
|
||||||
|
{
|
||||||
|
CFloatingDockContainer* _this;
|
||||||
|
CDockContainerWidget* DockContainer;
|
||||||
|
unsigned int zOrderIndex = ++zOrderCounter;
|
||||||
|
CDockManager* DockManager = nullptr;
|
||||||
|
bool DraggingActive = false;
|
||||||
|
QPoint DragStartMousePosition;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private data constructor
|
||||||
|
*/
|
||||||
|
FloatingDockContainerPrivate(CFloatingDockContainer* _public);
|
||||||
|
|
||||||
|
void titleMouseReleaseEvent();
|
||||||
|
void updateDropOverlays(const QPoint& GlobalPos);
|
||||||
|
void setDraggingActive(bool Active);
|
||||||
|
};
|
||||||
|
// struct FloatingDockContainerPrivate
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
FloatingDockContainerPrivate::FloatingDockContainerPrivate(CFloatingDockContainer* _public) :
|
||||||
|
_this(_public)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void FloatingDockContainerPrivate::titleMouseReleaseEvent()
|
||||||
|
{
|
||||||
|
setDraggingActive(false);
|
||||||
|
/*if (!m_DropContainer)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Dropped" << std::endl;
|
||||||
|
CMainContainerWidget* MainContainerWidget = mainContainerWidget();
|
||||||
|
m_DropContainer->dropFloatingWidget(this, QCursor::pos());
|
||||||
|
MainContainerWidget->dropOverlay()->hideDropOverlay();
|
||||||
|
MainContainerWidget->sectionDropOverlay()->hideDropOverlay();*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void FloatingDockContainerPrivate::updateDropOverlays(const QPoint& GlobalPos)
|
||||||
|
{
|
||||||
|
/*if (!isVisible())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CMainContainerWidget* MainContainerWidget = mainContainerWidget();
|
||||||
|
auto Containers = MainContainerWidget->m_Containers;
|
||||||
|
CContainerWidget* TopContainer = nullptr;
|
||||||
|
for (auto ContainerWidget : Containers)
|
||||||
|
{
|
||||||
|
if (!ContainerWidget->isVisible())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (containerWidget() == ContainerWidget)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPoint MappedPos = ContainerWidget->mapFromGlobal(GlobalPos);
|
||||||
|
if (ContainerWidget->rect().contains(MappedPos))
|
||||||
|
{
|
||||||
|
std::cout << "Container " << ContainerWidget << " contains mousepos" << std::endl;
|
||||||
|
if (!TopContainer || ContainerWidget->isInFrontOf(TopContainer))
|
||||||
|
{
|
||||||
|
TopContainer = ContainerWidget;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_DropContainer = TopContainer;
|
||||||
|
DropOverlay* ContainerDropOverlay = MainContainerWidget->dropOverlay();
|
||||||
|
DropOverlay* SectionDropOverlay = MainContainerWidget->sectionDropOverlay();
|
||||||
|
|
||||||
|
if (!TopContainer)
|
||||||
|
{
|
||||||
|
ContainerDropOverlay->hideDropOverlay();
|
||||||
|
SectionDropOverlay->hideDropOverlay();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ContainerDropOverlay->showDropOverlay(TopContainer);
|
||||||
|
ContainerDropOverlay->raise();
|
||||||
|
|
||||||
|
SectionWidget* sectionwidget = TopContainer->sectionWidgetAt(GlobalPos);
|
||||||
|
if (sectionwidget)
|
||||||
|
{
|
||||||
|
SectionDropOverlay->setAllowedAreas(AllAreas);
|
||||||
|
SectionDropOverlay->showDropOverlay(sectionwidget);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SectionDropOverlay->hideDropOverlay();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (TopContainer)
|
||||||
|
{
|
||||||
|
ContainerDropOverlay->showDropOverlay(TopContainer);
|
||||||
|
ContainerDropOverlay->raise();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ContainerDropOverlay->hideDropOverlay();
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void FloatingDockContainerPrivate::setDraggingActive(bool Active)
|
||||||
|
{
|
||||||
|
if (DraggingActive == Active)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DraggingActive = Active;
|
||||||
|
if (Active)
|
||||||
|
{
|
||||||
|
std::cout << "FloatingWidget:: InstallEventFilter" << std::endl;
|
||||||
|
qApp->installEventFilter(_this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "FloatingWidget:: RemoveEventFilter" << std::endl;
|
||||||
|
qApp->removeEventFilter(_this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
CFloatingDockContainer::CFloatingDockContainer(CDockManager* DockManager) :
|
||||||
|
QWidget(DockManager, Qt::Window),
|
||||||
|
d(new FloatingDockContainerPrivate(this))
|
||||||
|
{
|
||||||
|
d->DockManager = DockManager;
|
||||||
|
QBoxLayout* l = new QBoxLayout(QBoxLayout::TopToBottom);
|
||||||
|
l->setContentsMargins(0, 0, 0, 0);
|
||||||
|
l->setSpacing(0);
|
||||||
|
setLayout(l);
|
||||||
|
|
||||||
|
d->DockContainer = new CDockContainerWidget(DockManager, this);
|
||||||
|
l->addWidget(d->DockContainer);
|
||||||
|
DockManager->registerFloatingWidget(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
CFloatingDockContainer::CFloatingDockContainer(CDockAreaWidget* DockArea) :
|
||||||
|
CFloatingDockContainer(DockArea->dockManager())
|
||||||
|
{
|
||||||
|
d->DockContainer->addDockArea(DockArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
CFloatingDockContainer::CFloatingDockContainer(CDockWidget* DockWidget) :
|
||||||
|
CFloatingDockContainer(DockWidget->dockManager())
|
||||||
|
{
|
||||||
|
d->DockContainer->addDockWidget(CenterDockWidgetArea, DockWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
CFloatingDockContainer::~CFloatingDockContainer()
|
||||||
|
{
|
||||||
|
delete d;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
CDockContainerWidget* CFloatingDockContainer::dockContainer() const
|
||||||
|
{
|
||||||
|
return d->DockContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void CFloatingDockContainer::changeEvent(QEvent *event)
|
||||||
|
{
|
||||||
|
QWidget::changeEvent(event);
|
||||||
|
if ((event->type() == QEvent::ActivationChange) && isActiveWindow())
|
||||||
|
{
|
||||||
|
std::cout << "FloatingWidget::changeEvent QEvent::ActivationChange " << std::endl;
|
||||||
|
d->zOrderIndex = ++zOrderCounter;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void CFloatingDockContainer::moveEvent(QMoveEvent *event)
|
||||||
|
{
|
||||||
|
QWidget::moveEvent(event);
|
||||||
|
if (d->DraggingActive && qApp->mouseButtons().testFlag(Qt::LeftButton))
|
||||||
|
{
|
||||||
|
//updateDropOverlays(QCursor::pos());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
bool CFloatingDockContainer::event(QEvent *e)
|
||||||
|
{
|
||||||
|
if ((e->type() == QEvent::NonClientAreaMouseButtonPress))
|
||||||
|
{
|
||||||
|
if (QGuiApplication::mouseButtons() == Qt::LeftButton)
|
||||||
|
{
|
||||||
|
std::cout << "FloatingWidget::event Event::NonClientAreaMouseButtonPress" << e->type() << std::endl;
|
||||||
|
d->setDraggingActive(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (e->type() == QEvent::NonClientAreaMouseButtonDblClick)
|
||||||
|
{
|
||||||
|
std::cout << "FloatingWidget::event QEvent::NonClientAreaMouseButtonDblClick" << std::endl;
|
||||||
|
d->setDraggingActive(false);
|
||||||
|
}
|
||||||
|
else if ((e->type() == QEvent::NonClientAreaMouseButtonRelease) && d->DraggingActive)
|
||||||
|
{
|
||||||
|
std::cout << "FloatingWidget::event QEvent::NonClientAreaMouseButtonRelease" << std::endl;
|
||||||
|
d->titleMouseReleaseEvent();
|
||||||
|
}
|
||||||
|
return QWidget::event(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
bool CFloatingDockContainer::eventFilter(QObject *watched, QEvent *event)
|
||||||
|
{
|
||||||
|
if (event->type() == QEvent::MouseButtonRelease)
|
||||||
|
{
|
||||||
|
std::cout << "FloatingWidget::eventFilter QEvent::MouseButtonRelease" << std::endl;
|
||||||
|
d->titleMouseReleaseEvent();
|
||||||
|
}
|
||||||
|
else if ((event->type() == QEvent::MouseMove) && d->DraggingActive)
|
||||||
|
{
|
||||||
|
QMouseEvent* MouseEvent = dynamic_cast<QMouseEvent*>(event);
|
||||||
|
int BorderSize = (frameSize().width() - size().width()) / 2;
|
||||||
|
const QPoint moveToPos = QCursor::pos() - d->DragStartMousePosition - QPoint(BorderSize, 0);
|
||||||
|
move(moveToPos);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void CFloatingDockContainer::startFloating(const QPoint& Pos)
|
||||||
|
{
|
||||||
|
d->setDraggingActive(true);
|
||||||
|
QPoint TargetPos = QCursor::pos() - Pos;
|
||||||
|
move(TargetPos);
|
||||||
|
show();
|
||||||
|
d->DragStartMousePosition = Pos;
|
||||||
|
}
|
||||||
} // namespace ads
|
} // namespace ads
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -22,25 +22,73 @@
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
/// \file FloatingDockContainer.h
|
/// \file FloatingDockContainer.h
|
||||||
/// \author Uwe Kindler
|
/// \author Uwe Kindler
|
||||||
/// \date 23.02.2017
|
/// \date 01.03.2017
|
||||||
/// \brief Declaration of CFloatingDockContainer
|
/// \brief Declaration of CFloatingDockContainer class
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
// INCLUDES
|
// INCLUDES
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
namespace ads
|
namespace ads
|
||||||
{
|
{
|
||||||
|
struct FloatingDockContainerPrivate;
|
||||||
|
class CDockAreaWidget;
|
||||||
|
class CDockContainerWidget;
|
||||||
|
class CDockWidget;
|
||||||
|
class CDockManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* This implements a floating widget that is a dock container that accepts
|
||||||
|
* docking of dock widgets like the main window and that can be docked into
|
||||||
|
* another dock container
|
||||||
*/
|
*/
|
||||||
class CFloatingDockContainer
|
class CFloatingDockContainer : public QWidget
|
||||||
{
|
{
|
||||||
};
|
Q_OBJECT
|
||||||
|
private:
|
||||||
|
FloatingDockContainerPrivate* d; ///< private data (pimpl)
|
||||||
|
friend class FloatingDockContainerPrivate;
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Private constructor that is called from public constructors
|
||||||
|
*/
|
||||||
|
CFloatingDockContainer(CDockManager* DockManager);
|
||||||
|
|
||||||
} // namespace ads
|
protected: // reimplements QWidget
|
||||||
|
virtual void changeEvent(QEvent *event) override;
|
||||||
|
virtual void moveEvent(QMoveEvent *event) override;
|
||||||
|
virtual bool event(QEvent *e) override;
|
||||||
|
virtual bool eventFilter(QObject *watched, QEvent *event) override;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
public:
|
||||||
|
/**
|
||||||
|
* Create floating widget with the given dock area
|
||||||
|
*/
|
||||||
|
CFloatingDockContainer(CDockAreaWidget* DockArea);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create floating widget with the given dock widget
|
||||||
|
*/
|
||||||
|
CFloatingDockContainer(CDockWidget* DockWidget);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Virtual Destructor
|
||||||
|
*/
|
||||||
|
virtual ~CFloatingDockContainer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Access function for the internal dock container
|
||||||
|
*/
|
||||||
|
CDockContainerWidget* dockContainer() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts floating at the given global position
|
||||||
|
*/
|
||||||
|
void startFloating(const QPoint& Pos);
|
||||||
|
}; // class FloatingDockContainer
|
||||||
|
}
|
||||||
|
// namespace ads
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
#endif // FloatingDockContainerH
|
#endif // FloatingDockContainerH
|
||||||
|
@ -48,6 +48,14 @@ QSplitter* newSplitter(Qt::Orientation orientation, QWidget* parent)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void replaceSplitterWidget(QSplitter* Splitter, QWidget* From, QWidget* To)
|
||||||
|
{
|
||||||
|
int index = Splitter->indexOf(From);
|
||||||
|
From->setParent(0);
|
||||||
|
Splitter->insertWidget(index, To);
|
||||||
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
CDockInsertParam dockAreaInsertParameters(DockWidgetArea Area)
|
CDockInsertParam dockAreaInsertParameters(DockWidgetArea Area)
|
||||||
{
|
{
|
||||||
@ -64,24 +72,6 @@ CDockInsertParam dockAreaInsertParameters(DockWidgetArea Area)
|
|||||||
return CDockInsertParam(Qt::Vertical, false);
|
return CDockInsertParam(Qt::Vertical, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
QSplitter* findParentSplitter(QWidget* w)
|
|
||||||
{
|
|
||||||
QWidget* parentWidget = w;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
QSplitter* splitter = dynamic_cast<QSplitter*>(parentWidget);
|
|
||||||
if (splitter)
|
|
||||||
{
|
|
||||||
return splitter;
|
|
||||||
}
|
|
||||||
parentWidget = parentWidget->parentWidget();
|
|
||||||
}
|
|
||||||
while (parentWidget);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace ads
|
} // namespace ads
|
||||||
|
|
||||||
|
@ -57,6 +57,11 @@ namespace internal
|
|||||||
*/
|
*/
|
||||||
QSplitter* newSplitter(Qt::Orientation orientation, QWidget* parent = 0);
|
QSplitter* newSplitter(Qt::Orientation orientation, QWidget* parent = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace the from widget in the given splitter with the To widget
|
||||||
|
*/
|
||||||
|
void replaceSplitterWidget(QSplitter* Splitter, QWidget* From, QWidget* To);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience class for QPair to provide better naming than first and
|
* Convenience class for QPair to provide better naming than first and
|
||||||
* second
|
* second
|
||||||
@ -76,10 +81,26 @@ public:
|
|||||||
CDockInsertParam dockAreaInsertParameters(DockWidgetArea Area);
|
CDockInsertParam dockAreaInsertParameters(DockWidgetArea Area);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the parent splitter of the given widget or 0 if the widget is not
|
* Searches for the parent widget of the given type.
|
||||||
* child of any splitter
|
* Returns the parent widget of the given widget or 0 if the widget is not
|
||||||
|
* child of any widget of type T
|
||||||
*/
|
*/
|
||||||
QSplitter* findParentSplitter(QWidget* w);
|
template <class T>
|
||||||
|
T findParent(const QWidget* w)
|
||||||
|
{
|
||||||
|
QWidget* parentWidget = w->parentWidget();
|
||||||
|
while (parentWidget)
|
||||||
|
{
|
||||||
|
T ParentImpl = dynamic_cast<T>(parentWidget);
|
||||||
|
if (ParentImpl)
|
||||||
|
{
|
||||||
|
return ParentImpl;
|
||||||
|
}
|
||||||
|
parentWidget = parentWidget->parentWidget();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace ads
|
} // namespace ads
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user