void CPlotter::draw(float swide[], int i0) //draw() { int j,y2; float y; m_i0=i0; double gain = pow(10.0,0.05*(m_plotGain+7)); //move current data down one line (must do this before attaching a QPainter object) m_WaterfallPixmap.scroll(0,1,0,0,m_w,m_h1); QPainter painter1(&m_WaterfallPixmap); m_2DPixmap = m_OverlayPixmap.copy(0,0,m_w,m_h2); QPainter painter2D(&m_2DPixmap); painter2D.setPen(Qt::green); QPoint LineBuf[MAX_SCREENSIZE]; j=0; // int iz=XfromFreq(2000.0); int iz=XfromFreq(5000.0); m_fMax=FreqfromX(iz); for(int i=0; i<iz; i++) { if(i>iz) swide[i]=0; y=0.0; if(swide[i]>0.0) y = 10.0*log10(swide[i]); int y1 = 5.0*gain*y + 10*(m_plotZero-4); if (y1<0) y1=0; if (y1>254) y1=254; if (swide[i]>1.e29) y1=255; painter1.setPen(m_ColorTbl[y1]); painter1.drawPoint(i,0); y2=0; if(m_bCurrent) y2 = 0.4*gain*y - 15; if(m_bCumulative) { float sum=0.0; int j=m_binsPerPixel*i; for(int k=0; k<m_binsPerPixel; k++) { sum+=jt9com_.savg[j++]; } y2=gain*6.0*log10(sum/m_binsPerPixel) - 10.0; } y2 += m_plotZero; if(i==iz-1) painter2D.drawPolyline(LineBuf,j); LineBuf[j].setX(i); LineBuf[j].setY(m_h-(y2+0.8*m_h)); j++; } if(swide[0]>1.0e29) m_line=0; m_line++; if(m_line == 13) { UTCstr(); painter1.setPen(Qt::white); painter1.drawText(5,10,m_sutc); } update(); //trigger a new paintEvent }
void CPlotter::setTxFreq(int x, bool bf) //setTxFreq() { if(bf) { m_TxFreq=x; // x is freq in Hz m_xClick=XfromFreq(m_TxFreq); } else { if(x<0) x=0; // x is pixel number if(x>m_Size.width()) x=m_Size.width(); m_TxFreq = int(FreqfromX(x)+0.5); m_xClick=x; } DrawOverlay(); update(); }
////////////////////////////////////////////////////////////////////// // Called to draw an overlay bitmap containing grid and text that // does not need to be recreated every fft data update. ////////////////////////////////////////////////////////////////////// void CPlotter::DrawOverlay() { if (m_OverlayPixmap.isNull()) return; int w = m_OverlayPixmap.width(); int h = m_OverlayPixmap.height(); int x,y; float pixperdiv; QRect rect; QPainter painter(&m_OverlayPixmap); painter.initFrom(this); // horizontal grids (size and grid calcs could be moved to resize) m_VerDivs = h/m_VdivDelta+1; m_HorDivs = w/m_HdivDelta; if (m_HorDivs % 2) m_HorDivs++; // we want an odd number of divs so that we have a center line //m_OverlayPixmap.fill(Qt::black); // fill background with gradient QLinearGradient gradient(0, 0, 0 ,h); gradient.setColorAt(0, QColor(0x20,0x20,0x20,0xFF)); gradient.setColorAt(1, QColor(0x4F,0x4F,0x4F,0xFF)); painter.setBrush(gradient); painter.drawRect(0, 0, w, h); // Draw demod filter box if (m_FilterBoxEnabled) { // Clamping no longer necessary as we do it in mouseMove() //ClampDemodParameters(); m_DemodFreqX = XfromFreq(m_DemodCenterFreq); m_DemodLowCutFreqX = XfromFreq(m_DemodCenterFreq + m_DemodLowCutFreq); m_DemodHiCutFreqX = XfromFreq(m_DemodCenterFreq + m_DemodHiCutFreq); int dw = m_DemodHiCutFreqX - m_DemodLowCutFreqX; painter.setBrush(Qt::SolidPattern); painter.setOpacity(0.3); painter.fillRect(m_DemodLowCutFreqX, 0, dw, h, Qt::gray); painter.setOpacity(1.0); painter.setPen(QPen(QColor(0xFF,0x71,0x71,0xFF), 1, Qt::SolidLine)); painter.drawLine(m_DemodFreqX, 0, m_DemodFreqX, h); } // create Font to use for scales QFont Font("Arial"); Font.setPointSize(m_FontSize); QFontMetrics metrics(Font); Font.setWeight(QFont::Normal); painter.setFont(Font); // draw vertical grids pixperdiv = (float)w / (float)m_HorDivs; y = h - h/m_VerDivs/2; painter.setPen(QPen(QColor(0xF0,0xF0,0xF0,0x30), 1, Qt::DotLine)); for (int i = 1; i < m_HorDivs; i++) { x = (int)((float)i*pixperdiv); painter.drawLine(x, 0, x, y); } if (m_CenterLineEnabled) { // center line x = XfromFreq(m_CenterFreq); if (x > 0 && x < w) { painter.setPen(QPen(QColor(0x78,0x82,0x96,0xFF), 1, Qt::SolidLine)); painter.drawLine(x, 0, x, y); } } // draw frequency values MakeFrequencyStrs(); painter.setPen(QColor(0xD8,0xBA,0xA1,0xFF)); y = h - (h/m_VerDivs); m_XAxisYCenter = h - metrics.height()/2; for (int i = 1; i < m_HorDivs; i++) { x = (int)((float)i*pixperdiv - pixperdiv/2); rect.setRect(x, y, (int)pixperdiv, h/m_VerDivs); painter.drawText(rect, Qt::AlignHCenter|Qt::AlignBottom, m_HDivText[i]); } m_dBStepSize = abs(m_MaxdB-m_MindB)/(double)m_VerDivs; pixperdiv = (float)h / (float)m_VerDivs; painter.setPen(QPen(QColor(0xF0,0xF0,0xF0,0x30), 1,Qt::DotLine)); for (int i = 1; i < m_VerDivs; i++) { y = (int)((float) i*pixperdiv); painter.drawLine(5*metrics.width("0",-1), y, w, y); } // draw amplitude values painter.setPen(QColor(0xD8,0xBA,0xA1,0xFF)); //Font.setWeight(QFont::Light); painter.setFont(Font); int dB = m_MaxdB; m_YAxisWidth = metrics.width("-120 "); for (int i = 1; i < m_VerDivs; i++) { dB -= m_dBStepSize; // move to end if want to include maxdb y = (int)((float)i*pixperdiv); rect.setRect(0, y-metrics.height()/2, m_YAxisWidth, metrics.height()); painter.drawText(rect, Qt::AlignRight|Qt::AlignVCenter, QString::number(dB)); } if (!m_Running) { // if not running so is no data updates to draw to screen // copy into 2Dbitmap the overlay bitmap. m_2DPixmap = m_OverlayPixmap.copy(0,0,w,h); // trigger a new paintEvent update(); } }
////////////////////////////////////////////////////////////////////// // Called to draw an overlay bitmap containing grid and text that // does not need to be recreated every fft data update. ////////////////////////////////////////////////////////////////////// void CPlotter::DrawOverlay() { if (m_OverlayPixmap.isNull()) return; int w = m_OverlayPixmap.width(); int h = m_OverlayPixmap.height(); int x,y; float pixperdiv; QRect rect; QPainter painter(&m_OverlayPixmap); painter.initFrom(this); //m_OverlayPixmap.fill(Qt::black); //fill background with gradient QLinearGradient gradient(0, 0, 0 ,h); gradient.setColorAt(0, QColor(0x20,0x20,0x20,0xFF)); gradient.setColorAt(1, QColor(0x4F,0x4F,0x4F,0xFF)); painter.setBrush(gradient); painter.drawRect(0, 0, w, h); //Draw demod filter box ClampDemodParameters(); m_DemodFreqX = XfromFreq(m_DemodCenterFreq); m_DemodLowCutFreqX = XfromFreq(m_DemodCenterFreq + m_DemodLowCutFreq); m_DemodHiCutFreqX = XfromFreq(m_DemodCenterFreq + m_DemodHiCutFreq); int dw = m_DemodHiCutFreqX - m_DemodLowCutFreqX; painter.setBrush(Qt::SolidPattern); painter.setOpacity(0.3); painter.fillRect(m_DemodLowCutFreqX, 0, dw, h, Qt::gray); painter.setOpacity(1.0); // edge of filter -> we don't need different color //painter.setPen(QPen(Qt::gray, 1, Qt::SolidLine)); //painter.drawLine(m_DemodLowCutFreqX, 0, m_DemodLowCutFreqX, h); //painter.drawLine(m_DemodHiCutFreqX, 0, m_DemodHiCutFreqX, h); painter.setPen(QPen(QColor(0xFF,0x71,0x71,0xFF), 1, Qt::SolidLine)); painter.drawLine(m_DemodFreqX, 0, m_DemodFreqX, h); //create Font to use for scales QFont Font("Arial"); Font.setPointSize(9); QFontMetrics metrics(Font); y = h/VERT_DIVS; //if (y < metrics.height()) // Font.setPixelSize(y); Font.setWeight(QFont::Normal); painter.setFont(Font); //draw vertical grids pixperdiv = (float)w / (float)HORZ_DIVS; y = h - h/VERT_DIVS/2; for (int i = 1; i < HORZ_DIVS; i++) { x = (int)((float)i*pixperdiv); if (i == HORZ_DIVS/2) // center line painter.setPen(QPen(QColor(0x78,0x82,0x96,0xFF), 1, Qt::SolidLine)); else painter.setPen(QPen(QColor(0xF0,0xF0,0xF0,0x30), 1, Qt::DotLine)); painter.drawLine(x, 0, x , y); //painter.drawLine(x, h-5, x , h); } //draw frequency values MakeFrequencyStrs(); painter.setPen(QColor(0xD8,0xBA,0xA1,0xFF)); y = h - (h/VERT_DIVS); for (int i = 1; i < HORZ_DIVS; i++) { //if ((i==0) || (i==HORZ_DIVS)) //{ //left justify the leftmost text //x = (int)( (float)i*pixperdiv); //rect.setRect(x ,y, (int)pixperdiv, h/VERT_DIVS); //painter.drawText(rect, Qt::AlignLeft|Qt::AlignVCenter, m_HDivText[i]); //} //else if(HORZ_DIVS == i) //{ //right justify the rightmost text // x = (int)( (float)i*pixperdiv - pixperdiv); // rect.setRect(x ,y, (int)pixperdiv, h/VERT_DIVS); // painter.drawText(rect, Qt::AlignRight|Qt::AlignVCenter, m_HDivText[i]); //} //else //{ //center justify the rest of the text x = (int)((float)i*pixperdiv - pixperdiv/2); rect.setRect(x, y, (int)pixperdiv, h/VERT_DIVS); painter.drawText(rect, Qt::AlignHCenter|Qt::AlignBottom, m_HDivText[i]); //} } //draw horizontal grids pixperdiv = (float)h / (float)VERT_DIVS; painter.setPen(QPen(QColor(0xF0,0xF0,0xF0,0x30), 1,Qt::DotLine)); for (int i = 1; i < VERT_DIVS; i++) { y = (int)((float) i*pixperdiv); painter.drawLine(5*metrics.width("0",-1), y, w, y); } //draw amplitude values painter.setPen(QColor(0xD8,0xBA,0xA1,0xFF)); //Font.setWeight(QFont::Light); painter.setFont(Font); int dB = m_MaxdB; for (int i = 1; i < VERT_DIVS; i++) { dB -= m_dBStepSize; /* move to end if want to include maxdb */ y = (int)((float)i*pixperdiv); rect.setRect(0, y-metrics.height()/2, metrics.width("-120 "), metrics.height()); painter.drawText(rect, Qt::AlignRight|Qt::AlignVCenter, QString::number(dB)); } m_MindB = m_MaxdB - (VERT_DIVS)*m_dBStepSize; if (!m_Running) { //if not running so is no data updates to draw to screen //copy into 2Dbitmap the overlay bitmap. m_2DPixmap = m_OverlayPixmap.copy(0,0,w,h); //trigger a new paintEvent update(); } }
void CPlotter::DrawOverlay() //DrawOverlay() { if(m_OverlayPixmap.isNull() or m_WaterfallPixmap.isNull() or m_dialFreq==0) return; // int w = m_WaterfallPixmap.width(); int x,y; QRect rect; QPainter painter(&m_OverlayPixmap); painter.initFrom(this); QLinearGradient gradient(0, 0, 0 ,m_h2); //fill background with gradient gradient.setColorAt(1, Qt::black); gradient.setColorAt(0, Qt::darkBlue); painter.setBrush(gradient); painter.drawRect(0, 0, m_w, m_h2); painter.setBrush(Qt::SolidPattern); m_fSpan = m_w*m_fftBinWidth; int n=m_fSpan/10; m_freqPerDiv=10; if(n>25) m_freqPerDiv=50; if(n>70) m_freqPerDiv=100; if(n>140) m_freqPerDiv=200; if(n>310) m_freqPerDiv=500; float pixPerHdiv = m_freqPerDiv/m_fftBinWidth; float pixPerVdiv = float(m_h2)/float(VERT_DIVS); m_RFHz=int(1000000.0*m_dialFreq+m_StartFreq + 0.5) % 1000; m_hdivs = m_w*m_fftBinWidth/m_freqPerDiv + 0.9999; painter.setPen(QPen(Qt::white, 1,Qt::DotLine)); for( int i=1; i<m_hdivs; i++) //draw vertical grids { x=int(i*pixPerHdiv); painter.drawLine(x,0,x,m_h2); } for( int i=1; i<VERT_DIVS; i++) //draw horizontal grids { y = (int)( (float)i*pixPerVdiv ); painter.drawLine(0,y,m_w,y); } QRect rect0; QPainter painter0(&m_ScalePixmap); painter0.initFrom(this); //create Font to use for scales QFont Font("Arial"); Font.setPointSize(12); QFontMetrics metrics(Font); Font.setWeight(QFont::Normal); painter0.setFont(Font); painter0.setPen(Qt::black); m_ScalePixmap.fill(Qt::white); painter0.drawRect(0, 0, m_w, 30); //draw tick marks on upper scale for( int i=1; i<m_hdivs; i++) { //major ticks x = (int)( (float)i*pixPerHdiv ); painter0.drawLine(x,18,x,30); } int minor=5; if(m_freqPerDiv==200) minor=4; for( int i=1; i<minor*m_hdivs; i++) { //minor ticks x = i*pixPerHdiv/minor; painter0.drawLine(x,24,x,30); } //draw frequency values MakeFrequencyStrs(); for( int i=0; i<=m_hdivs; i++) { if(0==i) { //left justify the leftmost text x = (int)( (float)i*pixPerHdiv); rect0.setRect(x,0, (int)pixPerHdiv, 20); painter0.drawText(rect0, Qt::AlignLeft|Qt::AlignVCenter, m_HDivText[i]); } else if(m_hdivs == i) { //right justify the rightmost text x = (int)( (float)i*pixPerHdiv - pixPerHdiv); rect0.setRect(x,0, (int)pixPerHdiv, 20); painter0.drawText(rect0, Qt::AlignRight|Qt::AlignVCenter, m_HDivText[i]); } else { //center justify the rest of the text x = (int)( (float)i*pixPerHdiv - pixPerHdiv/2); rect0.setRect(x,0, (int)pixPerHdiv, 20); painter0.drawText(rect0, Qt::AlignHCenter|Qt::AlignVCenter, m_HDivText[i]); } } QPen pen0(Qt::green, 3); //Mark decoding range with green line painter0.setPen(pen0); int x1,x2; if(m_nsps==8192) { x=XfromFreq(1500); x1=x - 100/m_fftBinWidth; x2=x + 100/m_fftBinWidth; } else { x=XfromFreq(1612.5); x1=x - 12.5/m_fftBinWidth; x2=x + 12.5/m_fftBinWidth; } pen0.setWidth(6); painter0.drawLine(x1,28,x2,28); QPen pen1(Qt::red, 3); //Mark Tx Freq with red tick painter0.setPen(pen1); x = XfromFreq(m_TxFreq); painter0.drawLine(x,17,x,30); }
void CPlotter::DrawOverlay() //DrawOverlay() { if(m_OverlayPixmap.isNull()) return; if(m_WaterfallPixmap.isNull()) return; int w = m_WaterfallPixmap.width(); int x,y,x1,x2; // int nHzDiv[11]={0,50,100,200,200,200,500,500,500,500,500}; float pixperdiv; QRect rect; QPainter painter(&m_OverlayPixmap); painter.initFrom(this); QLinearGradient gradient(0, 0, 0 ,m_h2); //fill background with gradient gradient.setColorAt(1, Qt::black); gradient.setColorAt(0, Qt::darkBlue); painter.setBrush(gradient); painter.drawRect(0, 0, m_w, m_h2); painter.setBrush(Qt::SolidPattern); double df = m_binsPerPixel*m_fftBinWidth; pixperdiv = m_freqPerDiv/df; y = m_h2 - m_h2/VERT_DIVS; m_hdivs = w*df/m_freqPerDiv + 0.9999; for( int i=1; i<m_hdivs; i++) //draw vertical grids { x = (int)( (float)i*pixperdiv ); if(x >= 0 and x<=m_w) { painter.setPen(QPen(Qt::white, 1,Qt::DotLine)); painter.drawLine(x, 0, x , y); painter.drawLine(x, m_h2-5, x , m_h2); } } pixperdiv = (float)m_h2 / (float)VERT_DIVS; painter.setPen(QPen(Qt::white, 1,Qt::DotLine)); for( int i=1; i<VERT_DIVS; i++) //draw horizontal grids { y = (int)( (float)i*pixperdiv ); painter.drawLine(0, y, w, y); } QRect rect0; QPainter painter0(&m_ScalePixmap); painter0.initFrom(this); //create Font to use for scales QFont Font("Arial"); Font.setPointSize(12); QFontMetrics metrics(Font); Font.setWeight(QFont::Normal); painter0.setFont(Font); painter0.setPen(Qt::black); if(m_binsPerPixel < 1) m_binsPerPixel=1; m_fSpan = w*df; int n=m_fSpan/10; m_freqPerDiv=10; if(n>25) m_freqPerDiv=50; if(n>70) m_freqPerDiv=100; if(n>140) m_freqPerDiv=200; if(n>310) m_freqPerDiv=500; m_hdivs = w*df/m_freqPerDiv + 0.9999; m_ScalePixmap.fill(Qt::white); painter0.drawRect(0, 0, w, 30); //draw tick marks on upper scale pixperdiv = m_freqPerDiv/df; for( int i=1; i<m_hdivs; i++) { //major ticks x = (int)( (float)i*pixperdiv ); painter0.drawLine(x,18,x,30); } int minor=5; if(m_freqPerDiv==200) minor=4; for( int i=1; i<minor*m_hdivs; i++) { //minor ticks x = i*pixperdiv/minor; painter0.drawLine(x,24,x,30); } //draw frequency values MakeFrequencyStrs(); for( int i=0; i<=m_hdivs; i++) { if(0==i) { //left justify the leftmost text x = (int)( (float)i*pixperdiv); rect0.setRect(x,0, (int)pixperdiv, 20); painter0.drawText(rect0, Qt::AlignLeft|Qt::AlignVCenter, m_HDivText[i]); } else if(m_hdivs == i) { //right justify the rightmost text x = (int)( (float)i*pixperdiv - pixperdiv); rect0.setRect(x,0, (int)pixperdiv, 20); painter0.drawText(rect0, Qt::AlignRight|Qt::AlignVCenter, m_HDivText[i]); } else { //center justify the rest of the text x = (int)( (float)i*pixperdiv - pixperdiv/2); rect0.setRect(x,0, (int)pixperdiv, 20); painter0.drawText(rect0, Qt::AlignHCenter|Qt::AlignVCenter, m_HDivText[i]); } } float bw=9.0*12000.0/m_nsps; if(m_modeTx=="JT65") bw=66.0*11025.0/4096.0; QPen pen0(Qt::green, 3); //Mark Rx Freq with green painter0.setPen(pen0); x1=XfromFreq(m_rxFreq); x2=XfromFreq(m_rxFreq+bw); painter0.drawLine(x1,24,x1,30); painter0.drawLine(x1,28,x2,28); painter0.drawLine(x2,24,x2,30); if(m_mode=="JT9+JT65") { QPen pen2(Qt::blue, 3); //Mark the JT65 | JT9 divider painter0.setPen(pen2); x1=XfromFreq(m_fMin); if(x1<2) x1=2; x2=x1+30; painter0.drawLine(x1,8,x1,28); } QPen pen1(Qt::red, 3); //Mark Tx freq with red painter0.setPen(pen1); x1=XfromFreq(m_txFreq); x2=XfromFreq(m_txFreq+bw); painter0.drawLine(x1,17,x1,21); painter0.drawLine(x1,17,x2,17); painter0.drawLine(x2,17,x2,21); }