// Zoom on X axis (absolute level) void CPlotter::zoomOnXAxis(float level) { float current_level = (float)m_SampleFreq / (float)m_Span; zoomStepX(current_level / level, xFromFreq(m_DemodCenterFreq)); }
////////////////////////////////////////////////////////////////////// // 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 = qMin(w/m_HdivDelta, HORZ_DIVS_MAX); 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); // horizontal grids (size and grid calcs could be moved to resize) m_VerDivs = h/m_VdivDelta+1; m_HorDivs = qMin(w/m_HdivDelta, HORZ_DIVS_MAX); 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); } //Draw Bookmark Tags m_BookmarkTags.clear(); static const QFontMetrics fm(painter.font()); static const int fontHeight = fm.ascent()+1; // height(); static const int slant = 5; static const int levelHeight = fontHeight+5; static const int nLevels = 3; QList<BookmarkInfo> bookmarks = Bookmarks::Get().getBookmarksInRange(m_CenterFreq+m_FftCenter-m_Span/2, m_CenterFreq+m_FftCenter+m_Span/2); int tagEnd[nLevels] = {0}; for(int i=0; i<bookmarks.size(); i++) { x=xFromFreq(bookmarks[i].frequency); #if defined(_WIN16) || defined(_WIN32) || defined(_WIN64) int nameWidth= fm.width(bookmarks[i].name); #else int nameWidth= fm.boundingRect(bookmarks[i].name).width(); #endif int level = 0; for(; level<nLevels && tagEnd[level]>x; level++); level%=nLevels; tagEnd[level]=x+nameWidth+slant-1; m_BookmarkTags.append(qMakePair<QRect, qint64>(QRect(x, level*levelHeight, nameWidth+slant, fontHeight), bookmarks[i].frequency)); QColor color = QColor(bookmarks[i].GetColor()); color.setAlpha(0x60); painter.setPen(QPen(color, 1, Qt::DashLine)); painter.drawLine(x, level*levelHeight+fontHeight+slant, x, y); //Vertical line painter.setPen(QPen(color, 1, Qt::SolidLine)); painter.drawLine(x+slant, level*levelHeight+fontHeight, x+nameWidth+slant-1, level*levelHeight+fontHeight); //Horizontal line painter.drawLine(x+1,level*levelHeight+fontHeight+slant-1, x+slant-1, level*levelHeight+fontHeight+1); //Diagonal line /* painter.setPen(QPen(QColor(0xF0,0xF0,0xF0,0xB0), 1, Qt::SolidLine)); QPolygon polygon(6); polygon.setPoint(0, 0, 10); polygon.setPoint(1, 5, 15); polygon.setPoint(2, 5+nameWidth, 15); polygon.setPoint(3, 5+nameWidth, 0); polygon.setPoint(4, 5, 0); polygon.setPoint(5, 0, 5); polygon.translate(x, level*18); painter.drawPolygon(polygon); */ color.setAlpha(0xFF); painter.setPen(QPen(color, 2, Qt::SolidLine)); painter.drawText(x+slant,level*levelHeight, nameWidth, fontHeight, Qt::AlignVCenter | Qt::AlignHCenter, bookmarks[i].name); } 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 = fabs(m_MaxdB - m_MindB)/(float)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(); } painter.end(); }