Merge pull request #1540 from srcejon/android

GLSpectrum touchscreen updates
This commit is contained in:
Edouard Griffiths 2022-12-20 16:42:58 +01:00 committed by GitHub
commit 7f720a369e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 2017 additions and 1692 deletions

View File

@ -80,6 +80,11 @@ void SpectrumSettings::resetToDefaults()
m_measurementsPosition = PositionBelow; m_measurementsPosition = PositionBelow;
m_measurementPrecision = 1; m_measurementPrecision = 1;
m_findHistogramPeaks = false; m_findHistogramPeaks = false;
#ifdef ANDROID
m_showAllControls = false;
#else
m_showAllControls = true;
#endif
} }
QByteArray SpectrumSettings::serialize() const QByteArray SpectrumSettings::serialize() const
@ -132,6 +137,7 @@ QByteArray SpectrumSettings::serialize() const
s.writeS32(46, m_measurementCenterFrequencyOffset); s.writeS32(46, m_measurementCenterFrequencyOffset);
s.writeBool(47, m_findHistogramPeaks); s.writeBool(47, m_findHistogramPeaks);
s.writeBool(48, m_truncateFreqScale); s.writeBool(48, m_truncateFreqScale);
s.writeBool(49, m_showAllControls);
s.writeS32(100, m_histogramMarkers.size()); s.writeS32(100, m_histogramMarkers.size());
for (int i = 0; i < m_histogramMarkers.size(); i++) { for (int i = 0; i < m_histogramMarkers.size(); i++) {
@ -236,6 +242,11 @@ bool SpectrumSettings::deserialize(const QByteArray& data)
d.readS32(46, &m_measurementCenterFrequencyOffset, 0); d.readS32(46, &m_measurementCenterFrequencyOffset, 0);
d.readBool(47, &m_findHistogramPeaks, false); d.readBool(47, &m_findHistogramPeaks, false);
d.readBool(48, &m_truncateFreqScale, false); d.readBool(48, &m_truncateFreqScale, false);
#ifdef ANDROID
d.readBool(49, &m_showAllControls, false);
#else
d.readBool(49, &m_showAllControls, true);
#endif
int histogramMarkersSize; int histogramMarkersSize;
d.readS32(100, &histogramMarkersSize, 0); d.readS32(100, &histogramMarkersSize, 0);

View File

@ -138,6 +138,7 @@ public:
bool m_measurementHighlight; bool m_measurementHighlight;
MeasurementsPosition m_measurementsPosition; MeasurementsPosition m_measurementsPosition;
int m_measurementPrecision; int m_measurementPrecision;
bool m_showAllControls;
static const int m_log2FFTSizeMin = 6; // 64 static const int m_log2FFTSizeMin = 6; // 64
static const int m_log2FFTSizeMax = 15; // 32k static const int m_log2FFTSizeMax = 15; // 32k

View File

@ -24,6 +24,10 @@
#include <QVector4D> #include <QVector4D>
#include <QDebug> #include <QDebug>
#ifdef ANDROID
#include <GLES3/gl3.h>
#endif
#include "gui/glshadercolormap.h" #include "gui/glshadercolormap.h"
#include "util/colormap.h" #include "util/colormap.h"

View File

@ -26,6 +26,10 @@
#include <QVector4D> #include <QVector4D>
#include <QDebug> #include <QDebug>
#ifdef ANDROID
#include <GLES3/gl3.h>
#endif
#include "gui/glshaderspectrogram.h" #include "gui/glshaderspectrogram.h"
#include "util/colormap.h" #include "util/colormap.h"
@ -314,7 +318,7 @@ void GLShaderSpectrogram::initTextureMutable(const QImage& image)
glGenTextures(1, &m_textureId); glGenTextures(1, &m_textureId);
glBindTexture(GL_TEXTURE_2D, m_textureId); glBindTexture(GL_TEXTURE_2D, m_textureId);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, glTexImage2D(GL_TEXTURE_2D, 0, GL_R8,
image.width(), image.height(), 0, GL_RED, GL_UNSIGNED_BYTE, image.constScanLine(0)); image.width(), image.height(), 0, GL_RED, GL_UNSIGNED_BYTE, image.constScanLine(0));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

View File

@ -24,6 +24,10 @@
#include <QVector4D> #include <QVector4D>
#include <QDebug> #include <QDebug>
#ifdef ANDROID
#include <GLES3/gl3.h>
#endif
#include "gui/glshadertextured.h" #include "gui/glshadertextured.h"
GLShaderTextured::GLShaderTextured() : GLShaderTextured::GLShaderTextured() :
@ -296,7 +300,11 @@ bool GLShaderTextured::useImmutableStorage()
GLuint textureId; GLuint textureId;
glGenTextures(1, &textureId); glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId); glBindTexture(GL_TEXTURE_2D, textureId);
#ifdef ANDROID
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1);
#else
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
#endif
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data);
GLenum err = glGetError(); GLenum err = glGetError();
glDeleteTextures(1, &textureId); glDeleteTextures(1, &textureId);

