Added finishDragging() function to IFloatingWidget to prevent installing event filters

This commit is contained in:
Uwe Kindler 2019-12-13 11:52:50 +01:00
parent 5e230d8874
commit 02143eac71
7 changed files with 70 additions and 76 deletions

View File

@ -174,8 +174,13 @@ void CDockAreaTabBar::mouseReleaseEvent(QMouseEvent* ev)
{ {
ADS_PRINT("CDockAreaTabBar::mouseReleaseEvent"); ADS_PRINT("CDockAreaTabBar::mouseReleaseEvent");
ev->accept(); ev->accept();
d->FloatingWidget = nullptr;
d->DragStartMousePos = QPoint(); d->DragStartMousePos = QPoint();
if (d->FloatingWidget)
{
auto FloatingWidget = d->FloatingWidget;
d->FloatingWidget = nullptr;
FloatingWidget->finishDragging();
}
return; return;
} }
QScrollArea::mouseReleaseEvent(ev); QScrollArea::mouseReleaseEvent(ev);

View File

@ -205,6 +205,8 @@ bool DockManagerPrivate::checkFormat(const QByteArray &state, int version)
bool DockManagerPrivate::restoreStateFromXml(const QByteArray &state, int version, bool DockManagerPrivate::restoreStateFromXml(const QByteArray &state, int version,
bool Testing) bool Testing)
{ {
Q_UNUSED(version);
if (state.isEmpty()) if (state.isEmpty())
{ {
return false; return false;

View File

@ -311,14 +311,27 @@ void CDockWidgetTab::mousePressEvent(QMouseEvent* ev)
//============================================================================ //============================================================================
void CDockWidgetTab::mouseReleaseEvent(QMouseEvent* ev) void CDockWidgetTab::mouseReleaseEvent(QMouseEvent* ev)
{ {
// End of tab moving, emit signal auto CurrentDragState = d->DragState;
if (d->isDraggingState(DraggingTab) && d->DockArea)
{
emit moved(ev->globalPos());
}
d->DragStartMousePosition = QPoint(); d->DragStartMousePosition = QPoint();
d->DragState = DraggingInactive; d->DragState = DraggingInactive;
switch (CurrentDragState)
{
case DraggingTab:
// End of tab moving, emit signal
if (d->DockArea)
{
emit moved(ev->globalPos());
}
break;
case DraggingFloatingWidget:
d->FloatingWidget->finishDragging();
break;
default:; // do nothing
}
Super::mouseReleaseEvent(ev); Super::mouseReleaseEvent(ev);
} }

View File

@ -260,11 +260,6 @@ CFloatingDockContainer::CFloatingDockContainer(CDockManager *DockManager) :
#endif #endif
DockManager->registerFloatingWidget(this); DockManager->registerFloatingWidget(this);
// We install an event filter to detect mouse release events because we
// do not receive mouse release event if the floating widget is behind
// the drop overlay cross
qApp->installEventFilter(this);
} }
//============================================================================ //============================================================================
@ -493,20 +488,6 @@ bool CFloatingDockContainer::event(QEvent *e)
return QWidget::event(e); return QWidget::event(e);
} }
//============================================================================
bool CFloatingDockContainer::eventFilter(QObject *watched, QEvent *event)
{
Q_UNUSED(watched);
if (event->type() == QEvent::MouseButtonRelease
&& d->isState(DraggingFloatingWidget))
{
ADS_PRINT("FloatingWidget::eventFilter QEvent::MouseButtonRelease");
finishDragging();
d->titleMouseReleaseEvent();
}
return false;
}
//============================================================================ //============================================================================
void CFloatingDockContainer::startFloating(const QPoint &DragStartMousePos, void CFloatingDockContainer::startFloating(const QPoint &DragStartMousePos,
@ -640,6 +621,7 @@ void CFloatingDockContainer::finishDragging()
d->MouseEventHandler = nullptr; d->MouseEventHandler = nullptr;
} }
#endif #endif
d->titleMouseReleaseEvent();
} }
} // namespace ads } // namespace ads

View File

