Skip to content

Commit

Permalink
Merge pull request #96 from atc-net/feature/ThemeManagerHelper
Browse files Browse the repository at this point in the history
Feature/theme manager helper
  • Loading branch information
davidkallesen authored Dec 17, 2023
2 parents 950b543 + 404c891 commit 0d6fceb
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 20 deletions.
39 changes: 39 additions & 0 deletions src/Atc.Wpf.Theming/Enums/AtcAppsBrushKeyType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// ReSharper disable CheckNamespace
namespace Atc.Wpf.Theming;

public enum AtcAppsBrushKeyType
{
Highlight,
AccentBase,
Accent,
Accent2,
Accent3,
Accent4,
ThemeBackground,
ThemeBackground1,
ThemeBackground2,
ThemeBackground3,
ThemeBackground4,
ThemeBackground5,
ThemeBackground6,
ThemeBackground7,
ThemeForeground7,
ThemeForeground6,
ThemeForeground5,
ThemeForeground4,
ThemeForeground3,
ThemeForeground2,
ThemeForeground1,
ThemeForeground,
IdealForeground,
Gray1,
Gray2,
Gray3,
Gray4,
Gray5,
Gray6,
Gray7,
Gray8,
Gray9,
Gray10,
}
39 changes: 39 additions & 0 deletions src/Atc.Wpf.Theming/Enums/AtcAppsColorKeyType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// ReSharper disable CheckNamespace
namespace Atc.Wpf.Theming;

public enum AtcAppsColorKeyType
{
Highlight,
AccentBase,
Accent,
Accent2,
Accent3,
Accent4,
ThemeBackground,
ThemeBackground1,
ThemeBackground2,
ThemeBackground3,
ThemeBackground4,
ThemeBackground5,
ThemeBackground6,
ThemeBackground7,
ThemeForeground7,
ThemeForeground6,
ThemeForeground5,
ThemeForeground4,
ThemeForeground3,
ThemeForeground2,
ThemeForeground1,
ThemeForeground,
IdealForeground,
Gray1,
Gray2,
Gray3,
Gray4,
Gray5,
Gray6,
Gray7,
Gray8,
Gray9,
Gray10,
}
1 change: 1 addition & 0 deletions src/Atc.Wpf.Theming/GlobalUsings.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
global using System.Collections;
global using System.Collections.Concurrent;
global using System.Collections.ObjectModel;
global using System.Collections.Specialized;
global using System.ComponentModel;
Expand Down
80 changes: 80 additions & 0 deletions src/Atc.Wpf.Theming/Helpers/ThemeManagerHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
namespace Atc.Wpf.Theming.Helpers;

public static class ThemeManagerHelper
{
private static readonly ConcurrentDictionary<string, Color> CacheColors = new(StringComparer.Ordinal);
private static readonly ConcurrentDictionary<string, SolidColorBrush> CacheBrushes = new(StringComparer.Ordinal);

public static Color GetColorByResourceKey(
AtcAppsColorKeyType colorKey)
=> GetColorByResourceKey(colorKey.ToString());

public static Color GetColorByResourceKey(
string resourceKey)
{
ArgumentException.ThrowIfNullOrEmpty(resourceKey);

if (!resourceKey.StartsWith("AtcApps.Colors.", StringComparison.OrdinalIgnoreCase))
{
resourceKey = $"AtcApps.Colors.{resourceKey}";
}

var currentTheme = ThemeManager.Current.DetectTheme(Application.Current)!;
var cacheKey = $"{currentTheme.BaseColorScheme}_{resourceKey}";

if (CacheColors.TryGetValue(cacheKey, out var cacheColor))
{
return cacheColor;
}

var color = (Color)currentTheme.Resources[resourceKey]!;
CacheColors.TryAdd(cacheKey, color);
return color;
}

public static SolidColorBrush GetBrushByResourceKey(
AtcAppsBrushKeyType brushKey)
=> GetBrushByResourceKey(brushKey.ToString());

public static SolidColorBrush GetBrushByResourceKey(
string resourceKey)
{
ArgumentException.ThrowIfNullOrEmpty(resourceKey);

if (!resourceKey.StartsWith("AtcApps.Brushes.", StringComparison.OrdinalIgnoreCase))
{
resourceKey = $"AtcApps.Brushes.{resourceKey}";
}

var currentTheme = ThemeManager.Current.DetectTheme(Application.Current)!;
var cacheKey = $"{currentTheme.BaseColorScheme}_{resourceKey}";

if (CacheBrushes.TryGetValue(cacheKey, out var cacheBrush))
{
return cacheBrush;
}

var brush = (SolidColorBrush)currentTheme.Resources[resourceKey]!;
if (brush.CanFreeze)
{
brush.Freeze();
}

CacheBrushes.TryAdd(cacheKey, brush);
return brush;
}

public static Color GetPrimaryAccentColor()
{
var currentTheme = ThemeManager.Current.DetectTheme(Application.Current)!;
return currentTheme.PrimaryAccentColor;
}

public static SolidColorBrush GetPrimaryAccentBrush()
{
var color = GetPrimaryAccentColor();
var brush = new SolidColorBrush(color);
brush.Freeze();
return brush;
}
}
27 changes: 17 additions & 10 deletions src/Atc.Wpf/Helpers/ColorHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,21 @@ public static void InitializeWithSupportedLanguages()
ArgumentException.ThrowIfNullOrEmpty(value);
ArgumentNullException.ThrowIfNull(culture);

