From ffd35cbce3b5454d3ceaa2277129e218a3b39ffa Mon Sep 17 00:00:00 2001 From: Uwe Kindler Date: Mon, 16 Dec 2019 11:10:59 +0100 Subject: [PATCH] Added support for canceling non opaque docking with escape key, fixed state of non opaque docking when switching applications (if application becomes inactive) --- src/DockAreaTabBar.cpp | 10 ++++++++-- src/DockWidgetTab.cpp | 8 +++++++- src/FloatingOverlay.cpp | 39 +++++++++++++++++++++++++++++++++++++++ src/FloatingOverlay.h | 12 ++++++++++++ 4 files changed, 66 insertions(+), 3 deletions(-) diff --git a/src/DockAreaTabBar.cpp b/src/DockAreaTabBar.cpp index ed8e4e0..33a4e88 100644 --- a/src/DockAreaTabBar.cpp +++ b/src/DockAreaTabBar.cpp @@ -201,8 +201,9 @@ void CDockAreaTabBar::mouseReleaseEvent(QMouseEvent* ev) void CDockAreaTabBar::mouseMoveEvent(QMouseEvent* ev) { QScrollArea::mouseMoveEvent(ev); - if (ev->buttons() != Qt::LeftButton) + if (!(ev->buttons() & Qt::LeftButton) || d->isDraggingState(DraggingInactive)) { + d->DragState = DraggingInactive; return; } @@ -276,7 +277,12 @@ IFloatingWidget* CDockAreaTabBar::makeAreaFloating(const QPoint& Offset, eDragSt } else { - FloatingWidget = new CFloatingOverlay(d->DockArea); + auto w = new CFloatingOverlay(d->DockArea); + connect(w, &CFloatingOverlay::draggingCanceled, [=]() + { + d->DragState = DraggingInactive; + }); + FloatingWidget = w; } FloatingWidget->startFloating(Offset, Size, DragState, nullptr); diff --git a/src/DockWidgetTab.cpp b/src/DockWidgetTab.cpp index 1b86a8e..9e8abf6 100644 --- a/src/DockWidgetTab.cpp +++ b/src/DockWidgetTab.cpp @@ -151,7 +151,12 @@ struct DockWidgetTabPrivate } else { - return new CFloatingOverlay(Widget); + auto w = new CFloatingOverlay(Widget); + _this->connect(w, &CFloatingOverlay::draggingCanceled, [=]() + { + DragState = DraggingInactive; + }); + return w; } } }; @@ -246,6 +251,7 @@ bool DockWidgetTabPrivate::startFloating(eDragState DraggingState) IFloatingWidget* FloatingWidget = nullptr; bool OpaqueUndocking = CDockManager::configFlags().testFlag(CDockManager::OpaqueUndocking) || (DraggingFloatingWidget != DraggingState); + // If section widget has multiple tabs, we take only one tab // If it has only one single tab, we can move the complete // dock area into floating widget diff --git a/src/FloatingOverlay.cpp b/src/FloatingOverlay.cpp index 3e95250..b8a68b4 100644 --- a/src/FloatingOverlay.cpp +++ b/src/FloatingOverlay.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include "DockWidget.h" #include "DockAreaWidget.h" @@ -53,6 +54,17 @@ struct FloatingOverlayPrivate Hidden = Value; _this->update(); } + + /** + * Cancel dragging and emit the draggingCanceled event + */ + void cancelDragging() + { + emit _this->draggingCanceled(); + DockManager->containerOverlay()->hideOverlay(); + DockManager->dockAreaOverlay()->hideOverlay(); + _this->close(); + } }; // struct LedArrayPanelPrivate @@ -192,6 +204,9 @@ CFloatingOverlay::CFloatingOverlay(QWidget* Content, QWidget* parent) : d->ContentPreviewPixmap = QPixmap(Content->size()); Content->render(&d->ContentPreviewPixmap); } + + connect(qApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)), + SLOT(onApplicationStateChanged(Qt::ApplicationState))); } @@ -335,6 +350,30 @@ void CFloatingOverlay::paintEvent(QPaintEvent* event) } +//============================================================================ +void CFloatingOverlay::keyPressEvent(QKeyEvent *event) +{ + Super::keyPressEvent(event); + if (event->key() == Qt::Key_Escape) + { + d->cancelDragging(); + } +} + + +//============================================================================ +void CFloatingOverlay::onApplicationStateChanged(Qt::ApplicationState state) +{ + if (state != Qt::ApplicationActive) + { + disconnect(qApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)), + this, SLOT(onApplicationStateChanged(Qt::ApplicationState))); + d->cancelDragging(); + } +} + + + } // namespace ads diff --git a/src/FloatingOverlay.h b/src/FloatingOverlay.h index d218c92..c9af8c7 100644 --- a/src/FloatingOverlay.h +++ b/src/FloatingOverlay.h @@ -32,6 +32,9 @@ private: FloatingOverlayPrivate* d; friend class FloatingOverlayPrivate; +private slots: + void onApplicationStateChanged(Qt::ApplicationState state); + protected: /** * Updates the drop overlays @@ -43,6 +46,8 @@ protected: */ virtual void paintEvent(QPaintEvent *e) override; + virtual void keyPressEvent(QKeyEvent *event) override; + /** * The content is a DockArea or a DockWidget */ @@ -84,6 +89,13 @@ public: // implements IFloatingWidget ----------------------------------------- * of the assigned Content widget */ virtual void finishDragging() override; + +signals: + /** + * This signal is emitted, if dragging has been canceled by escape key + * or by active application switching via task manager + */ + void draggingCanceled(); };