@ -74,6 +74,11 @@ public:
* startFloating() was called * startFloating() was called
*/ */
virtual void moveFloating() = 0; virtual void moveFloating() = 0;
/**
* Tells the widget that to finish dragging if the mouse is released
*/
virtual void finishDragging() = 0;
}; };
@ -110,8 +115,8 @@ protected:
* Use moveToGlobalPos() to move the widget to a new position * Use moveToGlobalPos() to move the widget to a new position
* depending on the start position given in Pos parameter * depending on the start position given in Pos parameter
*/ */
void startFloating(const QPoint& DragStartMousePos, const QSize& Size, virtual void startFloating(const QPoint& DragStartMousePos, const QSize& Size,
eDragState DragState, QWidget* MouseEventHandler); eDragState DragState, QWidget* MouseEventHandler) override;
/** /**
* Call this function to start dragging the floating widget * Call this function to start dragging the floating widget
@ -126,7 +131,7 @@ protected:
* Call this function if you explicitly want to signal that dragging has * Call this function if you explicitly want to signal that dragging has
* finished * finished
*/ */
void finishDragging(); virtual void finishDragging() override;
/** /**
* Call this function if you just want to initialize the position * Call this function if you just want to initialize the position
@ -164,7 +169,6 @@ protected: // reimplements QWidget
virtual void closeEvent(QCloseEvent *event) override; virtual void closeEvent(QCloseEvent *event) override;
virtual void hideEvent(QHideEvent *event) override; virtual void hideEvent(QHideEvent *event) override;
virtual void showEvent(QShowEvent *event) override; virtual void showEvent(QShowEvent *event) override;
virtual bool eventFilter(QObject *watched, QEvent *event) override;
public: public:
using Super = QWidget; using Super = QWidget;

View File

@ -39,7 +39,6 @@ struct FloatingOverlayPrivate
CDockContainerWidget *DropContainer = nullptr; CDockContainerWidget *DropContainer = nullptr;
qreal WindowOpacity; qreal WindowOpacity;
bool Hidden = false; bool Hidden = false;
bool IgnoreMouseEvents = false;
QPixmap ContentPreviewPixmap; QPixmap ContentPreviewPixmap;
@ -184,10 +183,6 @@ CFloatingOverlay::CFloatingOverlay(QWidget* Content, QWidget* parent) :
#endif #endif
setWindowOpacity(0.6); setWindowOpacity(0.6);
// We install an event filter to detect mouse release events because we
// do not receive mouse release event if the floating widget is behind
// the drop overlay cross
qApp->installEventFilter(this);
// Create a static image of the widget that should get undocked // Create a static image of the widget that should get undocked
// This is like some kind preview image like it is uses in drag and drop // This is like some kind preview image like it is uses in drag and drop
@ -265,55 +260,44 @@ void CFloatingOverlay::moveEvent(QMoveEvent *event)
//============================================================================ //============================================================================
bool CFloatingOverlay::eventFilter(QObject *watched, QEvent *event) void CFloatingOverlay::finishDragging()
{ {
Q_UNUSED(watched); ADS_PRINT("CFloatingOverlay::finishDragging");
if (event->type() == QEvent::MouseButtonRelease && !d->IgnoreMouseEvents) auto DockDropArea = d->DockManager->dockAreaOverlay()->dropAreaUnderCursor();
auto ContainerDropArea = d->DockManager->containerOverlay()->dropAreaUnderCursor();
bool DropPossible = (DockDropArea != InvalidDockWidgetArea) || (ContainerDropArea != InvalidDockWidgetArea);
if (d->DropContainer && DropPossible)
{ {
ADS_PRINT("FloatingWidget::eventFilter QEvent::MouseButtonRelease"); d->DropContainer->dropWidget(d->Content, QCursor::pos());
}
auto DockDropArea = d->DockManager->dockAreaOverlay()->dropAreaUnderCursor(); else
auto ContainerDropArea = d->DockManager->containerOverlay()->dropAreaUnderCursor(); {
bool DropPossible = (DockDropArea != InvalidDockWidgetArea) || (ContainerDropArea != InvalidDockWidgetArea); CDockWidget* DockWidget = qobject_cast<CDockWidget*>(d->Content);
if (d->DropContainer && DropPossible) CFloatingDockContainer* FloatingWidget;
if (DockWidget)
{ {
d->DropContainer->dropWidget(d->Content, QCursor::pos()); FloatingWidget = new CFloatingDockContainer(DockWidget);
} }
else else
{ {
CDockWidget* DockWidget = qobject_cast<CDockWidget*>(d->Content); CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(d->Content);
CFloatingDockContainer* FloatingWidget; FloatingWidget = new CFloatingDockContainer(DockArea);
if (DockWidget) }
{ FloatingWidget->setGeometry(this->geometry());
FloatingWidget = new CFloatingDockContainer(DockWidget); FloatingWidget->show();
} if (!CDockManager::configFlags().testFlag(CDockManager::DragPreviewHasWindowFrame))
else {
{ QApplication::processEvents();
CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(d->Content); int FrameHeight = FloatingWidget->frameGeometry().height() - FloatingWidget->geometry().height();
FloatingWidget = new CFloatingDockContainer(DockArea); QRect FixedGeometry = this->geometry();
} FixedGeometry.adjust(0, FrameHeight, 0, 0);
FloatingWidget->setGeometry(this->geometry()); FloatingWidget->setGeometry(FixedGeometry);
FloatingWidget->show();
if (!CDockManager::configFlags().testFlag(CDockManager::DragPreviewHasWindowFrame))
{
QApplication::processEvents();
int FrameHeight = FloatingWidget->frameGeometry().height() - FloatingWidget->geometry().height();
QRect FixedGeometry = this->geometry();
FixedGeometry.adjust(0, FrameHeight, 0, 0);
FloatingWidget->setGeometry(FixedGeometry);
}
} }
this->close();
d->DockManager->containerOverlay()->hideOverlay();
d->DockManager->dockAreaOverlay()->hideOverlay();
// Because we use the event filter, we receive multiple mouse release
// events. To prevent multiple code execution, we ignore all mouse
// events after the first mouse event
d->IgnoreMouseEvents = true;
} }
return false; this->close();
d->DockManager->containerOverlay()->hideOverlay();
d->DockManager->dockAreaOverlay()->hideOverlay();
} }

View File

@ -31,7 +31,6 @@ private:
protected: protected:
virtual void moveEvent(QMoveEvent *event) override; virtual void moveEvent(QMoveEvent *event) override;
virtual bool eventFilter(QObject *watched, QEvent *event) override;
virtual void paintEvent(QPaintEvent *e) override; virtual void paintEvent(QPaintEvent *e) override;
/** /**
@ -57,6 +56,11 @@ public:
* startFloating() was called * startFloating() was called
*/ */
virtual void moveFloating() override; virtual void moveFloating() override;
/**
* Finishes dragging
*/
virtual void finishDragging() override;
}; };