Implemented support for container docking

This commit is contained in:
Uwe Kindler 2017-03-02 15:49:53 +01:00
parent fac5661280
commit f9f064dd71
7 changed files with 161 additions and 9 deletions

View File

@ -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
//---------------------------------------------------------------------------

View File

@ -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

View File

@ -148,6 +148,13 @@ const QList<CFloatingDockContainer*> CDockManager::floatingWidgets() const
{
return d->FloatingWidgets;
}
//============================================================================
unsigned int CDockManager::zOrderIndex() const
{
return 0;
}
} // namespace ads
//---------------------------------------------------------------------------

View File

@ -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
//-----------------------------------------------------------------------------

View File

@ -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

View File

@ -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)

View File

@ -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: