fix(waterfall): independently themable LIVE chip (red live / grey history)#3761
Conversation
…tory) The waterfall LIVE chip reused the shared color.accent.danger and color.text.label semantic tokens, so it couldn't be recolored without affecting unrelated danger/label UI — and its colors were reversed (grey when live, red when paused, #3744). Add dedicated color.waterfall.live (red) and color.waterfall.history (grey) tokens: registered in the ThemeManager defaults (fallback) and both preset themes (referencing each theme's red/gray palette so appearance is preserved), and editable like any color.* token in the Theme Editor. The chip is now red while live, grey while viewing history, and either state is recolorable independently of accent.danger/text.label. Supersedes #3745 (the reversed-colors fix) with the decoupled, themable version. Fixes #3744. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
0fe50b3 to
3d7d6cd
Compare
There was a problem hiding this comment.
Reviewed the diff and traced it against the source. This is a clean, correct, well-scoped fix. Thanks @ten9876. 👍
Correctness of the swap — confirmed. The old line was m_wfLive ? color.text.label : color.accent.danger, i.e. grey-while-live / red-while-history (the reversed bug from #3744). The new code paints color.waterfall.live (red) while live and color.waterfall.history (grey) while in history — the correct convention.
Appearance preserved — verified token-by-token:
- Fallback seed (
ThemeManager::seedBuiltinDefaults):waterfall.live=#ff4d4d(oldaccent.danger),waterfall.history=#506070(oldtext.labelseed value). So the cold/no-JSON path renders identically, just un-reversed. default-dark.json: history →gray.500matches darktext.label.default-light.json: history →gray.300matches lighttext.label. Live →red.500in both, matching oldaccent.danger. Byte-for-byte parity with the prior visible colors, with the reversal corrected.
Naming — color.waterfall.live / color.waterfall.history slot neatly under the existing color.waterfall.colormap.* family, so the decoupling from the shared accent.danger/text.label semantics is consistent with established convention and editable in the Theme Editor as claimed.
Tests — no token-count or coverage assertion in theme_manager_test.cpp keys off the full token set, and both the seed defaults and both preset JSONs were updated symmetrically, so adding these tokens won't regress the suite.
Nothing blocking — no convention, null-safety, scope, or error-handling concerns. Only open item is the unchecked visual verification box in the test plan (confirm red-live / grey-history on a real waterfall, and that recoloring color.waterfall.live moves only the chip), which is the right thing to tick before merge.
🤖 aethersdr-agent · cost: $2.2532 · model: claude-opus-4-8
…) (#3768) ## Summary Follow-up to #3763, mirroring the waterfall LIVE chip (#3761). #3763 gave the idle MOX button a distinct amber accent so it reads as the primary transmit control — but with hardcoded hex literals duplicated across its two styling sites. This tokenizes that accent behind dedicated `color.tx.mox.*` tokens so it becomes **editable in the Theme Editor**: | Token | Default | Role | |---|---|---| | `color.tx.mox.border` | `#d08020` | idle amber border | | `color.tx.mox.text` | `#f0c890` | idle amber text | | `color.tx.mox.border.hover` | `#e09030` | hover border | | `color.tx.mox.text.hover` | `#ffd8a0` | hover text | ### What changed - Both MOX styling sites (construction + the `moxChanged` return-to-idle branch) now share a single `kMoxIdleStyle` template via `ThemeManager::applyStyleSheet()`, which also removes the **duplicated-literal drift risk** the #3763 review flagged. - The **active-TX red branch** is converted from `setStyleSheet()` to `applyStyleSheet()` as well. Its template stays byte-identical literal hex, but routing it through the tracked path fixes a latent bug: a Theme Editor recolor *mid-transmit* would otherwise re-resolve the stale idle template over the active red. (The TUNE button already uses `applyStyleSheet` for both states for exactly this reason.) - Seed defaults (`ThemeManager::seedBuiltinDefaults`) and **both** preset JSONs carry the same literal values the buttons used before. The buttons don't respond to theme today (hardcoded hex), so seeding both presets identically preserves the rendered appearance exactly — only the editability is new. Background / hover-background / disabled colors stay literal (structural, shared with the neutral TUNE/ATU/MEM `btnStyle`); only the amber **accent** that defines MOX's identity is tokenized — the same focused scope as #3761. ## Constitution - **Principle VI** — appearance-only; no transmit-keying, interlock, or model path touched. - **Principle IV** — tokens and templates are original. ## Test plan - [x] Local build passes (`cmake --build build --target AetherSDR`) - [x] Both preset JSONs validate (`json.load`) - [ ] Visual: idle MOX renders amber identically to #3763; pressing MOX still shows solid red; releasing returns to amber; recoloring `color.tx.mox.border` in the Theme Editor moves only the MOX accent (and updates live, including while transmitting) Refs #3663. Follows #3763, #3761. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Summary
Fixes the reversed waterfall LIVE chip colors (#3744) and decouples them from the shared
accent.danger/text.labelsemantic tokens so the indicator can be recolored independently.color.waterfall.live(red) andcolor.waterfall.history(grey), registered in the ThemeManager defaults (fallback) and both preset themes (default-dark.json/default-light.json, referencing each theme'sred.500/gray.500palette so appearance is preserved).SpectrumWidget::drawTimeScalenow paints the chip red while live, grey while viewing history — the correct "currently live = red" convention from Coloring of waterfall historyLIVEbutton is reversed #3744 — via the new tokens.color.*token in the Theme Editor, so the live/history colors can be set independently of danger/label.Why supersede #3745
#3745 was a one-line color swap reusing
accent.danger/text.label. Per review, the live indicator shouldn't be coupled to the danger/label semantics (recoloring "danger" would recolor the LIVE chip). This PR lands the same visible fix with dedicated, independently-themable tokens. Closing #3745 in favor of this; credit to @jbettik for the report (#3744) and original fix.Test plan
cmake --build build --target AetherSDR)color.waterfall.livein the Theme Editor and confirm only the chip changes🤖 Generated with Claude Code