View File

@ -37,6 +37,8 @@
#include "gui/spectrummeasurementsdialog.h" #include "gui/spectrummeasurementsdialog.h"
#include "gui/spectrummeasurements.h" #include "gui/spectrummeasurements.h"
#include "gui/flowlayout.h" #include "gui/flowlayout.h"
#include "gui/dialogpositioner.h"
#include "gui/dialpopup.h"
#include "util/colormap.h" #include "util/colormap.h"
#include "util/simpleserializer.h" #include "util/simpleserializer.h"
#include "util/db.h" #include "util/db.h"
@ -94,6 +96,8 @@ GLSpectrumGUI::GLSpectrumGUI(QWidget* parent) :
CRightClickEnabler *calibrationPointsRightClickEnabler = new CRightClickEnabler(ui->calibration); CRightClickEnabler *calibrationPointsRightClickEnabler = new CRightClickEnabler(ui->calibration);
connect(calibrationPointsRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(openCalibrationPointsDialog(const QPoint &))); connect(calibrationPointsRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(openCalibrationPointsDialog(const QPoint &)));
DialPopup::addPopupsToChildDials(this);
displaySettings(); displaySettings();
setAveragingCombo(); setAveragingCombo();
applySettings(); applySettings();
@ -168,6 +172,7 @@ void GLSpectrumGUI::updateSettings()
void GLSpectrumGUI::displaySettings() void GLSpectrumGUI::displaySettings()
{ {
blockApplySettings(true); blockApplySettings(true);
ui->showAllControls->setChecked(m_settings.m_showAllControls);
ui->refLevel->setValue(m_settings.m_refLevel + m_calibrationShiftdB); ui->refLevel->setValue(m_settings.m_refLevel + m_calibrationShiftdB);
ui->levelRange->setValue(m_settings.m_powerRange); ui->levelRange->setValue(m_settings.m_powerRange);
ui->decay->setSliderPosition(m_settings.m_decay); ui->decay->setSliderPosition(m_settings.m_decay);
@ -176,7 +181,7 @@ void GLSpectrumGUI::displaySettings()
ui->waterfall->setChecked(m_settings.m_displayWaterfall); ui->waterfall->setChecked(m_settings.m_displayWaterfall);
ui->spectrogram->setChecked(m_settings.m_display3DSpectrogram); ui->spectrogram->setChecked(m_settings.m_display3DSpectrogram);
ui->spectrogramStyle->setCurrentIndex((int) m_settings.m_3DSpectrogramStyle); ui->spectrogramStyle->setCurrentIndex((int) m_settings.m_3DSpectrogramStyle);
ui->spectrogramStyle->setVisible(m_settings.m_display3DSpectrogram); ui->spectrogramStyle->setVisible(m_settings.m_display3DSpectrogram && m_settings.m_showAllControls);
ui->colorMap->setCurrentText(m_settings.m_colorMap); ui->colorMap->setCurrentText(m_settings.m_colorMap);
ui->currentLine->blockSignals(true); ui->currentLine->blockSignals(true);
ui->currentFill->blockSignals(true); ui->currentFill->blockSignals(true);
@ -236,6 +241,7 @@ void GLSpectrumGUI::displaySettings()
setAveragingToolitp(); setAveragingToolitp();
ui->calibration->setChecked(m_settings.m_useCalibration); ui->calibration->setChecked(m_settings.m_useCalibration);
displayGotoMarkers(); displayGotoMarkers();
displayControls();
ui->fftWindow->blockSignals(false); ui->fftWindow->blockSignals(false);
ui->averaging->blockSignals(false); ui->averaging->blockSignals(false);
@ -246,6 +252,37 @@ void GLSpectrumGUI::displaySettings()
updateMeasurements(); updateMeasurements();
} }
void GLSpectrumGUI::displayControls()
{
ui->grid->setVisible(m_settings.m_showAllControls);
ui->gridIntensity->setVisible(m_settings.m_showAllControls);
ui->truncateScale->setVisible(m_settings.m_showAllControls);
ui->clearSpectrum->setVisible(m_settings.m_showAllControls);
ui->histogram->setVisible(m_settings.m_showAllControls);
ui->maxHold->setVisible(m_settings.m_showAllControls);
ui->decay->setVisible(m_settings.m_showAllControls);
ui->decayDivisor->setVisible(m_settings.m_showAllControls);
ui->stroke->setVisible(m_settings.m_showAllControls);
ui->currentLine->setVisible(m_settings.m_showAllControls);
ui->currentFill->setVisible(m_settings.m_showAllControls);
ui->currentGradient->setVisible(m_settings.m_showAllControls);
ui->traceIntensity->setVisible(m_settings.m_showAllControls);
ui->colorMap->setVisible(m_settings.m_showAllControls);
ui->invertWaterfall->setVisible(m_settings.m_showAllControls);
ui->waterfall->setVisible(m_settings.m_showAllControls);
ui->spectrogram->setVisible(m_settings.m_showAllControls);
ui->spectrogramStyle->setVisible(m_settings.m_showAllControls);
ui->fftWindow->setVisible(m_settings.m_showAllControls);
ui->fftSize->setVisible(m_settings.m_showAllControls);
ui->fftOverlap->setVisible(m_settings.m_showAllControls);
ui->fps->setVisible(m_settings.m_showAllControls);
ui->linscale->setVisible(m_settings.m_showAllControls);
ui->save->setVisible(m_settings.m_showAllControls);
ui->wsSpectrum->setVisible(m_settings.m_showAllControls);
ui->calibration->setVisible(m_settings.m_showAllControls);
ui->markers->setVisible(m_settings.m_showAllControls);
}
void GLSpectrumGUI::displayGotoMarkers() void GLSpectrumGUI::displayGotoMarkers()
{ {
ui->gotoMarker->clear(); ui->gotoMarker->clear();
@ -484,6 +521,7 @@ void GLSpectrumGUI::on_markers_clicked(bool checked)
QRect mouseScreenGeometry = screen->geometry(); QRect mouseScreenGeometry = screen->geometry();
QPoint localCursorPos = globalCursorPos - mouseScreenGeometry.topLeft(); QPoint localCursorPos = globalCursorPos - mouseScreenGeometry.topLeft();
m_markersDialog->move(localCursorPos); m_markersDialog->move(localCursorPos);
new DialogPositioner(m_markersDialog, false);
m_markersDialog->show(); m_markersDialog->show();
} }
@ -616,7 +654,7 @@ void GLSpectrumGUI::on_spectrogram_toggled(bool checked)
ui->waterfall->setChecked(false); ui->waterfall->setChecked(false);
blockApplySettings(false); blockApplySettings(false);
} }
ui->spectrogramStyle->setVisible(m_settings.m_display3DSpectrogram); ui->spectrogramStyle->setVisible(m_settings.m_display3DSpectrogram && m_settings.m_showAllControls);
applySettings(); applySettings();
} }
@ -677,6 +715,13 @@ void GLSpectrumGUI::on_invertWaterfall_toggled(bool checked)
applySettings(); applySettings();
} }
void GLSpectrumGUI::on_showAllControls_toggled(bool checked)
{
m_settings.m_showAllControls = checked;
displayControls();
applySettings();
}
void GLSpectrumGUI::on_grid_toggled(bool checked) void GLSpectrumGUI::on_grid_toggled(bool checked)
{ {
m_settings.m_displayGrid = checked; m_settings.m_displayGrid = checked;
@ -987,6 +1032,7 @@ void GLSpectrumGUI::openWebsocketSpectrumSettingsDialog(const QPoint& p)
dialog.setPort(m_settings.m_wsSpectrumPort); dialog.setPort(m_settings.m_wsSpectrumPort);
dialog.move(p); dialog.move(p);
new DialogPositioner(&dialog, false);
dialog.exec(); dialog.exec();
if (dialog.hasChanged()) if (dialog.hasChanged())
@ -1010,6 +1056,7 @@ void GLSpectrumGUI::openCalibrationPointsDialog(const QPoint& p)
dialog.setCenterFrequency(m_glSpectrum->getCenterFrequency()); dialog.setCenterFrequency(m_glSpectrum->getCenterFrequency());
connect(&dialog, SIGNAL(updateCalibrationPoints()), this, SLOT(updateCalibrationPoints())); connect(&dialog, SIGNAL(updateCalibrationPoints()), this, SLOT(updateCalibrationPoints()));
dialog.move(p); dialog.move(p);
new DialogPositioner(&dialog, false);
dialog.exec(); dialog.exec();
m_settings.m_histogramMarkers = m_glSpectrum->getHistogramMarkers(); m_settings.m_histogramMarkers = m_glSpectrum->getHistogramMarkers();

View File

@ -79,6 +79,7 @@ private:
void applySettings(); void applySettings();
void applySpectrumSettings(); void applySpectrumSettings();
void displaySettings(); void displaySettings();
void displayControls();
void setAveragingCombo(); void setAveragingCombo();
void setNumberStr(int n, QString& s); void setNumberStr(int n, QString& s);
void setNumberStr(float v, int decimalPlaces, QString& s); void setNumberStr(float v, int decimalPlaces, QString& s);
@ -125,6 +126,7 @@ private slots:
void on_freeze_toggled(bool checked); void on_freeze_toggled(bool checked);
void on_calibration_toggled(bool checked); void on_calibration_toggled(bool checked);
void on_gotoMarker_currentIndexChanged(int index); void on_gotoMarker_currentIndexChanged(int index);
void on_showAllControls_toggled(bool checked);
void on_measure_clicked(bool checked); void on_measure_clicked(bool checked);

View File

@ -1130,6 +1130,29 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="ButtonSwitch" name="showAllControls">
<property name="toolTip">
<string>Toggle all controls</string>
</property>
<property name="text">
<string>Grid</string>
</property>
<property name="icon">
<iconset resource="../resources/res.qrc">
<normaloff>:/listing.png</normaloff>:/listing.png</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item> <item>
<widget class="QComboBox" name="gotoMarker"> <widget class="QComboBox" name="gotoMarker">
<property name="minimumSize"> <property name="minimumSize">

View File

@ -24,6 +24,9 @@
#include <QPainter> #include <QPainter>
#include <QFontDatabase> #include <QFontDatabase>
#include <QWindow> #include <QWindow>
#include <QGestureEvent>
#include <QPanGesture>
#include <QPinchGesture>
#include "maincore.h" #include "maincore.h"
#include "dsp/spectrumvis.h" #include "dsp/spectrumvis.h"
#include "gui/glspectrumview.h" #include "gui/glspectrumview.h"
@ -98,6 +101,10 @@ GLSpectrumView::GLSpectrumView(QWidget* parent) :
m_colorMapName("Angel"), m_colorMapName("Angel"),
m_scrollFrequency(false), m_scrollFrequency(false),
m_scrollStartCenterFreq(0), m_scrollStartCenterFreq(0),
m_pinching(false),
m_pinching3D(false),
m_frequencyRequested(false),
m_nextFrequencyValid(false),
m_histogramBuffer(nullptr), m_histogramBuffer(nullptr),
m_histogram(nullptr), m_histogram(nullptr),
m_displayHistogram(true), m_displayHistogram(true),
@ -223,6 +230,8 @@ GLSpectrumView::GLSpectrumView(QWidget* parent) :
// Handle KeyEvents // Handle KeyEvents
setFocusPolicy(Qt::StrongFocus); setFocusPolicy(Qt::StrongFocus);
installEventFilter(this); installEventFilter(this);
grabGesture(Qt::PinchGesture);
} }
GLSpectrumView::~GLSpectrumView() GLSpectrumView::~GLSpectrumView()
@ -260,11 +269,37 @@ GLSpectrumView::~GLSpectrumView()
} }
} }
void GLSpectrumView::queueRequestCenterFrequency(qint64 frequency)
{
if (!m_frequencyRequested)
{
m_frequencyRequested = true;
m_requestedFrequency = frequency;
emit requestCenterFrequency(frequency);
}
else
{
m_nextFrequencyValid = true;
m_nextFrequency = frequency;
}
}
void GLSpectrumView::setCenterFrequency(qint64 frequency) void GLSpectrumView::setCenterFrequency(qint64 frequency)
{ {
m_mutex.lock(); m_mutex.lock();
m_centerFrequency = frequency; m_centerFrequency = frequency;
// Handle queued frequency requests
if (m_frequencyRequested && (frequency == m_requestedFrequency))
{
m_frequencyRequested = false;
if (m_nextFrequencyValid)
{
m_nextFrequencyValid = false;
queueRequestCenterFrequency(m_nextFrequency);
}
}
if (m_useCalibration) { if (m_useCalibration) {
updateCalibrationPoints(); updateCalibrationPoints();
} }
@ -944,7 +979,7 @@ void GLSpectrumView::paintGL()
glFunctions->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glFunctions->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QMatrix4x4 spectrogramGridMatrix; QMatrix4x4 spectrogramGridMatrix;
int devicePixelRatio; float devicePixelRatio;
if (m_display3DSpectrogram) if (m_display3DSpectrogram)
{ {
@ -972,7 +1007,7 @@ void GLSpectrumView::paintGL()
if (window()->windowHandle()) { if (window()->windowHandle()) {
devicePixelRatio = window()->windowHandle()->devicePixelRatio(); devicePixelRatio = window()->windowHandle()->devicePixelRatio();
} else { } else {
devicePixelRatio = 1; devicePixelRatio = 1.0f;
} }
glFunctions->glViewport(0, m_3DSpectrogramBottom*devicePixelRatio, width()*devicePixelRatio, m_waterfallHeight*devicePixelRatio); glFunctions->glViewport(0, m_3DSpectrogramBottom*devicePixelRatio, width()*devicePixelRatio, m_waterfallHeight*devicePixelRatio);
m_glShaderSpectrogram.drawSurface(m_3DSpectrogramStyle, spectrogramGridMatrix, prop_y, m_invertedWaterfall); m_glShaderSpectrogram.drawSurface(m_3DSpectrogramStyle, spectrogramGridMatrix, prop_y, m_invertedWaterfall);
@ -3676,9 +3711,81 @@ void GLSpectrumView::updateCalibrationPoints()
m_changesPending = true; m_changesPending = true;
} }
bool GLSpectrumView::event(QEvent* event)
{
if (event->type() == QEvent::Gesture)
{
QGestureEvent *gestureEvent = static_cast<QGestureEvent *>(event);
if (QPanGesture *pan = static_cast<QPanGesture *>(gestureEvent->gesture(Qt::PanGesture)))
{
if (pan->state() == Qt::GestureStarted)
{
m_scrollStartCenterFreq = m_centerFrequency;
}
else if (pan->state() == Qt::GestureUpdated)
{
QPointF offset = pan->offset();
float histogramWidth = width() - m_leftMargin - m_rightMargin;
qint64 frequency = (qint64)(m_scrollStartCenterFreq + -offset.x()/histogramWidth * m_frequencyScale.getRange());
queueRequestCenterFrequency(frequency);
}
return true;
}
else if (QPinchGesture *pinch = static_cast<QPinchGesture *>(gestureEvent->gesture(Qt::PinchGesture)))
{
// Don't get GestureStarted and startCenterPoint is always 0,0
// https://bugreports.qt.io/browse/QTBUG-109205
if (!m_pinching)
{
m_scrollStartCenterFreq = m_centerFrequency;
m_pinchStart = pinch->centerPoint();
m_pinching = true;
m_pinching3D = m_display3DSpectrogram && pointInWaterfallOrSpectrogram(mapFromGlobal(m_pinchStart.toPoint()));
}
else
{
if (pinch->changeFlags() & QPinchGesture::CenterPointChanged)
{
if (!m_pinching3D)
{
// Scroll frequency up or down
QPointF offset = pinch->centerPoint() - m_pinchStart;
float histogramWidth = width() - m_leftMargin - m_rightMargin;
qint64 frequency = (qint64)(m_scrollStartCenterFreq + -offset.x()/histogramWidth * m_frequencyScale.getRange());
queueRequestCenterFrequency(frequency);
}
}
if (pinch->changeFlags() & QPinchGesture::ScaleFactorChanged)
{
if (!m_pinching3D)
{
// Zoom in/out of spectrum
QPoint p = mapFromGlobal(pinch->centerPoint().toPoint());
zoomFactor(p, pinch->scaleFactor());
}
else
{
// Scale Z axis of 3D spectragram
m_glShaderSpectrogram.userScaleZ(pinch->scaleFactor());
}
}
if (pinch->state() == Qt::GestureFinished)
{
m_pinching = false;
m_pinching3D = false;
}
}
return true;
}
}
return QOpenGLWidget::event(event);
}
void GLSpectrumView::mouseMoveEvent(QMouseEvent* event) void GLSpectrumView::mouseMoveEvent(QMouseEvent* event)
{ {
if (m_rotate3DSpectrogram) if (m_rotate3DSpectrogram && !m_pinching3D)
{ {
// Rotate 3D Spectrogram // Rotate 3D Spectrogram
QPointF delta = m_mousePrevLocalPos - event->localPos(); QPointF delta = m_mousePrevLocalPos - event->localPos();
@ -3718,7 +3825,7 @@ void GLSpectrumView::mouseMoveEvent(QMouseEvent* event)
QPointF delta = m_mousePrevLocalPos - event->localPos(); QPointF delta = m_mousePrevLocalPos - event->localPos();
float histogramWidth = width() - m_leftMargin - m_rightMargin; float histogramWidth = width() - m_leftMargin - m_rightMargin;
qint64 frequency = (qint64)(m_scrollStartCenterFreq + delta.x()/histogramWidth * m_frequencyScale.getRange()); qint64 frequency = (qint64)(m_scrollStartCenterFreq + delta.x()/histogramWidth * m_frequencyScale.getRange());
emit requestCenterFrequency(frequency); queueRequestCenterFrequency(frequency);
return; return;
} }
@ -3775,13 +3882,14 @@ void GLSpectrumView::mouseMoveEvent(QMouseEvent* event)
{ {
// Determine if user is trying to move the channel outside of the current frequency range // 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 // and if so, request an adjustment to the center frequency
// FIXME: This doesn't take zoom into account, so only works when zoomed out
Real freqAbs = m_frequencyScale.getValueFromPos(event->x() - m_leftMarginPixmap.width() - 1); Real freqAbs = m_frequencyScale.getValueFromPos(event->x() - m_leftMarginPixmap.width() - 1);
Real freqMin = m_centerFrequency - m_sampleRate / 2.0f; Real freqMin = m_centerFrequency - m_sampleRate / 2.0f;
Real freqMax = m_centerFrequency + m_sampleRate / 2.0f; Real freqMax = m_centerFrequency + m_sampleRate / 2.0f;
if (freqAbs < freqMin) { if (freqAbs < freqMin) {
emit requestCenterFrequency(m_centerFrequency - (freqMin - freqAbs)); queueRequestCenterFrequency(m_centerFrequency - (freqMin - freqAbs));
} else if (freqAbs > freqMax) { } else if (freqAbs > freqMax) {
emit requestCenterFrequency(m_centerFrequency + (freqAbs - freqMax)); queueRequestCenterFrequency(m_centerFrequency + (freqAbs - freqMax));
} }
Real freq = freqAbs - m_centerFrequency; Real freq = freqAbs - m_centerFrequency;
@ -4174,14 +4282,8 @@ void GLSpectrumView::wheelEvent(QWheelEvent *event)
} }
} }
void GLSpectrumView::zoom(QWheelEvent *event) void GLSpectrumView::zoomFactor(const QPointF& p, float factor)
{ {
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
const QPointF& p = event->position();
#else
const QPointF& p = event->pos();
#endif
float pwx = (p.x() - m_leftMargin) / (width() - m_leftMargin - m_rightMargin); // x position in window float pwx = (p.x() - m_leftMargin) / (width() - m_leftMargin - m_rightMargin); // x position in window
if ((pwx >= 0.0f) && (pwx <= 1.0f)) if ((pwx >= 0.0f) && (pwx <= 1.0f))
@ -4200,7 +4302,45 @@ void GLSpectrumView::zoom(QWheelEvent *event)
// Calculate what that difference would be if there was no zoom // Calculate what that difference would be if there was no zoom
float freqDiffZoom1 = freqDiff * m_frequencyZoomFactor; float freqDiffZoom1 = freqDiff * m_frequencyZoomFactor;
if (event->angleDelta().y() > 0) // zoom in m_frequencyZoomFactor *= factor;
m_frequencyZoomFactor = std::min(m_frequencyZoomFactor, m_maxFrequencyZoom);
m_frequencyZoomFactor = std::max(m_frequencyZoomFactor, 1.0f);
// Calculate what frequency difference should be at new zoom
float zoomedFreqDiff = freqDiffZoom1 / m_frequencyZoomFactor;
// Then calculate what the center frequency should be
float zoomedCF = zoomFreq + zoomedFreqDiff;
// Calculate zoom position which will set the desired center frequency
float zoomPos = (zoomedCF - m_centerFrequency) / m_sampleRate + 0.5;
zoomPos = std::max(0.0f, zoomPos);
zoomPos = std::min(1.0f, zoomPos);
frequencyZoom(zoomPos);
}
}
void GLSpectrumView::zoom(const QPointF& p, int y)
{
float pwx = (p.x() - m_leftMargin) / (width() - m_leftMargin - m_rightMargin); // x position in window
if ((pwx >= 0.0f) && (pwx <= 1.0f))
{
// When we zoom, we want the frequency under the cursor to remain the same
// Determine frequency at cursor position
float zoomFreq = m_frequencyScale.getRangeMin() + pwx*m_frequencyScale.getRange();
// Calculate current centre frequency
float currentCF = (m_frequencyZoomFactor == 1) ? m_centerFrequency : ((m_frequencyZoomPos - 0.5) * m_sampleRate + m_centerFrequency);
// Calculate difference from frequency under cursor to centre frequency
float freqDiff = (currentCF - zoomFreq);
// Calculate what that difference would be if there was no zoom
float freqDiffZoom1 = freqDiff * m_frequencyZoomFactor;
if (y > 0) // zoom in
{ {
if (m_frequencyZoomFactor < m_maxFrequencyZoom) { if (m_frequencyZoomFactor < m_maxFrequencyZoom) {
m_frequencyZoomFactor += 0.5f; m_frequencyZoomFactor += 0.5f;
@ -4247,11 +4387,11 @@ void GLSpectrumView::zoom(QWheelEvent *event)
//qDebug("GLSpectrumView::zoom: pwyh: %f pwyw: %f", pwyh, pwyw); //qDebug("GLSpectrumView::zoom: pwyh: %f pwyw: %f", pwyh, pwyw);
if ((pwyw >= 0.0f) && (pwyw <= 1.0f)) { if ((pwyw >= 0.0f) && (pwyw <= 1.0f)) {
timeZoom(event->angleDelta().y() > 0); timeZoom(y > 0);
} }
if ((pwyh >= 0.0f) && (pwyh <= 1.0f) && !m_linear) { if ((pwyh >= 0.0f) && (pwyh <= 1.0f) && !m_linear) {
powerZoom(pwyh, event->angleDelta().y() > 0); powerZoom(pwyh, y > 0);
} }
} }
} }
@ -4427,7 +4567,7 @@ void GLSpectrumView::channelMarkerMove(QWheelEvent *event, int mul)
} }
} }
zoom(event); zoom(event->position(), event->angleDelta().y());
} }
// Return if specified point is within the bounds of the waterfall / 3D spectrogram screen area // Return if specified point is within the bounds of the waterfall / 3D spectrogram screen area

