Skip to content

Commit ae59e31

Browse files
corvinszKeboo
andauthored
Inherit Windows accent color (#3812)
* -added "Inherit" enum member to PrimaryColor -added "Inherit" enum member to SecondaryColor -added a method to get the Systems accent color * use SetField in the rest of the BundledThemes properties * Update src/MaterialDesignThemes.Wpf/BundledTheme.cs make SetField static Co-authored-by: Kevin B <[email protected]> --------- Co-authored-by: Kevin B <[email protected]>
1 parent 92d9208 commit ae59e31

File tree

3 files changed

+75
-19
lines changed

3 files changed

+75
-19
lines changed

src/MaterialDesignColors.Wpf/MaterialDesignColor.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
public enum PrimaryColor
44
{
5+
Inherit,
56
Red = MaterialDesignColor.Red500,
67
Pink = MaterialDesignColor.Pink500,
78
Purple = MaterialDesignColor.Purple500,
@@ -25,6 +26,7 @@ public enum PrimaryColor
2526

2627
public enum SecondaryColor
2728
{
29+
Inherit,
2830
Red = MaterialDesignColor.RedSecondary,
2931
Pink = MaterialDesignColor.PinkSecondary,
3032
Purple = MaterialDesignColor.PurpleSecondary,

src/MaterialDesignThemes.Wpf/BundledTheme.cs

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using MaterialDesignColors;
1+
using System.Windows.Media;
2+
using MaterialDesignColors;
23

34
namespace MaterialDesignThemes.Wpf;
45

@@ -10,9 +11,8 @@ public BaseTheme? BaseTheme
1011
get => _baseTheme;
1112
set
1213
{
13-
if (_baseTheme != value)
14+
if (SetField(ref _baseTheme, value))
1415
{
15-
_baseTheme = value;
1616
SetTheme();
1717
}
1818
}
@@ -24,9 +24,8 @@ public PrimaryColor? PrimaryColor
2424
get => _primaryColor;
2525
set
2626
{
27-
if (_primaryColor != value)
27+
if (SetField(ref _primaryColor, value))
2828
{
29-
_primaryColor = value;
3029
SetTheme();
3130
}
3231
}
@@ -38,9 +37,8 @@ public SecondaryColor? SecondaryColor
3837
get => _secondaryColor;
3938
set
4039
{
41-
if (_secondaryColor != value)
40+
if (SetField(ref _secondaryColor, value))
4241
{
43-
_secondaryColor = value;
4442
SetTheme();
4543
}
4644
}
@@ -52,27 +50,44 @@ public ColorAdjustment? ColorAdjustment
5250
get => _colorAdjustment;
5351
set
5452
{
55-
if (_colorAdjustment != value)
53+
if (SetField(ref _colorAdjustment, value))
5654
{
57-
_colorAdjustment = value;
5855
SetTheme();
5956
}
6057
}
6158
}
6259

6360
private void SetTheme()
6461
{
65-
if (BaseTheme is BaseTheme baseTheme &&
66-
PrimaryColor is PrimaryColor primaryColor &&
67-
SecondaryColor is SecondaryColor secondaryColor)
62+
if (BaseTheme is not BaseTheme baseTheme ||
63+
PrimaryColor is not PrimaryColor primaryColor ||
64+
SecondaryColor is not SecondaryColor secondaryColor)
6865
{
69-
Theme theme = Theme.Create(baseTheme,
70-
SwatchHelper.Lookup[(MaterialDesignColor)primaryColor],
71-
SwatchHelper.Lookup[(MaterialDesignColor)secondaryColor]);
72-
theme.ColorAdjustment = ColorAdjustment;
73-
74-
ApplyTheme(theme);
66+
return;
7567
}
68+
69+
// only perform the registry lookup if needed, and only once
70+
Lazy<Color?> accentColor = new(Theme.GetSystemAccentColor);
71+
72+
Color colorPrimary = primaryColor == MaterialDesignColors.PrimaryColor.Inherit
73+
? (accentColor.Value ?? SwatchHelper.Lookup.First().Value)
74+
: SwatchHelper.Lookup[(MaterialDesignColor)primaryColor];
75+
76+
Color colorSecondary = secondaryColor == MaterialDesignColors.SecondaryColor.Inherit
77+
? (accentColor.Value ?? SwatchHelper.Lookup.First().Value)
78+
: SwatchHelper.Lookup[(MaterialDesignColor)secondaryColor];
79+
80+
Theme theme = Theme.Create(baseTheme, colorPrimary, colorSecondary);
81+
theme.ColorAdjustment = ColorAdjustment;
82+
83+
ApplyTheme(theme);
84+
}
85+
86+
protected static bool SetField<T>(ref T field, T value)
87+
{
88+
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
89+
field = value;
90+
return true;
7691
}
7792

7893
protected virtual void ApplyTheme(Theme theme) =>

src/MaterialDesignThemes.Wpf/Theme.cs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Windows.Media;
1+
using System.Diagnostics;
2+
using System.Windows.Media;
23
using MaterialDesignColors;
34
using Microsoft.Win32;
45

@@ -31,6 +32,44 @@ public partial class Theme
3132
}
3233
}
3334

35+
/// <summary>
36+
/// Get the current Windows accent color.
37+
/// Based on ControlzEx
38+
/// https://github.com/ControlzEx/ControlzEx/blob/48230bb023c588e1b7eb86ea83f7ddf7d25be735/src/ControlzEx/Theming/WindowsThemeHelper.cs#L53
39+
/// </summary>
40+
/// <returns></returns>
41+
public static Color? GetSystemAccentColor()
42+
{
43+
Color? accentColor = null;
44+
45+
try
46+
{
47+
var registryValue = Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM", "ColorizationColor", null);
48+
49+
if (registryValue is null)
50+
{
51+
return null;
52+
}
53+
54+
// We get negative values out of the registry, so we have to cast to int from object first.
55+
// Casting from int to uint works afterwards and converts the number correctly.
56+
var pp = (uint)(int)registryValue;
57+
if (pp > 0)
58+
{
59+
var bytes = BitConverter.GetBytes(pp);
60+
accentColor = Color.FromArgb(bytes[3], bytes[2], bytes[1], bytes[0]);
61+
}
62+
63+
return accentColor;
64+
}
65+
catch (Exception exception)
66+
{
67+
Trace.TraceError(exception.ToString());
68+
}
69+
70+
return accentColor;
71+
}
72+
3473
public static Theme Create(BaseTheme baseTheme, Color primary, Color secondary)
3574
{
3675
Theme theme = new();

0 commit comments

Comments
 (0)