| 5795 | } |
| 5796 | |
| 5797 | void SpectrumWidget::mousePressEvent(QMouseEvent* ev) |
| 5798 | { |
| 5799 | PerfInputScope perfScope("mousePress"); |
| 5800 | const auto dragStatePublisher = makeScopeExit([this] { publishPerfDragState(); }); |
| 5801 | (void)dragStatePublisher; |
| 5802 | |
| 5803 | const int chromeH = freqScaleH() + DIVIDER_H; |
| 5804 | const int contentH = height() - chromeH; |
| 5805 | const int specH = static_cast<int>(contentH * m_spectrumFrac); |
| 5806 | const int y = static_cast<int>(ev->position().y()); |
| 5807 | |
| 5808 | // Save press position for single-click-to-tune drag threshold |
| 5809 | if (ev->button() == Qt::LeftButton) |
| 5810 | m_clickPressPos = ev->position().toPoint(); |
| 5811 | |
| 5812 | // Click on prop forecast overlay → open dashboard |
| 5813 | if (ev->button() == Qt::LeftButton && !m_propClickRect.isNull()) { |
| 5814 | const QPoint pos(static_cast<int>(ev->position().x()), y); |
| 5815 | if (m_propClickRect.contains(pos)) { |
| 5816 | emit propForecastClicked(); |
| 5817 | m_spotClickConsumed = true; // suppress release-to-tune (#1647) |
| 5818 | ev->accept(); |
| 5819 | return; |
| 5820 | } |
| 5821 | } |
| 5822 | |
| 5823 | // Click on a spot label → tune to that frequency |
| 5824 | if (m_showSpots && ev->button() == Qt::LeftButton) { |
| 5825 | const QPoint pos(static_cast<int>(ev->position().x()), y); |
| 5826 | for (const auto& hr : m_spotClickRects) { |
| 5827 | if (hr.rect.contains(pos)) { |
| 5828 | if (hr.markerIndex >= 0 && hr.markerIndex < m_spotMarkers.size()) { |
| 5829 | const auto& marker = m_spotMarkers[hr.markerIndex]; |
| 5830 | if (marker.source == "Memory") { |
| 5831 | emit spotTriggered(marker.index); |
| 5832 | } else { |
| 5833 | emit frequencyClicked(hr.freqMhz); |
| 5834 | // Notify the radio that a spot was clicked (#341) |
| 5835 | emit spotTriggered(marker.index); |
| 5836 | } |
| 5837 | } else { |
| 5838 | // SHistory / QRM marker — markerIndex is past the regular |
| 5839 | // spot range. Optionally snap to the slice's step size to |
| 5840 | // counter detector edge-bin imprecision. |
| 5841 | const double tuneMhz = m_sHistorySnapToStep |
| 5842 | ? snapToStep(hr.freqMhz, m_stepHz) |
| 5843 | : hr.freqMhz; |
| 5844 | emit frequencyClicked(tuneMhz); |
| 5845 | } |
| 5846 | m_spotClickConsumed = true; // suppress release-to-tune (#530) |
| 5847 | ev->accept(); |
| 5848 | return; |
| 5849 | } |
| 5850 | } |
| 5851 | // Click on a cluster badge → show popup with collapsed spots |
| 5852 | for (const auto& cluster : m_spotClusters) { |
| 5853 | if (cluster.rect.contains(pos)) { |
| 5854 | showSpotClusterPopup(cluster, mapToGlobal(pos)); |
nothing calls this directly
no test coverage detected