Skip to content

Commit 8486c9b

Browse files
committed
Added inheritance extensibility to AccentAnalzyer
1 parent 012dc60 commit 8486c9b

File tree

2 files changed

+50
-53
lines changed

2 files changed

+50
-53
lines changed

components/AccentAnalyzer/src/AccentAnalyzer.Properties.cs

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,6 @@
55
using System.Windows.Input;
66
using Windows.UI;
77

8-
#if !WINAPPSDK
9-
using Windows.System;
10-
#endif
11-
12-
138
namespace CommunityToolkit.WinUI.Helpers;
149

1510
public partial class AccentAnalyzer
@@ -66,7 +61,7 @@ public partial class AccentAnalyzer
6661
public Color PrimaryAccentColor
6762
{
6863
get => (Color)GetValue(PrimaryAccentColorProperty);
69-
private set => SetValue(PrimaryAccentColorProperty, value);
64+
protected set => SetValue(PrimaryAccentColorProperty, value);
7065
}
7166

7267
/// <summary>
@@ -78,7 +73,7 @@ public Color PrimaryAccentColor
7873
public Color SecondaryAccentColor
7974
{
8075
get => (Color)GetValue(SecondaryAccentColorProperty);
81-
private set => SetValue(SecondaryAccentColorProperty, value);
76+
protected set => SetValue(SecondaryAccentColorProperty, value);
8277
}
8378

8479
/// <summary>
@@ -90,7 +85,7 @@ public Color SecondaryAccentColor
9085
public Color TertiaryAccentColor
9186
{
9287
get => (Color)GetValue(TertiaryAccentColorProperty);
93-
private set => SetValue(TertiaryAccentColorProperty, value);
88+
protected set => SetValue(TertiaryAccentColorProperty, value);
9489
}
9590

9691
/// <summary>
@@ -102,7 +97,7 @@ public Color TertiaryAccentColor
10297
public Color BaseColor
10398
{
10499
get => (Color)GetValue(BaseColorProperty);
105-
private set => SetValue(BaseColorProperty, value);
100+
protected set => SetValue(BaseColorProperty, value);
106101
}
107102

108103
/// <summary>
@@ -114,7 +109,7 @@ public Color BaseColor
114109
public Color DominantColor
115110
{
116111
get => (Color)GetValue(DominantColorProperty);
117-
private set => SetValue(DominantColorProperty, value);
112+
protected set => SetValue(DominantColorProperty, value);
118113
}
119114

120115
/// <summary>
@@ -154,19 +149,4 @@ private void SetSource(UIElement? source)
154149
_source = source;
155150
_ = UpdateAccentAsync();
156151
}
157-
158-
private void UpdateAccentProperties(Color primary, Color secondary, Color tertiary, Color baseColor, Color dominantColor, float colorfulness)
159-
{
160-
DispatcherQueue.GetForCurrentThread().TryEnqueue(() =>
161-
{
162-
PrimaryAccentColor = primary;
163-
SecondaryAccentColor = secondary;
164-
TertiaryAccentColor = tertiary;
165-
DominantColor = dominantColor;
166-
BaseColor = baseColor;
167-
Colorfulness = colorfulness;
168-
169-
AccentsUpdated?.Invoke(this, EventArgs.Empty);
170-
});
171-
}
172152
}

components/AccentAnalyzer/src/AccentAnalyzer.cs

Lines changed: 45 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,15 @@
44

55
#if !WINAPPSDK
66
global using Windows.UI.Xaml.Media.Imaging;
7+
global using Windows.System;
78
#else
89
global using Microsoft.UI;
910
global using Microsoft.UI.Dispatching;
1011
global using Microsoft.UI.Xaml.Media.Imaging;
11-
using System;
12-
1312
#endif
1413

1514
using System.Numerics;
1615
using System.Windows.Input;
17-
using Windows.UI;
18-
1916

2017
namespace CommunityToolkit.WinUI.Helpers;
2118

