Skip to content

Commit 9536a90

Browse files
committed
Added inheritance extensibility to AccentAnalzyer
1 parent 012dc60 commit 9536a90

File tree

2 files changed

+49
-48
lines changed

2 files changed

+49
-48
lines changed

components/AccentAnalyzer/src/AccentAnalyzer.Properties.cs

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
using Windows.System;
1010
#endif
1111

12-
1312
namespace CommunityToolkit.WinUI.Helpers;
1413

1514
public partial class AccentAnalyzer
@@ -66,7 +65,7 @@ public partial class AccentAnalyzer
6665
public Color PrimaryAccentColor
6766
{
6867
get => (Color)GetValue(PrimaryAccentColorProperty);
69-
private set => SetValue(PrimaryAccentColorProperty, value);
68+
protected set => SetValue(PrimaryAccentColorProperty, value);
7069
}
7170

7271
/// <summary>
@@ -78,7 +77,7 @@ public Color PrimaryAccentColor
7877
public Color SecondaryAccentColor
7978
{
8079
get => (Color)GetValue(SecondaryAccentColorProperty);
81-
private set => SetValue(SecondaryAccentColorProperty, value);
80+
protected set => SetValue(SecondaryAccentColorProperty, value);
8281
}
8382

8483
/// <summary>
@@ -90,7 +89,7 @@ public Color SecondaryAccentColor
9089
public Color TertiaryAccentColor
9190
{
9291
get => (Color)GetValue(TertiaryAccentColorProperty);
93-
private set => SetValue(TertiaryAccentColorProperty, value);
92+
protected set => SetValue(TertiaryAccentColorProperty, value);
9493
}
9594

9695
/// <summary>
@@ -102,7 +101,7 @@ public Color TertiaryAccentColor
102101
public Color BaseColor
103102
{
104103
get => (Color)GetValue(BaseColorProperty);
105-
private set => SetValue(BaseColorProperty, value);
104+
protected set => SetValue(BaseColorProperty, value);
106105
}
107106

108107
/// <summary>
@@ -114,7 +113,7 @@ public Color BaseColor
114113
public Color DominantColor
115114
{
116115
get => (Color)GetValue(DominantColorProperty);
117-
private set => SetValue(DominantColorProperty, value);
116+
protected set => SetValue(DominantColorProperty, value);
118117
}
119118

120119
/// <summary>
@@ -154,19 +153,4 @@ private void SetSource(UIElement? source)
154153
_source = source;
155154
_ = UpdateAccentAsync();
156155
}
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-
}
172156
}

components/AccentAnalyzer/src/AccentAnalyzer.cs

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,10 @@
88
global using Microsoft.UI;
99
global using Microsoft.UI.Dispatching;
1010
global using Microsoft.UI.Xaml.Media.Imaging;
11-
using System;
12-
1311
#endif
1412

1513
using System.Numerics;
1614
using System.Windows.Input;
17-
using Windows.UI;
1815

1916

2017
namespace CommunityToolkit.WinUI.Helpers;
@@ -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)