From d1670b3ab42de6f273b110761d03f699c4be3132 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Fri, 24 Jun 2022 14:47:33 +0100 Subject: [PATCH] Spectrum: Allow frequency scolling with middle mouse button and moving channel marker outside of frequency range --- sdrgui/gui/glspectrum.cpp | 47 ++++++++++++++++++++++++- sdrgui/gui/glspectrum.h | 8 +++++ sdrgui/mainspectrum/mainspectrumgui.cpp | 10 ++++++ sdrgui/mainspectrum/mainspectrumgui.h | 1 + 4 files changed, 65 insertions(+), 1 deletion(-) diff --git a/sdrgui/gui/glspectrum.cpp b/sdrgui/gui/glspectrum.cpp index 8e24ae9ee..4bdf5a476 100644 --- a/sdrgui/gui/glspectrum.cpp +++ b/sdrgui/gui/glspectrum.cpp @@ -92,6 +92,8 @@ GLSpectrum::GLSpectrum(QWidget* parent) : m_scaleZ3DSpectrogram(false), m_3DSpectrogramStyle(SpectrumSettings::Outline), m_colorMapName("Angel"), + m_scrollFrequency(false), + m_scrollStartCenterFreq(0), m_histogramBuffer(nullptr), m_histogram(nullptr), m_displayHistogram(true), @@ -2984,6 +2986,19 @@ void GLSpectrum::mouseMoveEvent(QMouseEvent* event) return; } + if (m_scrollFrequency) + { + // Request containing widget to adjust center frequency + // Not all containers will support this - mainly for MainSpectrumGUI + // This can be a little slow on some SDRs, so we use delta from where + // button was originally pressed rather than do it incrementally + QPointF delta = m_mousePrevLocalPos - event->localPos(); + float histogramWidth = width() - m_leftMargin - m_rightMargin; + qint64 frequency = (qint64)(m_scrollStartCenterFreq + delta.x()/histogramWidth * m_frequencyScale.getRange()); + emit requestCenterFrequency(frequency); + return; + } + if (m_displayWaterfall || m_displayHistogram || m_displayMaxHold || m_displayCurrent) { if (m_frequencyScaleRect.contains(event->pos())) @@ -3035,8 +3050,18 @@ void GLSpectrum::mouseMoveEvent(QMouseEvent* event) } else if (m_cursorState == CSChannelMoving) { - Real freq = m_frequencyScale.getValueFromPos(event->x() - m_leftMarginPixmap.width() - 1) - m_centerFrequency; + // Determine if user is trying to move the channel outside of the current frequency range + // and if so, request an adjustment to the center frequency + Real freqAbs = m_frequencyScale.getValueFromPos(event->x() - m_leftMarginPixmap.width() - 1); + Real freqMin = m_centerFrequency - m_sampleRate / 2.0f; + Real freqMax = m_centerFrequency + m_sampleRate / 2.0f; + if (freqAbs < freqMin) { + emit requestCenterFrequency(m_centerFrequency - (freqMin - freqAbs)); + } else if (freqAbs > freqMax) { + emit requestCenterFrequency(m_centerFrequency + (freqAbs - freqMax)); + } + Real freq = freqAbs - m_centerFrequency; if (m_channelMarkerStates[m_cursorChannel]->m_channelMarker->getMovable() && (m_channelMarkerStates[m_cursorChannel]->m_channelMarker->getSourceOrSinkStream() == m_displaySourceOrSink) && m_channelMarkerStates[m_cursorChannel]->m_channelMarker->streamIndexApplies(m_displayStreamIndex)) @@ -3096,6 +3121,14 @@ void GLSpectrum::mousePressEvent(QMouseEvent* event) { const QPointF& ep = event->localPos(); + if ((event->button() == Qt::MiddleButton) && (m_displayMaxHold || m_displayCurrent || m_displayHistogram) && pointInHistogram(ep)) + { + m_scrollFrequency = true; + m_scrollStartCenterFreq = m_centerFrequency; + m_mousePrevLocalPos = ep; + return; + } + if ((event->button() == Qt::MiddleButton) && m_display3DSpectrogram && pointInWaterfallOrSpectrogram(ep)) { m_pan3DSpectrogram = true; @@ -3341,6 +3374,7 @@ void GLSpectrum::mousePressEvent(QMouseEvent* event) void GLSpectrum::mouseReleaseEvent(QMouseEvent*) { + m_scrollFrequency = false; m_pan3DSpectrogram = false; m_rotate3DSpectrogram = false; m_scaleZ3DSpectrogram = false; @@ -3654,6 +3688,17 @@ bool GLSpectrum::pointInWaterfallOrSpectrogram(const QPointF &point) const return (pWat.x() >= 0) && (pWat.x() <= 1) && (pWat.y() >= 0) && (pWat.y() <= 1); } +// Return if specified point is within the bounds of the histogram screen area +bool GLSpectrum::pointInHistogram(const QPointF &point) const +{ + // m_histogramRect is normalised to [0,1] + QPointF p = point; + p.rx() = (point.x()/width() - m_histogramRect.left()) / m_histogramRect.width(); + p.ry() = (point.y()/height() - m_histogramRect.top()) / m_histogramRect.height(); + + return (p.x() >= 0) && (p.x() <= 1) && (p.y() >= 0) && (p.y() <= 1); +} + void GLSpectrum::enterEvent(QEvent* event) { m_mouseInside = true; diff --git a/sdrgui/gui/glspectrum.h b/sdrgui/gui/glspectrum.h index 60141499b..e074fcd40 100644 --- a/sdrgui/gui/glspectrum.h +++ b/sdrgui/gui/glspectrum.h @@ -319,6 +319,9 @@ private: SpectrumSettings::SpectrumStyle m_spectrumStyle; const float *m_colorMap; + bool m_scrollFrequency; + qint64 m_scrollStartCenterFreq; + QRgb m_histogramPalette[240]; QImage* m_histogramBuffer; quint8* m_histogram; //!< Spectrum phosphor matrix of FFT width and PSD height scaled to 100. values [0..239] @@ -391,6 +394,7 @@ private: void setPowerScale(int height); void getFrequencyZoom(int64_t& centerFrequency, int& frequencySpan); bool pointInWaterfallOrSpectrogram(const QPointF &point) const; + bool pointInHistogram(const QPointF &point) const; void enterEvent(QEvent* event); void leaveEvent(QEvent* event); @@ -432,6 +436,10 @@ private slots: void channelMarkerDestroyed(QObject* object); void openGLDebug(const QOpenGLDebugMessage &debugMessage); bool eventFilter(QObject *object, QEvent *event); + +signals: + // Emitted when user tries to scroll to frequency currently out of range + void requestCenterFrequency(qint64 frequency); }; #endif // INCLUDE_GLSPECTRUM_H diff --git a/sdrgui/mainspectrum/mainspectrumgui.cpp b/sdrgui/mainspectrum/mainspectrumgui.cpp index 60d4e1e14..8e82dddc6 100644 --- a/sdrgui/mainspectrum/mainspectrumgui.cpp +++ b/sdrgui/mainspectrum/mainspectrumgui.cpp @@ -29,6 +29,7 @@ #include "gui/glspectrumgui.h" #include "gui/workspaceselectiondialog.h" #include "dsp/spectrumvis.h" +#include "channel/channelwebapiutils.h" #include "mainspectrumgui.h" MainSpectrumGUI::MainSpectrumGUI(GLSpectrum *spectrum, GLSpectrumGUI *spectrumGUI, QWidget *parent) : @@ -141,6 +142,8 @@ MainSpectrumGUI::MainSpectrumGUI(GLSpectrum *spectrum, GLSpectrumGUI *spectrumGU connect(this, SIGNAL(forceShrink()), this, SLOT(shrinkWindow())); connect(m_hideButton, SIGNAL(clicked()), this, SLOT(hide())); + connect(spectrum, &GLSpectrum::requestCenterFrequency, this, &MainSpectrumGUI::onRequestCenterFrequency); + m_resizer.enableChildMouseTracking(); shrinkWindow(); } @@ -317,3 +320,10 @@ QString MainSpectrumGUI::getDeviceTypeTag() return "X"; } } + +// Handle request from GLSpectrum to adjust center frequency +void MainSpectrumGUI::onRequestCenterFrequency(qint64 frequency) +{ + double frequencyInHz = (double)frequency; + ChannelWebAPIUtils::setCenterFrequency(m_deviceSetIndex, frequencyInHz); +} diff --git a/sdrgui/mainspectrum/mainspectrumgui.h b/sdrgui/mainspectrum/mainspectrumgui.h index 1d9f0cabe..884359fa3 100644 --- a/sdrgui/mainspectrum/mainspectrumgui.h +++ b/sdrgui/mainspectrum/mainspectrumgui.h @@ -106,6 +106,7 @@ private slots: void showHelp(); void openMoveToWorkspaceDialog(); void shrinkWindow(); + void onRequestCenterFrequency(qint64 frequency); signals: void closing();