Skip to content

feat(gui): mouse-over numeric readout on TX meters (SWR/power/ALC/level/compression)#3936

Open
jensenpat wants to merge 1 commit into
aethersdr:mainfrom
jensenpat:feat/meter-value-tooltip
Open

feat(gui): mouse-over numeric readout on TX meters (SWR/power/ALC/level/compression)#3936
jensenpat wants to merge 1 commit into
aethersdr:mainfrom
jensenpat:feat/meter-value-tooltip

Conversation

@jensenpat

Copy link
Copy Markdown
Collaborator

Mouse-over numeric readout on the TX meters

While transmitting, the SWR, forward-power and ALC bar meters — and now the mic Level and Compression meters — only told you a value by how far the bar filled against its scale. You had to eyeball it. This adds a hover readout: mouse over any of those meters and a floating badge shows the exact numeric value.

Meter mouse-over value readouts

Proven live over the automation bridge against a FLEX-8400M, transmitting a two-tone into the ANT2 dummy load. Forward power, SWR and ALC show real keyed values; Mic Level and Compression are shown idle because two-tone bypasses the mic/speech path.

What it does

  • Hovering a TX meter pops a floating badge with its exact value:
    • Forward power → 12 W
    • SWR → 1.12 : 1
    • ALC → -6.4 dBFS
    • Mic Level → -12.5 dB
    • Compression → 6.0 dB (reported as a positive amount of compression)
  • The badge reuses the existing DragValuePopup — the same widget the sliders flash when you adjust them by keyboard/drag (20 px, weight-800, rounded cyan-bordered badge) — so font, size and style match exactly, as requested.
  • It follows the pointer, updates live as the meter value changes while hovered, and fades one second after the pointer leaves the bar.

Implementation

  • HGauge gains an opt-in hover readout: setHoverValuePopupEnabled(bool) + setHoverValueFormatter(...). Mouse tracking plus enter/move/leave events drive a per-gauge DragValuePopup; leave lingers for 1000 ms. Default off, so the telemetry gauges (PA temp, supply, fan) are untouched.
  • TxApplet enables it on the forward-power and SWR gauges with unit-aware formatters.
  • PhoneCwApplet enables it on the ALC, mic-Level and Compression gauges.

Automation bridge (testing support)

  • New hover <target> [leave] verb synthesizes a real hover (QEnterEvent + no-button QMouseMove; leave fires QEvent::Leave) so hover-driven UI is provable end-to-end. Documented in docs/automation-bridge.md.
  • amp_applet_test now links DragValuePopup.cpp (pulled in transitively by HGauge.h).

Verification

Driven entirely through the automation bridge:

Meter Badge Live meter reading State
Forward power 12 W ~11.7 W keyed two-tone, ANT2
SWR 1.12 : 1 1.11 keyed two-tone, ANT2
ALC -6.4 dBFS −6.39 dBFS keyed two-tone, ANT2
Mic Level -150.0 dB floor idle (mic-path)
Compression 0.0 dB 0 idle (mic-path)
  • Safety: the TX antenna was hard-verified as ANT2 (dummy load) via dumpTree before any keying; tune power held at ~15–20 %; the transmitter was unkeyed and state restored after capture (transmitting == false confirmed).
  • Fade timing: the badge was confirmed still visible 0.4 s after mouse-leave and gone by 1.2 s — i.e. the 1-second linger.

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

…el/comp)

While transmitting, the SWR, forward-power and ALC bar meters — plus the mic
Level and Compression meters — only conveyed a value by how far the bar filled
against its scale. Hovering now pops a floating badge with the exact numeric
value, so the operator can read watts / SWR ratio / dBFS directly instead of
eyeballing the fill.

The badge reuses the existing DragValuePopup — the same widget (20 px /
weight-800, rounded cyan-bordered) the sliders flash on keyboard/drag
adjustment — so the style, font and size match exactly. It follows the pointer,
updates live as the meter value changes while hovered, and fades one second
after the pointer leaves the bar.

Implementation:
- HGauge gains an opt-in hover readout (setHoverValuePopupEnabled +
  setHoverValueFormatter). Mouse tracking + enter/move/leave drive a per-gauge
  DragValuePopup; leave lingers for 1000 ms. Default off, so telemetry gauges
  (PA temp, supply, fan) are unaffected.
- TxApplet enables it on the forward-power ("N W") and SWR ("N.NN:1") gauges;
  PhoneCwApplet on the ALC/Level ("N.N dB(FS)") and Compression ("N.N dB",
  reported as a positive amount) gauges.