EnsureColorNamesForCulture(culture);

var colorKey = GetColorKeyFromCulture(culture);

if (value.StartsWith('#') &&
ColorConverter.ConvertFromString(value) is Color color)
if (value.StartsWith('#'))
{
return ColorNames[colorKey]
.FirstOrDefault(x => string.Equals(x.Key.ToString(GlobalizationConstants.EnglishCultureInfo), color.ToString(GlobalizationConstants.EnglishCultureInfo), StringComparison.OrdinalIgnoreCase))
.Key;
try
{
if (ColorConverter.ConvertFromString(value) is Color color)
{
return color;
}

return null;
}
catch
{
return null;
}
}

if (!value.Contains(' ', StringComparison.Ordinal))
Expand All @@ -52,7 +57,9 @@ public static void InitializeWithSupportedLanguages()
}
}

return ColorNames[colorKey]
EnsureColorNamesForCulture(culture);

return ColorNames[GetColorKeyFromCulture(culture)]
.FirstOrDefault(x => string.Equals(x.Value, value, StringComparison.OrdinalIgnoreCase))
.Key;
}
Expand Down
28 changes: 18 additions & 10 deletions src/Atc.Wpf/Helpers/SolidColorBrushHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ namespace Atc.Wpf.Helpers;
/// <summary>
/// A Helper class for the SolidColorBrush.
/// </summary>
[SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "OK.")]
public static class SolidColorBrushHelper
{
private static readonly ConcurrentDictionary<string, SolidColorBrush> BaseBrushes = new(StringComparer.Ordinal);
Expand All @@ -29,16 +30,21 @@ public static void InitializeWithSupportedLanguages()
ArgumentException.ThrowIfNullOrEmpty(value);
ArgumentNullException.ThrowIfNull(culture);

EnsureBrushNamesForCulture(culture);

var brushKey = GetBrushKeyFromCulture(culture);

if (value.StartsWith('#') &&
ColorConverter.ConvertFromString(value) is Color color)
if (value.StartsWith('#'))
{
return BrushNames[brushKey]
.FirstOrDefault(x => string.Equals(x.Key.Color.ToString(GlobalizationConstants.EnglishCultureInfo), color.ToString(GlobalizationConstants.EnglishCultureInfo), StringComparison.OrdinalIgnoreCase))
.Key;
try
{
if (ColorConverter.ConvertFromString(value) is Color color)
{
return new SolidColorBrush(color);
}

return null;
}
catch
{
return null;
}
}

if (!value.Contains(' ', StringComparison.Ordinal))
Expand All @@ -51,7 +57,9 @@ public static void InitializeWithSupportedLanguages()
}
}

return BrushNames[brushKey]
EnsureBrushNamesForCulture(culture);

return BrushNames[GetBrushKeyFromCulture(culture)]
.FirstOrDefault(x => string.Equals(x.Value, value, StringComparison.OrdinalIgnoreCase))
.Key;
}
Expand Down
2 changes: 2 additions & 0 deletions test/Atc.Wpf.Tests/Helpers/ColorHelperTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public void GetBrushFromString(string input, byte r, byte g, byte b, int lcid)
}

[Theory]
[InlineData("#FF333333", 0x33, 0x33, 0x33)]
[InlineData("#FF666666", 0x66, 0x66, 0x66)]
[InlineData("#FF00CED1", 0, 206, 209)]
[InlineData("#00CED1", 0, 206, 209)]
[InlineData("#FF2F4F4F", 47, 79, 79)]
Expand Down
2 changes: 2 additions & 0 deletions test/Atc.Wpf.Tests/Helpers/SolidColorBrushHelperTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public void GetBrushFromString(string input, byte r, byte g, byte b, int lcid)
}

[Theory]
[InlineData("#FF333333", 0x33, 0x33, 0x33)]
[InlineData("#FF666666", 0x66, 0x66, 0x66)]
[InlineData("#FF00CED1", 0, 206, 209)]
[InlineData("#00CED1", 0, 206, 209)]
[InlineData("#FF2F4F4F", 47, 79, 79)]
Expand Down

0 comments on commit 0d6fceb

Please sign in to comment.