Skip to content

Commit fef31ff

Browse files
authored
Added ThemeGenerator script for Fluent and generated combined Fluent theme resource dictionaries (#9422)
* Added theme generator script and modified resources to remove duplicate keys * Generated combined themeresource dictionaries * Modified ThemeManager to load combined resources
1 parent dd4d0fb commit fef31ff

File tree

11 files changed

+14224
-59
lines changed

11 files changed

+14224
-59
lines changed

src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ThemeManager.cs

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,18 @@ static ThemeManager()
1818
// TODO : Temprorary way of checking if setting Fluent theme enabled flag. Provide a property for theme switch.
1919
if (Application.Current != null)
2020
{
21+
string dictionarySource;
2122
foreach (ResourceDictionary mergedDictionary in Application.Current.Resources.MergedDictionaries)
2223
{
23-
if (mergedDictionary.Source != null && mergedDictionary.Source.ToString().EndsWith("Fluent.xaml"))
24+
if (mergedDictionary.Source != null)
2425
{
26+
dictionarySource = mergedDictionary.Source.ToString();
27+
28+
if (dictionarySource.EndsWith("Fluent.Light.xaml", StringComparison.OrdinalIgnoreCase)
29+
|| dictionarySource.EndsWith("Fluent.Dark.xaml", StringComparison.OrdinalIgnoreCase)
30+
|| dictionarySource.EndsWith("Fluent.HC.xaml", StringComparison.OrdinalIgnoreCase)
31+
|| dictionarySource.EndsWith("Fluent.xaml", StringComparison.OrdinalIgnoreCase))
32+
2533
_isFluentThemeEnabled = true;
2634
break;
2735
}
@@ -40,8 +48,8 @@ internal static void InitializeFluentTheme()
4048
_currentApplicationTheme = GetSystemTheme();
4149
_currentUseLightMode = IsSystemThemeLight();
4250

43-
var themeColorResourceUri = GetFluentWindowThemeColorResourceUri(_currentApplicationTheme, _currentUseLightMode);
44-
Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = themeColorResourceUri });
51+
var themeColorResourceUri = GetFluentThemeResourceUri(_currentApplicationTheme, _currentUseLightMode);
52+
AddOrUpdateThemeResources(themeColorResourceUri);
4553

4654
_isFluentThemeInitialized = true;
4755
}
@@ -103,7 +111,7 @@ private static void ApplyTheme(
103111
requestedAccentColor != _currentSystemAccentColor)
104112
{
105113

106-
Uri dictionaryUri = GetFluentWindowThemeColorResourceUri(requestedTheme, requestedUseLightMode);
114+
Uri dictionaryUri = GetFluentThemeResourceUri(requestedTheme, requestedUseLightMode);
107115
AddOrUpdateThemeResources(dictionaryUri);
108116

109117
foreach(Window window in windows)
@@ -191,11 +199,11 @@ private static void AddOrUpdateThemeResources(Uri dictionaryUri)
191199

192200
var newDictionary = new ResourceDictionary() { Source = dictionaryUri };
193201

194-
FindFluentThemeAndColorDictionary(out ResourceDictionary fluentDictionary, out ResourceDictionary colorDictionary);
202+
FindFluentThemeResourceDictionary(out ResourceDictionary fluentDictionary);
195203

196-
if (colorDictionary != null)
204+
if (fluentDictionary != null)
197205
{
198-
Application.Current.Resources.MergedDictionaries.Remove(colorDictionary);
206+
Application.Current.Resources.MergedDictionaries.Remove(fluentDictionary);
199207
}
200208

201209
Application.Current.Resources.MergedDictionaries.Add(newDictionary);
@@ -215,43 +223,37 @@ private static void AddOrUpdateThemeResources(Uri dictionaryUri)
215223

216224
#region Private Methods
217225

218-
private static Uri GetFluentWindowThemeColorResourceUri(string systemTheme, bool useLightMode)
226+
private static Uri GetFluentThemeResourceUri(string systemTheme, bool useLightMode)
219227
{
220-
string themeColorFileName = useLightMode ? "light.xaml" : "dark.xaml";
228+
string themeFileName = "Fluent." + (useLightMode ? "Light" : "Dark") + ".xaml";
221229

222230
if(SystemParameters.HighContrast)
223231
{
224-
themeColorFileName = "hc.xaml";
232+
themeFileName = "Fluent.HC.xaml";
225233
}
226234

227-
return new Uri("pack://application:,,,/PresentationFramework.Fluent;component/Resources/Theme/" + themeColorFileName, UriKind.Absolute);
228-
}
235+
return new Uri("pack://application:,,,/PresentationFramework.Fluent;component/Themes/" + themeFileName, UriKind.Absolute);
236+
}
229237