Automation bridge:
- New `hover <target> [leave]` verb synthesizes a real hover (QEnterEvent +
  no-button QMouseMove; `leave` fires QEvent::Leave) so hover-driven UI is
  provable end-to-end. Documented in docs/automation-bridge.md.
- amp_applet_test links DragValuePopup.cpp (HGauge.h now pulls it in).

Proven live over the bridge against a FLEX-8400M, transmitting a two-tone into
the ANT2 dummy load: forward power 12 W, SWR 1.12:1, ALC -6.4 dBFS all rendered
in the badge; badge confirmed visible 0.4 s after mouse-leave and gone by 1.2 s.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@jensenpat jensenpat marked this pull request as ready for review July 1, 2026 04:03
@jensenpat jensenpat requested review from a team as code owners July 1, 2026 04:03

@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.

Nice, well-scoped feature — the hover readout is a genuinely useful addition to the TX meters, and the implementation is clean. I checked the areas most likely to bite:

Verified good

  • Lifetime / RAII: m_hoverPopup = new AetherSDR::DragValuePopup(this) is parented to the HGauge, so Qt owns cleanup — no leak, and it matches the existing GuardedSlider/MeterSlider pattern. The popup's WA_TransparentForMouseEvents attribute means it won't intercept the pointer and cause an enter/leave flicker loop. All null-guarded (if (m_hoverPopup) before linger/hideNow).
  • Transitive-include link fix: including DragValuePopup.h from HGauge.h means every TU that compiles an HGauge consumer needs DragValuePopup.cpp linked. I confirmed the only test target outside the main build that compiles such a TU is amp_applet_test (via AmpApplet.cpp) — and that's exactly the one you added it to. The other four consumers (TxApplet/PhoneCwApplet/TunerApplet/MeterApplet) are main-build only, which already links DragValuePopup.cpp. Coverage is complete.
  • Opt-in default off keeps the telemetry gauges (PA temp/supply/fan) untouched, and mouse tracking is only enabled when the readout is.
  • static_cast<HGauge*>(m_fwdGauge) is needed because TxApplet declares those members as QWidget*; the objects are constructed as HGauge, so the cast is safe.
  • All six CI checks green (build + macOS/Windows/Linux + CodeQL + a11y).

One minor, non-blocking observation

  • Live updates route through setValue/setValueImmediateshowHoverPopupDragValuePopup::showValue, which calls raise() on every invocation. While a meter is hovered and actively updating during TX, that's a raise() per meter tick. It's negligible in practice (only while the pointer is parked on the bar), so no change needed — just noting it in case you ever see the badge fighting z-order with other tool windows.

Thanks for the thorough automation-bridge testing and the new hover verb — proving hover-driven UI end-to-end is a nice touch. 👍


🤖 aethersdr-agent · cost: $2.6941 · model: claude-opus-4-8

@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.

Nice, clean addition — thanks @jensenpat. The hover readout reuses DragValuePopup cleanly, the feature is opt-in so the telemetry gauges (PA temp/supply/fan) stay untouched, and the hover/hover … leave bridge verb makes it genuinely provable end-to-end. A few notes, nothing blocking:

Verified good:

  • No leak / no null risk. The popup is lazily created and parented to the HGauge (new DragValuePopup(this)), so it's destroyed with the gauge, and every showHoverPopup guards on m_hoverPopupEnabled + lazy-inits. linger() only arms its timer when visible, and showValue("") self-hides.
  • CMake fix is complete. Adding #include "DragValuePopup.h" to the header-only HGauge means any TU that constructs an HGauge now needs DragValuePopup.cpp at link. I checked every test target: amp_applet_test is the only test that pulls in an HGauge-bearing source, and it's exactly the one you added the source to. The main AetherSDR target already lists DragValuePopup.cpp. So nothing else link-breaks.
  • doHover boundary handling covers widget-not-found and not-visible, and the synthetic QEnterEvent + no-button QMouseMove faithfully mirrors a real hover (mouse tracking is enabled by setHoverValuePopupEnabled). std::lround in TxApplet.cpp is backed by an explicit <cmath>.

Minor, optional:

  • While hovered, setValue/setValueImmediate call showHoverPopupshowValuemove() + raise() on every meter tick. On a live TX meter that's ~10–20 Hz of re-raising a top-level tooltip window. It's harmless functionally (WA_ShowWithoutActivating keeps focus out of it), but you could cheaply gate the re-show on the formatted text actually changing (cache the last string) to avoid the churn. Not required for merge.

Looks good to me overall.


🤖 aethersdr-agent · cost: $2.8353 · model: claude-opus-4-8

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.

1 participant