diff --git a/src/widget/openglwindow.cpp b/src/widget/openglwindow.cpp index 6797c5428ee..8ab560f9b98 100644 --- a/src/widget/openglwindow.cpp +++ b/src/widget/openglwindow.cpp @@ -135,6 +135,7 @@ bool OpenGLWindow::event(QEvent* pEv) { // 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. + qWarning() << " ---- OpenGLWindow" << pEv; QApplication::sendEvent(m_pWidget, pEv); } diff --git a/src/widget/wspinnybase.cpp b/src/widget/wspinnybase.cpp index 7aad5845d0e..b2a254586a3 100644 --- a/src/widget/wspinnybase.cpp +++ b/src/widget/wspinnybase.cpp @@ -501,44 +501,43 @@ void WSpinnyBase::updateSlipEnabled(double enabled) { } void WSpinnyBase::mouseMoveEvent(QMouseEvent* e) { + if ((e->buttons() & Qt::LeftButton) || (e->buttons() & Qt::RightButton)) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - int y = static_cast(e->position().y()); - int x = static_cast(e->position().x()); + int y = static_cast(e->position().y()); + int x = static_cast(e->position().x()); #else - int y = e->y(); - int x = e->x(); + int y = e->y(); + int x = e->x(); #endif - // Keeping these around in case we want to switch to control relative - // to the original mouse position. - // int dX = x-m_iStartMouseX; - // int dY = y-m_iStartMouseY; - - // Coordinates from center of widget - double c_x = x - width() / 2; - double c_y = y - height() / 2; - double theta = (180.0 / M_PI) * atan2(c_x, -c_y); - - // qDebug() << "c_x:" << c_x << "c_y:" << c_y << - // "dX:" << dX << "dY:" << dY; - - // When we finish one full rotation (clockwise or anticlockwise), - // we'll need to manually add/sub 360 degrees because atan2()'s range is - // only within -180 to 180 degrees. We need a wider range so your position - // in the song can be tracked. - if (m_dPrevTheta > 100 && theta < 0) { - m_iFullRotations++; - } else if (m_dPrevTheta < -100 && theta > 0) { - m_iFullRotations--; - } - - m_dPrevTheta = theta; - theta += m_iFullRotations * 360; + // Keeping these around in case we want to switch to control relative + // to the original mouse position. + // int dX = x-m_iStartMouseX; + // int dY = y-m_iStartMouseY; + + // Coordinates from center of widget + double c_x = x - width() / 2; + double c_y = y - height() / 2; + double theta = (180.0 / M_PI) * atan2(c_x, -c_y); + + // qDebug() << "c_x:" << c_x << "c_y:" << c_y << + // "dX:" << dX << "dY:" << dY; + + // When we finish one full rotation (clockwise or anticlockwise), + // we'll need to manually add/sub 360 degrees because atan2()'s range is + // only within -180 to 180 degrees. We need a wider range so your position + // in the song can be tracked. + if (m_dPrevTheta > 100 && theta < 0) { + m_iFullRotations++; + } else if (m_dPrevTheta < -100 && theta > 0) { + m_iFullRotations--; + } - // qDebug() << "c t:" << theta << "pt:" << m_dPrevTheta << - // "icr" << m_iFullRotations; + m_dPrevTheta = theta; + theta += m_iFullRotations * 360; - if ((e->buttons() & Qt::LeftButton) || (e->buttons() & Qt::RightButton)) { + // qDebug() << "c t:" << theta << "pt:" << m_dPrevTheta << + // "icr" << m_iFullRotations; // Convert deltaTheta into a percentage of song length. double absPos = calculatePositionFromAngle(theta); double absPosInSamples = absPos * m_pTrackSamples->get(); @@ -609,12 +608,20 @@ void WSpinnyBase::mousePressEvent(QMouseEvent* e) { void WSpinnyBase::mouseReleaseEvent(QMouseEvent* e) { if (e->button() == Qt::LeftButton || e->button() == Qt::RightButton) { - QApplication::restoreOverrideCursor(); - m_pScratchToggle->set(0.0); - m_iFullRotations = 0; + stopScratching(); } } +void WSpinnyBase::leaveEvent(QEvent*) { + stopScratching(); +} + +void WSpinnyBase::stopScratching() { + QApplication::restoreOverrideCursor(); + m_pScratchToggle->set(0.0); + m_iFullRotations = 0; +} + void WSpinnyBase::showEvent(QShowEvent* event) { Q_UNUSED(event); WGLWidget::showEvent(event); diff --git a/src/widget/wspinnybase.h b/src/widget/wspinnybase.h index bc7703c6cae..9aef63527ab 100644 --- a/src/widget/wspinnybase.h +++ b/src/widget/wspinnybase.h @@ -72,11 +72,14 @@ class WSpinnyBase : public WGLWidget, void mouseMoveEvent(QMouseEvent* e) override; void mousePressEvent(QMouseEvent* e) override; void mouseReleaseEvent(QMouseEvent* e) override; + void leaveEvent(QEvent* e) override; void resizeEvent(QResizeEvent* /*unused*/) override; void showEvent(QShowEvent* event) override; void hideEvent(QHideEvent* event) override; bool event(QEvent* pEvent) override; + void stopScratching(); + // TrackDropTarget: bool handleDragAndDropEventFromWindow(QEvent* pEvent) override; diff --git a/src/widget/wwaveformviewer.cpp b/src/widget/wwaveformviewer.cpp index 9e672f12c9f..e0ecfb64c0b 100644 --- a/src/widget/wwaveformviewer.cpp +++ b/src/widget/wwaveformviewer.cpp @@ -41,6 +41,8 @@ WWaveformViewer::WWaveformViewer( setAttribute(Qt::WA_OpaquePaintEvent); setFocusPolicy(Qt::NoFocus); + + setCursor(Qt::OpenHandCursor); } WWaveformViewer::~WWaveformViewer() { @@ -132,6 +134,18 @@ void WWaveformViewer::mouseMoveEvent(QMouseEvent* event) { return; } + // Apparently it's possible that we don't receive button release events + // which means we assume we're still scratching or bending even though + // it's not desired anymore. + // Stop scratching/bending in this case + if (event->buttons().testFlag(Qt::NoButton)) { + qWarning() << " ."; + qWarning() << " moved, no button -> stop scratching and bending"; + qWarning() << " ."; + stopScratchingAndBending(); + return; + } + // Only send signals for mouse moving if the left button is pressed if (m_bScratching) { int eventPosValue = m_waveformWidget->getOrientation() == Qt::Horizontal ? @@ -178,18 +192,7 @@ void WWaveformViewer::mouseMoveEvent(QMouseEvent* event) { } void WWaveformViewer::mouseReleaseEvent(QMouseEvent* /*event*/) { - if (m_bScratching) { - m_pScratchPositionEnable->set(0.0); - m_bScratching = false; - } - if (m_bBending) { - m_pWheel->setParameter(0.5); - m_bBending = false; - } - m_mouseAnchor = QPoint(); - - // Set the cursor back to an arrow. - setCursor(Qt::ArrowCursor); + stopScratchingAndBending(); } void WWaveformViewer::wheelEvent(QWheelEvent* event) { @@ -215,10 +218,27 @@ bool WWaveformViewer::handleDragAndDropEventFromWindow(QEvent* pEvent) { } void WWaveformViewer::leaveEvent(QEvent*) { - if (m_pHoveredMark) { - unhighlightMark(m_pHoveredMark); - m_pHoveredMark = nullptr; + // if (m_pHoveredMark) { + // unhighlightMark(m_pHoveredMark); + // m_pHoveredMark = nullptr; + // } + // setCursor(Qt::ForbiddenCursor); + // stopScratchingAndBending(); +} + +void WWaveformViewer::stopScratchingAndBending() { + if (m_bScratching) { + m_pScratchPositionEnable->set(0.0); + m_bScratching = false; } + if (m_bBending) { + m_pWheel->setParameter(0.5); + m_bBending = false; + } + m_mouseAnchor = QPoint(); + + // Set the cursor back to an open hand. + setCursor(Qt::OpenHandCursor); } void WWaveformViewer::slotTrackLoaded(TrackPointer track) { diff --git a/src/widget/wwaveformviewer.h b/src/widget/wwaveformviewer.h index eead266f540..510c4763931 100644 --- a/src/widget/wwaveformviewer.h +++ b/src/widget/wwaveformviewer.h @@ -63,6 +63,8 @@ class WWaveformViewer : public WWidget, public TrackDropTarget { void setDisplayBeatGridAlpha(int alpha); void setPlayMarkerPosition(double position); + void stopScratchingAndBending(); + private: const QString m_group; UserSettingsPointer m_pConfig;