Moved title bar dragging code from DockAreaTabBar into DockAreaTitleBar

This commit is contained in:
Uwe Kindler 2020-02-07 12:16:26 +01:00
parent ae72f5e47d
commit b61f50982a
6 changed files with 194 additions and 200 deletions

View File

@ -54,13 +54,10 @@ namespace ads
struct DockAreaTabBarPrivate
{
CDockAreaTabBar* _this;
QPoint DragStartMousePos;
CDockAreaWidget* DockArea;
IFloatingWidget* FloatingWidget = nullptr;
QWidget* TabsContainerWidget;
QBoxLayout* TabsLayout;
int CurrentIndex = -1;
eDragState DragState = DraggingInactive;
/**
* Private data constructor
@ -72,14 +69,6 @@ struct DockAreaTabBarPrivate
* The function reassigns the stylesheet to update the tabs
*/
void updateTabs();
/**
* Test function for current drag state
*/
bool isDraggingState(eDragState dragState) const
{
return this->DragState == dragState;
}
};
// struct DockAreaTabBarPrivate
@ -164,149 +153,6 @@ void CDockAreaTabBar::wheelEvent(QWheelEvent* Event)
}
//============================================================================
void CDockAreaTabBar::mousePressEvent(QMouseEvent* ev)
{
if (ev->button() == Qt::LeftButton)
{
ev->accept();
d->DragStartMousePos = ev->pos();
d->DragState = DraggingMousePressed;
return;
}
Super::mousePressEvent(ev);
}
//============================================================================
void CDockAreaTabBar::mouseReleaseEvent(QMouseEvent* ev)
{
if (ev->button() == Qt::LeftButton)
{
ADS_PRINT("CDockAreaTabBar::mouseReleaseEvent");
ev->accept();
auto CurrentDragState = d->DragState;
d->DragStartMousePos = QPoint();
d->DragState = DraggingInactive;
if (DraggingFloatingWidget == CurrentDragState)
{
d->FloatingWidget->finishDragging();
}
return;
}
Super::mouseReleaseEvent(ev);
}
//============================================================================
void CDockAreaTabBar::mouseMoveEvent(QMouseEvent* ev)
{
Super::mouseMoveEvent(ev);
if (!(ev->buttons() & Qt::LeftButton) || d->isDraggingState(DraggingInactive))
{
d->DragState = DraggingInactive;
return;
}
// move floating window
if (d->isDraggingState(DraggingFloatingWidget))
{
d->FloatingWidget->moveFloating();
return;
}
// If this is the last dock area in a dock container it does not make
// sense to move it to a new floating widget and leave this one
// empty
if (d->DockArea->dockContainer()->isFloating()
&& d->DockArea->dockContainer()->visibleDockAreaCount() == 1)
{
return;
}
// If one single dock widget in this area is not floatable then the whole
// area is not floatable
if (!d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
{
return;
}
int DragDistance = (d->DragStartMousePos - ev->pos()).manhattanLength();
if (DragDistance >= CDockManager::startDragDistance())
{
ADS_PRINT("CTabsScrollArea::startFloating");
startFloating(d->DragStartMousePos);
auto Overlay = d->DockArea->dockManager()->containerOverlay();
Overlay->setAllowedAreas(OuterDockAreas);
}
return;
}
//============================================================================
void CDockAreaTabBar::mouseDoubleClickEvent(QMouseEvent *event)
{
// If this is the last dock area in a dock container it does not make
// sense to move it to a new floating widget and leave this one
// empty
if (d->DockArea->dockContainer()->isFloating() && d->DockArea->dockContainer()->dockAreaCount() == 1)
{
return;
}
if (!d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
{
return;
}
makeAreaFloating(event->pos(), DraggingInactive);
}
//============================================================================
IFloatingWidget* CDockAreaTabBar::makeAreaFloating(const QPoint& Offset, eDragState DragState)
{
QSize Size = d->DockArea->size();
d->DragState = DragState;
bool OpaqueUndocking = CDockManager::configFlags().testFlag(CDockManager::OpaqueUndocking) ||
(DraggingFloatingWidget != DragState);
CFloatingDockContainer* FloatingDockContainer = nullptr;
IFloatingWidget* FloatingWidget;
if (OpaqueUndocking)
{
FloatingWidget = FloatingDockContainer = new CFloatingDockContainer(d->DockArea);
}
else
{
auto w = new CFloatingDragPreview(d->DockArea);
connect(w, &CFloatingDragPreview::draggingCanceled, [=]()
{
d->DragState = DraggingInactive;
});
FloatingWidget = w;
}
FloatingWidget->startFloating(Offset, Size, DragState, nullptr);
if (FloatingDockContainer)
{
auto TopLevelDockWidget = FloatingDockContainer->topLevelDockWidget();
if (TopLevelDockWidget)
{
TopLevelDockWidget->emitTopLevelChanged(true);
}
}
return FloatingWidget;
}
//============================================================================
void CDockAreaTabBar::startFloating(const QPoint& Offset)
{
d->FloatingWidget = makeAreaFloating(Offset, DraggingFloatingWidget);
}
//============================================================================
void CDockAreaTabBar::setCurrentIndex(int index)
{
@ -625,7 +471,6 @@ bool CDockAreaTabBar::isTabOpen(int Index) const
QSize CDockAreaTabBar::minimumSizeHint() const
{
QSize Size = sizeHint();
//Size.setWidth(Super::minimumSizeHint().width());// this defines the minimum width of a dock area
Size.setWidth(10);
return Size;
}
@ -637,13 +482,6 @@ QSize CDockAreaTabBar::sizeHint() const
return d->TabsContainerWidget->sizeHint();
}
//===========================================================================
eDragState CDockAreaTabBar::dragState() const
{
return d->DragState;
}
} // namespace ads

View File

@ -67,42 +67,6 @@ private slots:
protected:
virtual void wheelEvent(QWheelEvent* Event) override;
/**
* Stores mouse position to detect dragging
*/
virtual void mousePressEvent(QMouseEvent* ev) override;
/**
* Stores mouse position to detect dragging
*/
virtual void mouseReleaseEvent(QMouseEvent* ev) override;
/**
* Starts floating the complete docking area including all dock widgets,
* if it is not the last dock area in a floating widget
*/
virtual void mouseMoveEvent(QMouseEvent* ev) override;
/**
* Double clicking the title bar also starts floating of the complete area
*/
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
/**
* Starts floating
*/
void startFloating(const QPoint& Offset);
/**
* Makes the dock area floating
*/
IFloatingWidget* makeAreaFloating(const QPoint& Offset, eDragState DragState);
/**
* Returns the current drag state
*/
eDragState dragState() const;
public:
using Super = QScrollArea;

View File

@ -41,6 +41,7 @@
#include "ads_globals.h"
#include "FloatingDockContainer.h"
#include "FloatingDragPreview.h"
#include "DockAreaWidget.h"
#include "DockOverlay.h"
#include "DockManager.h"
@ -72,6 +73,11 @@ struct DockAreaTitleBarPrivate
QMenu* TabsMenu;
QList<tTitleBarButton*> DockWidgetActionsButtons;
QPoint DragStartMousePos;
eDragState DragState = DraggingInactive;
IFloatingWidget* FloatingWidget = nullptr;
/**
* Private data constructor
*/
@ -102,6 +108,25 @@ struct DockAreaTitleBarPrivate
{
return CDockManager::configFlags().testFlag(Flag);
}
/**
* Test function for current drag state
*/
bool isDraggingState(eDragState dragState) const
{
return this->DragState == dragState;
}
/**
* Starts floating
*/
void startFloating(const QPoint& Offset);
/**
* Makes the dock area floating
*/
IFloatingWidget* makeAreaFloating(const QPoint& Offset, eDragState DragState);
};// struct DockAreaTitleBarPrivate
@ -241,6 +266,50 @@ void DockAreaTitleBarPrivate::createTabBar()
}
//============================================================================
IFloatingWidget* DockAreaTitleBarPrivate::makeAreaFloating(const QPoint& Offset, eDragState DragState)
{
QSize Size = DockArea->size();
this->DragState = DragState;
bool OpaqueUndocking = CDockManager::configFlags().testFlag(CDockManager::OpaqueUndocking) ||
(DraggingFloatingWidget != DragState);
CFloatingDockContainer* FloatingDockContainer = nullptr;
IFloatingWidget* FloatingWidget;
if (OpaqueUndocking)
{
FloatingWidget = FloatingDockContainer = new CFloatingDockContainer(DockArea);
}
else
{
auto w = new CFloatingDragPreview(DockArea);
QObject::connect(w, &CFloatingDragPreview::draggingCanceled, [=]()
{
this->DragState = DraggingInactive;
});
FloatingWidget = w;
}
FloatingWidget->startFloating(Offset, Size, DragState, nullptr);
if (FloatingDockContainer)
{
auto TopLevelDockWidget = FloatingDockContainer->topLevelDockWidget();
if (TopLevelDockWidget)
{
TopLevelDockWidget->emitTopLevelChanged(true);
}
}
return FloatingWidget;
}
//============================================================================
void DockAreaTitleBarPrivate::startFloating(const QPoint& Offset)
{
FloatingWidget = makeAreaFloating(Offset, DraggingFloatingWidget);
}
//============================================================================
CDockAreaTitleBar::CDockAreaTitleBar(CDockAreaWidget* parent) :
QFrame(parent),
@ -362,7 +431,7 @@ void CDockAreaTitleBar::onUndockButtonClicked()
{
if (d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
{
d->TabBar->makeAreaFloating(mapFromGlobal(QCursor::pos()), DraggingInactive);
d->makeAreaFloating(mapFromGlobal(QCursor::pos()), DraggingInactive);
}
}
@ -453,7 +522,7 @@ void CDockAreaTitleBar::setVisible(bool Visible)
//============================================================================
void CDockAreaTitleBar::showContextMenu(const QPoint& pos)
{
if (d->TabBar->dragState() == DraggingFloatingWidget)
if (d->DragState == DraggingFloatingWidget)
{
return;
}
@ -469,6 +538,105 @@ void CDockAreaTitleBar::showContextMenu(const QPoint& pos)
}
//============================================================================
void CDockAreaTitleBar::mousePressEvent(QMouseEvent* ev)
{
if (ev->button() == Qt::LeftButton)
{
ev->accept();
d->DragStartMousePos = ev->pos();
d->DragState = DraggingMousePressed;
return;
}
Super::mousePressEvent(ev);
}
//============================================================================
void CDockAreaTitleBar::mouseReleaseEvent(QMouseEvent* ev)
{
if (ev->button() == Qt::LeftButton)
{
ADS_PRINT("CDockAreaTitleBar::mouseReleaseEvent");
ev->accept();
auto CurrentDragState = d->DragState;
d->DragStartMousePos = QPoint();
d->DragState = DraggingInactive;
if (DraggingFloatingWidget == CurrentDragState)
{
d->FloatingWidget->finishDragging();
}
return;
}
Super::mouseReleaseEvent(ev);
}
//============================================================================
void CDockAreaTitleBar::mouseMoveEvent(QMouseEvent* ev)
{
Super::mouseMoveEvent(ev);
if (!(ev->buttons() & Qt::LeftButton) || d->isDraggingState(DraggingInactive))
{
d->DragState = DraggingInactive;
return;
}
// move floating window
if (d->isDraggingState(DraggingFloatingWidget))
{
d->FloatingWidget->moveFloating();
return;
}
// If this is the last dock area in a dock container it does not make
// sense to move it to a new floating widget and leave this one
// empty
if (d->DockArea->dockContainer()->isFloating()
&& d->DockArea->dockContainer()->visibleDockAreaCount() == 1)
{
return;
}
// If one single dock widget in this area is not floatable then the whole
// area is not floatable
if (!d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
{
return;
}
int DragDistance = (d->DragStartMousePos - ev->pos()).manhattanLength();
if (DragDistance >= CDockManager::startDragDistance())
{
ADS_PRINT("CTabsScrollArea::startFloating");
d->startFloating(d->DragStartMousePos);
auto Overlay = d->DockArea->dockManager()->containerOverlay();
Overlay->setAllowedAreas(OuterDockAreas);
}
return;
}
//============================================================================
void CDockAreaTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
{
// If this is the last dock area in a dock container it does not make
// sense to move it to a new floating widget and leave this one
// empty
if (d->DockArea->dockContainer()->isFloating() && d->DockArea->dockContainer()->dockAreaCount() == 1)
{
return;
}
if (!d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
{
return;
}
d->makeAreaFloating(event->pos(), DraggingInactive);
}
} // namespace ads
#include "DockAreaTitleBar.moc"

View File

@ -62,6 +62,28 @@ private slots:
void onCurrentTabChanged(int Index);
void showContextMenu(const QPoint& pos);
protected:
/**
* Stores mouse position to detect dragging
*/
virtual void mousePressEvent(QMouseEvent* ev) override;
/**
* Stores mouse position to detect dragging
*/
virtual void mouseReleaseEvent(QMouseEvent* ev) override;
/**
* Starts floating the complete docking area including all dock widgets,
* if it is not the last dock area in a floating widget
*/
virtual void mouseMoveEvent(QMouseEvent* ev) override;
/**
* Double clicking the title bar also starts floating of the complete area
*/
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
public slots:
/**
* Call this slot to tell the title bar that it should update the tabs menu

View File

@ -88,6 +88,7 @@ private:
friend struct DockWidgetTabPrivate;
friend class CFloatingDragPreview;
friend struct FloatingDragPreviewPrivate;
friend class CDockAreaTitleBar;
protected:
/**

View File

@ -74,6 +74,7 @@ protected:
friend class CDockAreaTabBar;
friend class CDockWidgetTab;
friend struct DockWidgetTabPrivate;
friend struct DockAreaTitleBarPrivate;
/**
* Assigns the dock manager that manages this dock widget