summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorm0dB maarten de boer <mdb.github@resorama.com>2023-05-06 03:46:11 +0200
committerm0dB <79429057+m0dB@users.noreply.github.com>2023-05-27 01:28:25 +0200
commit18378e439b1deadcda118d6489cdf0e538023df0 (patch)
tree58f41e124c9ec7c767613efb902d09b067e3b798
parentb3f0ed88f8dba5cb97f3dd13c6a3d2d138e082ea (diff)
use custom mechanism to deliver drag&drop events coming from the QOpenGLWindow
-rw-r--r--src/widget/openglwindow.cpp36
-rw-r--r--src/widget/openglwindow.h1
-rw-r--r--src/widget/trackdroptarget.h4
-rw-r--r--src/widget/wglwidgetqopengl.cpp9
-rw-r--r--src/widget/wglwidgetqopengl.h5
-rw-r--r--src/widget/wspinnybase.cpp8
-rw-r--r--src/widget/wspinnybase.h3
-rw-r--r--src/widget/wwaveformviewer.cpp15
-rw-r--r--src/widget/wwaveformviewer.h2
9 files changed, 63 insertions, 20 deletions
diff --git a/src/widget/openglwindow.cpp b/src/widget/openglwindow.cpp
index fca428bb3e..cbf8818ef3 100644
--- a/src/widget/openglwindow.cpp
+++ b/src/widget/openglwindow.cpp
@@ -5,6 +5,7 @@
#include "widget/tooltipqopengl.h"
#include "widget/wglwidget.h"
+#include "widget/trackdroptarget.h"
OpenGLWindow::OpenGLWindow(WGLWidget* widget)
: m_pWidget(widget) {
@@ -53,17 +54,11 @@ bool OpenGLWindow::event(QEvent* ev) {
// gets called recursive, potentially resulting in infinite recursion
// and a stack overflow. The boolean m_handlingEvent protects against
// this recursion.
-
- if (m_handlingEvent) {
- return false;
- }
- m_handlingEvent = true;
+ const auto t = ev->type();
bool result = QOpenGLWindow::event(ev);
if (m_pWidget) {
- const auto t = ev->type();
-
// Tooltip don't work by forwarding the events. This mimics the
// tooltip behavior.
if (t == QEvent::MouseMove) {
@@ -74,22 +69,33 @@ bool OpenGLWindow::event(QEvent* ev) {
ToolTipQOpenGL::singleton().stop(m_pWidget);
}
- if (t != QEvent::Resize && t != QEvent::Move && t != QEvent::Expose) {
- // Send all events to the widget that owns the window container widget that contains
- // this QOpenGLWindow.
- // Except for:
+ if (t == QEvent::DragEnter || t == QEvent::DragMove || t == QEvent::DragLeave || t == QEvent::Drop)
+ {
+ // Drag & Drop events are not delivered correctly when using QApplication::sendEvent
+ // and even result in a recursive call to this method, so we use our own mechanism.
+ if (m_pWidget->trackDropTarget()) {
+ return m_pWidget->trackDropTarget()->handleDragAndDropEventFromWindow(ev);
+ }
+
+ ev->ignore();
+ return false;
+ }
+
+ if (t == QEvent::Resize || t == QEvent::Move || t == QEvent::Expose) {
// - Resize and Move
// Any change to the geometry comes from m_pWidget and its child m_pContainerWidget.
// If we send the resulting events back to the m_pWidget we will quickly overflow
// the event queue with repeated resize and move events.
// - Expose
// This event is only for windows
-
- QApplication::sendEvent(m_pWidget, ev);
+ return result;
}
- }
- m_handlingEvent = false;
+ // Send all remaining events to the widget that owns the window container widget that contains
+ // this QOpenGLWindow. With this mouse events, keyboard events, etc all arrive as intended,
+ // including the events for the WWaveformViewer that contains the waveform widget.
+ QApplication::sendEvent(m_pWidget, ev);
+ }
return result;
}
diff --git a/src/widget/openglwindow.h b/src/widget/openglwindow.h
index 01a98d78eb..3d725ba462 100644
--- a/src/widget/openglwindow.h
+++ b/src/widget/openglwindow.h
@@ -11,7 +11,6 @@ class OpenGLWindow : public QOpenGLWindow {
WGLWidget* m_pWidget;
bool m_dirty{};
- bool m_handlingEvent{};
public:
OpenGLWindow(WGLWidget* widget);
diff --git a/src/widget/trackdroptarget.h b/src/widget/trackdroptarget.h
index 6933a4d70f..9171d177ef 100644
--- a/src/widget/trackdroptarget.h
+++ b/src/widget/trackdroptarget.h
@@ -2,6 +2,8 @@
#include <QString>
+class QEvent;
+
/// Mixin to mark a widget as a drop target for tracks.
///
/// This class is *not* derived from QObject (inheriting from 2 QObject classes
@@ -20,6 +22,8 @@ class TrackDropTarget {
emit trackDropped(filename, group); // clazy:exclude=incorrect-emit
}
+ virtual bool handleDragAndDropEventFromWindow(QEvent* event) { return false; }
+
signals:
virtual void trackDropped(const QString& filename, const QString& group) = 0;
virtual void cloneDeck(const QString& sourceGroup, const QString& targetGroup) = 0;
diff --git a/src/widget/wglwidgetqopengl.cpp b/src/widget/wglwidgetqopengl.cpp
index 9064955bdf..eaaae5cbfe 100644
--- a/src/widget/wglwidgetqopengl.cpp
+++ b/src/widget/wglwidgetqopengl.cpp
@@ -25,6 +25,15 @@ QPaintDevice* WGLWidget::paintDevice() {
return m_pOpenGLWindow;
}
+void WGLWidget::setTrackDropTarget(TrackDropTarget* target)
+{
+ m_pTrackDropTarget = target;
+}
+
+TrackDropTarget* WGLWidget::trackDropTarget() const {
+ return m_pTrackDropTarget;
+}
+
void WGLWidget::showEvent(QShowEvent* event) {
if (!m_pOpenGLWindow) {
m_pOpenGLWindow = new OpenGLWindow(this);
diff --git a/src/widget/wglwidgetqopengl.h b/src/widget/wglwidgetqopengl.h
index b775d4ea94..68b94b7921 100644
--- a/src/widget/wglwidgetqopengl.h
+++ b/src/widget/wglwidgetqopengl.h
@@ -12,11 +12,13 @@
class QPaintDevice;
class OpenGLWindow;
+class TrackDropTarget;
class WGLWidget : public QWidget {
private:
OpenGLWindow* m_pOpenGLWindow{};
QWidget* m_pContainerWidget{};
+ TrackDropTarget* m_pTrackDropTarget{};
public:
WGLWidget(QWidget* parent);
@@ -38,6 +40,9 @@ class WGLWidget : public QWidget {
virtual void resizeGL(int w, int h);
virtual void initializeGL();
+ void setTrackDropTarget(TrackDropTarget* target);
+ TrackDropTarget* trackDropTarget() const;
+
protected:
void showEvent(QShowEvent* event) override;
void resizeEvent(QResizeEvent* event) override;
diff --git a/src/widget/wspinnybase.cpp b/src/widget/wspinnybase.cpp
index 9e2deaaf0b..95cecd78a1 100644
--- a/src/widget/wspinnybase.cpp
+++ b/src/widget/wspinnybase.cpp
@@ -95,6 +95,10 @@ WSpinnyBase::WSpinnyBase(
this,
&WSpinnyBase::slotCoverInfoSelected);
connect(m_pCoverMenu, &WCoverArtMenu::reloadCoverArt, this, &WSpinnyBase::slotReloadCoverArt);
+
+#ifdef MIXXX_USE_QOPENGL
+ setTrackDropTarget(this);
+#endif
}
WSpinnyBase::~WSpinnyBase() {
@@ -649,6 +653,10 @@ bool WSpinnyBase::event(QEvent* pEvent) {
return WGLWidget::event(pEvent);
}
+bool WSpinnyBase::handleDragAndDropEventFromWindow(QEvent* ev) {
+ return event(ev);
+}
+
void WSpinnyBase::dragEnterEvent(QDragEnterEvent* event) {
DragAndDropHelper::handleTrackDragEnterEvent(event, m_group, m_pConfig);
}
diff --git a/src/widget/wspinnybase.h b/src/widget/wspinnybase.h
index a66840dcce..c42d1a900d 100644
--- a/src/widget/wspinnybase.h
+++ b/src/widget/wspinnybase.h
@@ -79,6 +79,9 @@ class WSpinnyBase : public WGLWidget,
void hideEvent(QHideEvent* event) override;
bool event(QEvent* pEvent) override;
+ // TrackDropTarget:
+ bool handleDragAndDropEventFromWindow(QEvent* ev) override;
+
double calculateAngle(double playpos);
int calculateFullRotations(double playpos);
double calculatePositionFromAngle(double angle);
diff --git a/src/widget/wwaveformviewer.cpp b/src/widget/wwaveformviewer.cpp
index a709e3c414..93c5f9d6e9 100644
--- a/src/widget/wwaveformviewer.cpp
+++ b/src/widget/wwaveformviewer.cpp
@@ -201,6 +201,10 @@ void WWaveformViewer::dropEvent(QDropEvent* event) {
DragAndDropHelper::handleTrackDropEvent(event, *this, m_group, m_pConfig);
}
+bool WWaveformViewer::handleDragAndDropEventFromWindow(QEvent* ev) {
+ return event(ev);
+}
+
void WWaveformViewer::leaveEvent(QEvent*) {
if (m_pHoveredMark) {
unhighlightMark(m_pHoveredMark);
@@ -268,12 +272,15 @@ void WWaveformViewer::setWaveformWidget(WaveformWidgetAbstract* waveformWidget)
connect(pWidget, &QWidget::destroyed, this, &WWaveformViewer::slotWidgetDead);
m_waveformWidget->getWidget()->setMouseTracking(true);
#ifdef MIXXX_USE_QOPENGL
- // The OpenGLWindow used to display the waveform widget interferes with the
- // normal Qt tooltip mechanism and uses it's own mechanism. We set the tooltip
- // of the waveform widget to the tooltip of its parent WWaveformViewer so the
- // OpenGLWindow will display it.
if (m_waveformWidget->getGLWidget()) {
+ // The OpenGLWindow used to display the waveform widget interferes with the
+ // normal Qt tooltip mechanism and uses it's own mechanism. We set the tooltip
+ // of the waveform widget to the tooltip of its parent WWaveformViewer so the
+ // OpenGLWindow will display it.
m_waveformWidget->getGLWidget()->setToolTip(toolTip());
+
+ // Tell the WGLWidget that this is its drag&drop target
+ m_waveformWidget->getGLWidget()->setTrackDropTarget(this);
}
#endif
// Make connection to show "Passthrough" label on the waveform, except for
diff --git a/src/widget/wwaveformviewer.h b/src/widget/wwaveformviewer.h
index 4afbe391d7..b486bf7308 100644
--- a/src/widget/wwaveformviewer.h
+++ b/src/widget/wwaveformviewer.h
@@ -32,6 +32,8 @@ class WWaveformViewer : public WWidget, public TrackDropTarget {
}
void setup(const QDomNode& node, const SkinContext& context);
+ bool handleDragAndDropEventFromWindow(QEvent* ev) override;
+
void dragEnterEvent(QDragEnterEvent *event) override;
void dropEvent(QDropEvent *event) override;