Skip to content

Plugin Theme Development

NyxionSoftware edited this page Aug 5, 2026 · 1 revision

Plugin Theme Development

A theme plugin applies a WPF ResourceDictionary that overrides application color keys. The existing shared brushes and controls consume those colors dynamically.

Base default palette

Color key Default Purpose
TransparentColor #00000000 Transparent surfaces
ControlForegroundColor #FFFFFFFF General control foreground
WindowBackgroundColor #101217 Main background
SidebarBackgroundColor #15181F Toolbar and sidebar
CardBackgroundColor #191D25 Cards
CardHoverColor #202530 Card/list hover
InputBackgroundColor #11141A Inputs and inset surfaces
BorderColor #2A303C Standard borders
AccentColor #7C5CFC Primary accent
AccentHoverColor #8E72FF Accent hover
AccentPressedColor #6748E5 Accent pressed
AccentMutedColor #2C254E Muted accent surface
SuccessColor #35C98A Online/success
WarningColor #F4B740 Transitional/warning
InfoColor #4C8DFF Information
ErrorColor #F05D6C Offline/error/destructive
PrimaryTextColor #F4F6FA Primary text
SecondaryTextColor #A8AFBC Supporting text
MutedTextColor #707887 Hints and inactive text
DataGridAlternatingRowColor #161A22 Alternating rows
DataGridHeaderBackgroundColor #1B2029 Grid header
DataGridRowHoverColor #202631 Grid hover

Button/control colors also available:

  • SecondaryButtonBackgroundColor, SecondaryButtonHoverColor, SecondaryButtonPressedColor
  • SuccessButtonBackgroundColor, SuccessButtonBorderColor, SuccessButtonHoverColor, SuccessButtonHoverBorderColor, SuccessButtonPressedColor, SuccessButtonFocusBorderColor
  • DangerButtonBackgroundColor, DangerButtonBorderColor, DangerButtonHoverColor, DangerButtonHoverBorderColor, DangerButtonPressedColor, DangerButtonFocusBorderColor
  • TextBoxHoverBorderColor

Override every key for predictable results. Missing keys fall back to whatever dictionary was previously active and can produce a mixed theme.

Brush keys consumed by controls

Each color has a corresponding brush such as WindowBackgroundBrush, CardBackgroundBrush, AccentBrush, SuccessBrush, PrimaryTextBrush, and DataGridAlternatingRowBrush. Theme dictionaries should normally override colors; shared brushes then update automatically.

Theme dictionary example

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Color x:Key="WindowBackgroundColor">#F5F7FA</Color>
  <Color x:Key="SidebarBackgroundColor">#FFFFFF</Color>
  <Color x:Key="CardBackgroundColor">#FFFFFF</Color>
  <Color x:Key="CardHoverColor">#EAF1FB</Color>
  <Color x:Key="InputBackgroundColor">#F1F4F8</Color>
  <Color x:Key="BorderColor">#D7DEE8</Color>
  <Color x:Key="AccentColor">#2167D5</Color>
  <!-- Override the remaining keys as well. -->
</ResourceDictionary>

Embed the XAML as a WPF Page, then apply it:

Uri uri = new("/MyThemePlugin;component/Themes/LightBlue.xaml", UriKind.Relative);
await context.ThemeManager.ApplyResourceDictionaryAsync(Info.PluginIdentifier, uri, cancellationToken);
await context.ThemeManager.SetWindowChromeModeAsync(Info.PluginIdentifier, PluginWindowChromeMode.Light, cancellationToken);

Restore the application theme during disablement:

await context.ThemeManager.RemoveResourceDictionaryAsync(Info.PluginIdentifier, cancellationToken);

The host snapshots and restores replaced resources, but a theme should still remove its dictionary explicitly.

Theme testing checklist

  • Main background, toolbar, sidebar, and every card.
  • Hover, pressed, selected, disabled, and keyboard-focus states.
  • Text boxes, combo boxes, checkboxes, and toggles.
  • DataGrid headers, normal rows, alternating rows, selection, and hover.
  • Notifications and status badges.
  • Manage Receivers, Manage Plugins, Settings, and plugin dialogs.
  • Light/dark title bar and window caption buttons.
  • Plugin-injected UI using DynamicResource.
  • Switching Theme A to Default without restarting.
  • Disabling/re-enabling and deleting the theme plugin.

Clone this wiki locally