From a1b769336e53670e2baba1d884de315561b5bb4f Mon Sep 17 00:00:00 2001 From: ericek111 Date: Wed, 25 Mar 2026 21:32:29 +0100 Subject: [PATCH] improved formatting and positioning of cursor labels --- src/core/Types.h | 27 +++++++++++++++++++++++---- src/ui/Application.cpp | 41 +++++++---------------------------------- src/ui/Cursors.cpp | 25 ++++++++----------------- 3 files changed, 38 insertions(+), 55 deletions(-) diff --git a/src/core/Types.h b/src/core/Types.h index 5b21f5d..4d3f6a7 100644 --- a/src/core/Types.h +++ b/src/core/Types.h @@ -99,14 +99,33 @@ inline int fmtFreq(char* buf, size_t sz, double freq) { return std::snprintf(buf, sz, "% 7.1f Hz", freq); } -// Format "label: freq, dB" into buf for sidebar display (fixed-width freq + dB). +// Format "label: freq dB" into buf for sidebar display (fixed-width freq + dB). +// If label is null or empty, omits the "label: " prefix. inline int fmtFreqDB(char* buf, size_t sz, const char* label, double freq, float dB) { + int off = 0; + if (label && label[0]) + off = std::snprintf(buf, sz, "%s: ", label); if (std::abs(freq) >= 1e6) - return std::snprintf(buf, sz, "%s: % 10.6f MHz %6.1f dB", label, freq / 1e6, dB); + off += std::snprintf(buf + off, sz - off, "% 10.6f MHz %6.1f dB", freq / 1e6, dB); else if (std::abs(freq) >= 1e3) - return std::snprintf(buf, sz, "%s: % 7.3f kHz %6.1f dB", label, freq / 1e3, dB); + off += std::snprintf(buf + off, sz - off, "% 7.3f kHz %6.1f dB", freq / 1e3, dB); else - return std::snprintf(buf, sz, "%s: % 7.1f Hz %6.1f dB", label, freq, dB); + off += std::snprintf(buf + off, sz - off, " % 7.1f Hz %6.1f dB", freq, dB); + return off; +} + +// Format "label: freq, time" into buf for sidebar/overlay display (fixed-width). +inline int fmtFreqTime(char* buf, size_t sz, const char* label, double freq, float seconds) { + int off = 0; + if (label && label[0]) + off = std::snprintf(buf, sz, "%s: ", label); + if (std::abs(freq) >= 1e6) + off += std::snprintf(buf + off, sz - off, "% 10.6f MHz %7.2f s", freq / 1e6, seconds); + else if (std::abs(freq) >= 1e3) + off += std::snprintf(buf + off, sz - off, "% 7.3f kHz %7.2f s", freq / 1e3, seconds); + else + off += std::snprintf(buf + off, sz - off, " % 7.1f Hz %7.2f s", freq, seconds); + return off; } // ── Spectrum data ──────────────────────────────────────────────────────────── diff --git a/src/ui/Application.cpp b/src/ui/Application.cpp index b36266d..d964795 100644 --- a/src/ui/Application.cpp +++ b/src/ui/Application.cpp @@ -478,48 +478,21 @@ void Application::render() { double binCenterFreq = fMin + (static_cast(cursors_.hover.bin) + 0.5) / bins * (fMax - fMin); - // Fixed-width frequency string to prevent jumping - char freqBuf[48]; - if (std::abs(binCenterFreq) >= 1e6) - std::snprintf(freqBuf, sizeof(freqBuf), "%12.6f MHz", binCenterFreq / 1e6); - else if (std::abs(binCenterFreq) >= 1e3) - std::snprintf(freqBuf, sizeof(freqBuf), "%9.3f kHz", binCenterFreq / 1e3); - else - std::snprintf(freqBuf, sizeof(freqBuf), "%7.1f Hz", binCenterFreq); - - char valBuf[48]; + char hoverBuf[128]; if (hoverPanel_ == HoverPanel::Spectrum) { - std::snprintf(valBuf, sizeof(valBuf), "%7.1f dB", cursors_.hover.dB); + fmtFreqDB(hoverBuf, sizeof(hoverBuf), "", binCenterFreq, cursors_.hover.dB); } else if (hoverPanel_ == HoverPanel::Waterfall) { - if (hoverWfTimeOffset_ >= 10.0f) - std::snprintf(valBuf, sizeof(valBuf), "%7.1f s", -hoverWfTimeOffset_); - else if (hoverWfTimeOffset_ >= 1.0f) - std::snprintf(valBuf, sizeof(valBuf), "%7.2f s", -hoverWfTimeOffset_); - else - std::snprintf(valBuf, sizeof(valBuf), "%5.0f ms", -hoverWfTimeOffset_ * 1000.0f); + fmtFreqTime(hoverBuf, sizeof(hoverBuf), "", binCenterFreq, -hoverWfTimeOffset_); } else { - valBuf[0] = '\0'; + fmtFreq(hoverBuf, sizeof(hoverBuf), binCenterFreq); } - // Draw as a single right-aligned line, fixed-width value column + // Right-align the text ImU32 hoverTextCol = IM_COL32(100, 230, 130, 240); float rightEdge = specPosX_ + specSizeX_ - 8; float hy2 = specPosY_ + 4; - - // Use a fixed-width reference for the value column to prevent jumping - ImVec2 refSz = ImGui::CalcTextSize("-000.0 dB"); - ImVec2 freqSz = ImGui::CalcTextSize(freqBuf); - float sepW = ImGui::CalcTextSize(" ").x; - float valColX = rightEdge - refSz.x; - float freqX = valColX - sepW - freqSz.x; - - if (valBuf[0]) { - ImVec2 valSz = ImGui::CalcTextSize(valBuf); - dlp->AddText({freqX, hy2}, hoverTextCol, freqBuf); - dlp->AddText({rightEdge - valSz.x, hy2}, hoverTextCol, valBuf); - } else { - dlp->AddText({rightEdge - freqSz.x, hy2}, hoverTextCol, freqBuf); - } + ImVec2 hSz = ImGui::CalcTextSize(hoverBuf); + dlp->AddText({rightEdge - hSz.x, hy2}, hoverTextCol, hoverBuf); } } } diff --git a/src/ui/Cursors.cpp b/src/ui/Cursors.cpp index e53755a..8aa0a91 100644 --- a/src/ui/Cursors.cpp +++ b/src/ui/Cursors.cpp @@ -97,7 +97,8 @@ void Cursors::draw(const SpectrumDisplay& specDisplay, formatLabel(buf, sizeof(buf), label, c.freq, dispDB); ImVec2 sz = ImGui::CalcTextSize(buf); float lineH = ImGui::GetTextLineHeight(); - float ty = posY + 4 + row * (lineH + 4); + // draw starting from the second line -- on the first line, we have cursor data + float ty = posY + 4 + (row + 1) * (lineH + 4); // Place right of cursor line; flip left if it would overflow. float tx; @@ -118,25 +119,15 @@ void Cursors::draw(const SpectrumDisplay& specDisplay, if (showDelta && cursorA.active && cursorB.active) { double dFreq = cursorB.freq - cursorA.freq; float dDB = bDB - aDB; - char val1[48], val2[48]; - fmtFreq(val1, sizeof(val1), dFreq); - std::snprintf(val2, sizeof(val2), "%.1f dB", dDB); + char deltaBuf[128]; + fmtFreqDB(deltaBuf, sizeof(deltaBuf), "D", dFreq, dDB); - ImVec2 labelSz = ImGui::CalcTextSize("dF = "); - ImVec2 v1Sz = ImGui::CalcTextSize(val1); - ImVec2 v2Sz = ImGui::CalcTextSize(val2); - float valW = std::max(v1Sz.x, v2Sz.x); - float lineH = labelSz.y; - float totalW = labelSz.x + valW; - float tx = posX + sizeX - totalW - 158; + ImVec2 dSz = ImGui::CalcTextSize(deltaBuf); + float tx = posX + sizeX - dSz.x - 178; + float lineH = ImGui::GetTextLineHeight(); float ty = posY + 4; ImU32 col = IM_COL32(255, 200, 100, 255); - float eqX = tx + labelSz.x; // values start here (right of '= ') - - dl->AddText({tx, ty}, col, "dF ="); - dl->AddText({eqX + valW - v1Sz.x, ty}, col, val1); - dl->AddText({tx, ty + lineH + 2}, col, "dA ="); - dl->AddText({eqX + valW - v2Sz.x, ty + lineH + 2}, col, val2); + dl->AddText({tx, ty}, col, deltaBuf); } // (Hover cursor line is drawn cross-panel by Application.)