Skip to content

feat(bar): customizable button bar — favorites + push-down drawer#3150

Merged
ten9876 merged 1 commit into
mainfrom
fix/button-bar
May 25, 2026
Merged

feat(bar): customizable button bar — favorites + push-down drawer#3150
ten9876 merged 1 commit into
mainfrom
fix/button-bar

Conversation

@ten9876

@ten9876 ten9876 commented May 25, 2026

Copy link
Copy Markdown
Collaborator

Summary

Replace the fixed two-row top button bar in AppletPanel with a single favorites row (top 5 buttons + drawer-toggle) and a push-down drawer that holds the rest. Right-click any bar button opens a non-modal PersistentDialog-derived picker with Active / Hidden columns and a "Favorites" divider rendered inside row 5.

Behaviour

  • Active column — every button shown in the bar. Positions 1-5 fill the favorites row, 6+ pack the drawer in the same order. Drag-reorder rearranges both halves.
  • Hidden column — buttons removed from the bar entirely. Moving a button here forces its applet off (Applet_<id>=False).
  • Hardware-conditional defaults — TUN / AMP / AG are absent from defaults until their hardware is detected; updateHardwareAvailability() then auto-appends them to Active and saves. SS keeps its hide-until-detected behaviour. LCK renamed to LOCK (id unchanged for layout-key compat).
  • ThemekButtonBase and kBlueActive in RxApplet were the last holdouts using hardcoded #1a2a3a / #205070 / #0070c0 / #0090e0. Tokenised through ThemeManager so the filter-preset buttons and the new bar buttons share color.accent.dim / color.accent.bright. Recalibrated canonical color.accent.dim from #0090e0#0070c0 to preserve the pre-refactor active-button shade across all ~92 call sites.
  • Persistence — new key ButtonBar/Layout = {\"order\":[...],\"hidden\":[...]} with one-shot migration from the interim ButtonBar/Favorites key. Drawer open/closed persists separately.

Files

  • src/gui/AppletPanel.{h,cpp} — bar restructure, BarButton registry, applyBarLayout, picker wiring.
  • src/gui/FavoritesPickerDialog.{h,cpp} (new) — non-modal frameless-aware picker per docs/style/dialog-patterns.md; two-list drag-drop + ↑↓/←→ arrows; custom delegate paints the "Favorites" divider inside row 5's cell so the QListWidget item count stays clean for drag semantics.
  • src/gui/RxApplet.cpp — tokenise kButtonBase / kBlueActive.
  • resources/themes/default-dark.json, docs/theming/canonical-tokens.mdcolor.accent.dim recalibration + doc note.
  • CMakeLists.txt — register new source file.

Test plan

  • Linux (x86_64, Cachy/Wayland) — local build green, visually verified favourites row, drawer toggle, picker drag-reorder, hide / un-hide → applet disable, defaults on first launch, hardware-conditional auto-add.
  • CI build green
  • Windows / macOS / Pi smoke test

🤖 Generated with Claude Code

Replace the fixed two-row top button bar with a single favorites row
(top 5 buttons + drawer-toggle) and a push-down drawer holding the
rest.  Right-click any bar button opens a non-modal, frameless-aware
picker (PersistentDialog) with Active/Hidden columns and a
"Favorites" divider rendered inside row 5; positions 1-5 fill the
favorites row, positions 6+ pack the drawer in the same order.
Buttons moved to the Hidden column disappear from the bar entirely
and their applets are forced off (Applet_<id>=False).

TUN/AMP/AG are omitted from defaults and only appear once their
hardware is detected — at which point updateHardwareAvailability()
appends them to Active and persists the layout.  User-hidden choices
are respected on subsequent detect events.  SS retains the
hide-until-detected behaviour through the same path; LCK renamed to
"LOCK" (id unchanged for layout-key compat).

Theme: tokenise kButtonBase / kBlueActive in RxApplet so the
filter-preset toggle buttons share the canonical color.accent.dim /
color.accent.bright resolution with the new bar buttons.  Recalibrate
color.accent.dim canonical to #0070c0 to preserve the pre-refactor
active-button shade across all ~92 token call sites.

Persistence: ButtonBar/Layout = {"order":[...], "hidden":[...]} with
one-shot migration from the interim ButtonBar/Favorites key.  Drawer
open/closed persists separately.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ten9876 ten9876 requested review from a team as code owners May 25, 2026 18:00
@ten9876 ten9876 enabled auto-merge (squash) May 25, 2026 18:00
@ten9876 ten9876 merged commit a6dad9e into main May 25, 2026
4 checks passed
@ten9876 ten9876 deleted the fix/button-bar branch May 25, 2026 18:28
ten9876 pushed a commit that referenced this pull request May 25, 2026
…n-bar refactor)