View File

@ -358,6 +358,14 @@ private:
bool m_scrollFrequency; bool m_scrollFrequency;
qint64 m_scrollStartCenterFreq; qint64 m_scrollStartCenterFreq;
bool m_pinching;
bool m_pinching3D;
QPointF m_pinchStart;
bool m_frequencyRequested; //!< Set when we have emitted requestCenterFrequency
qint64 m_requestedFrequency;
qint64 m_nextFrequency; //!< Next frequency to request when previous request completes
qint64 m_nextFrequencyValid;
QRgb m_histogramPalette[240]; QRgb m_histogramPalette[240];
QImage* m_histogramBuffer; QImage* m_histogramBuffer;
@ -448,12 +456,14 @@ private:
void stopDrag(); void stopDrag();
void applyChanges(); void applyChanges();
bool event(QEvent* event);
void mouseMoveEvent(QMouseEvent* event); void mouseMoveEvent(QMouseEvent* event);
void mousePressEvent(QMouseEvent* event); void mousePressEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event); void mouseReleaseEvent(QMouseEvent* event);
void wheelEvent(QWheelEvent*); void wheelEvent(QWheelEvent*);
void channelMarkerMove(QWheelEvent*, int mul); void channelMarkerMove(QWheelEvent*, int mul);
void zoom(QWheelEvent*); void zoomFactor(const QPointF& p, float factor);
void zoom(const QPointF& p, int y);
void frequencyZoom(float pw); void frequencyZoom(float pw);
void frequencyPan(QMouseEvent*); void frequencyPan(QMouseEvent*);
void timeZoom(bool zoomInElseOut); void timeZoom(bool zoomInElseOut);
@ -494,6 +504,7 @@ private:
const QRectF& glRect); const QRectF& glRect);
void formatTextInfo(QString& info); void formatTextInfo(QString& info);
void updateSortedAnnotationMarkers(); void updateSortedAnnotationMarkers();
void queueRequestCenterFrequency(qint64 frequency);
static bool annotationDisplayLessThan(const SpectrumAnnotationMarker *m1, const SpectrumAnnotationMarker *m2) static bool annotationDisplayLessThan(const SpectrumAnnotationMarker *m1, const SpectrumAnnotationMarker *m2)
{ {

View File

@ -18,6 +18,9 @@
#include <QMouseEvent> #include <QMouseEvent>
#include <QApplication> #include <QApplication>
#include <QScrollBar> #include <QScrollBar>
#include <QGestureEvent>
#include <QPinchGesture>
#include <qmath.h> #include <qmath.h>
#include "graphicsviewzoom.h" #include "graphicsviewzoom.h"
@ -30,6 +33,7 @@ GraphicsViewZoom::GraphicsViewZoom(QGraphicsView* view) :
{ {
m_view->viewport()->installEventFilter(this); m_view->viewport()->installEventFilter(this);
m_view->setMouseTracking(true); m_view->setMouseTracking(true);
m_view->viewport()->grabGesture(Qt::PinchGesture);
} }
void GraphicsViewZoom::gentleZoom(double factor) void GraphicsViewZoom::gentleZoom(double factor)
@ -79,6 +83,19 @@ bool GraphicsViewZoom::eventFilter(QObject *object, QEvent *event)
} }
} }
} }
else if (event->type() == QEvent::Gesture)
{
QGestureEvent *gestureEvent = static_cast<QGestureEvent *>(event);
if (QPinchGesture *pinchGesture = static_cast<QPinchGesture *>(gestureEvent->gesture(Qt::PinchGesture)))
{
if (pinchGesture->changeFlags() & QPinchGesture::ScaleFactorChanged)
{
m_view->scale(pinchGesture->scaleFactor(), pinchGesture->scaleFactor());
emit zoomed();
}
return true;
}
}
Q_UNUSED(object) Q_UNUSED(object)
return false; return false;

View File

@ -23,7 +23,7 @@
#include "export.h" #include "export.h"
// GraphicsView that allows scroll wheel to be used for zoom // GraphicsView that allows scroll wheel and pinch gesture to be used for zoom
// https://stackoverflow.com/questions/19113532/qgraphicsview-zooming-in-and-out-under-mouse-position-using-mouse-wheel // https://stackoverflow.com/questions/19113532/qgraphicsview-zooming-in-and-out-under-mouse-position-using-mouse-wheel
class SDRGUI_API GraphicsViewZoom : public QObject { class SDRGUI_API GraphicsViewZoom : public QObject {
Q_OBJECT Q_OBJECT
@ -39,7 +39,7 @@ private:
Qt::KeyboardModifiers m_modifiers; Qt::KeyboardModifiers m_modifiers;
double m_zoomFactorBase; double m_zoomFactorBase;
QPointF m_targetScenePos, m_targetViewportPos; QPointF m_targetScenePos, m_targetViewportPos;
bool eventFilter(QObject* object, QEvent* event); bool eventFilter(QObject* object, QEvent* event) override;
signals: signals:
void zoomed(); void zoomed();

File diff suppressed because it is too large Load Diff