230-
private static void FindFluentThemeAndColorDictionary(out ResourceDictionary fluentThemeDictionary, out ResourceDictionary fluentColorDictionary)
238+
private static void FindFluentThemeResourceDictionary(out ResourceDictionary fluentDictionary)
231239
{
232-
fluentThemeDictionary = null;
233-
fluentColorDictionary = null;
240+
fluentDictionary = null;
234241

235242
if (Application.Current == null) return;
236243

237244
foreach (ResourceDictionary mergedDictionary in Application.Current.Resources.MergedDictionaries)
238245
{
239246
if (mergedDictionary.Source != null)
240247
{
241-
if (mergedDictionary.Source.ToString() == fluentResourceDictionaryUri)
242-
{
243-
fluentThemeDictionary = mergedDictionary;
244-
}
245-
else if (mergedDictionary.Source.ToString().StartsWith(fluentColorResourceUriPart))
248+
if (mergedDictionary.Source.ToString().Contains(fluentThemeResoruceDictionaryUri))
246249
{
247-
fluentColorDictionary = mergedDictionary;
250+
fluentDictionary = mergedDictionary;
251+
break;
248252
}
249253
}
250254
}
251255
}
252256

253-
254-
255257
#endregion
256258

257259
#region Private Members
@@ -260,8 +262,7 @@ private static void FindFluentThemeAndColorDictionary(out ResourceDictionary flu
260262

261263
private static readonly string _regPersonalizeKeyPath = "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize";
262264

263-
private static readonly string fluentResourceDictionaryUri = "pack://application:,,,/PresentationFramework.Fluent;component/Resources/Fluent.xaml";
264-
private static readonly string fluentColorResourceUriPart = "pack://application:,,,/PresentationFramework.Fluent;component/Resources/Theme/";
265+
private static readonly string fluentThemeResoruceDictionaryUri = "pack://application:,,,/PresentationFramework.Fluent;component/Themes/";
265266

266267
private static string _currentApplicationTheme;
267268

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
[CmdletBinding(PositionalBinding=$false)]
2+
Param(
3+
[string][Alias('c')]$themeColor = "Light"
4+
)
5+
6+
$currentDir = Get-Location
7+
$fluentThemeDir = Join-Path $currentDir "..\PresentationFramework.Fluent\"
8+
9+
$outFilePath = Join-Path $fluentThemeDir "Themes\Fluent.$themeColor.xaml"
10+
11+
$styleFilesDir = Join-Path $fluentThemeDir "Styles"
12+
$resouceFilesDir = Join-Path $fluentThemeDir "Resources"
13+
$themeColorFilePath = Join-Path $resouceFilesDir "Theme\$themeColor.xaml"
14+
15+
[xml]$combinedXaml = '<ResourceDictionary
16+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
17+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
18+
xmlns:sys="clr-namespace:System;assembly=mscorlib"
19+
xmlns:controls="clr-namespace:System.Windows.Controls;assembly=PresentationFramework"
20+
xmlns:fluentcontrols="clr-namespace:Fluent.Controls"
21+
xmlns:system="clr-namespace:System;assembly=System.Runtime"
22+
xmlns:ui="clr-namespace:System.Windows.Documents;assembly=PresentationUI"
23+
xmlns:theme="clr-namespace:Microsoft.Windows.Themes"
24+
xmlns:base="clr-namespace:System.Windows;assembly=WindowsBase">
25+
</ResourceDictionary>'
26+
27+
foreach ($file in Get-ChildItem $resouceFilesDir -Filter "*.xaml") {
28+
if($file.BaseName -eq "Fluent") {
29+
continue
30+
}
31+
[xml]$currentXaml = Get-Content $file
32+
33+
$combinedXaml.ResourceDictionary.InnerXml += $currentXaml.ResourceDictionary.InnerXml
34+
}
35+
36+
[xml]$themeColorXaml = Get-Content $themeColorFilePath
37+
$combinedXaml.ResourceDictionary.InnerXml += $themeColorXaml.ResourceDictionary.InnerXml
38+
39+
foreach ($file in Get-ChildItem $styleFilesDir -Filter "*.xaml") {
40+
[xml]$currentXaml = Get-Content $file
41+
42+
$combinedXaml.ResourceDictionary.InnerXml += $currentXaml.ResourceDictionary.InnerXml
43+
}
44+
45+
([xml]$combinedXaml).Save($outFilePath)

src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Fluent/Resources/Variables.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
<Thickness x:Key="ComboBoxEditableTextPadding">10,0,30,0</Thickness>
4747

4848
<system:Double x:Key="ComboBoxMinHeight">24</system:Double>
49-
<Thickness x:Key="ComboBoxPadding">12,1,0,3</Thickness>
49+
<!-- <Thickness x:Key="ComboBoxPadding">12,1,0,3</Thickness> -->
5050
<system:Double x:Key="NavigationViewItemOnLeftMinHeight">32</system:Double>
5151

5252
</ResourceDictionary>

src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Fluent/Styles/Calendar.xaml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@
1010
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
1111
xmlns:system="clr-namespace:System;assembly=System.Runtime">
1212

13-
<system:String x:Key="CaretUpGlyph">&#xEDDB;</system:String>
14-
<system:String x:Key="CaretDownGlyph">&#xEDDC;</system:String>
15-
16-
1713
<!-- HINT: Day button style -->
1814
<Style x:Key="DefaultCalendarDayButtonStyle" TargetType="CalendarDayButton">
1915
<Setter Property="MinWidth" Value="30" />

src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Fluent/Styles/DataGrid.xaml

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
<ResourceDictionary
1919
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
2020
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
21-
xmlns:controls="clr-namespace:Fluent.Controls"
21+
xmlns:fluentcontrols="clr-namespace:Fluent.Controls"
2222
xmlns:system="clr-namespace:System;assembly=System.Runtime">
2323

2424

@@ -37,8 +37,8 @@
3737
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
3838
<Color x:Key="GlyphColor">#FF444444</Color>
3939

40-
<system:String x:Key="CheckBoxCheckedGlyph">&#xE73E;</system:String>
41-
<system:String x:Key="CheckBoxIndeterminateGlyph">&#xE9AE;</system:String>
40+
<system:String x:Key="DataGridCheckBoxCheckedGlyph">&#xE73E;</system:String>
41+
<system:String x:Key="DataGridCheckBoxIndeterminateGlyph">&#xE9AE;</system:String>
4242

4343
<LinearGradientBrush x:Key="MenuPopupBrush" StartPoint="0.5,0" EndPoint="0.5,1">
4444
<GradientStop Offset="0" Color="{DynamicResource ControlLightColor}" />
@@ -636,16 +636,16 @@
636636
</Style.Triggers>
637637
</Style>
638638

639-
<controls:FallbackBrushConverter x:Key="FallbackBrushConverter" />
639+
<fluentcontrols:FallbackBrushConverter x:Key="FallbackBrushConverter" />
640640

641-
<Color x:Key="FallbackColor">#FFFF0000</Color>
641+
<!-- <Color x:Key="FallbackColor">#FFFF0000</Color> -->
642642

643-
<Thickness x:Key="CheckBoxPadding">11,5,11,6</Thickness>
644-
<Thickness x:Key="CheckBoxBorderThemeThickness">1</Thickness>
645-
<Thickness x:Key="CheckBoxContentMargin">8,0,0,0</Thickness>
646-
<system:Double x:Key="CheckBoxIconSize">14</system:Double>
647-
<system:Double x:Key="CheckBoxHeight">22</system:Double>
648-
<system:Double x:Key="CheckBoxWidth">22</system:Double>
643+
<Thickness x:Key="DataGridCheckBoxPadding">11,5,11,6</Thickness>
644+
<Thickness x:Key="DataGridCheckBoxBorderThemeThickness">1</Thickness>
645+
<Thickness x:Key="DataGridCheckBoxContentMargin">8,0,0,0</Thickness>
646+
<system:Double x:Key="DataGridCheckBoxIconSize">14</system:Double>
647+
<system:Double x:Key="DataGridCheckBoxHeight">22</system:Double>
648+
<system:Double x:Key="DataGridCheckBoxWidth">22</system:Double>
649649

650650
<Style x:Key="DataGridCheckBoxElementDefaultStyle" TargetType="{x:Type CheckBox}">
651651
<!-- Universal WPF UI focus -->
@@ -658,8 +658,8 @@
658658
</Setter.Value>
659659
</Setter>
660660
<Setter Property="BorderBrush" Value="{DynamicResource ControlElevationBorderBrush}" />
661-
<Setter Property="BorderThickness" Value="{StaticResource CheckBoxBorderThemeThickness}" />
662-
<Setter Property="Padding" Value="{StaticResource CheckBoxPadding}" />
661+
<Setter Property="BorderThickness" Value="{StaticResource DataGridCheckBoxBorderThemeThickness}" />
662+
<Setter Property="Padding" Value="{StaticResource DataGridCheckBoxPadding}" />
663663
<Setter Property="Border.CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
664664
<Setter Property="HorizontalAlignment" Value="Center" />
665665
<Setter Property="VerticalAlignment" Value="Center" />
@@ -684,8 +684,8 @@
684684
<BulletDecorator.Bullet>
685685
<Border
686686
x:Name="ControlBorderIconPresenter"
687-
Width="{StaticResource CheckBoxHeight}"
688-
Height="{StaticResource CheckBoxWidth}"
687+
Width="{StaticResource DataGridCheckBoxHeight}"
688+
Height="{StaticResource DataGridCheckBoxWidth}"
689689
HorizontalAlignment="Left"
690690
VerticalAlignment="Center"
691691
Background="{TemplateBinding Background}"
@@ -698,10 +698,10 @@
698698
Margin="0"
699699
HorizontalAlignment="Center"
700700
VerticalAlignment="Center"
701-
FontSize="{StaticResource CheckBoxIconSize}"
701+
FontSize="{StaticResource DataGridCheckBoxIconSize}"
702702
FontWeight="Bold"
703703
FontFamily="{DynamicResource SegoeFluentIcons}"
704-
Text="{StaticResource CheckBoxCheckedGlyph}"
704+
Text="{StaticResource DataGridCheckBoxCheckedGlyph}"
705705
Visibility="Collapsed">
706706
<TextBlock.Foreground>
707707
<SolidColorBrush Color="{DynamicResource TextOnAccentFillColorPrimary}" />
@@ -712,7 +712,7 @@
712712
</BulletDecorator.Bullet>
713713
<ContentPresenter
714714
x:Name="ContentPresenter"
715-
Margin="{StaticResource CheckBoxContentMargin}"
715+
Margin="{StaticResource DataGridCheckBoxContentMargin}"
716716
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
717717
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
718718
RecognizesAccessKey="True" />
@@ -725,7 +725,7 @@
725725
<Setter TargetName="ContentPresenter" Property="Margin" Value="0" />
726726
</Trigger>
727727
<Trigger Property="IsChecked" Value="{x:Null}">
728-
<Setter TargetName="ControlIcon" Property="Text" Value="{StaticResource CheckBoxIndeterminateGlyph}" />
728+
<Setter TargetName="ControlIcon" Property="Text" Value="{StaticResource DataGridCheckBoxIndeterminateGlyph}" />
729729
<Setter TargetName="ControlIcon" Property="Visibility" Value="Visible" />
730730
<Setter TargetName="ControlBorderIconPresenter" Property="Background">
731731
<Setter.Value>

src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Fluent/Styles/Expander.xaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@
1212
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
1313
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
1414
xmlns:system="clr-namespace:System;assembly=System.Runtime"
15-
xmlns:controls="clr-namespace:Fluent.Controls"
15+
xmlns:fluentcontrols="clr-namespace:Fluent.Controls"
1616
>
1717

1818
<Thickness x:Key="ExpanderPadding">11,11,11,11</Thickness>
1919
<Thickness x:Key="ExpanderBorderThemeThickness">1</Thickness>
2020
<system:Double x:Key="ExpanderChevronSize">12.0</system:Double>
21-
<controls:AnimationFactorToValueConverter x:Key="AnimationFactorToValueConverter" />
21+
<fluentcontrols:AnimationFactorToValueConverter x:Key="AnimationFactorToValueConverter" />
2222
<system:String x:Key="ExpanderChevronUpGlyph">&#xE70E;</system:String>
2323
<system:String x:Key="ExpanderChevronDownGlyph">&#xE70D;</system:String>
2424
<system:String x:Key="ExpanderChevronLeftGlyph">&#xE76B;</system:String>

src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Fluent/Styles/ScrollBar.xaml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
<sys:Double x:Key="LineButtonHeight">12</sys:Double>
1818
<sys:Double x:Key="LineButtonWidth">12</sys:Double>
1919

20-
<system:String x:Key="CaretUpGlyph">&#xEDDB;</system:String>
21-
<system:String x:Key="CaretDownGlyph">&#xEDDC;</system:String>
22-
<system:String x:Key="CaretLeftGlyph">&#xEDD9;</system:String>
23-
<system:String x:Key="CaretRightGlyph">&#xEDDA;</system:String>
20+
<system:String x:Key="ScrollBarCaretUpGlyph">&#xEDDB;</system:String>
21+
<system:String x:Key="ScrollBarCaretDownGlyph">&#xEDDC;</system:String>
22+
<system:String x:Key="ScrollBarCaretLeftGlyph">&#xEDD9;</system:String>
23+
<system:String x:Key="ScrollBarCaretRightGlyph">&#xEDDA;</system:String>
2424

2525
<Style x:Key="ScrollBarLineButtonStyle" TargetType="{x:Type RepeatButton}">
2626
<Setter Property="Foreground" Value="{DynamicResource ScrollBarButtonArrowForeground}" />
@@ -137,7 +137,7 @@
137137
Grid.Row="0"
138138
HorizontalContentAlignment="Left"
139139
Command="ScrollBar.LineUpCommand"
140-
Content="{StaticResource CaretUpGlyph}"
140+
Content="{StaticResource ScrollBarCaretUpGlyph}"
141141
Opacity="0"
142142
AutomationProperties.Name="Scroll Up"
143143
Style="{StaticResource ScrollBarLineButtonStyle}" />
@@ -167,7 +167,7 @@
167167
Grid.Row="2"
168168
HorizontalContentAlignment="Left"
169169
Command="ScrollBar.LineDownCommand"
170-
Content="{StaticResource CaretDownGlyph}"
170+
Content="{StaticResource ScrollBarCaretDownGlyph}"
171171
Opacity="0"
172172
AutomationProperties.Name="Scroll Down"
173173
Style="{StaticResource ScrollBarLineButtonStyle}" />
@@ -259,7 +259,7 @@
259259
Grid.Column="0"
260260
VerticalAlignment="Center"
261261
Command="ScrollBar.LineLeftCommand"
262-
Content="{StaticResource CaretLeftGlyph}"
262+
Content="{StaticResource ScrollBarCaretLeftGlyph}"
263263
Opacity="0"
264264
AutomationProperties.Name="Scroll Left"
265265
Style="{StaticResource ScrollBarLineButtonStyle}" />
@@ -287,7 +287,7 @@
287287
Grid.Column="2"
288288
VerticalAlignment="Center"
289289
Command="ScrollBar.LineRightCommand"
290-
Content="{StaticResource CaretRightGlyph}"
290+
Content="{StaticResource ScrollBarCaretRightGlyph}"
291291
Opacity="0"
292292
AutomationProperties.Name="Scroll Right"
293293
Style="{StaticResource ScrollBarLineButtonStyle}" />

0 commit comments

Comments
 (0)