winui: model artwork, richer island/nav, custom tray menu, new icon - #7
Merged
Conversation
added 5 commits
August 9, 2026 14:45
…icon A pass over the WinUI client's visuals + tray, driven by dogfooding. Device artwork (Services/DeviceArt.cs — model number → asset family): - DeviceHeader shows the model's render instead of the generic airpods.png. - BatteryCard shows per-component bud/case artwork above each gauge. - The connect island uses the model render, with the last-seen model cached (AppSettings.LastModel) so it's right before the 0x1D metadata arrives. Noise control: the vertical RadioButtons become a segmented row of icon buttons (Off / NC / Transparency / Adaptive) with the active mode named below. Island: the message mode shows the mode icon for a noise-control change (not the device), and the whole popup now follows the app theme. Nav pane: the device item gains a model icon + a compact battery %, shown in the expanded pane (handy once multiple devices are listed). Tray: renamed TrayIcon -> TrayController; the WinUI MenuFlyout (which clipped to ~1 char in H.NotifyIcon's SecondWindow host) and a native Win32 menu (no per-item icons, no theme) are both unusable here, so the context menu is now a custom themed window (Popup/TrayMenuWindow + TrayMenuView) with an icon per row, the model image, battery, ANC checkmarks, mute/open/quit — dismissed on focus loss. The icon badge is a large battery number; the tooltip gains the ANC mode. Fixes: the "Connect?" prompt no longer shows while already connected; the one-column device layout drops the phantom right gap (collapsed Col1 kept its ColumnSpacing). New app/tray icon (transparent background). Settings: a UI-language selector (persisted, applied at startup). NOTE: runtime language switching is limited on the unpackaged build — PrimaryLanguageOverride does not re-resolve x:Uid there; a code-based localization pass is the follow-up.
The raster ANC art (anc_*.png) is fixed-colour — white washed out on the light acrylic, black vanished on dark. Show a Segoe Fluent FontIcon (follows the theme foreground) instead, matching the tray menu's mode glyphs.
The anc_*.png icons had inconsistent padding/weight so they framed unevenly next to the (glyph) Off button. Use uniform Segoe Fluent FontIcons — consistent framing, theme-following (incl. on the accent-selected button), matching the island + tray mode glyphs.
x:Uid + PrimaryLanguageOverride don't re-resolve on the unpackaged build, so the
language selector needed a full restart (and didn't even work). Replace it with an
Angular-style translate service:
- Services/Loc.cs — a singleton INotifyPropertyChanged that parses the embedded
Strings/<culture>/Resources.resw into a culture -> key -> value map. Indexer
Loc["Key"] returns the current-culture string; SetCulture() raises the indexer
PropertyChanged so every binding re-fetches → the whole UI switches LIVE.
- All UI text now binds to {Binding [Key_Prop], Source={StaticResource Loc}}
instead of x:Uid (keys are the resw names with '.' → '_' for the indexer path).
- Localize.Get (code-picked strings) delegates to Loc.
- The language selector calls Loc.SetCulture — no more restart hint.
- The .resw are embedded (LogicalName loc.<culture>) alongside the existing PRI
resources, so translations aren't duplicated.
Works on the unpackaged build (no MRT / x:Uid / PrimaryLanguageOverride).
Owner
Author
Update: live language switching now worksThe earlier "known limitation" (language override doesn't take effect on the unpackaged build) is resolved. Replaced x:Uid / PrimaryLanguageOverride with a runtime Loc service (Angular-style): all text binds to Extra test:
|
added 7 commits
August 9, 2026 21:41
…otify
WinUI (unlike WPF) doesn't refresh {Binding [key]} on an "Item[]" notification,
so switching language updated nothing outside the active page. Raise the empty-
string "all properties changed" notification so every binding re-fetches. Also
make the embedded-resw lookup scan the manifest names (not a hard-coded
LogicalName) so a prefixed/mangled name can't silently yield an empty map.
Confirmed: the whole app switches language live now.
The built-in NavigationView Settings item is OS-localized; re-label it from Loc (live) so it follows the in-app language. Update the language hint to say it applies immediately (no restart).
App.xaml instantiated a SECOND Loc via <services:Loc x:Key=Loc>, distinct from the static Loc.Instance used by code — so SetCulture changed one while the other stayed, leaving code strings in one language and XAML bindings in another. Inject the single Loc.Instance into Application.Resources instead.
A daemon overlay (e.g. "Connected · battery") is a one-shot string resolved when it arrives, so one shown before a language switch lingered in the old language. Close it on a culture change; the next overlay renders in the new language.
…sources write Mutating Application.Resources in the App ctor threw a COMException. Revert to declaring the one <services:Loc x:Key=Loc/> in App.xaml (which works), but drop the static new() so it's the ONLY instance; its ctor publishes Loc.Instance for code. No second instance → no culture split, and no runtime resource mutation.
…itch - ToggleSwitch On/Off content was OS-localized (system language); bind OnContent/ OffContent to Loc (Toggle_On/Toggle_Off keys, 4 languages) so it follows the app. - Code-picked strings (header status, mic state, ANC mode name) are only set when a snapshot arrives, so they lingered in the old language after a switch. Re-render the last snapshot on a culture change.
The BLE proximity watcher prompted "Connect?" and waited for a click. The buds being audio-connected in Windows doesn't open our AAP L2CAP session (separate channels), so the app sat on "Disconnected" until a manual Connect. Instead auto-connect on the proximity edge-trigger: set connect_requested (run_receiver opens the session) and nudge the OS audio up. Still edge-triggered per visit, so no reconnect spam.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A dogfooding pass over the WinUI client's visuals and the system tray.
What changed
Device artwork (
Services/DeviceArt.cs— model number → asset family)airpods.png.(
AppSettings.LastModel) so it's correct before the 0x1D metadata arrives.Noise control — vertical
RadioButtons→ segmented row of icon buttons(Off / NC / Transparency / Adaptive) with the active mode named below.
Island — message mode shows the noise-control mode icon (not the device) for
an ANC change; the whole popup now follows the app theme.
Nav pane — device item gains a model icon + a compact battery %, shown in the
expanded pane (for when multiple devices are listed).
Tray — renamed
TrayIcon→TrayController. The context menu is now a customthemed window (
Popup/TrayMenuWindow+TrayMenuView) — the WinUI MenuFlyoutclipped to ~1 char in H.NotifyIcon's SecondWindow host, and a native Win32 menu
can't carry per-item icons or the app theme. Icon per row, model image, battery,
ANC checkmarks, mute/open/quit; dismissed on focus loss. Icon badge is now a large
battery number; tooltip gains the ANC mode.
Fixes — the "Connect?" prompt no longer shows while already connected; the
one-column device layout drops the phantom right gap (collapsed
Col1kept itsColumnSpacing).New app/tray icon (transparent background).
Settings — a UI-language selector (persisted, applied at startup).
What to test
Device page
Nav pane
Island popup
Tray
Connect prompt
App icon
Settings
PrimaryLanguageOverridedoesn't re-resolvex:Uid) — a code-based localization pass is the follow-up.Notes