diff --git a/src/widget/knobeventhandler.h b/src/widget/knobeventhandler.h index 5273edd4eae..0280e3203fe 100644 --- a/src/widget/knobeventhandler.h +++ b/src/widget/knobeventhandler.h @@ -1,22 +1,28 @@ #pragma once -#include -#include -#include #include -#include +#include #include +#include +#include +#include #include "util/math.h" +// duration (ms) the cursor is blanked after a mouse wheel event +// 800 ms is the duration the parameter value is shown in the parameter name widget +// src/widget/weffectparameternamebase.cpp +constexpr int wheelEventCursorTimeout = 800; + template class KnobEventHandler { public: KnobEventHandler() - : m_bRightButtonPressed(false) { - QPixmap blankPixmap(32, 32); - blankPixmap.fill(QColor(0, 0, 0, 0)); - m_blankCursor = QCursor(blankPixmap); + : m_bRightButtonPressed(false), + m_pWheelCursorTimer(nullptr) { + QPixmap blankPixmap(32, 32); + blankPixmap.fill(Qt::transparent); + m_blankCursor = QCursor(blankPixmap); } double valueFromMouseEvent(T* pWidget, QMouseEvent* e) { @@ -103,6 +109,9 @@ class KnobEventHandler { } void wheelEvent(T* pWidget, QWheelEvent* e) { + // Hide/blank the cursor so the parameter value below the knob is not obscured. + // Restore the cursor when the timer runs out, or when the cursor leaves the widget. + pWidget->setCursor(m_blankCursor); // For legacy (MIDI) reasons this is tuned to 127. double wheelDirection = e->angleDelta().y() / (120.0 * 127.0); double newValue = pWidget->getControlParameter() + wheelDirection; @@ -113,6 +122,26 @@ class KnobEventHandler { pWidget->setControlParameter(newValue); pWidget->inputActivity(); e->accept(); + if (!m_pWheelCursorTimer) { + m_pWheelCursorTimer = new QTimer(pWidget); + m_pWheelCursorTimer->setSingleShot(true); + m_pWheelCursorTimer->setInterval(wheelEventCursorTimeout); + } + m_pWheelCursorTimer->start(); + m_pWheelCursorTimer->callOnTimeout( + [pWidget]() { + if (pWidget) { + pWidget->unsetCursor(); + } + }); + } + + void leaveEvent(T* pWidget, QEvent* e) { + if (m_pWheelCursorTimer && m_pWheelCursorTimer->isActive()) { + m_pWheelCursorTimer->stop(); + pWidget->unsetCursor(); + } + e->accept(); } private: @@ -123,4 +152,5 @@ class KnobEventHandler { QPoint m_startPos; QPoint m_prevPos; QCursor m_blankCursor; + QTimer* m_pWheelCursorTimer; }; diff --git a/src/widget/wknob.cpp b/src/widget/wknob.cpp index f31d1d15ba7..f4a4fb7ee54 100644 --- a/src/widget/wknob.cpp +++ b/src/widget/wknob.cpp @@ -38,6 +38,10 @@ void WKnob::wheelEvent(QWheelEvent* e) { m_handler.wheelEvent(this, e); } +void WKnob::leaveEvent(QEvent* e) { + m_handler.leaveEvent(this, e); +} + void WKnob::inputActivity() { #ifdef __APPLE__ m_renderTimer.activity(); diff --git a/src/widget/wknob.h b/src/widget/wknob.h index 95ffe710794..84b341fcfa7 100644 --- a/src/widget/wknob.h +++ b/src/widget/wknob.h @@ -21,6 +21,7 @@ class WKnob : public WDisplay { protected: void wheelEvent(QWheelEvent *e) override; + void leaveEvent(QEvent* e) override; void mouseMoveEvent(QMouseEvent *e) override; void mousePressEvent(QMouseEvent *e) override; void mouseDoubleClickEvent(QMouseEvent* e) override; diff --git a/src/widget/wknobcomposed.cpp b/src/widget/wknobcomposed.cpp index cc318ac80dd..deaff61ec8c 100644 --- a/src/widget/wknobcomposed.cpp +++ b/src/widget/wknobcomposed.cpp @@ -227,6 +227,10 @@ void WKnobComposed::wheelEvent(QWheelEvent* e) { m_handler.wheelEvent(this, e); } +void WKnobComposed::leaveEvent(QEvent* e) { + m_handler.leaveEvent(this, e); +} + void WKnobComposed::inputActivity() { #ifdef __APPLE__ m_renderTimer.activity(); diff --git a/src/widget/wknobcomposed.h b/src/widget/wknobcomposed.h index cf3e287575c..da35a2175e7 100644 --- a/src/widget/wknobcomposed.h +++ b/src/widget/wknobcomposed.h @@ -28,6 +28,7 @@ class WKnobComposed : public WWidget { protected: void wheelEvent(QWheelEvent *e) override; + void leaveEvent(QEvent* e) override; void mouseMoveEvent(QMouseEvent *e) override; void mousePressEvent(QMouseEvent *e) override; void mouseDoubleClickEvent(QMouseEvent* e) override;