From b61f50982a1122e404d5581c7eefb217b2664757 Mon Sep 17 00:00:00 2001 From: Uwe Kindler Date: Fri, 7 Feb 2020 12:16:26 +0100 Subject: [PATCH] Moved title bar dragging code from DockAreaTabBar into DockAreaTitleBar --- src/DockAreaTabBar.cpp | 162 ------------------------------------ src/DockAreaTabBar.h | 36 -------- src/DockAreaTitleBar.cpp | 172 ++++++++++++++++++++++++++++++++++++++- src/DockAreaTitleBar.h | 22 +++++ src/DockManager.h | 1 + src/DockWidget.h | 1 + 6 files changed, 194 insertions(+), 200 deletions(-) diff --git a/src/DockAreaTabBar.cpp b/src/DockAreaTabBar.cpp index 8620f13..91a511c 100644 --- a/src/DockAreaTabBar.cpp +++ b/src/DockAreaTabBar.cpp @@ -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 diff --git a/src/DockAreaTabBar.h b/src/DockAreaTabBar.h index 8e0c487..c8f71d2 100644 --- a/src/DockAreaTabBar.h +++ b/src/DockAreaTabBar.h @@ -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; diff --git a/src/DockAreaTitleBar.cpp b/src/DockAreaTitleBar.cpp index 93d2246..7d48aba 100644 --- a/src/DockAreaTitleBar.cpp +++ b/src/DockAreaTitleBar.cpp @@ -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 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" diff --git a/src/DockAreaTitleBar.h b/src/DockAreaTitleBar.h index 1215239..b77d139 100644 --- a/src/DockAreaTitleBar.h +++ b/src/DockAreaTitleBar.h @@ -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 diff --git a/src/DockManager.h b/src/DockManager.h index 68655d6..b036038 100644 --- a/src/DockManager.h +++ b/src/DockManager.h @@ -88,6 +88,7 @@ private: friend struct DockWidgetTabPrivate; friend class CFloatingDragPreview; friend struct FloatingDragPreviewPrivate; + friend class CDockAreaTitleBar; protected: /** diff --git a/src/DockWidget.h b/src/DockWidget.h index dd0edb1..29f573e 100644 --- a/src/DockWidget.h +++ b/src/DockWidget.h @@ -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