Rebases @jensenpat's PR #3133 onto the customisable button-bar
architecture introduced in PR #3150.  HealthApplet.{h,cpp} are
preserved verbatim from PR #3133; the integration changes are the
delta that lets the new BarButton registry + favorites/drawer model
own placement.

Changes vs PR #3133 originally targeted at main:

* Default placement moved from position 4 (between TX and PHNE,
  inside the new favorites zone) to after MTR in the drawer.
  Reasoning: HLTH is a diagnostic, not an every-tune control —
  putting it in favorites by default would push PHNE out of the
  5-button favorites row and surprise shipping users.  Operators
  who want HLTH in favorites can right-click any bar button →
  Favorites picker → drag HLTH up.
* makeEntry() call uses m_drawer / m_drawerLayout (the new drawer
  layout from PR #3150), matching the convention every other
  drawer-resident applet now uses.
* Bar-button registration is automatic via PR #3150's
  registerBarButton() inside makeEntry() — no manual btnRow1/2
  routing needed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ten9876 added a commit that referenced this pull request May 25, 2026
…on-bar refactor (#3153)

## Summary

Rebased version of @jensenpat's #3133 onto PR #3150's customisable
button-bar architecture. Same `HealthApplet.{h,cpp}` source verbatim
from #3133 (zero changes to applet code) — this PR is purely the
AppletPanel integration delta that adapts to PR #3150's new `BarButton`
registry + favorites/drawer model.

**Depends on #3150** — currently targets `fix/button-bar`. Once #3150
merges to main, this PR's base will be retargeted to main and the diff
will collapse to just the HLTH integration touchpoints.

## What changed vs #3133

Three integration touchpoints adjusted; HealthApplet itself untouched:

1. **`makeEntry()` callsite** routes through `m_drawer` /
`m_drawerLayout` (the new drawer layout from #3150), matching every
other drawer-resident applet's pattern. PR #3150's `registerBarButton()`
inside `makeEntry()` handles bar-button registration automatically — no
manual `btnRow2` plumbing required.

2. **Default position** moved from index 4 (between TX and PHNE) to
after MTR in the drawer:
   ```cpp
   "RX", "TUN", "AMP", "TX", "PHNE", "P/CW", "EQ", "WAVE", "TXDSP",
   "CAT", "DAX", "TCI", "IQ", "MTR", "HLTH", "AG", "SS"
   ```
With the new 5-button favorites row, putting HLTH at index 4 would push
PHNE out of favorites and surprise shipping users. Operators who want
HLTH up top can drag it via the right-click Favorites picker.

3. **CMakeLists.txt** — `src/gui/HealthApplet.cpp` added to
`GUI_SOURCES`.

## Credit

Commit attribution stays with @jensenpat as the HealthApplet author.
This PR exists only so the HLTH work doesn't have to wait on the
contributor doing a manual rebase after #3150 lands — they're welcome to
keep #3133 open if they'd prefer to do the rebase themselves.

## Review of HLTH itself

The applet code is well-built — appreciated zero hardcoded colours
(every paint and stylesheet call reads from `ThemeManager`), clean
paint-method separation, visibility-gated 20 Hz timer, three-tier meter
source priority (amp → TGXL tuner → radio TX), and EWMA + recent-window
variance detection.

One small consistency note for a follow-up: HLTH uses
`widget->setStyleSheet(theme.resolve(...))` (~8 sites) instead of
`theme.applyStyleSheet(widget, ...)`. That's the pattern PR #3144 swept
across the rest of the codebase to make widgets inspector-discoverable.
A two-line conversion would let the Phase 5 inspector find HLTH labels.
Tiny follow-up — not blocking this PR.

## Test plan

- [x] Linux (x86_64) — builds clean against `fix/button-bar` (`cmake
--build --target all`)
- [ ] Live smoke: HLTH appears in the drawer after MTR; right-click bar
→ Favorites picker shows HLTH in Active column
- [ ] Once #3150 merges, retarget base to main, confirm no further diff
change

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Pat Jensen <jensenpat@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
NF0T pushed a commit that referenced this pull request Jun 5, 2026
…ettings key (#3358) (#3409)

## Problem

\`ButtonBar/Layout\`, \`ButtonBar/DrawerOpen\`, and
\`ButtonBar/Favorites\` all contain a \`/\`. \`AppSettings::save()\`
silently drops any key not matching \`^[A-Za-z_][A-Za-z0-9_]*$\` — the
validator was tightened in #985 to prevent invalid XML element names.
The customisable button bar shipped in #3150 *after* that tightening, so
its layout, drawer state, and favourites have **never round-tripped to
disk for any user**.

## Fix

Rename the three keys to \`ButtonBarLayout\`, \`ButtonBarDrawerOpen\`,
\`ButtonBarFavorites\`. No migration needed — nothing was ever written
to the old slash-containing keys, so there is no on-disk state to
convert.

## Testing

Verified locally on macOS (Apple Silicon, dev build off \`main\`):
- Before fix: \`ButtonBar/Layout\` and \`ButtonBar/DrawerOpen\` absent
from \`AetherSDR.settings\` after every save (silently discarded)
- After fix: \`ButtonBarLayout\` and \`ButtonBarDrawerOpen\` present in
\`AetherSDR.settings\` with correct JSON values
- Button bar order and drawer state survive app restart

Fixes #3358
G6PWY-Chris pushed a commit to G6PWY-Chris/AetherSDR that referenced this pull request Jun 22, 2026
…thersdr#3150)

## Summary

Replace the fixed two-row top button bar in `AppletPanel` with a single
favorites row (top 5 buttons + drawer-toggle) and a push-down drawer
that holds the rest. Right-click any bar button opens a non-modal
`PersistentDialog`-derived picker with Active / Hidden columns and a
\"Favorites\" divider rendered inside row 5.

## Behaviour

- **Active column** — every button shown in the bar. Positions 1-5 fill
the favorites row, 6+ pack the drawer in the same order. Drag-reorder
rearranges both halves.
- **Hidden column** — buttons removed from the bar entirely. Moving a
button here forces its applet off (`Applet_<id>=False`).
- **Hardware-conditional defaults** — TUN / AMP / AG are absent from
defaults until their hardware is detected;
`updateHardwareAvailability()` then auto-appends them to Active and
saves. SS keeps its hide-until-detected behaviour. LCK renamed to
**LOCK** (id unchanged for layout-key compat).
- **Theme** — `kButtonBase` and `kBlueActive` in `RxApplet` were the
last holdouts using hardcoded `#1a2a3a / #205070 / #0070c0 / #0090e0`.
Tokenised through `ThemeManager` so the filter-preset buttons and the
new bar buttons share `color.accent.dim` / `color.accent.bright`.
Recalibrated canonical `color.accent.dim` from `#0090e0` → `#0070c0` to
preserve the pre-refactor active-button shade across all ~92 call sites.
- **Persistence** — new key `ButtonBar/Layout =
{\"order\":[...],\"hidden\":[...]}` with one-shot migration from the
interim `ButtonBar/Favorites` key. Drawer open/closed persists
separately.

## Files

- `src/gui/AppletPanel.{h,cpp}` — bar restructure, `BarButton` registry,
`applyBarLayout`, picker wiring.
- `src/gui/FavoritesPickerDialog.{h,cpp}` (new) — non-modal
frameless-aware picker per `docs/style/dialog-patterns.md`; two-list
drag-drop + ↑↓/←→ arrows; custom delegate paints the \"Favorites\"
divider inside row 5's cell so the QListWidget item count stays clean
for drag semantics.
- `src/gui/RxApplet.cpp` — tokenise `kButtonBase` / `kBlueActive`.
- `resources/themes/default-dark.json`,
`docs/theming/canonical-tokens.md` — `color.accent.dim` recalibration +
doc note.
- `CMakeLists.txt` — register new source file.

## Test plan

- [x] Linux (x86_64, Cachy/Wayland) — local build green, visually
verified favourites row, drawer toggle, picker drag-reorder, hide /
un-hide → applet disable, defaults on first launch, hardware-conditional
auto-add.
- [ ] CI build green
- [ ] Windows / macOS / Pi smoke test

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
G6PWY-Chris pushed a commit to G6PWY-Chris/AetherSDR that referenced this pull request Jun 22, 2026
…3150 button-bar refactor (aethersdr#3153)

## Summary

Rebased version of @jensenpat's aethersdr#3133 onto PR aethersdr#3150's customisable
button-bar architecture. Same `HealthApplet.{h,cpp}` source verbatim
from aethersdr#3133 (zero changes to applet code) — this PR is purely the
AppletPanel integration delta that adapts to PR aethersdr#3150's new `BarButton`
registry + favorites/drawer model.

**Depends on aethersdr#3150** — currently targets `fix/button-bar`. Once aethersdr#3150
merges to main, this PR's base will be retargeted to main and the diff
will collapse to just the HLTH integration touchpoints.

## What changed vs aethersdr#3133

Three integration touchpoints adjusted; HealthApplet itself untouched:

1. **`makeEntry()` callsite** routes through `m_drawer` /
`m_drawerLayout` (the new drawer layout from aethersdr#3150), matching every
other drawer-resident applet's pattern. PR aethersdr#3150's `registerBarButton()`
inside `makeEntry()` handles bar-button registration automatically — no
manual `btnRow2` plumbing required.

2. **Default position** moved from index 4 (between TX and PHNE) to
after MTR in the drawer:
   ```cpp
   "RX", "TUN", "AMP", "TX", "PHNE", "P/CW", "EQ", "WAVE", "TXDSP",
   "CAT", "DAX", "TCI", "IQ", "MTR", "HLTH", "AG", "SS"
   ```
With the new 5-button favorites row, putting HLTH at index 4 would push
PHNE out of favorites and surprise shipping users. Operators who want
HLTH up top can drag it via the right-click Favorites picker.

3. **CMakeLists.txt** — `src/gui/HealthApplet.cpp` added to
`GUI_SOURCES`.

## Credit

Commit attribution stays with @jensenpat as the HealthApplet author.
This PR exists only so the HLTH work doesn't have to wait on the
contributor doing a manual rebase after aethersdr#3150 lands — they're welcome to
keep aethersdr#3133 open if they'd prefer to do the rebase themselves.

## Review of HLTH itself

The applet code is well-built — appreciated zero hardcoded colours
(every paint and stylesheet call reads from `ThemeManager`), clean
paint-method separation, visibility-gated 20 Hz timer, three-tier meter
source priority (amp → TGXL tuner → radio TX), and EWMA + recent-window
variance detection.

One small consistency note for a follow-up: HLTH uses
`widget->setStyleSheet(theme.resolve(...))` (~8 sites) instead of
`theme.applyStyleSheet(widget, ...)`. That's the pattern PR aethersdr#3144 swept
across the rest of the codebase to make widgets inspector-discoverable.
A two-line conversion would let the Phase 5 inspector find HLTH labels.
Tiny follow-up — not blocking this PR.

## Test plan

- [x] Linux (x86_64) — builds clean against `fix/button-bar` (`cmake
--build --target all`)
- [ ] Live smoke: HLTH appears in the drawer after MTR; right-click bar
→ Favorites picker shows HLTH in Active column
- [ ] Once aethersdr#3150 merges, retarget base to main, confirm no further diff
change

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Pat Jensen <jensenpat@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
G6PWY-Chris pushed a commit to G6PWY-Chris/AetherSDR that referenced this pull request Jun 22, 2026
…ettings key (aethersdr#3358) (aethersdr#3409)

## Problem

\`ButtonBar/Layout\`, \`ButtonBar/DrawerOpen\`, and
\`ButtonBar/Favorites\` all contain a \`/\`. \`AppSettings::save()\`
silently drops any key not matching \`^[A-Za-z_][A-Za-z0-9_]*$\` — the
validator was tightened in aethersdr#985 to prevent invalid XML element names.
The customisable button bar shipped in aethersdr#3150 *after* that tightening, so
its layout, drawer state, and favourites have **never round-tripped to
disk for any user**.

## Fix

Rename the three keys to \`ButtonBarLayout\`, \`ButtonBarDrawerOpen\`,
\`ButtonBarFavorites\`. No migration needed — nothing was ever written
to the old slash-containing keys, so there is no on-disk state to
convert.

## Testing

Verified locally on macOS (Apple Silicon, dev build off \`main\`):
- Before fix: \`ButtonBar/Layout\` and \`ButtonBar/DrawerOpen\` absent
from \`AetherSDR.settings\` after every save (silently discarded)
- After fix: \`ButtonBarLayout\` and \`ButtonBarDrawerOpen\` present in
\`AetherSDR.settings\` with correct JSON values
- Button bar order and drawer state survive app restart

Fixes aethersdr#3358
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