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. 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; diff --git a/src/qtgui/plotter.cpp b/src/qtgui/plotter.cpp index cb3b2f955..72ae6868a 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; @@ -1003,16 +1004,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; @@ -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; @@ -1033,7 +1036,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) { @@ -1054,6 +1057,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 ); @@ -1061,6 +1070,7 @@ void CPlotter::wheelEvent(QWheelEvent * event) } updateOverlay(); + m_CumWheelDelta = 0; } // Called when screen size changes so must recalculate bitmaps @@ -2238,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 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;