Skip to content

Flat design system: Phases 1-4 token layer + UI cleanup#2374

Closed
LU5DX wants to merge 2 commits into
aethersdr:mainfrom
LU5DX:feat/flat-design-system-phases-1-4
Closed

Flat design system: Phases 1-4 token layer + UI cleanup#2374
LU5DX wants to merge 2 commits into
aethersdr:mainfrom
LU5DX:feat/flat-design-system-phases-1-4

Conversation

@LU5DX

@LU5DX LU5DX commented May 5, 2026

Copy link
Copy Markdown

Summary

Implements RFC #2294 — Flat Design System, Phases 1-4:

  • Phase 1: New DesignTokens.h vocabulary, Theme.h rewritten to use tokens, ComboStyle.h token substitution
  • Phase 2: PanadapterApplet title bar gradient → flat
  • Phase 3: RxApplet/TxApplet token substitution + dynamic property pattern for TX active state
  • Phase 4: ContainerWidget card borders via QPainter, ContainerTitleBar gradient→flat, VfoWidget font tokens, CW panel normalization, AppletPanel spacing/layout fixes (kWidth=280, 6px stack gap), NetworkDiagnosticsDialog native title bar conversion

Test plan

  • Build: cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo && cmake --build build -j$(nproc)
  • Launch without radio — verify all applets render with correct flat colors
  • Check button corners (3px radius), slider handles (10px)
  • Check title bars are flat (no gradient)
  • Check CW decode panel buttons and labels
  • Verify sidebar applets have visible card borders with spacing between them

🤖 Generated with Claude Code

@LU5DX LU5DX requested review from jensenpat and ten9876 as code owners May 5, 2026 07:11
@LU5DX LU5DX force-pushed the feat/flat-design-system-phases-1-4 branch from 5d8700d to c2eb746 Compare May 5, 2026 07:13
@LU5DX

LU5DX commented May 5, 2026

Copy link
Copy Markdown
Author

CI runs are blocked with action_required — needs workflow approval from a maintainer with write access (@ten9876) since this is from a fork. Could you approve the workflows in the Actions tab? Thanks.

@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 the design system work — the centralized DesignTokens.h plus the migration of Theme.h / ComboStyle.h to use it is a nice cleanup, and the txActive dynamic property pattern in TxApplet is a clear win over the old "rebuild the whole stylesheet on every state change" approach. Removing the custom frameless title bar in NetworkDiagnosticsDialog in favor of native chrome also drops a meaningful chunk of duplicated drag/resize/event-filter code. A few things worth a look:

1. PanadapterApplet border stylesheet probably won't render. In PanadapterApplet.cpp:

setStyleSheet(
    "PanadapterApplet { border: 1px solid " + DesignTokens::kBorderControl + "; "
    "border-radius: 4px; }");

A class-selector stylesheet on a QWidget subclass that does not override paintEvent and does not have Qt::WA_StyledBackground set is silently dropped by Qt — this is the same trap ContainerWidget already handles correctly in this PR (the new paintEvent + setAttribute(Qt::WA_StyledBackground, true) pair). PanadapterApplet has neither (PanadapterApplet.h:18 is a plain QWidget subclass with no paintEvent), so this border rule is dead. Either drop the rule, or do what ContainerWidget does (add setAttribute(Qt::WA_StyledBackground, true) and a paintEvent that calls style()->drawPrimitive(QStyle::PE_Widget, …)). The PR test plan only checks sidebar applets (which get their border from ContainerWidget), so this would have passed visual review even though the panadapter itself isn't actually getting the intended border.

2. QColor(kTextSecondary.data()) in ComboStyle.h is fragile.

p.setBrush(QColor(kTextSecondary.data()));

QLatin1StringView::data() is not guaranteed to be null-terminated in general; it happens to be here because the view is constructed from a string literal, but it's a footgun if anyone later changes the construction site. Safer alternatives that don't depend on null-termination: QColor(QLatin1String(kTextSecondary)) or QColor::fromString(kTextSecondary).

3. QColor::setNamedColor() is deprecated since Qt 6.6. In ContainerWidget::paintEvent:

QColor bg;
bg.setNamedColor(DesignTokens::kSurfacePanel);

Prefer QColor bg = QColor::fromString(DesignTokens::kSurfacePanel); (same for border). Functional today but will spit deprecation warnings on Qt ≥ 6.6.

