Skip to content

feat(gui): user-adjustable frequency-scale text size (#3501)#3503

Merged
jensenpat merged 1 commit into
aethersdr:mainfrom
nigelfenton:feat/freq-scale-text-size
Jun 11, 2026
Merged

feat(gui): user-adjustable frequency-scale text size (#3501)#3503
jensenpat merged 1 commit into
aethersdr:mainfrom
nigelfenton:feat/freq-scale-text-size

Conversation

@nigelfenton

Copy link
Copy Markdown
Contributor

Summary

Closes #3501 — reported by KN7K via Discord: the panadapter frequency-scale labels were fixed at 8 pt with no way to enlarge them.

This adds a "Scale text" dropdown (8/9/10/11/12/14 pt) to the per-pan Display overlay menu, directly under the existing "Grid:" spacing control, mirroring the #1390 pattern end-to-end: per-pan persisted setting (DisplayFreqScaleFontPt), signal wiring in MainWindow, state sync when the menu reopens, and Reset-defaults restores 8 pt.

Implementation notes

  • The fixed FREQ_SCALE_H (20 px) becomes freqScaleH(), derived from the configured font, at all 28 layout/hit-test sites — larger labels get a taller strip instead of clipped ascenders. At the default 8 pt the height is byte-identical to today (never below 20 px), so existing layouts are untouched.
  • drawFreqScale() gains a right-column guard: ruler labels are clamped (or skipped, tick retained) clear of the dBm / waterfall-time scale column. This collision existed marginally at 8 pt and became obvious at larger sizes — found during live testing.
  • The dBm strip's own label size is unchanged; if there's appetite, it could get the same treatment in a follow-up.

Testing

  • Built RelWithDebInfo/Ninja (MSVC, Qt 6.10.3) and ran live against a FLEX-6700.
  • Verified visually at every step from 8 → 14 → 8 pt: labels grow/shrink, strip height follows with no clipping, divider drag and waterfall click zones track the moved boundary, last label stays clear of the dBm/time column, menu reopens showing the current value, Reset-defaults returns to 8 pt.

First concrete operator-facing item under the #3443 accessibility initiative.

🤖 Generated with Claude Code

@nigelfenton nigelfenton requested a review from a team as a code owner June 10, 2026 03:17
@nigelfenton

Copy link
Copy Markdown
Contributor Author

Heads-up: #3504 (@rfoust) touches the same drawFreqScale() — the changes are complementary (this PR: label size / strip height; that one: label formatting). Textual conflict for whichever lands second; happy to rebase mine if his goes first. The combination is arguably the best outcome for #3501/#3480 — shorter labels at a larger size.

@rfoust

rfoust commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

The bot says:

Best practical path:
Merge #3504 first if maintainers can. It is the smaller PR and fixes #3480 directly.
Then #3503’s author rebases/updates #3503 and keeps their font-size work, changing their formatter line to:const QString label = formatFreqScaleLabel(freq, decimals);
and removing the < 0.01 4-decimal branch.
If #3503 merges first, then I update #3504 by rebasing onto latest main and applying our tiny formatter helper into their new drawFreqScale().
I would not update #3504 to include #3503 right now, because that would drag #3503’s whole font-size feature into our PR and make #3504 no longer a focused fix for #3480. The cleaner fix is merge-order or a small rebase after one PR lands.

@aethersdr-agent aethersdr-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this, @nigelfenton — the feature itself is well-scoped and the implementation is clean. The freqScaleH() derivation with the 8 pt byte-identity guard, the right-column label clamp, AppSettings persistence, signal wiring through MainWindow, and Reset-defaults restoration all follow the #1390 pattern faithfully. CI is green across all six checks.

There is, however, one blocker that I'd like fixed before merge:

Encoding corruption in src/gui/SpectrumWidget.cpp

The PR's copy of this file has been re-encoded in a way that breaks it as UTF-8. Two concrete symptoms:

  1. A UTF-8 BOM (EF BB BF) was prepended to the file. main has no BOM (23 69 6e 63 6c 75 64 65 — bare #include); your branch starts with EF BB BF 23 69 6e 63 6c 75 64 65. Verified locally:

    $ git show <pr-head>:src/gui/SpectrumWidget.cpp | head -c 12 | xxd
    00000000: efbb bf23 696e 636c 7564 6520 2253      ...#include "S
    

    No other file in src/gui/ carries a BOM; this is inconsistent with the project convention.

  2. All non-ASCII characters in the file are mojibake. 88 occurrences of the †byte sequence — the classic signature of UTF-8 bytes being re-interpreted as cp1252 and then re-saved as UTF-8. Examples from the diff (lines that aren't part of your feature):

    • // ─── Waterfall color scheme gradient cache ───// ─── Waterfall color scheme gradient cache ───
    • // black→white ramp// blackâ†'white ramp
    • qWarning() << "SpectrumWidget: running under XWayland with OpenGL — "... OpenGL â€" "
    • User-visible string regression: QStringLiteral("Connecting to radio…")QStringLiteral("Connecting to radio…"). That ellipsis renders on the spectrum widget during connect — operators will see mojibake instead of .

The build passes because MSVC tolerates BOMs and comments are still valid C++, but the connect-overlay string and any qDebug/qWarning output with em-dashes are now broken at runtime. This looks like an editor saving the file with cp1252 → UTF-8 round-tripping (common with Windows editors when "UTF-8 with BOM" is auto-selected on a non-BOM source).

Suggested fix: rebase the actual feature edits (setFreqScaleFontPt, freqScaleH(), the 28 FREQ_SCALE_H → freqScaleH() substitutions, the drawFreqScale label clamp, the loadSettings/sync hookups, the include for <QFontMetrics>) onto the current main copy of SpectrumWidget.cpp so the BOM and mojibake are dropped. The functional diff against main is small; the bulk of this PR's +280/-218 against the corrupted version is the round-tripped text.

One small follow-up note (non-blocking)

SpectrumWidget.cpp:loadSettings() clamps the persisted value with std::clamp(..., 8, 14), but the dropdown offers {8, 9, 10, 11, 12, 14} — a stored value of 13 (e.g. from a manual settings edit, or a future expanded dropdown) would clamp through but render as the dropdown's "8 pt default" fallback in syncExtraDisplaySettings (via the findData(...) >= 0 ? ... : 0 line). Fine as-is for the supplied dropdown, just worth keeping in mind if the choices ever change.

Otherwise this is a nice, contained, well-documented contribution — first-time SDR ops on visually constrained displays will be happy. Once the encoding is sorted I'd be glad to see it land.


🤖 aethersdr-agent · cost: $11.8488 · model: claude-opus-4-7

Adds a "Scale text" dropdown (8-14 pt) to the per-pan Display overlay
menu, mirroring the aethersdr#1390 grid-spacing pattern: per-pan persisted
setting (DisplayFreqScaleFontPt), signal wiring, state sync on menu
open, and Reset-defaults support.

The fixed FREQ_SCALE_H strip height becomes freqScaleH(), derived from
the configured font at all 28 layout/hit-test sites, so larger labels
get a taller strip instead of clipped ascenders (never below the
existing 20 px at the 8 pt default).

drawFreqScale() also gains a right-column guard: ruler labels are
clamped/skipped clear of the dBm / waterfall-time scale column, fixing
a collision that existed marginally at 8 pt and became obvious at 14.

Reported by KN7K via Discord; first concrete item under the aethersdr#3443
accessibility initiative.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@nigelfenton nigelfenton force-pushed the feat/freq-scale-text-size branch from 5d8ee59 to 1e5316d Compare June 10, 2026 22:14
@nigelfenton

Copy link
Copy Markdown
Contributor Author

Rebased onto main — #3504's formatFreqScaleLabel() now feeds the sizing/clamp logic directly, so the combination (trimmed labels at user-chosen sizes) is what ships. Re-verified live on the FLEX-6700 across 8-14 pt: trimmed labels grow/shrink with the strip, right-column guard holding, menu state sync and reset intact. Also cleaned unintended encoding churn from the first push — the diff is now the true +96/-34.

@jensenpat jensenpat left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the diff: follows the #1390 per-pan setting pattern faithfully (persisted setting, signal wiring, sync with QSignalBlocker, reset-defaults). Verified the earlier encoding blocker is fixed on the current head — no BOM, zero mojibake. All CI checks green. Approving.

@jensenpat jensenpat merged commit 6a0648b into aethersdr:main Jun 11, 2026
6 checks passed
@nigelfenton nigelfenton deleted the feat/freq-scale-text-size branch June 12, 2026 13:00
G6PWY-Chris pushed a commit to G6PWY-Chris/AetherSDR that referenced this pull request Jun 22, 2026
Adds a "Scale text" dropdown (8-14 pt) to the per-pan Display overlay
menu, mirroring the aethersdr#1390 grid-spacing pattern: per-pan persisted
setting (DisplayFreqScaleFontPt), signal wiring, state sync on menu
open, and Reset-defaults support.

The fixed FREQ_SCALE_H strip height becomes freqScaleH(), derived from
the configured font at all 28 layout/hit-test sites, so larger labels
get a taller strip instead of clipped ascenders (never below the
existing 20 px at the 8 pt default).

drawFreqScale() also gains a right-column guard: ruler labels are
clamped/skipped clear of the dBm / waterfall-time scale column, fixing
a collision that existed marginally at 8 pt and became obvious at 14.

Reported by KN7K via Discord; first concrete item under the aethersdr#3443
accessibility initiative.

Squashed-from: aethersdr#3503

Co-authored-by: Nigel Fenton <2791007+nigelfenton@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Pat Jensen <jensenpat@users.noreply.github.com>
NF0T pushed a commit that referenced this pull request Jun 26, 2026
… Principle XI. (#3839)

## The bug

The frequency readout **clips its leading (most-significant) digits** in
two places — the VFO slice flag (`VfoWidget`) and the RX Controls box
(`RxApplet`). The operator loses the MHz digits, the worst ones to lose.
Reported in #3463 (Default Light, Windows/FLEX‑6400, "first number
cut"); also visible on macOS default **dark** in the RX Controls box.

## Root cause

Both surfaces render the frequency as a plain `QLabel` styled by the
theme tokens `font.size.freq` / `font.family.freq` (DSEG7 Modern, 20px
dark / 26px light), poured into a **fixed-width box with no
shrink-to-fit and no elision**. When the rendered DSEG7 string is wider
than the box, the right-aligned label clips on the left:

- **`RxApplet`** — the freq stack shares its row with TX/mode/WFM inside
the fixed **~248px** `AppletPanel` column. The leftover is **~124px**
(measured live via the bridge), narrower than even `21.074.000` at the
default 20px → the leading **`2`** clips **on the default dark theme**.
In light theme (26px) only `074.000` survives.
- **`VfoWidget`** — the 252px flag fits 2-digit-MHz HF in dark, but the
light-theme 26px digits (and the wider Windows metrics in #3463)
overflow and clip the leading digit.

This is the unfinished half of #844/#851 (which widened the digit
*template* for 4-digit MHz but left a hardcoded pixel probe), and it
mirrors the font-derived-sizing precedent from #3503.

## The fix

A QSS `font-size` **overrides** `setFont()` (verified empirically),
which is why the size couldn't be adjusted in code before. So:

- Drop `font-size` from each freq label's stylesheet
(family/weight/colour stay, theme-reactive) and drive the pixel size via
**`setFont()` with a width-fitted size**, capped at the theme nominal —
new shared `src/gui/FreqLabelFit.h`.
- Re-fit on text update, label `QEvent::Resize`, and
`ThemeManager::themeChanged` (so Dark↔Light and Theme-Editor font edits
stay correct).
- `RxApplet`'s freq stack is made `Expanding` (stretch removed) so it
fills a **font-independent** width — avoids a fit↔reflow oscillation.

Digits stay **full-size whenever they fit** and shrink only as much as
needed to keep the leading digits on screen. (This fixes the clipping;
making the digits *larger* — #3515 — remains a separate enhancement.)

## Proof — agent automation bridge

Driven against a live FLEX‑8400M (RX-only, `tune` + `grab`), before vs
after, both themes. Top row = before (clipped), bottom row = after
(fixed):

**RX Controls box — default dark, 21.074 MHz** (leading `2` clipped →
full)
![RxApplet dark
before/after](https://raw.githubusercontent.com/jensenpat/AetherSDR/assets-vfo-freq-clip/pr-rxapplet-dark.png)

**RX Controls box — light theme, 21.074 MHz** (only `074.000` visible →
full)
![RxApplet light
before/after](https://raw.githubusercontent.com/jensenpat/AetherSDR/assets-vfo-freq-clip/pr-rxapplet-light.png)

**VFO slice flag — light theme, 21.074 MHz** (leading `2` clipped →
full)
![VfoWidget light
before/after](https://raw.githubusercontent.com/jensenpat/AetherSDR/assets-vfo-freq-clip/pr-vfo-light.png)

| Surface / case | Before | After |
|---|---|---|
| RxApplet, dark, 21.074 MHz | leading `2` clipped | full `21.074.000` |
| RxApplet, dark, 144.2 MHz | `1` gone, `4` clipped (`~44.200.000`) |
full `144.200.000` |
| RxApplet, light, 21.074 MHz | only `074.000` | full `21.074.000` |
| VfoWidget, light, 21.074 MHz | leading `2` clipped | full `21.074.000`
|
| VfoWidget, dark (already fit) | — | unchanged, no regression |

## Files

- `src/gui/FreqLabelFit.h` (new) — `fitFreqPixelSize()` +
`applyFittedFreqFont()`
- `src/gui/VfoWidget.{h,cpp}`, `src/gui/RxApplet.{h,cpp}` — drop QSS
font-size, `applyFreqFit()`, re-fit hooks, RxApplet stack `Expanding`

Closes #3463. Refs #3515.

💻 Generated with Claude Code (Opus 4.8) with architecture by @jensenpat

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

a11y(gui): user-adjustable text size for the panadapter frequency scale

3 participants