From 90239648f0e8612fd768abbcb992c2c3ce2ac3c3 Mon Sep 17 00:00:00 2001 From: Sultan Qasim Khan Date: Thu, 10 Aug 2023 23:29:58 -0400 Subject: [PATCH 1/6] plotter: fix zoom with smooth scrolling Most modern trackpads and some wired mice implement smooth scrolling, where frequent mouse events are sent with small deltas. The old calculation logic did not handle this properly, as it zoomed the same amount regardless of the size (delta) of the scroll event, resulting in excessively fast zoom and jitteriness. The new logic zooms proportional to the delta, allowing smooth and precise zoom on mice with smooth scrolling, while still also handling the large infrequent scroll events of old fashioned mice properly. --- src/qtgui/plotter.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/qtgui/plotter.cpp b/src/qtgui/plotter.cpp index cb3b2f955..40c0bb2ad 100644 --- a/src/qtgui/plotter.cpp +++ b/src/qtgui/plotter.cpp @@ -1003,16 +1003,15 @@ void CPlotter::wheelEvent(QWheelEvent * event) int px = qRound((qreal)pt.x() * m_DPR); int py = qRound((qreal)pt.y() * m_DPR); + // delta is in eigths of a degree, 15 degrees is one step int delta = m_InvertScrolling? -event->angleDelta().y() : event->angleDelta().y(); - int numDegrees = delta / 8; - int numSteps = numDegrees / 15; /** FIXME: Only used for direction **/ + double numSteps = delta / (8.0 * 15.0); - /** FIXME: zooming could use some optimisation **/ if (m_CursorCaptured == YAXIS) { // Vertical zoom. Wheel down: zoom out, wheel up: zoom in // During zoom we try to keep the point (dB or kHz) under the cursor fixed - float zoom_fac = delta < 0 ? 1.1 : 0.9; + float zoom_fac = pow(0.9, numSteps); float ratio = (float) py / (float) h; float db_range = m_PandMaxdB - m_PandMindB; float y_range = (float) h; @@ -1033,7 +1032,7 @@ void CPlotter::wheelEvent(QWheelEvent * event) } else if (m_CursorCaptured == XAXIS) { - zoomStepX(delta < 0 ? 1.1 : 0.9, px); + zoomStepX(pow(0.9, numSteps), px); } else if (event->modifiers() & Qt::ControlModifier) { From af12d5ede4fa35f5dd39c5c27c2e1ae089c29c7e Mon Sep 17 00:00:00 2001 From: Sultan Qasim Khan Date: Fri, 11 Aug 2023 00:09:02 -0400 Subject: [PATCH 2/6] plotter: accumulate small scroll events On devices with smooth scrolling (like most modern laptops), scroll events are frequent and have small deltas that are usually less than one step unless one is scrolling very quickly. Due to the tuning logic adjusting the frequency one "click" for every mouse "step", and rounding to the nearest click, slow scrolling for precise frequency adjustment on computers with smooth scrolling just gets lost to the rounding logic. This new logic accumulates scroll event deltas for frequency adjustment, making precise and comfortable tuning possible using smooth scrolling mice/trackpads. --- src/qtgui/plotter.cpp | 8 ++++++++ src/qtgui/plotter.h | 1 + 2 files changed, 9 insertions(+) diff --git a/src/qtgui/plotter.cpp b/src/qtgui/plotter.cpp index 40c0bb2ad..20f46970e 100644 --- a/src/qtgui/plotter.cpp +++ b/src/qtgui/plotter.cpp @@ -142,6 +142,7 @@ CPlotter::CPlotter(QWidget *parent) : QFrame(parent) m_PandMaxdB = m_WfMaxdB = 0.f; m_PandMindB = m_WfMindB = FFT_MAX_DB; + m_CumWheelDelta = 0; m_FreqUnits = 1000000; m_CursorCaptured = NOCAP; m_Running = false; @@ -1053,6 +1054,12 @@ void CPlotter::wheelEvent(QWheelEvent * event) } else { + // small steps will be lost by roundFreq, let them accumulate + m_CumWheelDelta += delta; + if (abs(m_CumWheelDelta) < 8*15) + return; + numSteps = m_CumWheelDelta / (8.0 * 15.0); + // inc/dec demod frequency m_DemodCenterFreq += (numSteps * m_ClickResolution); m_DemodCenterFreq = roundFreq(m_DemodCenterFreq, m_ClickResolution ); @@ -1060,6 +1067,7 @@ void CPlotter::wheelEvent(QWheelEvent * event) } updateOverlay(); + m_CumWheelDelta = 0; } // Called when screen size changes so must recalculate bitmaps diff --git a/src/qtgui/plotter.h b/src/qtgui/plotter.h index b4938f645..435931141 100644 --- a/src/qtgui/plotter.h +++ b/src/qtgui/plotter.h @@ -310,6 +310,7 @@ public slots: qint64 m_Span; float m_SampleFreq; /*!< Sample rate. */ qint32 m_FreqUnits; + qint32 m_CumWheelDelta; qreal m_ClickResolution; qreal m_FilterClickResolution; ePlotMode m_PlotMode; From 20cb177804117657626bc109bead3813555b7a63 Mon Sep 17 00:00:00 2001 From: Sultan Qasim Khan Date: Fri, 11 Aug 2023 03:20:08 -0400 Subject: [PATCH 3/6] plotter: prevent zooming signal strength OOB In some situations, it was possible to zoom in a way that causes the minimum dB value in the plotter to become too low. --- src/qtgui/plotter.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/qtgui/plotter.cpp b/src/qtgui/plotter.cpp index 20f46970e..52ea6cf20 100644 --- a/src/qtgui/plotter.cpp +++ b/src/qtgui/plotter.cpp @@ -1025,6 +1025,9 @@ void CPlotter::wheelEvent(QWheelEvent * event) m_PandMaxdB = FFT_MAX_DB; m_PandMindB = m_PandMaxdB - db_range; + if (m_PandMindB < FFT_MIN_DB) + m_PandMindB = FFT_MIN_DB; + m_MaxHoldValid = false; m_MinHoldValid = false; m_histIIRValid = false; From 55e32c1b65fe4d497480f4b9ed8945d63edad076 Mon Sep 17 00:00:00 2001 From: Sultan Qasim Khan Date: Fri, 11 Aug 2023 04:30:53 -0400 Subject: [PATCH 4/6] plotter: consistently show signal stength labels Depending on the vertical position and zoom/scale, the top most signal strength label was sometimes not being drawn despite the associated line being drawn and there being plenty of space to draw the label. This was due to a mismatch of <= being used for counting the lines, but < being used for counting the labels. The new logic makes the label indexing consistent with the line drawing indexing, while adding a check to make sure the label is not cut off vertically. --- src/qtgui/plotter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qtgui/plotter.cpp b/src/qtgui/plotter.cpp index 52ea6cf20..72ae6868a 100644 --- a/src/qtgui/plotter.cpp +++ b/src/qtgui/plotter.cpp @@ -2248,12 +2248,12 @@ void CPlotter::drawOverlay() } // draw amplitude values (y axis) - for (int i = 0; i < m_VerDivs; i++) + for (int i = 0; i <= m_VerDivs; i++) { qreal y = h - ((double)i * pixperdiv + adjoffset); qreal th = metrics.height(); qreal shadowOffset = th / 20.0; - if (y < h -xAxisHeight) + if ((y < h - xAxisHeight) && (y > th / 2)) { int dB = mindbadj + dbstepsize * i; // Shadow From 2e6301e6e442463105b188ee24013e9c848de078 Mon Sep 17 00:00:00 2001 From: Sultan Qasim Khan Date: Sat, 12 Aug 2023 19:51:32 -0400 Subject: [PATCH 5/6] freqctrl: accumulate small scroll events For computers with smooth scrolling that issue frequent scroll wheel events with small deltas. --- src/qtgui/freqctrl.cpp | 10 +++++++++- src/qtgui/freqctrl.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/qtgui/freqctrl.cpp b/src/qtgui/freqctrl.cpp index 9a616a38d..a8b96d0e2 100644 --- a/src/qtgui/freqctrl.cpp +++ b/src/qtgui/freqctrl.cpp @@ -68,6 +68,7 @@ CFreqCtrl::CFreqCtrl(QWidget *parent) : m_InvertScrolling = false; m_UnitsFont = QFont("Arial", 12, QFont::Normal); m_DigitFont = QFont("Arial", 12, QFont::Normal); + m_CumWheelDelta = 0; setStatusTip(tr(STATUS_TIP)); } @@ -492,9 +493,14 @@ void CFreqCtrl::wheelEvent(QWheelEvent *event) QPointF pt = event->position(); #endif int delta = m_InvertScrolling ? -event->angleDelta().y() : event->angleDelta().y(); - int numDegrees = delta / 8; + m_CumWheelDelta += delta; + int numDegrees = m_CumWheelDelta / 8; int numSteps = numDegrees / 15; + // accumulate enough wheel deltas to reach at least one step + if (abs(numSteps) == 0) + return; + for (int i = m_DigStart; i < m_NumDigits; i++) { if (inRect(m_DigitInfo[i].dQRect, pt)) // if in i'th digit @@ -505,6 +511,8 @@ void CFreqCtrl::wheelEvent(QWheelEvent *event) decFreq(); } } + + m_CumWheelDelta = 0; } void CFreqCtrl::keyPressEvent(QKeyEvent *event) diff --git a/src/qtgui/freqctrl.h b/src/qtgui/freqctrl.h index 46066fae6..842655e5c 100644 --- a/src/qtgui/freqctrl.h +++ b/src/qtgui/freqctrl.h @@ -106,6 +106,7 @@ public slots: int m_LastEditDigit; int m_DecPos; int m_NumSeps; + int m_CumWheelDelta; qint64 m_MinStep; qint64 m_freq; From a70fd75bd91e1a9f4dfe03468330b2af7cd1e6bb Mon Sep 17 00:00:00 2001 From: Clayton Smith Date: Wed, 27 Sep 2023 00:40:32 -0400 Subject: [PATCH 6/6] Update news --- resources/news.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/news.txt b/resources/news.txt index 0afc7731c..9b54c088a 100644 --- a/resources/news.txt +++ b/resources/news.txt @@ -27,6 +27,7 @@ IMPROVED: Added 6 dB attenuation to WAV file recordings to prevent clipping. IMPROVED: Use logarithmic scale for frequency zoom slider. IMPROVED: Reduced CPU utilization of demodulators. + IMPROVED: Properly handle smooth scrolling. CHANGED: Frequency zoom slider zooms around center of display. CHANGED: Disallow scrolling beyond the FFT frequency limits. CHANGED: Default narrow FM deviation increased to 5 kHz.