4. Width bump 260 → 280 is a user-visible change. AppletPanel::kWidth = 280 is called out in the PR body, but worth confirming that the +20px on the right column is intended for everyone — users with saved/expected layouts will see the center pane shrink by 20px on next launch (the existing s.remove("SplitterState") already wipes saved state, so the new sizing applies immediately).

Nothing here is a blocker — #1 is the one I'd want addressed (or the dead rule deleted) before merge. Nice work on the token layer.

Introduce DesignTokens.h vocabulary, rewrite Theme.h to use tokens,
and consolidate stylesheet overrides across 15 files. Includes card
borders via QPainter, gradient→flat title bars, spacing/layout fixes
(kWidth 280, 6px stack gap), and NetworkDiagnosticsDialog native
title bar conversion.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@LU5DX LU5DX force-pushed the feat/flat-design-system-phases-1-4 branch from c2eb746 to 6bea0df Compare May 6, 2026 18:29
@LU5DX

LU5DX commented May 6, 2026

Copy link
Copy Markdown
Author

Rebased onto latest origin/main (11 new upstream commits) + addressed review feedback:

  • Removed dead PanadapterApplet border stylesheet — class-selector rule on a QWidget without paintEvent or WA_StyledBackground is silently dropped by Qt
  • Fixed fragile QLatin1StringView::data() in ComboStyle.h → QColor::fromString()
  • Replaced deprecated setNamedColor() in ContainerWidget.cpp → QColor::fromString()

Builds clean at 6bea0df.

…amedColor deprecation

- Remove PanadapterApplet border stylesheet — class-selector rule on QWidget
  without paintEvent or WA_StyledBackground is silently dropped by Qt
- Replace QLatin1StringView::data() with QColor::fromString() in ComboStyle.h
- Replace deprecated setNamedColor() with QColor::fromString() in ContainerWidget
@ten9876

ten9876 commented May 7, 2026

Copy link
Copy Markdown
Collaborator

Claude here — first, thanks for the substantial work, MARTIN. The token vocabulary you proposed (kSurfaceBase, kBorderControl, kColorAccent, etc.) is sound and maps cleanly onto the W3C Design Tokens Format that's the modern industry standard.

After working through this with Jeremy, the project direction is going to be slightly different from what this PR proposes:

  • Runtime theming with BYOT (bring-your-own-themes) IS the goal — users drop a JSON file in their config directory and the theme appears in a View → Theme menu. Spec'd out in Runtime theming infrastructure with BYOT support (W3C Design Tokens) #2453.
  • Tokens stored as W3C-format JSON, not constexpr C++ — so users (and the community) can author themes without rebuilding.
  • The 'flat' visual direction isn't being committed to as default — AetherSDR's current instrument-style look (gradient title bars, card borders with depth) is the visual identity for the default theme. Your flat design ideas are absolutely welcome as a bundled alternative theme (flat.json) shipping alongside default and high-contrast themes — users who prefer flat can pick it via the View → Theme menu.

So this PR as it stands would need to be reworked rather substantially:

  1. Drop the visual changes to PanadapterApplet / ContainerTitleBar / NetworkDiagnosticsDialog (those are design direction, not refactor).
  2. Restructure tokens to be runtime-mutable (loaded from JSON), not compile-time constants.
  3. Add ThemeManager + themeChanged signal + JSON loader.
  4. Default theme JSON should preserve the current hardcoded values exactly — no visible UX change at first.

That's effectively a different PR. Two paths forward:

A. Close this PR; we open #2453 fresh for the foundation work, you (or anyone) can take a stab at it with the new spec.

B. Keep this PR open while you rework it against #2453's spec — the token vocabulary you've already established here directly informs the JSON structure.

Either is fine — your call. The visual flat design ideas can also become the flat.json bundled theme as part of #2453's bundled-themes deliverable.

There's also a real conflict with #2449 (just merged) on NetworkDiagnosticsDialog that would need rebasing regardless — that PR added per-dialog frameless support that this PR's NetworkDiagnostics rewrite would silently regress.

Thanks for the work and patience.

73, Jeremy KK7GWY & Claude (AI dev partner)

@LU5DX

LU5DX commented May 7, 2026

Copy link
Copy Markdown
Author

Closing this one as per the recommended option A.

@LU5DX LU5DX closed this May 7, 2026
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.

2 participants