Skip to content

feat: Dynamic Accent Theme + Background Blur/Gradient Support - #914

Open
soyelmismo wants to merge 41 commits into
supersonic-app:mainfrom
soyelmismo:dynamic-accent
Open

feat: Dynamic Accent Theme + Background Blur/Gradient Support#914
soyelmismo wants to merge 41 commits into
supersonic-app:mainfrom
soyelmismo:dynamic-accent

Conversation

@soyelmismo

@soyelmismo soyelmismo commented Apr 18, 2026

Copy link
Copy Markdown

This PR introduces a comprehensive Dynamic Theme System that extracts vibrant accent colors from album cover art and applies them throughout the UI, with optional blur/gradient backgrounds for immersive browsing.

imagen

✨ Major Features

1. Dynamic Theme Engine

  • Automatic color extraction: Extracts dominant vibrant colors from current track's cover art
  • Smart palette generation: Creates complete color palette (accent, background, surface, text) from a single accent color
  • Live preview: Real-time palette preview when adjusting settings
simplescreenrecorder-2026-04-18_14.50.09.mp4

2. Background Blur/Gradient Support

  • Three modes: disabled, gradient, blur
  • New pages supported: Album, Artist, Playlist (NowPlaying page keeps the original option)
  • *Background generation runs in goroutines with context cancellation
imagen

3. Theme Configuration UI

New appearance settings in Settings → Appearance:

  • Theme selector: "Default" (traditional .toml files) or "Dynamic" (accent-based)
  • Hue slider: Rainbow color selector (0-360°) with visual palette preview
  • Saturation slider
  • Contrast slider
  • Extract from cover button: Instantly extract accent from currently playing track
imagen

4. Technical Implementation

  • Color extraction algorithm: Samples pixels with perceptual weighting for vibrancy
  • Color normalization: Ensures extracted colors remain visible in current base mode (dark/light/black)
  • Caching system: Palettes and backgrounds are cached to avoid regeneration
  • Thread-safe: Background processing uses mutexes and context cancellation

Core Theme System:

  • ui/theme/theme.go: Add dynamic theme constants and theme file support
  • ui/theme/palette.go: Palette generation from accent color with configurable saturation/contrast
  • ui/theme/extractor.go: Vibrant color extraction from images
  • ui/theme/colornormalizer.go: Color visibility normalization for dark/light/black modes
  • ui/theme/colorutil.go: Color space conversion utilities (HSL, perceptual hue)

Background System:

  • ui/browsing/background.go: BackgroundManager with blur/gradient generation
  • ui/browsing/backgroundwrapper.go: Container wrapper for background integration

Page Integrations:

  • ui/browsing/albumpage.go: Background support + transparent headers
  • ui/browsing/artistpage.go: Background support
  • ui/browsing/playlistpage.go: Background support + transparent headers
  • ui/browsing/nowplayingpage.go: Simplified layout with background support
  • ui/browsing/router.go: Pass background mode to the new pages

Settings & Configuration:

  • backend/config.go: Add ThemeConfig, fields (AccentColor, Saturation, Contrast, BaseMode)
  • ui/dialogs/settingsdialog.go: Appearance tab with the new dynamic controls
  • ui/controller/controller.go: Accent extraction integration and callbacks
  • ui/mainwindow.go: Theme update callbacks and page reloading

