Fix cursor frequency readout never matching VFO flag value (#1369)#1699
Fix cursor frequency readout never matching VFO flag value (#1369)#1699M7HNF-Ian wants to merge 1 commit into
Conversation
…#1369) Two changes in SpectrumWidget: 1. mhzToX() used static_cast<int>(px) which truncates toward zero, placing every VFO/filter/spot marker up to 1 pixel left of its true position. Changed to std::round() so markers are centred on the correct pixel. 2. The cursor frequency label computed xToMhz(cursorPixel) which maps a pixel back to MHz. Because pixels are discrete, hovering directly over a VFO marker still showed a slightly different value to what the VFO flag displayed (off by up to half a pixel's worth of bandwidth — kHz-scale on typical zoom levels). Added a snap: if the cursor is within 8 px of any slice's VFO marker, show the exact radio-reported frequency instead of the pixel-derived approximation. The readout now exactly matches the flag when near a VFO, and shows the pixel-derived value elsewhere. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Nice fix, @Chaosuk97 — both the rounding fix in mhzToX() and the cursor snap logic are clean and well-targeted. A couple of observations:
The std::round() change (line 1503) — Correct fix. The old static_cast<int> truncation gave a systematic leftward bias on the VFO marker, filter edges, and spot pins. std::round() centres them properly. No issues here.
The cursor snap loop (lines 3198–3204) — The approach is sound: iterate m_sliceOverlays, check pixel distance, snap if within 8 px. Two minor things to consider:
-
mhzToX()called per slice per frame — This is inside the GPU render path (renderGpuFrame), so it runs every paint. With typical slice counts (1–4) this is negligible. If someone ever had an unusual number of slices it still wouldn't matter sincemhzToXis just arithmetic. No concern here, just noting I checked. -
Snap priority with overlapping slices — If two VFO markers are within 16 px of each other (possible at very narrow zoom), the cursor snaps to whichever slice appears first in
m_sliceOverlays. This seems fine for the use case — the user would need to be at an extreme zoom for this to matter, and thebreakensures deterministic behaviour. Not worth over-engineering.
Scope check — Only SpectrumWidget.cpp changed, both hunks directly address #1369. No scope creep.
Potential merge conflict — PR #1694 (aetherclaude/issue-1690) also touches SpectrumWidget.cpp/.h. Whichever lands second will need a trivial rebase, but the changes are in different areas so it should be clean.
Overall this looks good to merge. Thanks for the contribution!
|
Claude here — superseded by #1703 (just merged as 8c33310), which includes everything from this PR plus the Thanks for the fix Ian — since both came from you, no credit lost either way. — 73, Jeremy KK7GWY & Claude (AI dev partner) |
Summary
Two bugs in
SpectrumWidgetcombined to make the cursor frequency overlay always disagree with the VFO flag:1.
mhzToX()truncated instead of roundingstatic_cast<int>(px)floors toward zero, so every VFO marker, filter edge, and spot pin was drawn up to 1 pixel left of its true frequency. Changed tostd::round().2. Cursor readout had no VFO snap
xToMhz(cursorPixel)maps a discrete pixel back to MHz. At typical zoom levels (1 MHz bandwidth, 800px wide) one pixel ≈ 1250 Hz, so hovering directly over a VFO marker could show a frequency several hundred Hz away from the flag value — the two could never be exactly equal.Fix: if the cursor is within 8 px of any slice's VFO marker, the readout snaps to the radio-reported exact frequency. Elsewhere it continues to show the pixel-derived value.
Test plan
🤖 Generated with Claude Code