2761 lines
76 KiB
C++
2761 lines
76 KiB
C++
/**
|
|
* @file cusdr_oglDistancePanel.cpp
|
|
* @brief distance panel class for cuSDR
|
|
* @author Hermann von Hasseln, DL3HVH
|
|
* @version 0.1
|
|
* @date 2012-02-14
|
|
*/
|
|
|
|
/*
|
|
* Copyright 2012 Hermann von Hasseln, DL3HVH
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU Library General Public License version 2 as
|
|
* published by the Free Software Foundation
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details
|
|
*
|
|
* You should have received a copy of the GNU Library General Public
|
|
* License along with this program; if not, write to the
|
|
* Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#define LOG_GRAPHICS
|
|
|
|
#include "cusdr_oglDistancePanel.h"
|
|
|
|
//#include <QtGui>
|
|
//#include <QDebug>
|
|
////#include <QFileInfo>
|
|
//#include <QTimer>
|
|
//#include <QImage>
|
|
//#include <QString>
|
|
//#include <QGLFramebufferObject>
|
|
|
|
|
|
#ifndef GL_MULTISAMPLE
|
|
#define GL_MULTISAMPLE 0x809D
|
|
#endif
|
|
|
|
QGLDistancePanel::QGLDistancePanel(QWidget *parent)
|
|
: QGLWidget(QGLFormat(QGL::SampleBuffers|QGL::AlphaChannel), parent)
|
|
|
|
, set(Settings::instance())
|
|
, m_serverMode(set->getCurrentServerMode())
|
|
, m_hwInterface(set->getHWInterface())
|
|
, m_dataEngineState(QSDR::DataEngineDown)
|
|
, m_panMode(set->getPanadapterMode(0))
|
|
, m_mousePos(QPoint(-1, -1))
|
|
, m_mouseDownPos(QPoint(-1, -1))
|
|
, m_specAveragingCnt(set->getSpectrumAveragingCnt(0))
|
|
, m_freqRulerDisplayWidth(0)
|
|
, m_panSpectrumMinimumHeight(70)
|
|
, m_spectrumUpdate(false)
|
|
, m_showZerodBmLine(false)
|
|
, m_spectrumVertexColorUpdate(false)
|
|
, m_spectrumColorsChanged(true)
|
|
, m_showChirpFFT(false)
|
|
, m_spectrumAveraging(set->getSpectrumAveraging(0))
|
|
, m_spectrumAveragingOld(m_spectrumAveraging)
|
|
, m_crossHairCursor(false)
|
|
, m_panGrid(set->getPanGridStatus(0))
|
|
, m_freqRulerPosition(0.5)
|
|
, m_distRulerDisplayDelta(0.0)
|
|
, m_distRulerDisplayDeltaStep(500.0)
|
|
, m_distRulerMaxDist(150000.0)
|
|
, m_freqScaleZoomFactor(1.0f)
|
|
, m_distScaleZoomFactor(1.0) // 0.2 .. 1.0
|
|
, m_scaleMult(1.0f)
|
|
, m_filterLowerFrequency(-3050.0)
|
|
, m_filterUpperFrequency(-150.0)
|
|
, m_snapMouse(3)
|
|
, m_sampleRate(set->getSampleRate())
|
|
, m_downRate(set->getChirpDownSampleRate())
|
|
, m_chirpBufferLength(set->getChirpBufferLength())
|
|
{
|
|
// QGL::setPreferredPaintEngine(QPaintEngine::OpenGL);
|
|
|
|
setAutoBufferSwap(true);
|
|
setAutoFillBackground(false);
|
|
|
|
setMouseTracking(true);
|
|
setFocusPolicy(Qt::StrongFocus);
|
|
|
|
setupDisplayRegions(size());
|
|
m_oldWidth = size().width();
|
|
|
|
m_rxDataList = set->getReceiverDataList();
|
|
//m_frequency = m_rxDataList.at(0).frequency;
|
|
m_frequency = m_rxDataList.at(0).vfoFrequency;
|
|
|
|
m_dBmScalePanadapterRenew = true;
|
|
m_dBmScalePanadapterUpdate = true;
|
|
m_freqScalePanadapterRenew = true;
|
|
m_freqScalePanadapterUpdate = true;
|
|
m_panGridRenew = true;
|
|
m_panGridUpdate = true;
|
|
|
|
HamBand band = m_rxDataList.at(0).hamBand;
|
|
|
|
m_dBmPanMin = m_rxDataList.at(0).dBmPanScaleMinList.at(band);
|
|
m_dBmPanMax = m_rxDataList.at(0).dBmPanScaleMaxList.at(band);
|
|
|
|
m_filterLowerFrequency = m_rxDataList.at(0).filterLo;
|
|
m_filterUpperFrequency = m_rxDataList.at(0).filterHi;
|
|
|
|
fonts = new CFonts(this);
|
|
m_fonts = fonts->getFonts();
|
|
|
|
m_oglTextTiny = new OGLText(m_fonts.tinyFont);
|
|
m_oglTextSmall = new OGLText(m_fonts.smallFont);
|
|
m_oglTextNormal = new OGLText(m_fonts.normalFont);
|
|
|
|
timer = 0;
|
|
|
|
setupConnections();
|
|
|
|
m_displayTime.start();
|
|
m_resizeTime.start();
|
|
//freqChangeTimer.start();
|
|
|
|
memset(m_spectrumBuffer, -10000, 4 * BUFFER_SIZE * sizeof(float));
|
|
memset(m_distanceSpectrumBuffer, -10000, 16 * BUFFER_SIZE * sizeof(float));
|
|
|
|
m_kilometersPerGate = 0.5f * 3E5 / (m_sampleRate/m_downRate);
|
|
|
|
m_dBmPanLogGain = 69; // allow user to calibrate this value
|
|
|
|
m_dBmDistMin = set->getdBmDistScaleMin();
|
|
m_dBmDistMax = set->getdBmDistScaleMax();
|
|
m_dBmDistScaleMin = m_dBmDistMin;
|
|
m_dBmDistScaleMax = m_dBmDistMax;
|
|
|
|
m_panSpectrumBinsLength = 0;
|
|
|
|
/*m_bkgRed = (GLfloat)(set->getPanadapterColors().panBackgroundColor.red() / 256.0);
|
|
m_bkgGreen = (GLfloat)(set->getPanadapterColors().panBackgroundColor.green() / 256.0);
|
|
m_bkgBlue = (GLfloat)(set->getPanadapterColors().panBackgroundColor.blue() / 256.0);*/
|
|
|
|
m_red = (GLfloat)(set->getPanadapterColors().panLineColor.red() / 256.0);
|
|
m_green = (GLfloat)(set->getPanadapterColors().panLineColor.green() / 256.0);
|
|
m_blue = (GLfloat)(set->getPanadapterColors().panLineColor.blue() / 256.0);
|
|
|
|
m_redF = (GLfloat)(set->getPanadapterColors().panLineFilledColor.red() / 256.0);
|
|
m_greenF = (GLfloat)(set->getPanadapterColors().panLineFilledColor.green() / 256.0);
|
|
m_blueF = (GLfloat)(set->getPanadapterColors().panLineFilledColor.blue() / 256.0);
|
|
|
|
m_redST = (GLfloat)(set->getPanadapterColors().panSolidTopColor.red() / 256.0);
|
|
m_greenST = (GLfloat)(set->getPanadapterColors().panSolidTopColor.green() / 256.0);
|
|
m_blueST = (GLfloat)(set->getPanadapterColors().panSolidTopColor.blue() / 256.0);
|
|
|
|
m_redSB = (GLfloat)(set->getPanadapterColors().panSolidBottomColor.red() / 256.0);
|
|
m_greenSB = (GLfloat)(set->getPanadapterColors().panSolidBottomColor.green() / 256.0);
|
|
m_blueSB = (GLfloat)(set->getPanadapterColors().panSolidBottomColor.blue() / 256.0);
|
|
|
|
m_frequencyScaleFBO = 0;
|
|
m_dBmScaleFBO = 0;
|
|
m_panadapterGridFBO = 0;
|
|
m_textureFBO = 0;
|
|
|
|
if (m_specAveragingCnt > 0)
|
|
m_scale = 1.0f / m_specAveragingCnt;
|
|
else
|
|
m_scale = 1.0f;
|
|
|
|
memset(m_tmpBuf, 0, SAMPLE_BUFFER_SIZE * sizeof(float));
|
|
|
|
updateGL();
|
|
}
|
|
|
|
QGLDistancePanel::~QGLDistancePanel() {
|
|
|
|
disconnect(set, 0, this, 0);
|
|
|
|
makeCurrent();
|
|
glFinish();
|
|
|
|
if (m_frequencyScaleFBO) {
|
|
|
|
delete m_frequencyScaleFBO;
|
|
m_frequencyScaleFBO = 0;
|
|
}
|
|
|
|
if (m_textureFBO) {
|
|
|
|
delete m_textureFBO;
|
|
m_textureFBO = 0;
|
|
}
|
|
|
|
if (m_dBmScaleFBO) {
|
|
|
|
delete m_dBmScaleFBO;
|
|
m_dBmScaleFBO = 0;
|
|
}
|
|
|
|
if (m_panadapterGridFBO) {
|
|
|
|
delete m_panadapterGridFBO;
|
|
m_panadapterGridFBO = 0;
|
|
}
|
|
|
|
while (!specAv_queue.isEmpty())
|
|
specAv_queue.dequeue();
|
|
}
|
|
|
|
//QSize QGLDistancePanel::minimumSizeHint() const {
|
|
//
|
|
// //return QSize(1000, 1024);
|
|
// return QSize(width(), height());
|
|
//}
|
|
|
|
QSize QGLDistancePanel::sizeHint() const {
|
|
|
|
return QSize(width(), height());
|
|
}
|
|
|
|
void QGLDistancePanel::setupConnections() {
|
|
|
|
CHECKED_CONNECT(
|
|
set,
|
|
SIGNAL(systemStateChanged(
|
|
QObject *,
|
|
QSDR::_Error,
|
|
QSDR::_HWInterfaceMode,
|
|
QSDR::_ServerMode,
|
|
QSDR::_DataEngineState)),
|
|
this,
|
|
SLOT(systemStateChanged(
|
|
QObject *,
|
|
QSDR::_Error,
|
|
QSDR::_HWInterfaceMode,
|
|
QSDR::_ServerMode,
|
|
QSDR::_DataEngineState)));
|
|
|
|
CHECKED_CONNECT(
|
|
set,
|
|
SIGNAL(graphicModeChanged(
|
|
QObject *,
|
|
int,
|
|
PanGraphicsMode,
|
|
WaterfallColorMode)),
|
|
this,
|
|
SLOT(graphicModeChanged(
|
|
QObject *,
|
|
int,
|
|
PanGraphicsMode,
|
|
WaterfallColorMode)));
|
|
|
|
CHECKED_CONNECT(
|
|
set,
|
|
SIGNAL(freqRulerPositionChanged(float, int)),
|
|
this,
|
|
SLOT(freqRulerPositionChanged(float, int)));
|
|
|
|
CHECKED_CONNECT(
|
|
set,
|
|
SIGNAL(sampleRateChanged(QObject *, int)),
|
|
this,
|
|
SLOT(sampleRateChanged(QObject *, int)));
|
|
|
|
CHECKED_CONNECT(
|
|
set,
|
|
SIGNAL(filterFrequenciesChanged(QObject *, int, qreal, qreal)),
|
|
this,
|
|
SLOT(setFilterFrequencies(QObject *, int, qreal, qreal)));
|
|
|
|
CHECKED_CONNECT_OPT(
|
|
set,
|
|
SIGNAL(chirpSpectrumBufferChanged(int, qint64, const float *)),
|
|
this,
|
|
SLOT(distanceSpectrumBufferChanged(int, qint64, const float *)),
|
|
Qt::DirectConnection);
|
|
|
|
CHECKED_CONNECT(
|
|
set,
|
|
SIGNAL(chirpFFTShowChanged(bool)),
|
|
this,
|
|
SLOT(setChirpFFTShow(bool)));
|
|
|
|
CHECKED_CONNECT(
|
|
set,
|
|
SIGNAL(waterfallTimeChanged(int, int)),
|
|
this,
|
|
SLOT(setWaterfallTime(int, int)));
|
|
|
|
CHECKED_CONNECT(
|
|
set,
|
|
SIGNAL(waterfallOffesetLoChanged(int, int)),
|
|
this,
|
|
SLOT(setWaterfallOffesetLo(int, int)));
|
|
|
|
CHECKED_CONNECT(
|
|
set,
|
|
SIGNAL(waterfallOffesetHiChanged(int, int)),
|
|
this,
|
|
SLOT(setWaterfallOffesetHi(int, int)));
|
|
|
|
CHECKED_CONNECT(
|
|
set,
|
|
SIGNAL(spectrumAveragingChanged(bool)),
|
|
this,
|
|
SLOT(setSpectrumAveraging(bool)));
|
|
|
|
CHECKED_CONNECT(
|
|
set,
|
|
SIGNAL(spectrumAveragingCntChanged(int)),
|
|
this,
|
|
SLOT(setSpectrumAveragingCnt(int)));
|
|
|
|
CHECKED_CONNECT(
|
|
set,
|
|
SIGNAL(panGridStatusChanged(bool)),
|
|
this,
|
|
SLOT(setPanGridStatus(bool)));
|
|
|
|
CHECKED_CONNECT(
|
|
set,
|
|
SIGNAL(panadapterColorChanged()),
|
|
this,
|
|
SLOT(setPanadapterColors()));
|
|
}
|
|
|
|
void QGLDistancePanel::initializeGL() {
|
|
|
|
if (!isValid()) return;
|
|
|
|
/*QOpenGLInfo glInfo;
|
|
glInfo.getInfo();
|
|
glInfo.printSelf();*/
|
|
|
|
//*****************************************************************
|
|
// default initialization
|
|
|
|
//glShadeModel(GL_FLAT);
|
|
glShadeModel(GL_SMOOTH);
|
|
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // 4-byte pixel alignment
|
|
//glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
|
//glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
|
|
|
|
glDepthFunc(GL_LESS);
|
|
glEnable(GL_DEPTH_TEST);
|
|
glDisable(GL_CULL_FACE);
|
|
|
|
m_cnt = 0;
|
|
|
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|
}
|
|
|
|
void QGLDistancePanel::paintGL() {
|
|
|
|
switch (m_serverMode) {
|
|
|
|
case QSDR::SDRMode:
|
|
|
|
drawGLRect(QRect(0, 0, width(), height()), QColor(0, 0, 0));
|
|
break;
|
|
|
|
case QSDR::ChirpWSPR:
|
|
case QSDR::ChirpWSPRFile:
|
|
|
|
//if (freqChangeTimer.elapsed() > 50) m_spectrumAveraging = m_spectrumAveragingOld;
|
|
|
|
if (m_resizeTime.elapsed() > 100 || m_dataEngineState == QSDR::DataEngineDown) {
|
|
|
|
paintReceiverDisplay();
|
|
paintChirpWSPRDisplay();
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
//****************************************************
|
|
// painting modes
|
|
void QGLDistancePanel::paintReceiverDisplay() {
|
|
|
|
QRect mouse_rect(0, 0, 100, 100);
|
|
mouse_rect.moveCenter(m_mousePos);
|
|
|
|
drawPanadapter();
|
|
drawPanHorizontalScale();
|
|
drawPanVerticalScale();
|
|
|
|
if (m_panGrid)
|
|
drawPanadapterGrid();
|
|
|
|
drawPanFilter();
|
|
|
|
if (m_mouseRegion == panadapterRegion && m_crossHairCursor)
|
|
drawCrossHair();
|
|
|
|
m_oldFreq = m_frequency;
|
|
}
|
|
|
|
void QGLDistancePanel::paintChirpWSPRDisplay() {
|
|
|
|
//drawGLBackground(m_distanceSpectrumRect);
|
|
|
|
distanceSpectrumBufferMutex.lock();
|
|
drawDistanceSpectrum();
|
|
distanceSpectrumBufferMutex.unlock();
|
|
|
|
drawDistHorizontalScale();
|
|
drawDistVerticalScale();
|
|
|
|
//// chirp distance spectrum
|
|
//m_distancePanadapter->drawGLDistanceRuler(
|
|
// m_freqScaleDistancePanRect,
|
|
// m_freqScalePanadapterRect,
|
|
// m_mouseRegion,
|
|
// m_distRulerZoomFactor,
|
|
// m_distRulerDisplayDelta,
|
|
// m_kilometersPerGate,
|
|
// m_showChirpFFT,
|
|
// m_chirpBufferLength);
|
|
|
|
//m_distancePanadapter->drawGLdBmScale(
|
|
// m_dBmScaleDistancePanRect,
|
|
// m_distanceSpectrumRect,
|
|
// m_mouseRegion,
|
|
// m_dBmDistScaleMin,
|
|
// m_dBmDistScaleMax,
|
|
// m_showZerodBmLine);
|
|
|
|
//m_distancePanadapter->drawGLGrid(m_distanceSpectrumRect, m_dBmScaleDistancePanRect);
|
|
}
|
|
|
|
void QGLDistancePanel::drawPanadapter() {
|
|
|
|
GLint vertexArrayLength = (GLint)m_panadapterBins.size();
|
|
|
|
GLint height = m_panRect.height();
|
|
GLint x1 = m_panRect.left();
|
|
GLint y1 = m_panRect.top();
|
|
GLint x2 = x1 + m_panRect.width();
|
|
GLint y2 = y1 + m_panRect.height();
|
|
|
|
// y scale
|
|
float yScale;
|
|
float yScaleColor;
|
|
float yTop;
|
|
|
|
qreal dBmRange = qAbs(m_dBmPanMax - m_dBmPanMin);
|
|
|
|
yScale = m_panRect.height() / dBmRange;
|
|
//yScaleColor = 4.0f / dBmRange;
|
|
yScaleColor = 10.0f / dBmRange;
|
|
yTop = (float) y2;
|
|
|
|
if (m_dataEngineState == QSDR::DataEngineUp)
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
|
else
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
glEnable(GL_MULTISAMPLE);
|
|
glEnable(GL_LINE_SMOOTH);
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
glEnable(GL_BLEND);
|
|
glLineWidth(1);
|
|
|
|
// draw background
|
|
if (m_dataEngineState == QSDR::DataEngineUp) {
|
|
|
|
if (m_panGrid) {
|
|
|
|
glBegin(GL_TRIANGLE_STRIP);
|
|
glColor3f(0.15f, 0.15f, 0.3f); glVertex3f(x1, y1, -3.0); // top left corner
|
|
glColor3f(0.15f, 0.15f, 0.3f); glVertex3f(x2, y1, -3.0); // top right corner
|
|
glColor3f(0.15f, 0.15f, 0.51f); glVertex3f(x1, y2, -3.0); // bottom left corner
|
|
glColor3f(0.15f, 0.15f, 0.61f); glVertex3f(x2, y2, -3.0); // bottom right corner
|
|
glEnd();
|
|
}
|
|
else {
|
|
|
|
glBegin(GL_TRIANGLE_STRIP);
|
|
glColor3f(0.05f, 0.05f, 0.2f); glVertex3f(x1, y1, -3.0); // top left corner
|
|
glColor3f(0.05f, 0.05f, 0.2f); glVertex3f(x2, y1, -3.0); // top right corner
|
|
glColor3f(0.05f, 0.05f, 0.31f); glVertex3f(x1, y2, -3.0); // bottom left corner
|
|
glColor3f(0.05f, 0.05f, 0.41f); glVertex3f(x2, y2, -3.0); // bottom right corner
|
|
glEnd();
|
|
}
|
|
}
|
|
else {
|
|
|
|
drawGLRect(m_panRect, QColor(30, 30, 50, 155), -3.0f);
|
|
}
|
|
|
|
//glBegin(GL_TRIANGLE_STRIP);
|
|
//glColor3f(m_bkgRed, m_bkgGreen, m_bkgBlue); glVertex3f(x1, y1, -3.0); // top left corner
|
|
//glColor3f(m_bkgRed, m_bkgGreen, m_bkgBlue); glVertex3f(x2, y1, -3.0); // top right corner
|
|
//glColor3f(m_bkgRed * 1.2, m_bkgGreen * 1.2, m_bkgBlue * 1.2); glVertex3f(x1, y2, -3.0); // bottom left corner
|
|
//glColor3f(m_bkgRed * 1.6, m_bkgGreen * 1.6, m_bkgBlue * 1.6); glVertex3f(x2, y2, -3.0); // bottom right corner
|
|
//glEnd();
|
|
|
|
// set a scissor box
|
|
glScissor(x1, size().height() - y2, x2, height);
|
|
glEnable(GL_SCISSOR_TEST);
|
|
|
|
TGL3float *vertexArray = new TGL3float[vertexArrayLength];
|
|
TGL3float *vertexColorArray = new TGL3float[vertexArrayLength];
|
|
|
|
TGL3float *vertexArrayBg = new TGL3float[2*vertexArrayLength];
|
|
TGL3float *vertexColorArrayBg = new TGL3float[2*vertexArrayLength];
|
|
|
|
switch (m_panMode) {
|
|
|
|
case (PanGraphicsMode) FilledLine:
|
|
|
|
for (int i = 0; i < vertexArrayLength; i++) {
|
|
|
|
mutex.lock();
|
|
vertexColorArrayBg[2*i].x = m_redF;
|
|
vertexColorArrayBg[2*i].y = m_greenF;
|
|
vertexColorArrayBg[2*i].z = m_blueF;
|
|
|
|
vertexColorArrayBg[2*i+1].x = 0.3 * m_redF;
|
|
vertexColorArrayBg[2*i+1].y = 0.3 * m_greenF;
|
|
vertexColorArrayBg[2*i+1].z = 0.3 * m_blueF;
|
|
|
|
vertexColorArray[i].x = m_red * (yScaleColor * m_panadapterBins.at(i));
|
|
vertexColorArray[i].y = m_green * (yScaleColor * m_panadapterBins.at(i));
|
|
vertexColorArray[i].z = m_blue * (yScaleColor * m_panadapterBins.at(i));
|
|
mutex.unlock();
|
|
|
|
vertexArrayBg[2*i].x = (GLfloat)(i/m_scaleMult);
|
|
vertexArrayBg[2*i].y = (GLfloat)(yTop - yScale * m_panadapterBins.at(i));
|
|
vertexArrayBg[2*i].z = -2.5;
|
|
|
|
vertexArrayBg[2*i+1].x = (GLfloat)(i/m_scaleMult);
|
|
vertexArrayBg[2*i+1].y = (GLfloat)yTop;
|
|
vertexArrayBg[2*i+1].z = -2.5;
|
|
|
|
vertexArray[i].x = (GLfloat)(i/m_scaleMult);
|
|
vertexArray[i].y = (GLfloat)(yTop - yScale * m_panadapterBins.at(i));
|
|
vertexArray[i].z = -1.0;
|
|
}
|
|
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
glEnableClientState(GL_COLOR_ARRAY);
|
|
|
|
glVertexPointer(3, GL_FLOAT, 0, vertexArrayBg);
|
|
glColorPointer(3, GL_FLOAT, 0, vertexColorArrayBg);
|
|
glDrawArrays(GL_QUAD_STRIP, 0, 2*vertexArrayLength);
|
|
|
|
glVertexPointer(3, GL_FLOAT, 0, vertexArray);
|
|
glColorPointer(3, GL_FLOAT, 0, vertexColorArray);
|
|
glDrawArrays(GL_LINE_STRIP, 0, vertexArrayLength);
|
|
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
glDisableClientState(GL_COLOR_ARRAY);
|
|
|
|
delete[] vertexArray;
|
|
delete[] vertexColorArray;
|
|
delete[] vertexArrayBg;
|
|
delete[] vertexColorArrayBg;
|
|
|
|
break;
|
|
|
|
case (PanGraphicsMode) Line:
|
|
|
|
for (int i = 0; i < vertexArrayLength; i++) {
|
|
|
|
mutex.lock();
|
|
vertexColorArray[i].x = m_red * (yScaleColor * m_panadapterBins.at(i));
|
|
vertexColorArray[i].y = m_green * (yScaleColor * m_panadapterBins.at(i));
|
|
vertexColorArray[i].z = m_blue * (yScaleColor * m_panadapterBins.at(i));
|
|
mutex.unlock();
|
|
|
|
vertexArray[i].x = (GLfloat)(i/m_scaleMult);
|
|
vertexArray[i].y = (GLfloat)(yTop - yScale * m_panadapterBins.at(i));
|
|
vertexArray[i].z = -1.0;
|
|
}
|
|
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
glEnableClientState(GL_COLOR_ARRAY);
|
|
|
|
glVertexPointer(3, GL_FLOAT, 0, vertexArray);
|
|
glColorPointer(3, GL_FLOAT, 0, vertexColorArray);
|
|
glDrawArrays(GL_LINE_STRIP, 0, vertexArrayLength);
|
|
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
glDisableClientState(GL_COLOR_ARRAY);
|
|
|
|
delete[] vertexArray;
|
|
delete[] vertexColorArray;
|
|
delete[] vertexArrayBg;
|
|
delete[] vertexColorArrayBg;
|
|
|
|
break;
|
|
|
|
case (PanGraphicsMode) Solid:
|
|
|
|
glDisable(GL_MULTISAMPLE);
|
|
glDisable(GL_LINE_SMOOTH);
|
|
|
|
for (int i = 0; i < vertexArrayLength; i++) {
|
|
|
|
mutex.lock();
|
|
vertexColorArrayBg[2*i].x = m_redST;
|
|
vertexColorArrayBg[2*i].y = m_greenST;
|
|
vertexColorArrayBg[2*i].z = m_blueST;
|
|
|
|
vertexColorArrayBg[2*i+1].x = m_redSB;
|
|
vertexColorArrayBg[2*i+1].y = m_greenSB;
|
|
vertexColorArrayBg[2*i+1].z = m_blueSB;
|
|
mutex.unlock();
|
|
|
|
vertexArrayBg[2*i].x = (GLfloat)(i/m_scaleMult);
|
|
vertexArrayBg[2*i].y = (GLfloat)(yTop - yScale * m_panadapterBins.at(i));
|
|
vertexArrayBg[2*i].z = -2.0f;
|
|
|
|
vertexArrayBg[2*i+1].x = (GLfloat)(i/m_scaleMult);
|
|
vertexArrayBg[2*i+1].y = (GLfloat)yTop;
|
|
vertexArrayBg[2*i+1].z = -2.0f;
|
|
}
|
|
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
glEnableClientState(GL_COLOR_ARRAY);
|
|
|
|
glVertexPointer(3, GL_FLOAT, 0, vertexArrayBg);
|
|
glColorPointer(3, GL_FLOAT, 0, vertexColorArrayBg);
|
|
//glDrawArrays(GL_QUAD_STRIP, 0, 2*vertexArrayLength);
|
|
glDrawArrays(GL_LINES, 0, 2*vertexArrayLength);
|
|
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
glDisableClientState(GL_COLOR_ARRAY);
|
|
|
|
//glEnable(GL_MULTISAMPLE);
|
|
//glEnable(GL_LINE_SMOOTH);
|
|
|
|
delete[] vertexArray;
|
|
delete[] vertexColorArray;
|
|
delete[] vertexArrayBg;
|
|
delete[] vertexColorArrayBg;
|
|
|
|
break;
|
|
}
|
|
|
|
glDisable(GL_MULTISAMPLE);
|
|
glDisable(GL_LINE_SMOOTH);
|
|
|
|
// disable scissor box
|
|
glDisable(GL_SCISSOR_TEST);
|
|
}
|
|
|
|
void QGLDistancePanel::drawPanVerticalScale() {
|
|
|
|
if (!m_dBmScalePanRect.isValid()) return;
|
|
|
|
int width = m_dBmScalePanRect.width();
|
|
int height = m_dBmScalePanRect.height();
|
|
|
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
|
glColor3f(0.65f, 0.76f, 0.81f);
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
glEnable(GL_BLEND);
|
|
|
|
if (!m_dBmScaleFBO || m_dBmScalePanadapterUpdate || m_dBmScalePanadapterRenew) {
|
|
|
|
if (!m_dBmScaleFBO || m_dBmScalePanadapterRenew) {
|
|
|
|
if (m_dBmScaleFBO) {
|
|
|
|
delete m_dBmScaleFBO;
|
|
m_dBmScaleFBO = 0;
|
|
}
|
|
m_dBmScaleFBO = new QGLFramebufferObject(width, height);
|
|
}
|
|
|
|
m_dBmScaleFBO->bind();
|
|
renderPanVerticalScale();
|
|
m_dBmScaleFBO->release();
|
|
|
|
m_dBmScalePanadapterUpdate = false;
|
|
m_dBmScalePanadapterRenew = false;
|
|
}
|
|
|
|
renderTexture(m_dBmScalePanRect, m_dBmScaleFBO->texture(), 0.0f);
|
|
|
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|
glColor3f(0.65f, 0.76f, 0.81f);
|
|
}
|
|
|
|
void QGLDistancePanel::drawPanHorizontalScale() {
|
|
|
|
if (!m_freqScalePanRect.isValid()) return;
|
|
|
|
int width = m_freqScalePanRect.width();
|
|
int height = m_freqScalePanRect.height();
|
|
|
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
|
glColor3f(0.65f, 0.76f, 0.81f);
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
glEnable(GL_BLEND);
|
|
|
|
if (!m_frequencyScaleFBO || m_freqScalePanadapterUpdate || m_freqScalePanadapterRenew) {
|
|
|
|
if (!m_frequencyScaleFBO || m_freqScalePanadapterRenew) {
|
|
|
|
if (m_frequencyScaleFBO) {
|
|
|
|
delete m_frequencyScaleFBO;
|
|
m_frequencyScaleFBO = 0;
|
|
}
|
|
|
|
m_frequencyScaleFBO = new QGLFramebufferObject(width, height);
|
|
}
|
|
|
|
glPushAttrib(GL_VIEWPORT_BIT);
|
|
glViewport(0, 0, width, height);
|
|
setProjectionOrthographic(width, height);
|
|
|
|
m_frequencyScaleFBO->bind();
|
|
renderPanHorizontalScale();
|
|
m_frequencyScaleFBO->release();
|
|
|
|
glPopAttrib();
|
|
glViewport(0, 0, size().width(), size().height());
|
|
setProjectionOrthographic(size().width(), size().height());
|
|
|
|
m_freqScalePanadapterUpdate = false;
|
|
m_freqScalePanadapterRenew = false;
|
|
}
|
|
|
|
renderTexture(m_freqScalePanRect, m_frequencyScaleFBO->texture(), 0.0f);
|
|
|
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|
glColor3f(0.65f, 0.76f, 0.81f);
|
|
}
|
|
|
|
void QGLDistancePanel::drawPanadapterGrid() {
|
|
|
|
if (!m_panRect.isValid()) return;
|
|
|
|
int width = m_panRect.width();
|
|
int height = m_panRect.height();
|
|
|
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
|
//glColor4f(0.35, 0.46, 0.51, 0.7);
|
|
//glColor4f(0.45, 0.56, 0.61, 1.0);
|
|
glColor4f(0.45f, 0.56f, 0.61f, 0.8f);
|
|
|
|
glDisable(GL_MULTISAMPLE);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
glEnable(GL_BLEND);
|
|
|
|
if (!m_panadapterGridFBO || m_panGridUpdate || m_panGridRenew) {
|
|
|
|
if (!m_panadapterGridFBO || m_panGridRenew) {
|
|
|
|
if (m_panadapterGridFBO) {
|
|
|
|
delete m_panadapterGridFBO;
|
|
m_panadapterGridFBO = 0;
|
|
}
|
|
|
|
m_panadapterGridFBO = new QGLFramebufferObject(width, height);
|
|
}
|
|
|
|
glPushAttrib(GL_VIEWPORT_BIT);
|
|
glViewport(0, 0, width, height);
|
|
setProjectionOrthographic(width, height);
|
|
|
|
m_panadapterGridFBO->bind();
|
|
renderPanadapterGrid();
|
|
m_panadapterGridFBO->release();
|
|
|
|
glPopAttrib();
|
|
glViewport(0, 0, size().width(), size().height());
|
|
setProjectionOrthographic(size().width(), size().height());
|
|
|
|
m_panGridUpdate = false;
|
|
m_panGridRenew = false;
|
|
}
|
|
|
|
//renderTexture(m_panRect, m_panadapterGridFBO->texture(), -2.0f);
|
|
//renderTexture(m_panRect, m_panadapterGridFBO->texture(), -1.5f);
|
|
renderTexture(m_panRect, m_panadapterGridFBO->texture(), -2.0f);
|
|
|
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|
glColor3f(0.65f, 0.76f, 0.81f);
|
|
glEnable(GL_MULTISAMPLE);
|
|
}
|
|
|
|
void QGLDistancePanel::drawPanFilter() {
|
|
|
|
qreal freqLo = m_filterLowerFrequency / m_sampleRate;
|
|
qreal freqHi = m_filterUpperFrequency / m_sampleRate;
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
glEnable(GL_BLEND);
|
|
//glColor4f(0.65, 0.65, 0.65, 0.25);
|
|
QColor color = QColor(150, 150, 150, 100);
|
|
|
|
GLint x1 = m_panRect.left() + qRound((qreal)(m_panRect.width()/2.0f) + freqLo * m_panRect.width() / m_freqScaleZoomFactor);
|
|
GLint x2 = m_panRect.left() + qRound((qreal)(m_panRect.width()/2.0f) + freqHi * m_panRect.width() / m_freqScaleZoomFactor);
|
|
GLint y1 = m_panRect.top() + 1;
|
|
GLint y2 = m_panRect.top() + m_panRect.height() - 1;
|
|
|
|
QRect filterRect = QRect(x1, y1, x2 - x1, y2 - y1);
|
|
|
|
if ((x1 >= m_panRect.left() && x1 <= m_panRect.right()) ||
|
|
(x2 >= m_panRect.left() && x2 <= m_panRect.right()) ||
|
|
(x1 < m_panRect.left() && x2 > m_panRect.right()))
|
|
{
|
|
if (filterRect.height() > 5)
|
|
drawGLRect(filterRect, color, 3.0);
|
|
}
|
|
|
|
// draw a line for the display center
|
|
y1 = m_panRect.top() + 3;
|
|
y2 = m_panRect.top() + (m_panRect.height() - 3);
|
|
|
|
if (y2 > y1 + 3) {
|
|
|
|
GLint x = m_panRect.width()/2;
|
|
|
|
color = set->getPanadapterColors().panCenterLineColor;
|
|
|
|
//glDisable(GL_LINE_SMOOTH);
|
|
glDisable(GL_MULTISAMPLE);
|
|
glLineWidth(1);
|
|
glColor4ub(color.red(), color.green(), color.blue(), color.alpha());
|
|
glBegin(GL_LINES);
|
|
/*glVertex2i(x, y1);
|
|
glVertex2i(x, y2);*/
|
|
glVertex3f(x, y1, 4.0f);
|
|
glVertex3f(x, y2, 4.0f);
|
|
glEnd();
|
|
glEnable(GL_MULTISAMPLE);
|
|
}
|
|
}
|
|
|
|
void QGLDistancePanel::drawCrossHair() {
|
|
|
|
QRect rect(0, m_panRect.top(), width(), height() - m_panRect.top());
|
|
|
|
int x = m_mousePos.x();
|
|
int y = m_mousePos.y();
|
|
|
|
glDisable(GL_MULTISAMPLE);
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
glDisable(GL_LINE_SMOOTH);
|
|
glLineWidth(1.0f);
|
|
|
|
qglColor(QColor(255, 255, 255, 80));
|
|
|
|
// set a scissor box
|
|
glScissor(rect.left(), rect.top(), rect.width() - 1, rect.height());
|
|
glEnable(GL_SCISSOR_TEST);
|
|
|
|
// horizontal line
|
|
glBegin(GL_LINES);
|
|
glVertex3f(m_dBmScalePanRect.right() - 2, y, 4.0f);
|
|
glVertex3f(rect.right() - 1, y, 4.0f);
|
|
glEnd();
|
|
|
|
// vertical line
|
|
glBegin(GL_LINES);
|
|
glVertex3f(x, rect.top() + 1, 4.0f);
|
|
glVertex3f(x, rect.bottom() - 1, 4.0f);
|
|
glEnd();
|
|
|
|
// cross hair
|
|
qglColor(QColor(255, 255, 255, 180));
|
|
glBegin(GL_LINES);
|
|
glVertex3f(x , y - 20, 5.0f);
|
|
glVertex3f(x , y + 20, 5.0f);
|
|
glVertex3f(x - 20, y, 5.0f);
|
|
glVertex3f(x + 20, y, 5.0f);
|
|
glEnd();
|
|
|
|
// text only on panadapter
|
|
//if (m_mouseRegion == panadapterRegion) {
|
|
|
|
QString str;
|
|
qglColor(QColor(255, 255, 255, 255));
|
|
|
|
int dx = m_panRect.width()/2 - x;
|
|
qreal unit = (qreal)((m_sampleRate * m_freqScaleZoomFactor) / m_panRect.width());
|
|
qreal df = unit * dx;
|
|
qreal frequency = m_frequency - df;
|
|
|
|
str = frequencyString(-df, true);
|
|
if (x > m_panRect.width() - 85)
|
|
m_oglTextSmall->renderText(x -90, y - 30, 5.0f, str);
|
|
else
|
|
m_oglTextSmall->renderText(x + 4, y - 30, 5.0f, str);
|
|
|
|
str = frequencyString(frequency);
|
|
if (x > m_panRect.width() - 85)
|
|
m_oglTextSmall->renderText(x - 90, y - 18, 5.0f, str);
|
|
else
|
|
m_oglTextSmall->renderText(x + 4, y - 18, 5.0f, str);
|
|
|
|
if (m_mouseRegion == panadapterRegion) {
|
|
|
|
qreal dBm = m_dBmPanMax - ((m_dBmPanMax - m_dBmPanMin) * ((qreal)(y - m_panRect.top()) / m_panRect.height()));
|
|
str = QString::number(dBm, 'f', 1) + " dBm";
|
|
if (x > m_panRect.width() - 85)
|
|
m_oglTextSmall->renderText(x - 90, y + 6, 5.0f, str);
|
|
else
|
|
m_oglTextSmall->renderText(x + 4, y + 6, 5.0f, str);
|
|
}
|
|
|
|
// disable scissor box
|
|
glDisable(GL_SCISSOR_TEST);
|
|
|
|
glEnable(GL_MULTISAMPLE);
|
|
}
|
|
|
|
//************
|
|
void QGLDistancePanel::drawDistanceSpectrum() {
|
|
|
|
//float yScale;
|
|
//float yScaleColor;
|
|
//float yTop;
|
|
float localMax;
|
|
|
|
GLint displayWidth = (GLint)m_distanceSpectrumRect.width();
|
|
|
|
double distScale = 0;
|
|
//freqScale = (float)m_sampleRate / rect.width();
|
|
//distScale = 1024.0f / rect.width();
|
|
|
|
distScale = (double)(1.0f * qRound(m_chirpBufferLength * m_distScaleZoomFactor) / m_distanceSpectrumRect.width());
|
|
if (distScale < 1.0) distScale = 1.0;
|
|
|
|
if (distScale < 0) {
|
|
|
|
drawGLRect(m_distanceSpectrumRect, Qt::black);
|
|
//GRAPHICS_DEBUG << "drawDistanceSpectrum bad distance scale:" << distScale;
|
|
return;
|
|
}
|
|
|
|
//qreal dBmRange = qAbs(dBmMax - dBmMin);
|
|
qreal dBmRange = (m_dBmDistMax - m_dBmDistMin) * m_distScaleZoomFactor;
|
|
|
|
float yScale = m_distanceSpectrumRect.height() / dBmRange;
|
|
//float yScaleColor = 2.0f / dBmRange;
|
|
float yTop = m_distanceSpectrumRect.top() + m_distanceSpectrumRect.height();
|
|
|
|
int idx = 0;
|
|
int lIdx = 0;
|
|
int rIdx = 0;
|
|
|
|
// set a scissor box
|
|
glScissor(m_distanceSpectrumRect.left(), size().height() - m_distanceSpectrumRect.bottom() - 1, m_distanceSpectrumRect.left() + m_distanceSpectrumRect.width(), m_distanceSpectrumRect.height());
|
|
glEnable(GL_SCISSOR_TEST);
|
|
|
|
GLint vertexArrayLength = 0;
|
|
|
|
/*if (m_vertexArray) {
|
|
|
|
delete [] m_vertexArray;
|
|
m_vertexArray = 0;
|
|
}
|
|
|
|
if (m_vertexColorArray) {
|
|
|
|
delete [] m_vertexColorArray;
|
|
m_vertexColorArray = 0;
|
|
}*/
|
|
|
|
glLineWidth(1);
|
|
glShadeModel(GL_SMOOTH);
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
vertexArrayLength = displayWidth;
|
|
TGL2float *vertexArray = new TGL2float[vertexArrayLength];
|
|
TGL3float *vertexColorArray = new TGL3float[vertexArrayLength];
|
|
|
|
//TGL3float *vertexArrayBg = new TGL3float[2*vertexArrayLength];
|
|
//TGL3float *vertexColorArrayBg = new TGL3float[2*vertexArrayLength];
|
|
|
|
//m_vertexArray = new TGL2float[vertexArrayLength];
|
|
//m_vertexColorArray = new TGL3float[vertexArrayLength];
|
|
|
|
m_redD = (GLfloat)(set->getPanadapterColors().distanceLineColor.red() / 256.0);
|
|
m_greenD = (GLfloat)(set->getPanadapterColors().distanceLineColor.green() / 256.0);
|
|
m_blueD = (GLfloat)(set->getPanadapterColors().distanceLineColor.blue() / 256.0);
|
|
|
|
/*m_rf = (GLfloat)(set->getPanadapterColors().panLineFilledColor.red() / 256.0);
|
|
m_gf = (GLfloat)(set->getPanadapterColors().panLineFilledColor.green() / 256.0);
|
|
m_bf = (GLfloat)(set->getPanadapterColors().panLineFilledColor.blue() / 256.0);*/
|
|
|
|
for (int i = 0; i < vertexArrayLength; i++) {
|
|
|
|
lIdx = (int)floor((qreal)(i * distScale));
|
|
rIdx = (int)floor((qreal)(i * distScale) + distScale);
|
|
|
|
// max value; later we try mean value also!
|
|
localMax = -10000.0F;
|
|
for (int j = lIdx; j < rIdx; j++) {
|
|
if (m_distanceSpectrumBuffer[j] > localMax) {
|
|
|
|
localMax = m_distanceSpectrumBuffer[j];
|
|
idx = j;
|
|
}
|
|
}
|
|
|
|
/*m_spectrumVertexColorArrayBg[2*i].x = 0.10;
|
|
m_spectrumVertexColorArrayBg[2*i].y = 0.20;
|
|
m_spectrumVertexColorArrayBg[2*i].z = 0.25;*/
|
|
|
|
vertexColorArray[i].x = m_redD;// * (yScaleColor * (m_distanceSpectrumBuffer[idx] - dBmMin));
|
|
vertexColorArray[i].y = m_greenD;// * (yScaleColor * (m_distanceSpectrumBuffer[idx] - dBmMin));
|
|
vertexColorArray[i].z = m_blueD;// * (yScaleColor * (m_distanceSpectrumBuffer[idx] - dBmMin));
|
|
|
|
vertexArray[i].x = i;
|
|
vertexArray[i].y = yTop - yScale * (m_distanceSpectrumBuffer[idx] - m_dBmDistMin);
|
|
}
|
|
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
glEnableClientState(GL_COLOR_ARRAY);
|
|
|
|
glVertexPointer(2, GL_FLOAT, 0, vertexArray);
|
|
glColorPointer(3, GL_FLOAT, 0, vertexColorArray);
|
|
glDrawArrays(GL_LINE_STRIP, 0, vertexArrayLength);
|
|
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
glDisableClientState(GL_COLOR_ARRAY);
|
|
|
|
delete[] vertexArray;
|
|
delete[] vertexColorArray;
|
|
|
|
// disable scissor box
|
|
glDisable(GL_SCISSOR_TEST);
|
|
}
|
|
|
|
void QGLDistancePanel::drawDistHorizontalScale() {
|
|
|
|
if (m_freqScaleDistancePanRect.isEmpty()) return;
|
|
|
|
//QFontMetrics d_fm(m_smallFont);
|
|
|
|
int rulerFontHeight;
|
|
int rulerFontMaxWidth;
|
|
double maxSpanDist;
|
|
|
|
if (m_showChirpFFT) {
|
|
|
|
rulerFontHeight = m_fonts.smallFontMetrics->tightBoundingRect(".0Hz").height();
|
|
rulerFontMaxWidth = m_fonts.smallFontMetrics->boundingRect("000000").width();
|
|
|
|
//maxSpanDist = m_sampleRate / 2;
|
|
maxSpanDist = m_sampleRate / 4;
|
|
//maxSpanDist = m_sampleRate;
|
|
}
|
|
else {
|
|
|
|
rulerFontHeight = m_fonts.smallFontMetrics->tightBoundingRect(".0kmM").height();
|
|
rulerFontMaxWidth = m_fonts.smallFontMetrics->boundingRect("0000000").width();
|
|
|
|
maxSpanDist = m_chirpBufferLength * m_kilometersPerGate;
|
|
}
|
|
|
|
qreal kilometerSpan = maxSpanDist * m_distScaleZoomFactor;
|
|
|
|
qreal lowerDist = 0;
|
|
qreal upperDist = 0;
|
|
|
|
if (m_showChirpFFT)
|
|
lowerDist = -maxSpanDist/2;
|
|
else {
|
|
|
|
lowerDist = m_dBmDistDelta;
|
|
if (lowerDist < 0.0) lowerDist = 0.0;
|
|
}
|
|
|
|
upperDist = lowerDist + kilometerSpan;
|
|
if (upperDist > maxSpanDist) {
|
|
|
|
upperDist = maxSpanDist;
|
|
lowerDist = maxSpanDist - kilometerSpan;
|
|
}
|
|
|
|
qreal unit = (float)(m_freqScaleDistancePanRect.width() / kilometerSpan);
|
|
|
|
m_distanceScale = getXRuler(m_freqScaleDistancePanRect, rulerFontMaxWidth, unit, lowerDist, upperDist);
|
|
|
|
// draw the scale background
|
|
drawGLScaleBackground(m_freqScaleDistancePanRect, Qt::black);
|
|
|
|
// draw the distance scale
|
|
int offset_X = -1;
|
|
int textOffset_y = 17;
|
|
double distScale = 1;
|
|
|
|
// char *str;
|
|
// if (m_showChirpFFT)
|
|
// str = " Hz ";
|
|
// else
|
|
// str = " km ";
|
|
|
|
QRect scaledTextRect(0, textOffset_y, 1, rulerFontHeight);
|
|
//scaledTextRect.setWidth(d_fm.width(str));
|
|
scaledTextRect.moveLeft(m_freqScaleDistancePanRect.width() - scaledTextRect.width());// - menu_pull_right_rect.width());
|
|
|
|
glColor3f(0.94f, 0.22f, 0.43f);
|
|
glRasterPos3f(m_freqScaleDistancePanRect.width() - 30, m_freqScaleDistancePanRect.top() + textOffset_y, 0.0);
|
|
//writeBitmapString(GLUT_BITMAP_HELVETICA_10, str);
|
|
|
|
if (m_mouseRegion == freqScaleDistancePanRegion)
|
|
glColor3f(0.8f, 0.92f, 0.97f);
|
|
else
|
|
glColor3f(0.65f, 0.76f, 0.81f);
|
|
|
|
int len = m_distanceScale.mainPointPositions.length();
|
|
if (len > 0) {
|
|
|
|
glLineWidth(3);
|
|
glBegin(GL_LINES);
|
|
for (int i = 0; i < len; i++) {
|
|
|
|
glVertex3f(m_distanceScale.mainPointPositions.at(i), m_freqScaleDistancePanRect.top() + 1, 0.0f); // origin of the line
|
|
glVertex3f(m_distanceScale.mainPointPositions.at(i), m_freqScaleDistancePanRect.top() + 4, 0.0f); // ending point of the line
|
|
}
|
|
glEnd();
|
|
|
|
for (int i = 0; i < len; i++) {
|
|
|
|
QString str = QString::number(m_distanceScale.mainPoints.at(i) / distScale, 'f', 0);
|
|
|
|
int textWidth = m_fonts.smallFontMetrics->width(str);
|
|
QRect textRect(m_distanceScale.mainPointPositions.at(i) + offset_X - (textWidth / 2), textOffset_y, textWidth, rulerFontHeight);
|
|
|
|
QByteArray ba = str.toLatin1();
|
|
char *cstr = ba.data();
|
|
|
|
if (textRect.left() < 0 || textRect.right() >= scaledTextRect.left()) continue;
|
|
|
|
glRasterPos3f(m_distanceScale.mainPointPositions.at(i) + offset_X - (textWidth / 2), m_freqScaleDistancePanRect.top() + textOffset_y, 0.0);
|
|
m_oglTextSmall->renderText(textRect.x(), textRect.y(), cstr);
|
|
//writeBitmapString(GLUT_BITMAP_HELVETICA_10, cstr);
|
|
}
|
|
}
|
|
|
|
len = m_distanceScale.subPointPositions.length();
|
|
if (len > 0) {
|
|
|
|
glLineWidth(1);
|
|
glBegin(GL_LINES);
|
|
for (int i = 0; i < len; i++) {
|
|
|
|
glVertex3f(m_distanceScale.subPointPositions.at(i), m_freqScaleDistancePanRect.top() + 1, 0.0f); // origin of the line
|
|
glVertex3f(m_distanceScale.subPointPositions.at(i), m_freqScaleDistancePanRect.top() + 3, 0.0f); // ending point of the line
|
|
}
|
|
glEnd();
|
|
}
|
|
}
|
|
|
|
void QGLDistancePanel::drawDistVerticalScale() {
|
|
/*const QRect &rect,
|
|
const QRect &distRect,
|
|
int region,
|
|
qreal dBmMin,
|
|
qreal dBmMax,
|
|
bool showZerodBmLine*/
|
|
|
|
if (m_dBmScaleDistancePanRect.isEmpty()) return;
|
|
|
|
//QFontMetrics d_fm(m_smallFont);
|
|
int spacing = 5;
|
|
int fontHeight = m_fonts.smallFontMetrics->tightBoundingRect(".0dBm").height() + spacing;
|
|
int fontMaxWidth = m_fonts.smallFontMetrics->boundingRect("-000.0").width();
|
|
|
|
qreal dBmRange = qAbs(m_dBmDistScaleMax - m_dBmDistScaleMin);
|
|
//if (dBmRange <= 0) return;
|
|
|
|
qreal unit = (float)(m_dBmScaleDistancePanRect.height() / dBmRange);
|
|
|
|
m_dBmScale = getYRuler(m_dBmScaleDistancePanRect, fontHeight, unit, m_dBmDistScaleMin, m_dBmDistScaleMax);
|
|
|
|
// draw the scale background
|
|
drawGLScaleBackground(m_dBmScaleDistancePanRect, QColor(60, 60, 60, 80));
|
|
|
|
QRect textRect(0, 0, fontMaxWidth, fontHeight);
|
|
textRect.moveRight(14);
|
|
int yOld = -textRect.height();
|
|
|
|
if (m_mouseRegion == dBmScaleDistancePanRegion)
|
|
glColor3f(0.8f, 0.92f, 0.97f);
|
|
else
|
|
glColor3f(0.65f, 0.76f, 0.81f);
|
|
|
|
|
|
glLineWidth(1);
|
|
int len = m_dBmScale.mainPointPositions.length();
|
|
|
|
if (len > 0) {
|
|
|
|
glBegin(GL_LINES);
|
|
for (int i = 0; i < len; i++) {
|
|
|
|
glVertex3f(m_dBmScaleDistancePanRect.left(), m_dBmScale.mainPointPositions.at(i), 0.0f); // origin of the line
|
|
glVertex3f(m_dBmScaleDistancePanRect.left() + 4, m_dBmScale.mainPointPositions.at(i), 0.0f); // ending point of the line
|
|
}
|
|
glEnd();
|
|
|
|
for (int i = 0; i < len; i++) {
|
|
|
|
textRect.moveTop(m_dBmScale.mainPointPositions.at(i) + textRect.height()/3);
|
|
|
|
QString str;
|
|
if (textRect.y() >= yOld &&
|
|
textRect.bottom() <= (m_dBmScaleDistancePanRect.top() + m_dBmScaleDistancePanRect.height() - textRect.height()) &&
|
|
m_dBmScale.mainPointPositions.at(i) > 10 + m_dBmScaleDistancePanRect.top())
|
|
{
|
|
str = QString::number(m_dBmScale.mainPoints.at(i), 'f', 1);
|
|
QByteArray ba = str.toLatin1();
|
|
//char *cstr = ba.data();
|
|
glRasterPos3f(textRect.right() + m_dBmScaleDistancePanRect.left(), textRect.y(), 0.0);
|
|
//writeBitmapString(GLUT_BITMAP_TIMES_ROMAN_10, cstr);
|
|
yOld = textRect.bottom();
|
|
}
|
|
|
|
if (qRound(m_dBmScale.mainPoints.at(i)) == 0 && m_showZerodBmLine) {
|
|
|
|
int zerodBmLine = m_dBmScale.mainPointPositions.at(i);
|
|
if (zerodBmLine > m_dBmScaleDistancePanRect.top() && zerodBmLine < m_dBmScaleDistancePanRect.bottom()) {
|
|
|
|
glColor3f(0.2f, 0.87f, 0.87f);
|
|
glBegin(GL_LINES);
|
|
glVertex3f(m_distanceSpectrumRect.left(), zerodBmLine, 0.0f); // origin of the line
|
|
glVertex3f(m_distanceSpectrumRect.width() - m_dBmScaleDistancePanRect.width() + 4, zerodBmLine, 0.0f); // ending point of the line
|
|
glEnd();
|
|
|
|
if (m_mouseRegion == dBmScaleDistancePanRegion)
|
|
glColor3f(0.8f, 0.92f, 0.97f);
|
|
else
|
|
glColor3f(0.65f, 0.76f, 0.81f);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (m_mouseRegion == dBmScaleDistancePanRegion)
|
|
glColor3f(0.5f, 0.62f, 0.67f);
|
|
else
|
|
glColor3f(0.35f, 0.46f, 0.51f);
|
|
|
|
if (m_dBmScale.subPointPositions.length() > 0) {
|
|
|
|
glBegin(GL_LINES);
|
|
for (int i = 0; i < m_dBmScale.subPointPositions.length(); i++) {
|
|
|
|
glVertex3f(m_dBmScaleDistancePanRect.left(), m_dBmScale.subPointPositions.at(i), 0.0f); // origin of the line
|
|
glVertex3f(m_dBmScaleDistancePanRect.left() + 2, m_dBmScale.subPointPositions.at(i), 0.0f); // ending point of the line
|
|
}
|
|
glEnd();
|
|
}
|
|
|
|
//char* s = "dBm";
|
|
textRect.moveTop(m_dBmScaleDistancePanRect.top() + m_dBmScaleDistancePanRect.height() - textRect.height());
|
|
glColor3f(0.94f, 0.22f, 0.43f);
|
|
//glRasterPos3f(textRect.left(), textRect.center().y(), 0.0);
|
|
//glRasterPos3f(textRect.right() + right, textRect.center().y(), 0.0);
|
|
glRasterPos3f(textRect.right() + m_dBmScaleDistancePanRect.left(), textRect.center().y(), 0.0);
|
|
//writeBitmapString(GLUT_BITMAP_HELVETICA_10, s);
|
|
|
|
//glPushMatrix();
|
|
// glTranslatef(0.0, 0.0, 0.0);
|
|
// //glRotatef(45.0, 0.0, 0.0, 1.0);
|
|
// glScalef(0.25, 0.25, 0.25);
|
|
// writeStrokeString(GLUT_STROKE_ROMAN, s);
|
|
//glPopMatrix();
|
|
}
|
|
|
|
//**********************************************************************************************
|
|
// The algorithms of the scale functions renderPanVerticalScale() and renderPanHorizontalScale()
|
|
// are taken from SDRMAXIII (c) Catherine Moss, with permission.
|
|
|
|
void QGLDistancePanel::renderPanVerticalScale() {
|
|
|
|
QString str;
|
|
//QFontMetrics d_fm(m_smallFont);
|
|
//QFontMetrics d_fm(m_normalFont);
|
|
|
|
int spacing = 7;
|
|
int fontHeight = m_fonts.smallFontMetrics->tightBoundingRect(".0dBm").height() + spacing;
|
|
int fontMaxWidth = m_fonts.smallFontMetrics->boundingRect("-000.0").width();
|
|
|
|
GLint width = m_dBmScalePanRect.width();
|
|
GLint height = m_dBmScalePanRect.height();
|
|
|
|
qreal unit = (qreal)(m_dBmScalePanRect.height() / qAbs(m_dBmPanMax - m_dBmPanMin));
|
|
|
|
m_dBmScale = getYRuler2(m_dBmScalePanRect, fontHeight, unit, m_dBmPanMin, m_dBmPanMax);
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
QRect textRect(0, 0, fontMaxWidth, fontHeight);
|
|
textRect.moveLeft(3);
|
|
int yOld = -textRect.height();
|
|
|
|
int len = m_dBmScale.mainPointPositions.length();
|
|
int sublen = m_dBmScale.subPointPositions.length();
|
|
|
|
glViewport(0, 0, width, height);
|
|
setProjectionOrthographic(width, height);
|
|
|
|
// draw the scale background
|
|
drawGLScaleBackground(QRect(0, 0, width, height), QColor(30, 30, 30, 180));
|
|
|
|
if (len > 0) {
|
|
|
|
glColor3f(0.65f, 0.76f, 0.81f);
|
|
glLineWidth(1);
|
|
|
|
glBegin(GL_LINES);
|
|
for (int i = 0; i < len; i++) {
|
|
|
|
glVertex3f(width, m_dBmScale.mainPointPositions.at(i), 0.0f); // origin of the line
|
|
glVertex3f(width - 4, m_dBmScale.mainPointPositions.at(i), 0.0f); // ending point of the line
|
|
}
|
|
glEnd();
|
|
|
|
glColor3f(0.45f, 0.56f, 0.61f);
|
|
if (sublen > 0) {
|
|
|
|
glBegin(GL_LINES);
|
|
for (int i = 0; i < sublen; i++) {
|
|
|
|
glVertex3f(width, m_dBmScale.subPointPositions.at(i), 0.0f); // origin of the line
|
|
glVertex3f(width - 2, m_dBmScale.subPointPositions.at(i), 0.0f); // ending point of the line
|
|
}
|
|
glEnd();
|
|
}
|
|
|
|
glColor3f(0.75f, 0.86f, 0.91f);
|
|
for (int i = 0; i < len; i++) {
|
|
|
|
textRect.moveBottom(m_dBmScale.mainPointPositions.at(i) + textRect.height()/2);
|
|
|
|
if (textRect.y() >= yOld && textRect.bottom() <= (m_dBmScalePanRect.height() - textRect.height())) {
|
|
|
|
str = QString::number(m_dBmScale.mainPoints.at(i), 'f', 1);
|
|
m_oglTextSmall->renderText(textRect.x() + fontMaxWidth - m_fonts.smallFontMetrics->tightBoundingRect(str).width(), textRect.y(), str);
|
|
yOld = textRect.bottom();
|
|
}
|
|
}
|
|
}
|
|
|
|
textRect.moveTop(m_dBmScalePanRect.height() - textRect.height());
|
|
glColor3f(0.94f, 0.22f, 0.43f);
|
|
|
|
str = QString("dBm");
|
|
m_oglTextSmall->renderText(textRect.x(), textRect.y(), str);
|
|
|
|
glViewport(0, 0, size().width(), size().height());
|
|
setProjectionOrthographic(size().width(), size().height());
|
|
}
|
|
|
|
void QGLDistancePanel::renderPanHorizontalScale() {
|
|
|
|
//GRAPHICS_DEBUG << "render frequency scale";
|
|
//QFontMetrics d_fm(m_smallFont);
|
|
int fontHeight = m_fonts.smallFontMetrics->tightBoundingRect(".0kMGHz").height();
|
|
int fontMaxWidth = m_fonts.smallFontMetrics->boundingRect("000.000.0").width();
|
|
|
|
qreal freqSpan = (qreal)(m_sampleRate * m_freqScaleZoomFactor);
|
|
qreal lowerFreq = (qreal)m_frequency - freqSpan / 2;
|
|
qreal upperFreq = (qreal)m_frequency + freqSpan / 2;
|
|
qreal unit = (qreal)(m_freqScalePanRect.width() / freqSpan);
|
|
|
|
m_frequencyScale = getXRuler(m_freqScalePanRect, fontMaxWidth, unit, lowerFreq, upperFreq);
|
|
|
|
// draw the frequency scale
|
|
int offset_X = -1;
|
|
int textOffset_y = 5;
|
|
double freqScale = 1;
|
|
|
|
QString fstr = QString(" Hz ");
|
|
if (upperFreq >= 1e6) { freqScale = 1e6; fstr = QString(" MHz "); }
|
|
else
|
|
if (upperFreq >= 1e3) { freqScale = 1e3; fstr = QString(" kHz "); }
|
|
|
|
// draw the scale background
|
|
drawGLScaleBackground(QRect(0, 0, m_freqScalePanRect.width(), m_freqScalePanRect.height()), QColor(0, 0, 0, 255));
|
|
|
|
QRect scaledTextRect(0, textOffset_y, 1, m_freqScalePanRect.height());
|
|
scaledTextRect.setWidth(m_fonts.smallFontMetrics->width(fstr));
|
|
scaledTextRect.moveLeft(m_freqScalePanRect.width() - scaledTextRect.width());
|
|
|
|
glColor3f(0.65f, 0.76f, 0.81f);
|
|
int len = m_frequencyScale.mainPointPositions.length();
|
|
if (len > 0) {
|
|
|
|
glLineWidth(3);
|
|
glBegin(GL_LINES);
|
|
for (int i = 0; i < len; i++) {
|
|
|
|
glVertex3f(m_frequencyScale.mainPointPositions.at(i), 1.0f, 0.0f);
|
|
glVertex3f(m_frequencyScale.mainPointPositions.at(i), 4.0f, 0.0f);
|
|
}
|
|
glEnd();
|
|
|
|
for (int i = 0; i < len; i++) {
|
|
|
|
QString str = QString::number(m_frequencyScale.mainPoints.at(i) / freqScale, 'f', 3);
|
|
|
|
if (i > 0) {
|
|
|
|
double delta = m_frequencyScale.mainPoints.at(i) - m_frequencyScale.mainPoints.at(i-1);
|
|
if (delta < 1000.0)
|
|
str = QString::number(m_frequencyScale.mainPoints.at(i) / freqScale, 'f', 4);
|
|
else
|
|
if (freqScale == 1e3)
|
|
while (str.endsWith('0')) str.remove(str.size() - 1, 1);
|
|
}
|
|
if (str.endsWith('.')) str.remove(str.size() - 1, 1);
|
|
|
|
int text_width = m_fonts.smallFontMetrics->width(str);
|
|
QRect textRect(m_frequencyScale.mainPointPositions.at(i) + offset_X - (text_width / 2), textOffset_y, text_width, fontHeight);
|
|
|
|
if (textRect.left() < 0 || textRect.right() >= scaledTextRect.left()) continue;
|
|
|
|
m_oglTextSmall->renderText(textRect.x(), textRect.y(), str);
|
|
}
|
|
}
|
|
|
|
if (m_frequencyScale.subPointPositions.length() > 0) {
|
|
|
|
glLineWidth(1);
|
|
glBegin(GL_LINES);
|
|
for (int i = 0; i < m_frequencyScale.subPointPositions.length(); i++) {
|
|
|
|
glVertex3f(m_frequencyScale.subPointPositions.at(i), 1.0f, 0.0f);
|
|
glVertex3f(m_frequencyScale.subPointPositions.at(i), 3.0f, 0.0f);
|
|
}
|
|
glEnd();
|
|
}
|
|
|
|
glColor3f(0.94f, 0.22f, 0.43f);
|
|
m_oglTextSmall->renderText(m_freqScalePanRect.width() - 30, textOffset_y, fstr);
|
|
}
|
|
|
|
void QGLDistancePanel::renderPanadapterGrid() {
|
|
|
|
//GRAPHICS_DEBUG << "render panadapter grid";
|
|
//glLineStipple(1, 0xCCCC);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
glLineStipple(1, 0x9999);
|
|
glEnable(GL_LINE_STIPPLE);
|
|
glLineWidth(1.0f);
|
|
|
|
// vertical lines
|
|
int len = m_frequencyScale.mainPointPositions.length();
|
|
if (len > 0) {
|
|
|
|
GLint x1 = m_panRect.left();
|
|
GLint x2 = 1;
|
|
if (m_dBmScalePanRect.isValid()) x2 += m_dBmScalePanRect.width();
|
|
|
|
//GLint y1 = rect.top() + 1;
|
|
GLint y1 = 1;
|
|
GLint y2 = m_panRect.bottom() - 1;
|
|
|
|
TGL2int *vertexArray = new TGL2int[len * 2];
|
|
int vertexArrayLen = 0;
|
|
|
|
TGL2int point1, point2;
|
|
point1.y = y1;
|
|
point2.y = y2;
|
|
for (int i = 0; i < len; i++) {
|
|
|
|
GLint x = m_frequencyScale.mainPointPositions.at(i);
|
|
if (x < x2) continue;
|
|
x += x1;
|
|
point1.x = x;
|
|
point2.x = x;
|
|
vertexArray[vertexArrayLen++] = point1;
|
|
vertexArray[vertexArrayLen++] = point2;
|
|
}
|
|
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
glVertexPointer(2, GL_INT, 0, vertexArray);
|
|
glDrawArrays(GL_LINES, 0, vertexArrayLen);
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
|
|
delete[] vertexArray;
|
|
}
|
|
|
|
// horizontal lines
|
|
len = m_dBmScale.mainPointPositions.length();
|
|
if (len > 0) {
|
|
|
|
TGL2float *vertexArray = new TGL2float[len * 2];
|
|
int vertexArrayLen = 0;
|
|
|
|
TGL2float point1, point2;
|
|
point1.x = m_panRect.left() + m_dBmScalePanRect.width();
|
|
point2.x = m_panRect.right();
|
|
|
|
for (int i = 0; i < len; i++) {
|
|
|
|
GLfloat y = m_dBmScale.mainPointPositions.at(i);
|
|
|
|
point1.y = y;
|
|
point2.y = y;
|
|
|
|
vertexArray[vertexArrayLen++] = point1;
|
|
vertexArray[vertexArrayLen++] = point2;
|
|
}
|
|
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
glVertexPointer(2, GL_FLOAT, 0, vertexArray);
|
|
glDrawArrays(GL_LINES, 0, vertexArrayLen);
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
|
|
delete[] vertexArray;
|
|
|
|
}
|
|
glDisable(GL_LINE_STIPPLE);
|
|
}
|
|
|
|
|
|
//********************************************************************
|
|
|
|
void QGLDistancePanel::getRegion(QPoint p) {
|
|
|
|
QRect mouse_rect(0, 0, 100, 100);
|
|
mouse_rect.moveCenter(p);
|
|
|
|
if (m_freqScalePanRect.contains(p)) {
|
|
|
|
m_mouseRegion = freqScalePanadapterRegion;
|
|
|
|
if (m_displayTime.elapsed() >= 50) {
|
|
|
|
m_displayTime.restart();
|
|
update();
|
|
}
|
|
}
|
|
else if (m_dBmScalePanRect.contains(p)) {
|
|
|
|
m_mouseRegion = dBmScalePanadapterRegion;
|
|
|
|
if (m_displayTime.elapsed() >= 50) {
|
|
|
|
m_displayTime.restart();
|
|
update();
|
|
}
|
|
}
|
|
else if (abs(p.x() - m_filterRect.left()) < m_snapMouse &&
|
|
m_panRect.contains(p)
|
|
) {
|
|
m_mouseRegion = filterRegionLow;
|
|
m_mouseDownFilterFrequencyLo = m_filterLowerFrequency;
|
|
}
|
|
|
|
else if (abs(p.x() - m_filterRect.right()) < m_snapMouse &&
|
|
m_panRect.contains(p)
|
|
) {
|
|
m_mouseRegion = filterRegionHigh;
|
|
m_mouseDownFilterFrequencyHi = m_filterUpperFrequency;
|
|
}
|
|
|
|
else if (m_panRect.contains(p)) {
|
|
|
|
m_mouseRegion = panadapterRegion;
|
|
|
|
if (m_displayTime.elapsed() >= 50) {
|
|
|
|
m_displayTime.restart();
|
|
update();
|
|
}
|
|
}
|
|
|
|
else if (m_freqScaleDistancePanRect.contains(p)) {
|
|
|
|
m_mouseRegion = freqScaleDistancePanRegion;
|
|
m_distRulerUpdate = true;
|
|
|
|
if (m_displayTime.elapsed() >= 50) {
|
|
|
|
m_displayTime.restart();
|
|
update();
|
|
}
|
|
}
|
|
|
|
else if (m_dBmScaleDistancePanRect.contains(p)) {
|
|
|
|
m_mouseRegion = dBmScaleDistancePanRegion;
|
|
|
|
if (m_displayTime.elapsed() >= 50) {
|
|
|
|
m_displayTime.restart();
|
|
update();
|
|
}
|
|
}
|
|
else if (m_distanceSpectrumRect.contains(p)) {
|
|
|
|
m_mouseRegion = distancePanRegion;
|
|
|
|
if (m_displayTime.elapsed() >= 50) {
|
|
|
|
m_displayTime.restart();
|
|
update();
|
|
}
|
|
}
|
|
else
|
|
m_mouseRegion = elsewhere;
|
|
|
|
/*if (m_displayTime.elapsed() >= 50) {
|
|
|
|
m_displayTime.restart();
|
|
updateGL();
|
|
update();
|
|
}*/
|
|
//GRAPHICS_DEBUG << "region" << m_mouseRegion;
|
|
}
|
|
|
|
void QGLDistancePanel::resizeGL(int iWidth, int iHeight) {
|
|
|
|
int width = (int)(iWidth/2) * 2;
|
|
int height = iHeight;
|
|
|
|
if (width != m_oldWidth) {
|
|
|
|
m_freqScalePanadapterRenew = true;
|
|
m_panGridRenew = true;
|
|
|
|
m_oldWidth = width;
|
|
}
|
|
|
|
m_spectrumVertexColorUpdate = true;
|
|
//m_displayData.size = QSize(width, height);
|
|
|
|
glFinish();
|
|
|
|
m_resizeTime.restart();
|
|
setupDisplayRegions(QSize(width, height));
|
|
glViewport(0, 0, (GLsizei)width, (GLsizei)height);
|
|
|
|
setProjectionOrthographic(width, height);
|
|
}
|
|
|
|
void QGLDistancePanel::setupDisplayRegions(QSize size) {
|
|
|
|
m_displayTop = 0;
|
|
int freqScaleRectHeight = 20;
|
|
int dBmScaleWidth = 45;
|
|
int distScaleRectHeight = 20;
|
|
|
|
m_freqScalePanRect = QRect(
|
|
0,
|
|
m_displayTop + qRound((size.height() - m_displayTop - freqScaleRectHeight) * m_freqRulerPosition),
|
|
size.width(),
|
|
freqScaleRectHeight);
|
|
|
|
m_panRect = QRect(
|
|
0,
|
|
m_displayTop,
|
|
size.width(),
|
|
m_freqScalePanRect.top() - m_displayTop);
|
|
|
|
if (m_panRect.height() != m_oldPanRectHeight) {
|
|
|
|
m_dBmScalePanadapterRenew = true;
|
|
m_panGridRenew = true;
|
|
}
|
|
|
|
m_oldPanRectHeight = m_panRect.height();
|
|
m_panRectWidth = (GLint)m_panRect.width();
|
|
|
|
m_freqScaleDistancePanRect = QRect(
|
|
0,
|
|
size.height() - m_displayTop - distScaleRectHeight + 1,
|
|
size.width(),
|
|
distScaleRectHeight);
|
|
|
|
m_distanceSpectrumRect = QRect(
|
|
m_freqScalePanRect.left(),
|
|
m_freqScalePanRect.bottom(),
|
|
m_freqScalePanRect.width(),
|
|
size.height() - m_displayTop - m_freqScalePanRect.bottom() - distScaleRectHeight + 1);
|
|
|
|
m_distancePanRect = QRect(
|
|
m_freqScalePanRect.left(),
|
|
m_freqScalePanRect.bottom(),
|
|
m_freqScalePanRect.width(),
|
|
size.height() - m_displayTop - m_freqScalePanRect.bottom() - distScaleRectHeight + 1);
|
|
|
|
m_dBmScaleDistancePanRect = QRect(
|
|
m_distanceSpectrumRect.right() - dBmScaleWidth,
|
|
m_freqScalePanRect.bottom(),
|
|
dBmScaleWidth,
|
|
size.height() - m_displayTop - m_freqScalePanRect.bottom() - distScaleRectHeight + 1);
|
|
|
|
m_dBmScalePanRect = QRect(
|
|
m_panRect.left(),
|
|
m_displayTop,
|
|
45,
|
|
m_panRect.height());
|
|
|
|
m_freqScalePanadapterUpdate = true;
|
|
m_dBmScalePanadapterUpdate = true;
|
|
m_panGridUpdate = true;
|
|
|
|
//***************************************************************************
|
|
/*GRAPHICS_DEBUG << "***************************************************************************";
|
|
GRAPHICS_DEBUG << "total size" << size.height();
|
|
GRAPHICS_DEBUG << "sizes (top, bottom, height):";
|
|
GRAPHICS_DEBUG << "panRect: " << m_panRect.top() << " " << m_panRect.bottom() << " " << m_panRect.height();
|
|
GRAPHICS_DEBUG << "freqScalePanRect: " << m_freqScalePanRect.top() << " " << m_freqScalePanRect.bottom() << " " << m_freqScalePanRect.height();
|
|
GRAPHICS_DEBUG << "dBmScalePanRect: " << m_dBmScalePanRect.top() << " " << m_dBmScalePanRect.bottom() << " " << m_dBmScalePanRect.height();
|
|
GRAPHICS_DEBUG << "m_distanceSpectrumRect: " << m_distanceSpectrumRect.top() << " " << m_distanceSpectrumRect.bottom() << " " << m_distanceSpectrumRect.height();
|
|
GRAPHICS_DEBUG << "m_freqScaleDistancePanRect: " << m_freqScaleDistancePanRect.top() << " " << m_freqScaleDistancePanRect.bottom() << " " << m_freqScaleDistancePanRect.height();
|
|
GRAPHICS_DEBUG << "m_dBmScaleDistancePanRect: " << m_dBmScaleDistancePanRect.top() << " " << m_dBmScaleDistancePanRect.bottom() << " " << m_dBmScaleDistancePanRect.height();
|
|
GRAPHICS_DEBUG << "";*/
|
|
}
|
|
|
|
void QGLDistancePanel::saveGLState() {
|
|
|
|
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
|
glMatrixMode(GL_PROJECTION);
|
|
glPushMatrix();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glPushMatrix();
|
|
}
|
|
|
|
void QGLDistancePanel::restoreGLState() {
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
glPopMatrix();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glPopMatrix();
|
|
glPopAttrib();
|
|
}
|
|
|
|
//********************************************************************
|
|
// HMI control
|
|
|
|
void QGLDistancePanel::enterEvent(QEvent *event) {
|
|
|
|
setFocus(Qt::MouseFocusReason);
|
|
|
|
m_mousePos = QPoint(-1, -1);
|
|
m_mouseRegion = elsewhere;
|
|
update();
|
|
|
|
QGLWidget::enterEvent(event);
|
|
}
|
|
|
|
void QGLDistancePanel::leaveEvent(QEvent *event) {
|
|
|
|
m_mousePos = QPoint(-1, -1);
|
|
m_mouseRegion = elsewhere;
|
|
update();
|
|
|
|
QGLWidget::leaveEvent(event);
|
|
}
|
|
|
|
void QGLDistancePanel::wheelEvent(QWheelEvent* event) {
|
|
|
|
//GRAPHICS_DEBUG << "wheelEvent";
|
|
QPoint pos = event->pos();
|
|
|
|
if (event->buttons() == Qt::NoButton) getRegion(pos);
|
|
|
|
double freqStep = set->getMouseWheelFreqStep(0);
|
|
|
|
switch (m_mouseRegion) {
|
|
|
|
case panadapterRegion:
|
|
|
|
double delta = 0;
|
|
if (event->delta() < 0) delta = -freqStep;
|
|
else
|
|
if (event->delta() > 0) delta = freqStep;
|
|
|
|
if (m_frequency + delta > MAXFREQUENCY)
|
|
m_frequency = MAXFREQUENCY;
|
|
else
|
|
if (m_frequency + delta < 0)
|
|
m_frequency = 0;
|
|
else
|
|
// snap to the frequency step
|
|
m_frequency = (long)(qRound((m_frequency + delta) / qAbs(freqStep)) * qAbs(freqStep));
|
|
|
|
//set->setFrequency(this, true, 0, m_frequency);
|
|
set->setVFOFrequency(this, 0, 0, m_frequency);
|
|
|
|
/*if (m_spectrumAveragingOld) {
|
|
|
|
m_spectrumAveragingOld = true;
|
|
m_spectrumAveraging = false;
|
|
|
|
freqChangeTimer.restart();
|
|
}*/
|
|
break;
|
|
}
|
|
|
|
//updateGL();
|
|
update();
|
|
}
|
|
|
|
void QGLDistancePanel::mousePressEvent(QMouseEvent* event) {
|
|
|
|
//GRAPHICS_DEBUG << "mousePressEvent";
|
|
m_mousePos = event->pos();
|
|
m_mouseDownPos = m_mousePos;
|
|
|
|
getRegion(m_mousePos);
|
|
|
|
if (m_mouseRegion == panadapterRegion) {
|
|
|
|
if (event->buttons() == Qt::RightButton) {
|
|
|
|
if (m_crossHairCursor) {
|
|
|
|
m_crossHairCursor = false;
|
|
setCursor(Qt::ArrowCursor);
|
|
}
|
|
else {
|
|
|
|
m_crossHairCursor = true;
|
|
setCursor(Qt::BlankCursor);
|
|
}
|
|
}
|
|
else if (event->buttons() == Qt::LeftButton && m_crossHairCursor) {
|
|
|
|
double freqStep = set->getMouseWheelFreqStep(0);
|
|
int dx = m_panRect.width()/2 - m_mousePos.x();
|
|
qreal unit = (qreal)((m_sampleRate * m_freqScaleZoomFactor) / m_panRect.width());
|
|
m_frequency -= unit * dx;
|
|
|
|
m_frequency = (long)(qRound(m_frequency / qAbs(freqStep)) * qAbs(freqStep));
|
|
|
|
//set->setFrequency(this, true, 0, m_frequency);
|
|
set->setVFOFrequency(this, 0, 0, m_frequency);
|
|
update();
|
|
}
|
|
}
|
|
else if (m_mouseRegion == freqScalePanadapterRegion) {
|
|
|
|
m_rulerMouseDownPos = m_freqScalePanRect.topLeft();
|
|
|
|
if (event->buttons() == Qt::RightButton) setCursor(Qt::SplitHCursor);
|
|
update();
|
|
|
|
return;
|
|
}
|
|
else if (m_mouseRegion == freqScaleDistancePanRegion) {
|
|
|
|
m_rulerMouseDownPos = m_freqScaleDistancePanRect.topLeft();
|
|
|
|
if (event->buttons() == Qt::RightButton) setCursor(Qt::SplitHCursor);
|
|
update();
|
|
|
|
return;
|
|
}
|
|
else if (m_mouseRegion == dBmScalePanadapterRegion) {
|
|
|
|
m_rulerMouseDownPos = m_dBmScaleDistancePanRect.topLeft();
|
|
|
|
if (event->buttons() == Qt::RightButton) setCursor(Qt::SplitVCursor);
|
|
update();
|
|
|
|
return;
|
|
}
|
|
else if (m_mouseRegion == dBmScaleDistancePanRegion) {
|
|
|
|
m_rulerMouseDownPos = m_dBmScaleDistancePanRect.topLeft();
|
|
|
|
if (event->buttons() == Qt::RightButton) setCursor(Qt::SplitVCursor);
|
|
update();
|
|
|
|
return;
|
|
}
|
|
|
|
update();
|
|
}
|
|
|
|
void QGLDistancePanel::mouseReleaseEvent(QMouseEvent *event) {
|
|
|
|
//GRAPHICS_DEBUG << "mouseReleaseEvent";
|
|
m_mousePos = event->pos();
|
|
m_mouseDownPos = m_mousePos;
|
|
|
|
getRegion(m_mousePos);
|
|
|
|
if (m_mouseRegion == freqScalePanadapterRegion) {
|
|
|
|
return;
|
|
}
|
|
else if (m_mouseRegion == freqScaleDistancePanRegion) {
|
|
|
|
return;
|
|
}
|
|
else if (m_mouseRegion == dBmScaleDistancePanRegion) {
|
|
|
|
if (event->button() == Qt::LeftButton && m_showZerodBmLine) {
|
|
|
|
m_showZerodBmLine = false;
|
|
}
|
|
else if (event->button() == Qt::RightButton) {
|
|
}
|
|
update();
|
|
return;
|
|
}
|
|
update();
|
|
}
|
|
|
|
void QGLDistancePanel::mouseMoveEvent(QMouseEvent* event) {
|
|
|
|
//GRAPHICS_DEBUG << "mouseMoveEvent";
|
|
QPoint pos = event->pos();
|
|
m_mousePos = event->pos();
|
|
|
|
if (event->buttons() == Qt::NoButton) getRegion(pos);
|
|
|
|
switch (m_mouseRegion) {
|
|
|
|
case distancePanRegion:
|
|
//GRAPHICS_DEBUG << "distancePanRegion";
|
|
setCursor(Qt::ArrowCursor);
|
|
//update();
|
|
break;
|
|
|
|
case panadapterRegion:
|
|
//GRAPHICS_DEBUG << "panadapterRegion Rx:" << m_receiver;
|
|
if (m_crossHairCursor)
|
|
setCursor(Qt::BlankCursor);
|
|
else
|
|
setCursor(Qt::ArrowCursor);
|
|
|
|
if (event->buttons() == Qt::LeftButton) {
|
|
|
|
QPoint dPos = m_mouseDownPos - pos;
|
|
|
|
qreal unit = (qreal)((m_sampleRate * m_freqScaleZoomFactor) / m_freqScalePanRect.width());
|
|
qreal deltaFreq = unit * dPos.x();
|
|
|
|
long newFrequency = m_frequency + deltaFreq;
|
|
if (newFrequency > MAXFREQUENCY)
|
|
newFrequency = MAXFREQUENCY;
|
|
else
|
|
if (newFrequency + deltaFreq < 0)
|
|
newFrequency = 0;
|
|
else
|
|
m_frequency += deltaFreq;
|
|
|
|
//set->setFrequency(this, true, 0, m_frequency);
|
|
set->setVFOFrequency(this, 0, 0, m_frequency);
|
|
m_mouseDownPos = pos;
|
|
}
|
|
//update();
|
|
break;
|
|
|
|
case dBmScalePanadapterRegion:
|
|
//GRAPHICS_DEBUG << "dBmScalePanadapterRegion";
|
|
if (event->buttons() == Qt::LeftButton) {
|
|
|
|
QPoint dPos = m_mouseDownPos - pos;
|
|
qreal unit = (qreal)(qAbs(m_dBmPanMax - m_dBmPanMin) / m_panRect.height());
|
|
|
|
qreal newMin = m_dBmPanMin - unit * dPos.y();
|
|
qreal newMax = m_dBmPanMax - unit * dPos.y();
|
|
|
|
if (newMin > MINDBM && newMax < MAXDBM) {
|
|
|
|
m_dBmPanMin = newMin;
|
|
m_dBmPanMax = newMax;
|
|
|
|
set->setdBmPanScaleMin(0, m_dBmPanMin);
|
|
set->setdBmPanScaleMax(0, m_dBmPanMax);
|
|
}
|
|
|
|
m_mouseDownPos = pos;
|
|
m_dBmScalePanadapterUpdate = true;
|
|
m_panGridUpdate = true;
|
|
}
|
|
else
|
|
if (event->buttons() == Qt::RightButton) {
|
|
|
|
QPoint dPos = m_mouseDownPos - pos;
|
|
if (dPos.y() > 0)
|
|
m_dBmPanDelta = 1.0;
|
|
else if (dPos.y() < 0)
|
|
m_dBmPanDelta = -1.0f;
|
|
|
|
m_dBmPanMin += m_dBmPanDelta;
|
|
m_dBmPanMax -= m_dBmPanDelta;
|
|
|
|
if (qAbs(m_dBmPanMax - m_dBmPanMin) < 10) {
|
|
|
|
m_dBmPanMin -= m_dBmPanDelta;
|
|
m_dBmPanMax += m_dBmPanDelta;
|
|
}
|
|
if (m_dBmPanMin < MINDBM) m_dBmPanMin = MINDBM;
|
|
if (m_dBmPanMax > MAXDBM) m_dBmPanMax = MAXDBM;
|
|
|
|
set->setdBmPanScaleMin(0, m_dBmPanMin);
|
|
set->setdBmPanScaleMax(0, m_dBmPanMax);
|
|
|
|
m_mouseDownPos = pos;
|
|
m_dBmScalePanadapterUpdate = true;
|
|
m_panGridUpdate = true;
|
|
}
|
|
else
|
|
setCursor(Qt::ArrowCursor);
|
|
|
|
//update();
|
|
break;
|
|
|
|
case dBmScaleDistancePanRegion:
|
|
//GRAPHICS_DEBUG << "dBmScaleDistancePanRegion";
|
|
if (event->buttons() == Qt::LeftButton &&
|
|
event->modifiers() == Qt::ControlModifier) {
|
|
|
|
m_showZerodBmLine = true;
|
|
QPoint dPos = m_mouseDownPos - pos;
|
|
|
|
qreal unit = (qreal)(qAbs(m_dBmDistScaleMax - m_dBmDistScaleMin) / m_distanceSpectrumRect.height());
|
|
|
|
qreal newMin = m_dBmDistScaleMin - unit * dPos.y();
|
|
qreal newMax = m_dBmDistScaleMax - unit * dPos.y();
|
|
|
|
if (newMin > MINDISTDBM && newMax < MAXDISTDBM) {
|
|
|
|
m_dBmDistScaleMin = newMin;
|
|
m_dBmDistScaleMax = newMax;
|
|
}
|
|
m_mouseDownPos = pos;
|
|
}
|
|
else
|
|
if (event->buttons() == Qt::LeftButton) {
|
|
|
|
QPoint dPos = m_mouseDownPos - pos;
|
|
|
|
qreal unit = (qreal)(qAbs(m_dBmDistMax - m_dBmDistMin) / m_distanceSpectrumRect.height());
|
|
|
|
qreal newMin = m_dBmDistMin - unit * dPos.y();
|
|
qreal newMax = m_dBmDistMax - unit * dPos.y();
|
|
|
|
if (newMin > MINDISTDBM && newMax < MAXDISTDBM) {
|
|
|
|
m_dBmDistMin = newMin;
|
|
m_dBmDistMax = newMax;
|
|
}
|
|
m_mouseDownPos = pos;
|
|
|
|
m_dBmDistScaleMin = m_dBmDistMin;
|
|
m_dBmDistScaleMax = m_dBmDistMax;
|
|
}
|
|
else
|
|
if (event->buttons() == Qt::RightButton) {
|
|
|
|
QPoint dPos = m_mouseDownPos - pos;
|
|
if (dPos.y() > 0)
|
|
m_dBmDistDelta = 1.0;
|
|
else if (dPos.y() < 0)
|
|
m_dBmDistDelta = -1.0f;
|
|
|
|
m_dBmDistMin += m_dBmDistDelta;
|
|
m_dBmDistMax -= m_dBmDistDelta;
|
|
|
|
if (qAbs(m_dBmDistMax - m_dBmDistMin) < 10) {
|
|
|
|
m_dBmDistMin -= m_dBmDistDelta;
|
|
m_dBmDistMax += m_dBmDistDelta;
|
|
}
|
|
if (m_dBmDistMin < MINDISTDBM) m_dBmDistMin = MINDISTDBM;
|
|
if (m_dBmDistMax > MAXDISTDBM) m_dBmDistMax = MAXDISTDBM;
|
|
|
|
m_dBmDistScaleMin = m_dBmDistMin;
|
|
m_dBmDistScaleMax = m_dBmDistMax;
|
|
|
|
m_mouseDownPos = pos;
|
|
}
|
|
else
|
|
setCursor(Qt::ArrowCursor);
|
|
//update();
|
|
break;
|
|
|
|
case freqScalePanadapterRegion:
|
|
//GRAPHICS_DEBUG << "freqScalePanadapterRegion Rx" << m_receiver;
|
|
if (event->buttons() == Qt::LeftButton) {
|
|
|
|
QPoint dPos = m_mouseDownPos - pos;
|
|
int bottom_y = height() - m_freqScalePanRect.height();
|
|
int new_y = m_rulerMouseDownPos.y() - dPos.y();
|
|
|
|
if (new_y < m_panRect.top() + m_panSpectrumMinimumHeight)
|
|
new_y = m_panRect.top() + m_panSpectrumMinimumHeight;
|
|
if (new_y > bottom_y)
|
|
new_y = bottom_y;
|
|
|
|
m_freqRulerPosition = (float)(new_y - m_panRect.top()) / (bottom_y - m_panRect.top());
|
|
set->setFreqRulerPosition(this, 0, m_freqRulerPosition);
|
|
}
|
|
else
|
|
if (event->buttons() == Qt::RightButton) {
|
|
|
|
QPoint dPos = m_mouseDownPos - pos;
|
|
if (dPos.x() > 0)
|
|
m_freqScaleZoomFactor += 0.01;
|
|
else if (dPos.x() < 0)
|
|
m_freqScaleZoomFactor -= 0.01;
|
|
|
|
if (m_freqScaleZoomFactor > 1.0) m_freqScaleZoomFactor = 1.0;
|
|
//if (m_freqScaleZoomFactor < 0.05) m_freqScaleZoomFactor = 0.05;
|
|
if (m_freqScaleZoomFactor < 0.15) m_freqScaleZoomFactor = 0.15;
|
|
|
|
m_mouseDownPos = pos;
|
|
m_freqScalePanadapterUpdate = true;
|
|
m_panGridUpdate = true;
|
|
}
|
|
else
|
|
setCursor(Qt::ArrowCursor);
|
|
|
|
//update();
|
|
break;
|
|
|
|
case freqScaleDistancePanRegion:
|
|
//GRAPHICS_DEBUG << "freqScaleDistancePanRegion";
|
|
if (event->buttons() == Qt::LeftButton) {
|
|
|
|
if (m_distScaleZoomFactor < 1.0) {
|
|
QPoint dPos = m_mouseDownPos - pos;
|
|
if (dPos.x() > 0)
|
|
m_distRulerDisplayDelta += m_distRulerDisplayDeltaStep;
|
|
else if (dPos.x() < 0)
|
|
m_distRulerDisplayDelta -= m_distRulerDisplayDeltaStep;
|
|
|
|
if (m_distRulerDisplayDelta < 0)
|
|
m_distRulerDisplayDelta = 0.0;
|
|
|
|
if (m_distRulerDisplayDelta > m_chirpBufferLength * m_kilometersPerGate)
|
|
m_distRulerDisplayDelta -= m_distRulerDisplayDeltaStep;
|
|
|
|
m_mouseDownPos = pos;
|
|
}
|
|
else
|
|
m_distRulerDisplayDelta = 0.0;
|
|
}
|
|
else if (event->buttons() == Qt::RightButton) {
|
|
|
|
QPoint dPos = m_mouseDownPos - pos;
|
|
if (dPos.x() > 0)
|
|
m_distScaleZoomFactor += 0.005;
|
|
else if (dPos.x() < 0)
|
|
m_distScaleZoomFactor -= 0.005;
|
|
|
|
if (m_distScaleZoomFactor > 1.0) m_distScaleZoomFactor = 1.0;
|
|
if (m_distScaleZoomFactor < 0.1) m_distScaleZoomFactor = 0.1;
|
|
|
|
m_mouseDownPos = pos;
|
|
}
|
|
else
|
|
setCursor(Qt::ArrowCursor);
|
|
|
|
//update();
|
|
break;
|
|
|
|
case filterRegionLow:
|
|
|
|
setCursor(Qt::SizeHorCursor);
|
|
if (event->buttons() == Qt::LeftButton) {
|
|
|
|
QPoint dPos = m_mouseDownPos - pos;
|
|
qreal dFreq = (qreal)(dPos.x() * m_sampleRate * m_freqScaleZoomFactor) / m_panRect.width();
|
|
|
|
m_filterLowerFrequency = qRound(m_mouseDownFilterFrequencyLo - dFreq);
|
|
set->setRXFilter(this, 0, m_filterLowerFrequency, m_filterUpperFrequency);
|
|
}
|
|
break;
|
|
|
|
case filterRegionHigh:
|
|
|
|
setCursor(Qt::SizeHorCursor);
|
|
if (event->buttons() == Qt::LeftButton) {
|
|
|
|
QPoint dPos = m_mouseDownPos - pos;
|
|
qreal dFreq = (qreal)(dPos.x() * m_sampleRate * m_freqScaleZoomFactor) / m_panRect.width();
|
|
|
|
m_filterUpperFrequency = qRound(m_mouseDownFilterFrequencyHi - dFreq);
|
|
set->setRXFilter(this, 0, m_filterLowerFrequency, m_filterUpperFrequency);
|
|
}
|
|
break;
|
|
|
|
case elsewhere:
|
|
//GRAPHICS_DEBUG << "elsewhere";
|
|
|
|
//update();
|
|
break;
|
|
}
|
|
|
|
if (m_displayTime.elapsed() >= 50) {
|
|
|
|
m_displayTime.restart();
|
|
update();
|
|
}
|
|
//setupDisplayRegions(size());
|
|
//update();
|
|
|
|
//locker.unlock();
|
|
}
|
|
|
|
void QGLDistancePanel::keyPressEvent(QKeyEvent* event) {
|
|
|
|
//GRAPHICS_DEBUG << "keyPressEvent";
|
|
if (event->key() == Qt::Key_Control) {
|
|
|
|
//m_keyCTRLpressed = true;
|
|
//GRAPHICS_DEBUG << "m_keyCTRLpressed =" << m_keyCTRLpressed;
|
|
//printf("Ry %f\n",ry);
|
|
//ry+=10.0f;
|
|
}
|
|
else if (event->key() == Qt::Key_T) {
|
|
|
|
//printf("Ry %f\n",ry);
|
|
//ry-=10.0f;
|
|
}
|
|
else if (event->key() == Qt::Key_P) {
|
|
|
|
//drawTeapot = !drawTeapot;
|
|
}
|
|
else if (event->key() == Qt::Key_W) {
|
|
|
|
//approach -= 0.1f;
|
|
}
|
|
else if (event->key() == Qt::Key_S) {
|
|
|
|
//approach += 0.1f;
|
|
}
|
|
else {
|
|
|
|
//m_keyCTRLpressed = false;
|
|
//GRAPHICS_DEBUG << "m_keyCTRLpressed =" << m_keyCTRLpressed;
|
|
//event->ignore();
|
|
}
|
|
|
|
QWidget::keyPressEvent(event);
|
|
//updateGL();
|
|
update();
|
|
}
|
|
|
|
void QGLDistancePanel::timerEvent(QTimerEvent *) {
|
|
|
|
update();
|
|
}
|
|
|
|
//********************************************************************
|
|
|
|
void QGLDistancePanel::setFrequency(QObject *sender, bool value, long freq) {
|
|
|
|
Q_UNUSED(sender)
|
|
Q_UNUSED(value)
|
|
|
|
m_frequency = freq;
|
|
//m_displayData.frequency = freq;
|
|
m_freqScalePanadapterUpdate = true;
|
|
m_panGridUpdate = true;
|
|
|
|
//updateGL();
|
|
update();
|
|
}
|
|
|
|
void QGLDistancePanel::setFilterFrequencies(QObject *sender, int rx, qreal lo, qreal hi) {
|
|
|
|
Q_UNUSED(sender)
|
|
|
|
if (rx == 0) {
|
|
|
|
m_filterLowerFrequency = lo;
|
|
m_filterUpperFrequency = hi;
|
|
}
|
|
|
|
update();
|
|
}
|
|
|
|
void QGLDistancePanel::freqRulerPositionChanged(float pos, int rx) {
|
|
|
|
if (rx == 0) {
|
|
|
|
m_freqRulerPosition = pos;
|
|
|
|
setupDisplayRegions(size());
|
|
update();
|
|
}
|
|
}
|
|
|
|
void QGLDistancePanel::setSpectrumBuffer(const float *buffer) {
|
|
|
|
if (m_spectrumAveraging) {
|
|
|
|
QVector<float> m_specBuf(SAMPLE_BUFFER_SIZE);
|
|
|
|
//spectrumBufferMutex.lock();
|
|
|
|
memcpy(
|
|
(float *) m_specBuf.data(),
|
|
(float *) &buffer[0],
|
|
SAMPLE_BUFFER_SIZE * sizeof(float));
|
|
|
|
specAv_queue.enqueue(m_specBuf);
|
|
if (specAv_queue.size() <= m_specAveragingCnt) {
|
|
|
|
for (int i = 0; i < SAMPLE_BUFFER_SIZE; i++)
|
|
m_tmpBuf[i] += specAv_queue.last().data()[i];
|
|
|
|
//spectrumBufferMutex.unlock();
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < SAMPLE_BUFFER_SIZE; i++) {
|
|
|
|
m_tmpBuf[i] -= specAv_queue.first().at(i);
|
|
m_tmpBuf[i] += specAv_queue.last().at(i);
|
|
m_avgBuf[i] = m_tmpBuf[i] * m_scale;
|
|
}
|
|
|
|
computeDisplayBins(m_avgBuf);
|
|
specAv_queue.dequeue();
|
|
|
|
//spectrumBufferMutex.unlock();
|
|
}
|
|
else
|
|
computeDisplayBins(buffer);
|
|
}
|
|
|
|
void QGLDistancePanel::computeDisplayBins(const float *panBuffer) {
|
|
|
|
int newSampleSize = 0;
|
|
int deltaSampleSize = 0;
|
|
int idx = 0;
|
|
int lIdx = 0;
|
|
int rIdx = 0;
|
|
qreal localMax;
|
|
|
|
if (m_serverMode == QSDR::ChirpWSPRFile) {
|
|
|
|
newSampleSize = (int)floor(2 * BUFFER_SIZE * m_freqScaleZoomFactor);
|
|
deltaSampleSize = 2 * BUFFER_SIZE - newSampleSize;
|
|
}
|
|
else {
|
|
|
|
newSampleSize = (int)floor(4 * BUFFER_SIZE * m_freqScaleZoomFactor);
|
|
deltaSampleSize = 4 * BUFFER_SIZE - newSampleSize;
|
|
}
|
|
|
|
/*if (deltaSampleSize%2 != 0) {
|
|
deltaSampleSize += 1;
|
|
newSampleSize -= 1;
|
|
}*/
|
|
|
|
m_panScale = (qreal)(1.0 * newSampleSize / m_panRectWidth);
|
|
m_scaleMultOld = m_scaleMult;
|
|
|
|
if (m_panScale < 0.125) {
|
|
m_scaleMult = 0.0625;
|
|
}
|
|
else if (m_panScale < 0.25) {
|
|
m_scaleMult = 0.125;
|
|
}
|
|
else if (m_panScale < 0.5) {
|
|
m_scaleMult = 0.25;
|
|
}
|
|
else if (m_panScale < 1.0) {
|
|
m_scaleMult = 0.5;
|
|
}
|
|
else {
|
|
m_scaleMult = 1.0;
|
|
}
|
|
|
|
m_panSpectrumBinsLength = (GLint)(m_scaleMult * m_panRectWidth);
|
|
|
|
/*if (bins != binsOld) {
|
|
|
|
GRAPHICS_DEBUG << "newSampleSize" << newSampleSize;
|
|
GRAPHICS_DEBUG << "m_panScale" << m_panScale;
|
|
GRAPHICS_DEBUG << "bins:" << bins;
|
|
}*/
|
|
|
|
m_panadapterBins.clear();
|
|
|
|
for (int i = 0; i < m_panSpectrumBinsLength; i++) {
|
|
|
|
idx = 0;
|
|
lIdx = (int)floor((qreal)(i * m_panScale / m_scaleMult));
|
|
rIdx = (int)floor((qreal)(i * m_panScale / m_scaleMult) + m_panScale / m_scaleMult);
|
|
|
|
// max value; later we try mean value also!
|
|
localMax = -10000.0F;
|
|
for (int j = lIdx; j < rIdx; j++) {
|
|
|
|
if (panBuffer[j] > localMax) {
|
|
|
|
localMax = panBuffer[j];
|
|
idx = j;
|
|
}
|
|
}
|
|
idx += deltaSampleSize/2;
|
|
|
|
m_panadapterBins << panBuffer[idx] - m_dBmPanMin - m_dBmPanLogGain;
|
|
}
|
|
update();
|
|
}
|
|
|
|
void QGLDistancePanel::setDistanceSpectrumBuffer(int sampleRate, qint64 length, const float *buffer) {
|
|
|
|
Q_UNUSED(sampleRate)
|
|
Q_UNUSED(length)
|
|
Q_UNUSED(buffer)
|
|
}
|
|
|
|
void QGLDistancePanel::distanceSpectrumBufferChanged(int sampleRate, qint64 length, const float *buffer) {
|
|
|
|
Q_UNUSED(sampleRate)
|
|
|
|
distanceSpectrumBufferMutex.lock();
|
|
m_kilometersPerGate = 1.0f * 3E5 / sampleRate;
|
|
//m_kilometersPerGate = 0.5f * 3E5 / 12000;
|
|
m_chirpBufferLength = length;
|
|
memcpy(m_distanceSpectrumBuffer, buffer, m_chirpBufferLength * sizeof(float));
|
|
distanceSpectrumBufferMutex.unlock();
|
|
|
|
update();
|
|
}
|
|
|
|
// get waterfall colors - taken from PowerSDR/KISS Konsole
|
|
//QColor QGLDistancePanel::getWaterfallColorAtPixel(qreal value) {
|
|
//
|
|
// QColor color;
|
|
// //int r = 0; int g = 0; int b = 0;
|
|
// int r, g, b;
|
|
// int lowerThreshold = (int)m_dBmPanMin - m_waterfallOffsetLo;
|
|
// int upperThreshold = (int)m_dBmPanMax + m_waterfallOffsetHi;
|
|
//
|
|
// float offset;
|
|
// float globalRange;
|
|
// float localRange;
|
|
// float percent;
|
|
//
|
|
// switch (m_waterColorScheme) {
|
|
//
|
|
// case QSDRGraphics::simple:
|
|
//
|
|
// if (value <= lowerThreshold)
|
|
// color = m_waterfallLoColor;
|
|
// else
|
|
// if (value >= upperThreshold)
|
|
// color = QColor(255, 255, 255);//m_waterfallHiColor;
|
|
// else {
|
|
//
|
|
// percent = (value - lowerThreshold) / (upperThreshold - lowerThreshold);
|
|
// if (percent <= 0.5) { // use a gradient between low and mid colors
|
|
//
|
|
// percent *= 2;
|
|
//
|
|
// r = (int)((1 - percent) * m_waterfallLoColor.red() + percent * m_waterfallMidColor.red());
|
|
// g = (int)((1 - percent) * m_waterfallLoColor.green() + percent * m_waterfallMidColor.green());
|
|
// b = (int)((1 - percent) * m_waterfallLoColor.blue() + percent * m_waterfallMidColor.blue());
|
|
// }
|
|
// else { // use a gradient between mid and high colors
|
|
//
|
|
// percent = (float)(percent - 0.5) * 2;
|
|
//
|
|
// r = (int)((1 - percent) * m_waterfallMidColor.red() + percent * 255);//m_waterfallHiColor.red());
|
|
// g = (int)((1 - percent) * m_waterfallMidColor.green() + percent * 255);//m_waterfallHiColor.green());
|
|
// b = (int)((1 - percent) * m_waterfallMidColor.blue() + percent * 255);//m_waterfallHiColor.blue());
|
|
// }
|
|
//
|
|
// if (r > 255) r = 255;
|
|
// if (g > 255) g = 255;
|
|
// if (b > 255) b = 255;
|
|
// color = QColor(r, g, b, m_waterfallAlpha);
|
|
// }
|
|
//
|
|
// break;
|
|
//
|
|
// case QSDRGraphics::enhanced:
|
|
//
|
|
// if (value <= lowerThreshold)
|
|
// color = m_waterfallLoColor;
|
|
// else
|
|
// if (value >= upperThreshold)
|
|
// color = m_waterfallHiColor;
|
|
// else {
|
|
//
|
|
// offset = value - lowerThreshold;
|
|
// globalRange = offset / m_waterfallColorRange; // value from 0.0 to 1.0 where 1.0 is high and 0.0 is low.
|
|
//
|
|
// if (globalRange < (float)2/9) { // background to blue
|
|
//
|
|
// localRange = globalRange / ((float)2/9);
|
|
// r = (int)((1.0 - localRange) * m_waterfallLoColor.red());
|
|
// g = (int)((1.0 - localRange) * m_waterfallLoColor.green());
|
|
// b = (int)(m_waterfallLoColor.blue() + localRange * (255 - m_waterfallLoColor.blue()));
|
|
// }
|
|
// else
|
|
// if (globalRange < (float)3/9) { // blue to blue-green
|
|
//
|
|
// localRange = (globalRange - (float)2/9) / ((float)1/9);
|
|
// r = 0;
|
|
// g = (int)(localRange * 255);
|
|
// b = 255;
|
|
// }
|
|
// else
|
|
// if (globalRange < (float)4/9) { // blue-green to green
|
|
//
|
|
// localRange = (globalRange - (float)3/9) / ((float)1/9);
|
|
// r = 0;
|
|
// g = 255;
|
|
// b = (int)((1.0 - localRange) * 255);
|
|
// }
|
|
// else
|
|
// if (globalRange < (float)5/9) { // green to red-green
|
|
//
|
|
// localRange = (globalRange - (float)4/9) / ((float)1/9);
|
|
// r = (int)(localRange * 255);
|
|
// g = 255;
|
|
// b = 0;
|
|
// }
|
|
// else
|
|
// if (globalRange < (float)7/9) { // red-green to red
|
|
//
|
|
// localRange = (globalRange - (float)5/9) / ((float)2/9);
|
|
// r = 255;
|
|
// g = (int)((1.0 - localRange) * 255);
|
|
// b = 0;
|
|
// }
|
|
// else
|
|
// if (globalRange < (float)8/9) { // red to red-blue
|
|
//
|
|
// localRange = (globalRange - (float)7/9) / ((float)1/9);
|
|
// r = 255;
|
|
// g = 0;
|
|
// b = (int)(localRange * 255);
|
|
// }
|
|
// else { // red-blue to purple end
|
|
//
|
|
// localRange = (globalRange - (float)8/9) / ((float)1/9);
|
|
// r = (int)((0.75 + 0.25 * (1.0 - localRange)) * 255);
|
|
// g = (int)(localRange * 255 * 0.5);
|
|
// b = 255;
|
|
// }
|
|
// if (r > 255) r = 255;
|
|
// if (g > 255) g = 255;
|
|
// if (b > 255) b = 255;
|
|
// if (r < 0) r = 0;
|
|
// if (g < 0) g = 0;
|
|
// if (b < 0) b = 0;
|
|
// color = QColor(r, g, b, m_waterfallAlpha);
|
|
// }
|
|
//
|
|
// break;
|
|
//
|
|
// case QSDRGraphics::spectran:
|
|
//
|
|
// break;
|
|
// }
|
|
//
|
|
// return color;
|
|
//}
|
|
|
|
void QGLDistancePanel::setChirpFFTShow(bool value) {
|
|
|
|
distanceSpectrumBufferMutex.lock();
|
|
m_showChirpFFT = value;
|
|
distanceSpectrumBufferMutex.unlock();
|
|
|
|
update();
|
|
}
|
|
|
|
void QGLDistancePanel::systemStateChanged(
|
|
QObject *sender,
|
|
QSDR::_Error err,
|
|
QSDR::_HWInterfaceMode hwmode,
|
|
QSDR::_ServerMode mode,
|
|
QSDR::_DataEngineState state)
|
|
{
|
|
Q_UNUSED (sender)
|
|
Q_UNUSED (err)
|
|
Q_UNUSED (hwmode)
|
|
Q_UNUSED (state)
|
|
|
|
if (m_dataEngineState != state)
|
|
m_dataEngineState = state;
|
|
|
|
if (m_serverMode != mode) {
|
|
|
|
//memset(m_wbSpectrumBuffer, -10000, 4 * BUFFER_SIZE * sizeof(float));
|
|
memset(m_spectrumBuffer, -10000, 4 * BUFFER_SIZE * sizeof(float));
|
|
memset(m_distanceSpectrumBuffer, -10000, 16 * BUFFER_SIZE * sizeof(float));
|
|
m_serverMode = mode;
|
|
}
|
|
|
|
//resizeGL(width(), height());
|
|
m_displayTime.restart();
|
|
|
|
update();
|
|
}
|
|
|
|
|
|
void QGLDistancePanel::graphicModeChanged(
|
|
QObject *sender,
|
|
int rx,
|
|
PanGraphicsMode panMode,
|
|
WaterfallColorMode colorScheme)
|
|
{
|
|
Q_UNUSED (sender)
|
|
Q_UNUSED (colorScheme)
|
|
Q_UNUSED (rx)
|
|
|
|
if (m_panMode != panMode)
|
|
m_panMode = panMode;
|
|
|
|
/*if (m_waterColorScheme != colorScheme) {
|
|
|
|
m_waterColorScheme = colorScheme;
|
|
change = true;
|
|
}*/
|
|
|
|
//if (!change) return;
|
|
|
|
update();
|
|
}
|
|
|
|
void QGLDistancePanel::setSpectrumAveraging(bool value) {
|
|
|
|
spectrumBufferMutex.lock();
|
|
|
|
if (m_spectrumAveraging == value)
|
|
return;
|
|
else
|
|
m_spectrumAveraging = value;
|
|
|
|
spectrumBufferMutex.unlock();
|
|
}
|
|
|
|
void QGLDistancePanel::setSpectrumAveragingCnt(int value) {
|
|
|
|
spectrumBufferMutex.lock();
|
|
|
|
memset(m_tmpBuf, 0, SAMPLE_BUFFER_SIZE * sizeof(float));
|
|
|
|
while (!specAv_queue.isEmpty())
|
|
specAv_queue.dequeue();
|
|
|
|
m_specAveragingCnt = value;
|
|
|
|
if (m_specAveragingCnt > 0)
|
|
m_scale = 1.0f / m_specAveragingCnt;
|
|
else
|
|
m_scale = 1.0f;
|
|
|
|
spectrumBufferMutex.unlock();
|
|
}
|
|
|
|
void QGLDistancePanel::setPanGridStatus(bool value) {
|
|
|
|
spectrumBufferMutex.lock();
|
|
|
|
if (m_panGrid == value)
|
|
return;
|
|
else
|
|
m_panGrid = value;
|
|
|
|
spectrumBufferMutex.unlock();
|
|
|
|
update();
|
|
}
|
|
|
|
void QGLDistancePanel::sampleRateChanged(QObject *sender, int value) {
|
|
|
|
Q_UNUSED(sender)
|
|
|
|
m_sampleRate = value;
|
|
update();
|
|
}
|
|
|
|
void QGLDistancePanel::setPanadapterColors() {
|
|
|
|
m_spectrumColorsChanged = true;
|
|
|
|
mutex.lock();
|
|
/*m_bkgRed = (GLfloat)(set->getPanadapterColors().panBackgroundColor.red() / 256.0);
|
|
m_bkgGreen = (GLfloat)(set->getPanadapterColors().panBackgroundColor.green() / 256.0);
|
|
m_bkgBlue = (GLfloat)(set->getPanadapterColors().panBackgroundColor.blue() / 256.0);*/
|
|
|
|
/*if (m_bkgRed * 1.2 > 1.0) m_bkgRed = 1.0f;
|
|
if (m_bkgGreen * 1.2 > 1.0) m_bkgGreen = 1.0f;
|
|
if (m_bkgBlue * 1.2 > 1.0) m_bkgBlue = 1.0f;
|
|
|
|
if (m_bkgRed * 1.6 > 1.0) m_bkgRed = 1.0f;
|
|
if (m_bkgGreen * 1.6 > 1.0) m_bkgGreen = 1.0f;
|
|
if (m_bkgBlue * 1.6 > 1.0) m_bkgBlue = 1.0f;*/
|
|
|
|
m_red = (GLfloat)(set->getPanadapterColors().panLineColor.red() / 256.0);
|
|
m_green = (GLfloat)(set->getPanadapterColors().panLineColor.green() / 256.0);
|
|
m_blue = (GLfloat)(set->getPanadapterColors().panLineColor.blue() / 256.0);
|
|
|
|
m_redF = (GLfloat)(set->getPanadapterColors().panLineFilledColor.red() / 256.0);
|
|
m_greenF = (GLfloat)(set->getPanadapterColors().panLineFilledColor.green() / 256.0);
|
|
m_blueF = (GLfloat)(set->getPanadapterColors().panLineFilledColor.blue() / 256.0);
|
|
|
|
m_redST = (GLfloat)(set->getPanadapterColors().panSolidTopColor.red() / 256.0);
|
|
m_greenST = (GLfloat)(set->getPanadapterColors().panSolidTopColor.green() / 256.0);
|
|
m_blueST = (GLfloat)(set->getPanadapterColors().panSolidTopColor.blue() / 256.0);
|
|
|
|
m_redSB = (GLfloat)(set->getPanadapterColors().panSolidBottomColor.red() / 256.0);
|
|
m_greenSB = (GLfloat)(set->getPanadapterColors().panSolidBottomColor.green() / 256.0);
|
|
m_blueSB = (GLfloat)(set->getPanadapterColors().panSolidBottomColor.blue() / 256.0);
|
|
|
|
mutex.unlock();
|
|
|
|
update();
|
|
}
|
|
|
|
//void QGLDistancePanel::setWaterfallTime(int rx, int value) {
|
|
//
|
|
// if (rx == 0)
|
|
// m_waterfallTime = value;
|
|
//}
|
|
|
|
//void QGLDistancePanel::setWaterfallOffesetLo(int rx, int value) {
|
|
//
|
|
// if (rx == 0)
|
|
// m_waterfallOffsetLo = value;
|
|
//
|
|
// update();
|
|
//}
|
|
//
|
|
//void QGLDistancePanel::setWaterfallOffesetHi(int rx, int value) {
|
|
//
|
|
// if (rx = 0)
|
|
// m_waterfallOffsetHi = value;
|
|
//
|
|
// update();
|
|
//}
|
|
|
|
void QGLDistancePanel::closeEvent(QCloseEvent *event) {
|
|
|
|
emit closeEvent(this);
|
|
QWidget::closeEvent(event);
|
|
}
|
|
|
|
void QGLDistancePanel::showEvent(QShowEvent *event) {
|
|
|
|
emit showEvent(this);
|
|
QWidget::showEvent(event);
|
|
}
|