@@ -79,38 +76,41 @@ private async Task UpdateAccentAsync()
7976
var clusters = KMeansCluster(samples, k, out var sizes);
8077
var colorData = clusters
8178
.Select((color, i) => new AccentColorInfo(color, (float)sizes[i] / samples.Length));
79+
80+
// Evaluate colorfulness
81+
// TODO: Should this be weighted by cluster sizes?
82+
var overallColorfulness = FindColorfulness(clusters);
83+
84+
// Select accent colors
85+
SelectAccentColors(colorData, overallColorfulness);
8286

8387
// Update accent colors property
84-
// Not a dependency property, so don't update form
88+
// Not a dependency property, so no need to update from the UI Thread
8589
#if !WINDOWS_UWP
8690
AccentColors = [..colorData];
8791
#else
8892
AccentColors = colorData.ToList();
8993
#endif
9094

91-
// Select accent colors
92-
Color primary, secondary, tertiary, baseColor;
93-
(primary, secondary, tertiary, baseColor) = SelectAccents(colorData);
94-
95-
// Get dominant color by prominence
96-
#if NET6_0_OR_GREATER
97-
var dominantColor = colorData
98-
.MaxBy(x => x.Prominence).Color;
99-
#else
100-
var dominantColor = colorData
101-
.OrderByDescending((x) => x.Prominence)
102-
.First().Color;
103-
#endif
104-
105-
// Evaluate colorfulness
106-
// TODO: Should this be weighted by cluster sizes?
107-
var overallColorfulness = FindColorfulness(clusters);
108-
109-
// Update using the color data
110-
UpdateAccentProperties(primary, secondary, tertiary, baseColor, dominantColor, overallColorfulness);
95+
// Update the colorfulness and invoke accents updated event,
96+
// both from the UI thread
97+
DispatcherQueue.GetForCurrentThread().TryEnqueue(() =>
98+
{
99+
Colorfulness = overallColorfulness;
100+
AccentsUpdated?.Invoke(this, EventArgs.Empty);
101+
});
111102
}
112103

113-
private (Color primary, Color secondary, Color tertiary, Color baseColor) SelectAccents(IEnumerable<AccentColorInfo> colorData)
104+
/// <summary>
105+
/// This method takes the processed color information and selects the accent colors from it.
106+
/// </summary>
107+
/// <remarks>
108+
/// There is no guarentee that this method will be called from the UI Thread.
109+
/// Dependency properties should be updated using a dispatcher.
110+
/// </remarks>
111+
/// <param name="colorData">The analyzed accent color info from the image.</param>
112+
/// <param name="imageColorfulness">The overall colorfulness of the image.</param>
113+
protected virtual void SelectAccentColors(IEnumerable<AccentColorInfo> colorData, float imageColorfulness)
114114
{
115115
// Select accent colors
116116
var accentColors = colorData
@@ -127,8 +127,25 @@ private async Task UpdateAccentAsync()
127127
// Get base color
128128
var baseColor = accentColors.Last();
129129

130-
// Return palette
131-
return (primary, secondary, tertiary, baseColor);
130+
// Get dominant color by prominence
131+
#if NET6_0_OR_GREATER
132+
var dominantColor = colorData
133+
.MaxBy(x => x.Prominence).Color;
134+
#else
135+
var dominantColor = colorData
136+
.OrderByDescending((x) => x.Prominence)
137+
.First().Color;
138+
#endif
139+
140+
// Batch update the dependency properties in the UI Thread
141+
DispatcherQueue.GetForCurrentThread().TryEnqueue(() =>
142+
{
143+
PrimaryAccentColor = primary;
144+
SecondaryAccentColor = secondary;
145+
TertiaryAccentColor = tertiary;
146+
BaseColor = baseColor;
147+
DominantColor = dominantColor;
148+
});
132149
}
133150

134151
private async Task<Vector3[]> SampleSourcePixelColorsAsync(int sampleCount)

0 commit comments

Comments
 (0)