mirror of
https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git
synced 2025-03-16 02:59:51 +08:00
Implemented support for container docking
This commit is contained in:
parent
fac5661280
commit
f9f064dd71
@ -40,6 +40,7 @@
|
|||||||
#include "DockAreaWidget.h"
|
#include "DockAreaWidget.h"
|
||||||
#include "DockWidget.h"
|
#include "DockWidget.h"
|
||||||
#include "FloatingDockContainer.h"
|
#include "FloatingDockContainer.h"
|
||||||
|
#include "DockOverlay.h"
|
||||||
#include "ads_globals.h"
|
#include "ads_globals.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -51,7 +52,7 @@ static unsigned int zOrderCounter = 0;
|
|||||||
/**
|
/**
|
||||||
* Helper function to ease insertion of dock area into splitter
|
* Helper function to ease insertion of dock area into splitter
|
||||||
*/
|
*/
|
||||||
static void insertDockAreaIntoSplitter(QSplitter* Splitter, QWidget* widget, bool Append)
|
static void insertWidgetIntoSplitter(QSplitter* Splitter, QWidget* widget, bool Append)
|
||||||
{
|
{
|
||||||
if (Append)
|
if (Append)
|
||||||
{
|
{
|
||||||
@ -106,6 +107,17 @@ struct DockContainerWidgetPrivate
|
|||||||
* Add dock area to this container
|
* Add dock area to this container
|
||||||
*/
|
*/
|
||||||
void addDockArea(CDockAreaWidget* NewDockWidget, DockWidgetArea area = CenterDockWidgetArea);
|
void addDockArea(CDockAreaWidget* NewDockWidget, DockWidgetArea area = CenterDockWidgetArea);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drop floating widget into container
|
||||||
|
*/
|
||||||
|
void dropIntoContainer(CFloatingDockContainer* FloatingWidget, DockWidgetArea area);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drop floating widget into dock area
|
||||||
|
*/
|
||||||
|
void dropIntoSection(CFloatingDockContainer* FloatingWidget,
|
||||||
|
CDockAreaWidget* targetSection, DockWidgetArea area);
|
||||||
}; // struct DockContainerWidgetPrivate
|
}; // struct DockContainerWidgetPrivate
|
||||||
|
|
||||||
|
|
||||||
@ -117,6 +129,86 @@ DockContainerWidgetPrivate::DockContainerWidgetPrivate(CDockContainerWidget* _pu
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void DockContainerWidgetPrivate::dropIntoContainer(CFloatingDockContainer* FloatingWidget,
|
||||||
|
DockWidgetArea area)
|
||||||
|
{
|
||||||
|
QSplitter* OldSplitter = _this->findChild<QSplitter*>(QString(), Qt::FindDirectChildrenOnly);
|
||||||
|
auto InsertParam = internal::dockAreaInsertParameters(area);
|
||||||
|
auto NewDockAreas = FloatingWidget->dockContainer()->findChildren<CDockAreaWidget*>(
|
||||||
|
QString(), Qt::FindChildrenRecursively);
|
||||||
|
|
||||||
|
if (DockAreas.isEmpty())
|
||||||
|
{
|
||||||
|
auto Widget = FloatingWidget->dockContainer()->findChild<QWidget*>(QString(), Qt::FindDirectChildrenOnly);
|
||||||
|
Layout->addWidget(Widget, 0, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QSplitter* OldSplitter = _this->findChild<QSplitter*>(QString(), Qt::FindDirectChildrenOnly);
|
||||||
|
// First replace the dock widget with a splitter
|
||||||
|
if (DockAreas.count() == 1)
|
||||||
|
{
|
||||||
|
auto DockArea = dynamic_cast<CDockAreaWidget*>(Layout->itemAtPosition(0, 0)->widget());
|
||||||
|
QSplitter* NewSplitter = internal::newSplitter(InsertParam.orientation());
|
||||||
|
Layout->replaceWidget(DockArea, NewSplitter);
|
||||||
|
NewSplitter->addWidget(DockArea);
|
||||||
|
OldSplitter = NewSplitter;
|
||||||
|
}
|
||||||
|
else if (OldSplitter->orientation() != InsertParam.orientation())
|
||||||
|
{
|
||||||
|
QSplitter* NewSplitter = internal::newSplitter(InsertParam.orientation());
|
||||||
|
QLayoutItem* li = Layout->replaceWidget(OldSplitter, NewSplitter);
|
||||||
|
NewSplitter->addWidget(OldSplitter);
|
||||||
|
OldSplitter = NewSplitter;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Widget = FloatingWidget->dockContainer()->findChild<QWidget*>(QString(), Qt::FindDirectChildrenOnly);
|
||||||
|
auto FloatingSplitter = dynamic_cast<QSplitter*>(Widget);
|
||||||
|
|
||||||
|
if (!FloatingSplitter)
|
||||||
|
{
|
||||||
|
insertWidgetIntoSplitter(OldSplitter, Widget, InsertParam.append());
|
||||||
|
}
|
||||||
|
else if (FloatingSplitter->orientation() == InsertParam.orientation())
|
||||||
|
{
|
||||||
|
while (FloatingSplitter->count())
|
||||||
|
{
|
||||||
|
insertWidgetIntoSplitter(OldSplitter, FloatingSplitter->widget(0), InsertParam.append());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
insertWidgetIntoSplitter(OldSplitter, FloatingSplitter, InsertParam.append());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::cout << "Adding " << NewDockAreas.count() << " dock areas" << std::endl;
|
||||||
|
int CountBefore = DockAreas.count();
|
||||||
|
int NewAreaCount = NewDockAreas.count();
|
||||||
|
DockAreas.append(NewDockAreas);
|
||||||
|
if (1 == CountBefore)
|
||||||
|
{
|
||||||
|
DockAreas.at(0)->updateDockArea();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (1 == NewAreaCount)
|
||||||
|
{
|
||||||
|
DockAreas.last()->updateDockArea();
|
||||||
|
}
|
||||||
|
FloatingWidget->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void DockContainerWidgetPrivate::dropIntoSection(CFloatingDockContainer* FloatingWidget,
|
||||||
|
CDockAreaWidget* targetSection, DockWidgetArea area)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
CDockAreaWidget* DockContainerWidgetPrivate::dockWidgetIntoContainer(DockWidgetArea area,
|
CDockAreaWidget* DockContainerWidgetPrivate::dockWidgetIntoContainer(DockWidgetArea area,
|
||||||
CDockWidget* Dockwidget)
|
CDockWidget* Dockwidget)
|
||||||
@ -142,14 +234,14 @@ void DockContainerWidgetPrivate::addDockArea(CDockAreaWidget* NewDockArea, DockW
|
|||||||
auto DockArea = dynamic_cast<CDockAreaWidget*>(Layout->itemAtPosition(0, 0)->widget());
|
auto DockArea = dynamic_cast<CDockAreaWidget*>(Layout->itemAtPosition(0, 0)->widget());
|
||||||
Layout->replaceWidget(DockArea, Splitter);
|
Layout->replaceWidget(DockArea, Splitter);
|
||||||
Splitter->addWidget(DockArea);
|
Splitter->addWidget(DockArea);
|
||||||
insertDockAreaIntoSplitter(Splitter, NewDockArea, InsertParam.append());
|
insertWidgetIntoSplitter(Splitter, NewDockArea, InsertParam.append());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QSplitter* Splitter = _this->findChild<QSplitter*>(QString(), Qt::FindDirectChildrenOnly);
|
QSplitter* Splitter = _this->findChild<QSplitter*>(QString(), Qt::FindDirectChildrenOnly);
|
||||||
if (Splitter->orientation() == InsertParam.orientation())
|
if (Splitter->orientation() == InsertParam.orientation())
|
||||||
{
|
{
|
||||||
insertDockAreaIntoSplitter(Splitter, NewDockArea, InsertParam.append());
|
insertWidgetIntoSplitter(Splitter, NewDockArea, InsertParam.append());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -201,7 +293,7 @@ CDockAreaWidget* DockContainerWidgetPrivate::dockWidgetIntoDockArea(DockWidgetAr
|
|||||||
std::cout << "TargetAreaSplitter->orientation() != InsertParam.orientation()" << std::endl;
|
std::cout << "TargetAreaSplitter->orientation() != InsertParam.orientation()" << std::endl;
|
||||||
QSplitter* NewSplitter = internal::newSplitter(InsertParam.orientation());
|
QSplitter* NewSplitter = internal::newSplitter(InsertParam.orientation());
|
||||||
NewSplitter->addWidget(TargetDockArea);
|
NewSplitter->addWidget(TargetDockArea);
|
||||||
insertDockAreaIntoSplitter(NewSplitter, NewDockArea, InsertParam.append());
|
insertWidgetIntoSplitter(NewSplitter, NewDockArea, InsertParam.append());
|
||||||
TargetAreaSplitter->insertWidget(index, NewSplitter);
|
TargetAreaSplitter->insertWidget(index, NewSplitter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,6 +457,39 @@ int CDockContainerWidget::dockAreaCount() const
|
|||||||
{
|
{
|
||||||
return d->DockAreas.count();
|
return d->DockAreas.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWidget,
|
||||||
|
const QPoint& TargetPos)
|
||||||
|
{
|
||||||
|
std::cout << "CDockContainerWidget::dropFloatingWidget" << std::endl;
|
||||||
|
CDockAreaWidget* DockArea = dockAreaAt(TargetPos);
|
||||||
|
auto dropArea = InvalidDockWidgetArea;
|
||||||
|
if (DockArea)
|
||||||
|
{
|
||||||
|
auto dropOverlay = d->DockManager->dockAreaOverlay();
|
||||||
|
dropOverlay->setAllowedAreas(AllDockAreas);
|
||||||
|
dropArea = dropOverlay->showOverlay(DockArea);
|
||||||
|
if (dropArea != InvalidDockWidgetArea)
|
||||||
|
{
|
||||||
|
std::cout << "Dock Area Drop Content: " << dropArea << std::endl;
|
||||||
|
d->dropIntoSection(FloatingWidget, DockArea, dropArea);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// mouse is over container
|
||||||
|
if (InvalidDockWidgetArea == dropArea)
|
||||||
|
{
|
||||||
|
dropArea = d->DockManager->containerOverlay()->dropAreaUnderCursor();
|
||||||
|
std::cout << "Container Drop Content: " << dropArea << std::endl;
|
||||||
|
if (dropArea != InvalidDockWidgetArea)
|
||||||
|
{
|
||||||
|
d->dropIntoContainer(FloatingWidget, dropArea);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ads
|
} // namespace ads
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -40,6 +40,7 @@ struct DockContainerWidgetPrivate;
|
|||||||
class CDockAreaWidget;
|
class CDockAreaWidget;
|
||||||
class CDockWidget;
|
class CDockWidget;
|
||||||
class CDockManager;
|
class CDockManager;
|
||||||
|
class CFloatingDockContainer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Container that manages a number of dock areas with single dock widgets
|
* Container that manages a number of dock areas with single dock widgets
|
||||||
@ -68,6 +69,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual ~CDockContainerWidget();
|
virtual ~CDockContainerWidget();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drop floating widget into the container
|
||||||
|
*/
|
||||||
|
void dropFloatingWidget(CFloatingDockContainer* FloatingWidget, const QPoint& TargetPos);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds dockwidget into the given area.
|
* Adds dockwidget into the given area.
|
||||||
* If DockAreaWidget is not null, then the area parameter indicates the area
|
* If DockAreaWidget is not null, then the area parameter indicates the area
|
||||||
@ -91,7 +97,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Returns the current zOrderIndex
|
* Returns the current zOrderIndex
|
||||||
*/
|
*/
|
||||||
unsigned int zOrderIndex() const;
|
virtual unsigned int zOrderIndex() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function returns true if this container widgets z order index is
|
* This function returns true if this container widgets z order index is
|
||||||
|
@ -148,6 +148,13 @@ const QList<CFloatingDockContainer*> CDockManager::floatingWidgets() const
|
|||||||
{
|
{
|
||||||
return d->FloatingWidgets;
|
return d->FloatingWidgets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
unsigned int CDockManager::zOrderIndex() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
} // namespace ads
|
} // namespace ads
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -108,6 +108,12 @@ public:
|
|||||||
* Returns the list of all floating widgets
|
* Returns the list of all floating widgets
|
||||||
*/
|
*/
|
||||||
const QList<CFloatingDockContainer*> floatingWidgets() const;
|
const QList<CFloatingDockContainer*> floatingWidgets() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function always return 0 because the main window is always behind
|
||||||
|
* any floating widget
|
||||||
|
*/
|
||||||
|
virtual unsigned int zOrderIndex() const;
|
||||||
}; // class DockManager
|
}; // class DockManager
|
||||||
} // namespace ads
|
} // namespace ads
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -219,6 +219,7 @@ void CDockWidgetTitleBar::mousePressEvent(QMouseEvent* ev)
|
|||||||
{
|
{
|
||||||
if (ev->button() == Qt::LeftButton)
|
if (ev->button() == Qt::LeftButton)
|
||||||
{
|
{
|
||||||
|
std::cout << "CDockWidgetTitleBar::mousePressEvent" << std::endl;
|
||||||
ev->accept();
|
ev->accept();
|
||||||
d->DragStartMousePosition = ev->pos();
|
d->DragStartMousePosition = ev->pos();
|
||||||
d->DragState = DraggingMousePressed;
|
d->DragState = DraggingMousePressed;
|
||||||
@ -263,6 +264,8 @@ void CDockWidgetTitleBar::mouseReleaseEvent(QMouseEvent* ev)
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
void CDockWidgetTitleBar::mouseMoveEvent(QMouseEvent* ev)
|
void CDockWidgetTitleBar::mouseMoveEvent(QMouseEvent* ev)
|
||||||
{
|
{
|
||||||
|
std::cout << "CDockWidgetTitleBar::mouseMoveEventmouseMoveEvent DragState "
|
||||||
|
<< d->DragState << std::endl;
|
||||||
if (!(ev->buttons() & Qt::LeftButton) || d->isDraggingState(DraggingInactive))
|
if (!(ev->buttons() & Qt::LeftButton) || d->isDraggingState(DraggingInactive))
|
||||||
{
|
{
|
||||||
d->DragState = DraggingInactive;
|
d->DragState = DraggingInactive;
|
||||||
@ -286,8 +289,6 @@ void CDockWidgetTitleBar::mouseMoveEvent(QMouseEvent* ev)
|
|||||||
if (!MouseInsideTitleArea)
|
if (!MouseInsideTitleArea)
|
||||||
{
|
{
|
||||||
d->startFloating(ev->globalPos());
|
d->startFloating(ev->globalPos());
|
||||||
// do not delegate handling of mouse move event base class to prevent
|
|
||||||
// move events for the title area
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (d->DockArea->count() > 1
|
else if (d->DockArea->count() > 1
|
||||||
|
@ -90,8 +90,7 @@ void FloatingDockContainerPrivate::titleMouseReleaseEvent()
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Dropped" << std::endl;
|
std::cout << "Dropped" << std::endl;
|
||||||
/*CMainContainerWidget* MainContainerWidget = mainContainerWidget();
|
DropContainer->dropFloatingWidget(_this, QCursor::pos());
|
||||||
m_DropContainer->dropFloatingWidget(this, QCursor::pos());*/
|
|
||||||
DockManager->containerOverlay()->hideOverlay();
|
DockManager->containerOverlay()->hideOverlay();
|
||||||
DockManager->dockAreaOverlay()->hideOverlay();
|
DockManager->dockAreaOverlay()->hideOverlay();
|
||||||
}
|
}
|
||||||
@ -259,6 +258,13 @@ void CFloatingDockContainer::moveEvent(QMoveEvent *event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void CFloatingDockContainer::closeEvent(QCloseEvent *event)
|
||||||
|
{
|
||||||
|
d->setDraggingActive(false);
|
||||||
|
QWidget::closeEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
bool CFloatingDockContainer::event(QEvent *e)
|
bool CFloatingDockContainer::event(QEvent *e)
|
||||||
|
@ -60,6 +60,7 @@ protected: // reimplements QWidget
|
|||||||
virtual void changeEvent(QEvent *event) override;
|
virtual void changeEvent(QEvent *event) override;
|
||||||
virtual void moveEvent(QMoveEvent *event) override;
|
virtual void moveEvent(QMoveEvent *event) override;
|
||||||
virtual bool event(QEvent *e) override;
|
virtual bool event(QEvent *e) override;
|
||||||
|
virtual void closeEvent(QCloseEvent *event) override;
|
||||||
virtual bool eventFilter(QObject *watched, QEvent *event) override;
|
virtual bool eventFilter(QObject *watched, QEvent *event) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Loading…
Reference in New Issue
Block a user