i18n Support (16 languages):

  • res/translations/*.json: Add "Accent Color", "Saturation", "Contrast", "Extract from playing track"

⚙️ Configuration

[Theme]
  ThemeFile = "dynamic"  # or "Default/Installed .toml file"
  Appearance = "Dark"  # Dark, Light, or Auto
  AccentColor = "#286ef4"  # Default blue
  Saturation = 1.5
  Contrast = 0.0

soyelmismo and others added 30 commits April 13, 2026 12:26
- Extend ThemeConfig with accent, saturation, contrast and base mode fields
- Add appearance tab UI controls for custom accent theme engine
- Update settings dialog controller with accent update & close callbacks
- Implement live preview callbacks for realtime theme adjustments
- Maintain backward compatibility with existing theme file system
- Add theme config fields for auto-extraction flag and transition duration
- Implement controller logic to pull dominant color from active track cover
- Add appearance tab UI controls including manual extraction button
- Auto extraction remains disabled initially, only manual trigger available
…anslations

* Reorganize ThemeConfig struct with improved clear comment documentation
* Remove legacy unused auto accent cover extraction configuration fields
* Add complete Spanish translation strings for all theme setting controls
* Begin updating settings dialog UI for revised accent color system
…theme mode

- Remove unused `UseCustomAccent` flag from theme configuration struct
- Add Dynamic as official first-class selectable theme option
- Update cover art accent extraction to activate only for dynamic theme
- Correct accent color translation string in Spanish locale
- Clean up and improve theme config documentation comments
…lack mode

Simplify valid theme base modes to only dark/light. Replace separate grey mode with
hybrid interpolated behaviour for black mode: automatically adjusts palette
smoothly between grey-style low contrast and AMOLED pure black high contrast
using the existing contrast slider setting. Remove obsolete theme default
initialisation code and redundant config sync logic in settings/main windows.
…rounds

Cache processed cover art assets to improve UI responsiveness during track transitions:
- Add state fields for current cover image, cached blurred background, dominant color
- Skip expensive reprocessing when the loaded cover image has not changed
- Offload heavy image/color processing to background goroutines
- Extract dedicated background apply helper methods for readability
- Implement clean transition behaviour when switching background modes
…w in settings

Replaced the isolated accent color preview rectangle with a complete generated theme palette preview. All palette swatches update live when adjusting hue, saturation, or contrast sliders.

This change includes proper themed styling, background container, and graceful error fallback handling for palette generation, enabling users to view full theme impact while tuning appearance settings instead of only seeing the accent color.
…readability

Add ensureSurfaceContrast helper to guarantee 30% luminance difference
between UI surface background and accent colors. Automatically adjust
accent shade (darken on light mode, brighten on dark mode) when contrast
is too low, preventing unreadable hyperlinks with custom accent colors.
… artist pages

- Add BackgroundMode config property supporting disabled/gradient/blur modes
- Introduce shared BackgroundManager for consistent page background rendering
- Refactor AlbumPage layout to use stack layout with background under content
- Align background transition behaviour with existing now playing page patterns
- Prepare artist page structure for upcoming background implementation
- Add proper render lifecycle handling for background initialization
Add BackgroundMode setting to global AppConfig and PlaylistPageConfig
to support configurable page background styles (disabled/gradient/blur).
Refactor AlbumPage, NowPlayingPage to use new BackgroundWrapper component,
pass global background mode value through all page initializer methods.
Adjust background rendering to respect active dark/light system theme:
- Adjust image brightness before applying blur for wallpaper backgrounds
- Scale dominant color brightness appropriately for gradient backgrounds
- Fix processing order: flip image before blur/brightness operations
Ensures proper contrast and readability regardless of selected user theme.
…controls

Fixes incorrect initial slider positioning on the settings appearance tab.
Setting slider step configuration before applying the saved config value prevents unwanted value snapping/rounding when sliders first load. This ensures correct display of the user's existing theme settings.
* Cancel in-flight processing before starting new background render work
* Remove debug logging statements from BackgroundManager
* Prevent stale orphaned goroutines from running after new image is requested
* Gracefully abort pending blur / gradient calculation jobs when superseded
- Lower background blur radius from 50 to 15 improves rendering performance
- Remove unused old rgbToHslFloat implementation and dead helper functions
- Migrate all color conversion calls to use standard shared utility functions
- Update palette generation call signatures to match refactored helpers
- Clean up unused imports from theme extractor module
…ed accent colors

* Replace hardcoded brightness offsets with dynamic luminance matching from theme palette
* Blend album cover extracted colors with theme accent for consistent UI styling
* Add normalization step for cover-extracted accents to ensure visibility across modes
* Tune default adjustment factors for improved contrast in both light/dark themes
* Retain graceful fallback behaviour for standard non-dynamic themes
* Refactor adjustment logic with proper theme instance handling
…e coherence

- Cache raw extracted dominant color, re-apply theme adjustment on every use
  Fixes incorrect background colors after theme switching while colors were cached
- Replace simple brightness scaling with controlled HSL luminance locking
- Enforce saturation bounds to avoid garish or washed-out backgrounds
- Use centralized dark mode detection helper for consistency across codebase
- Guarantee safe text contrast with fixed luminance values per theme variant
…odes

Update theme slider bounds for improved usability:
- Light mode: raised saturation min/max, increased contrast floor
- Black mode: increased saturation range, lowered contrast minimum
- Default mode: set contrast minimum to 0 for full adjustment range
…selected

Previously auto appearance mode always defaulted to the black theme
regardless of actual system theme preference. Now properly checks active
OS dark/light state and applies matching base theme mode on selection.
…d state

* Resize backgrounds to 128x72 before blurring for large performance gains
* Add mutex lock to prevent race conditions on cached background values
* Fix gradient color comparison by comparing RGBA values directly
* Remove leftover debug logging from Tracklist header transparency method
… accent extraction

* Add mutex locking around all BackgroundManager cached value access to eliminate data races
* Pass current theme base mode to color extractor for correct grayscale album cover accent generation
* Remove unused `applySaturationToHSL` utility function
* Restructure controller accent extraction flow to avoid duplicate theme instance lookup
- Remove disabled unused auto cover accent extraction functionality
- Delete unused DeepRefreshFunc and dead deep refresh implementation
- Replace hardcoded "dynamic" theme string checks with proper myTheme.ThemeFileDynamic constant
- Remove obsolete controller init calls no longer required for removed features
- Clean up dead commented out code from controller struct
… performance

- Remove unused target size fields and related SetTargetSize methods
- Fix gradient end color check to validate all RGBA channel values
- Replace accent slider throttling with proper debounce for smoother performance
… method

Eliminate duplicated `useBlur` mode check logic that was repeated at every call site across album and artist pages. This flag is now resolved internally within the BackgroundManager directly from the provided background mode string, simplifying all invocations and removing unnecessary code duplication.
* Add `getTracklistFromCtr` helper to safely retrieve tracklist from container
* Remove duplicated nil/type checking logic across all ArtistPage methods
* Eliminate unsafe direct container access that could cause runtime panics
* Introduce generation counter in BackgroundManager to fix goroutine race conditions
* Update mutex protection documentation for background cache values
…lper function

- Replace all calls to unexported blendColors with public BlendColors API
- Delete duplicate unused private color blending implementation
- Remove unused AddHeaderBackgroundTransparent utility method
- Standardize function usage across theme palette and blend logic
Add new translation keys for page background settings: Blur, Disabled, Gradient, Page background mode across de/en/es locales
Translate previously untranslated core UI strings for the Romanian language
soyelmismo added 8 commits April 18, 2026 06:07
…state

* Refactor extractAndTransitionAccentFromCover to return success flag + hex color
* Update OnExtractFromCover callback signature to return extracted color value
* Sync settings dialog hue slider and palette preview after color extraction
* Persist extracted accent color correctly to application config
* Fixes settings UI not updating immediately when extracting from playing track cover
…tency

Change scrollbar thumb color from TextPrimary to Hyperlink, add explicit
ScrollBarBackground color using SurfaceHover. This maintains proper contrast
behaviour that works correctly across both light and dark theme modes.
- Increase saturation slider maximum to 1.5 for vibrant oversaturated colors
- Remove redundant hyperlink contrast checks handled upstream in accent logic
- Add luminosity correction guard that respects high contrast user selections
- Fix waveform seekbar refresh race by dispatching safely to Fyne UI thread
…tion panics

- Add palette cache invalidation and forced window content refresh on theme change
- Use nil theme toggle to trigger full Fyne theme cache invalidation
- Add nil theme guard in ThemedRectangle to avoid panics during theme transitions
… apply

- Moved refresh implementation from NowPlayingPage to backgroundwrapper
- Remove panicked nil theme reset when applying updated theme
…nce property

Remove obsolete duplicated BaseMode field from ThemeConfig:
  * Migrate all usages in palette generation and color extraction logic
  * Delete redundant manual sync code from appearance settings dialog
  * Eliminates duplicate theme mode state that risked desynchronization
  * Establish single source of truth for theme display mode across the app
@soyelmismo

Copy link
Copy Markdown
Author

i have an edge branch with all my PRs if u want to test it quickly (0 conflicts when i merged everything into it)

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