mirror of
https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git
synced 2024-12-25 07:31:33 +08:00
Implemented support for container docking
This commit is contained in:
parent
fac5661280
commit
f9f064dd71
@ -40,6 +40,7 @@
|
||||
#include "DockAreaWidget.h"
|
||||
#include "DockWidget.h"
|
||||
#include "FloatingDockContainer.h"
|
||||
#include "DockOverlay.h"
|
||||
#include "ads_globals.h"
|
||||
|
||||
#include <iostream>
|
||||
@ -51,7 +52,7 @@ static unsigned int zOrderCounter = 0;
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
@ -106,6 +107,17 @@ struct DockContainerWidgetPrivate
|
||||
* Add dock area to this container
|
||||
*/
|
||||
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
|
||||
|
||||
|
||||
@ -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,
|
||||
CDockWidget* Dockwidget)
|
||||
@ -142,14 +234,14 @@ void DockContainerWidgetPrivate::addDockArea(CDockAreaWidget* NewDockArea, DockW
|
||||
auto DockArea = dynamic_cast<CDockAreaWidget*>(Layout->itemAtPosition(0, 0)->widget());
|
||||
Layout->replaceWidget(DockArea, Splitter);
|
||||
Splitter->addWidget(DockArea);
|
||||
insertDockAreaIntoSplitter(Splitter, NewDockArea, InsertParam.append());
|
||||
insertWidgetIntoSplitter(Splitter, NewDockArea, InsertParam.append());
|
||||
}
|
||||
else
|
||||
{
|
||||
QSplitter* Splitter = _this->findChild<QSplitter*>(QString(), Qt::FindDirectChildrenOnly);
|
||||
if (Splitter->orientation() == InsertParam.orientation())
|
||||
{
|
||||
insertDockAreaIntoSplitter(Splitter, NewDockArea, InsertParam.append());
|
||||
insertWidgetIntoSplitter(Splitter, NewDockArea, InsertParam.append());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -201,7 +293,7 @@ CDockAreaWidget* DockContainerWidgetPrivate::dockWidgetIntoDockArea(DockWidgetAr
|
||||
std::cout << "TargetAreaSplitter->orientation() != InsertParam.orientation()" << std::endl;
|
||||
QSplitter* NewSplitter = internal::newSplitter(InsertParam.orientation());
|
||||
NewSplitter->addWidget(TargetDockArea);
|
||||
insertDockAreaIntoSplitter(NewSplitter, NewDockArea, InsertParam.append());
|
||||
insertWidgetIntoSplitter(NewSplitter, NewDockArea, InsertParam.append());
|
||||
TargetAreaSplitter->insertWidget(index, NewSplitter);
|
||||
}
|
||||
|
||||
@ -365,6 +457,39 @@ int CDockContainerWidget::dockAreaCount() const
|
||||
{
|
||||
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
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -40,6 +40,7 @@ struct DockContainerWidgetPrivate;
|
||||
class CDockAreaWidget;
|
||||
class CDockWidget;
|
||||
class CDockManager;
|
||||
class CFloatingDockContainer;
|
||||
|
||||
/**
|
||||
* Container that manages a number of dock areas with single dock widgets
|
||||
@ -68,6 +69,11 @@ public:
|
||||
*/
|
||||
virtual ~CDockContainerWidget();
|
||||
|
||||
/**
|
||||
* Drop floating widget into the container
|
||||
*/
|
||||
void dropFloatingWidget(CFloatingDockContainer* FloatingWidget, const QPoint& TargetPos);
|
||||
|
||||
/**
|
||||
* Adds dockwidget into the given area.
|
||||
* If DockAreaWidget is not null, then the area parameter indicates the area
|
||||
@ -91,7 +97,7 @@ public:
|
||||
/**
|
||||
* 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
|
||||
|
@ -148,6 +148,13 @@ const QList<CFloatingDockContainer*> CDockManager::floatingWidgets() const
|
||||
{
|
||||
return d->FloatingWidgets;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
unsigned int CDockManager::zOrderIndex() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
} // namespace ads
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -108,6 +108,12 @@ public:
|
||||
* Returns the list of all floating widgets
|
||||
*/
|
||||
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
|
||||
} // namespace ads
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -219,6 +219,7 @@ void CDockWidgetTitleBar::mousePressEvent(QMouseEvent* ev)
|
||||
{
|
||||
if (ev->button() == Qt::LeftButton)
|
||||
{
|
||||
std::cout << "CDockWidgetTitleBar::mousePressEvent" << std::endl;
|
||||
ev->accept();
|
||||
d->DragStartMousePosition = ev->pos();
|
||||
d->DragState = DraggingMousePressed;
|
||||
@ -263,6 +264,8 @@ void CDockWidgetTitleBar::mouseReleaseEvent(QMouseEvent* ev)
|
||||
//============================================================================
|
||||
void CDockWidgetTitleBar::mouseMoveEvent(QMouseEvent* ev)
|
||||
{
|
||||
std::cout << "CDockWidgetTitleBar::mouseMoveEventmouseMoveEvent DragState "
|
||||
<< d->DragState << std::endl;
|
||||
if (!(ev->buttons() & Qt::LeftButton) || d->isDraggingState(DraggingInactive))
|
||||
{
|
||||
d->DragState = DraggingInactive;
|
||||
@ -286,8 +289,6 @@ void CDockWidgetTitleBar::mouseMoveEvent(QMouseEvent* ev)
|
||||
if (!MouseInsideTitleArea)
|
||||
{
|
||||
d->startFloating(ev->globalPos());
|
||||
// do not delegate handling of mouse move event base class to prevent
|
||||
// move events for the title area
|
||||
return;
|
||||
}
|
||||
else if (d->DockArea->count() > 1
|
||||
|
@ -90,8 +90,7 @@ void FloatingDockContainerPrivate::titleMouseReleaseEvent()
|
||||
}
|
||||
|
||||
std::cout << "Dropped" << std::endl;
|
||||
/*CMainContainerWidget* MainContainerWidget = mainContainerWidget();
|
||||
m_DropContainer->dropFloatingWidget(this, QCursor::pos());*/
|
||||
DropContainer->dropFloatingWidget(_this, QCursor::pos());
|
||||
DockManager->containerOverlay()->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)
|
||||
|
@ -60,6 +60,7 @@ protected: // reimplements QWidget
|
||||
virtual void changeEvent(QEvent *event) override;
|
||||
virtual void moveEvent(QMoveEvent *event) override;
|
||||
virtual bool event(QEvent *e) override;
|
||||
virtual void closeEvent(QCloseEvent *event) override;
|
||||
virtual bool eventFilter(QObject *watched, QEvent *event) override;
|
||||
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user