Skip to content

Commit

Permalink
feat(styles): Populate ThemeDictionaries defined in XAML
Browse files Browse the repository at this point in the history
  • Loading branch information
davidjohnoliver committed Jun 3, 2020
1 parent 332c825 commit 18240f7
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,7 @@ private void InitializeAndBuildResourceDictionary(IIndentedStringBuilder writer,
writer.AppendLineInvariant("new ResourceDictionary {{");
BuildResourceDictionary(writer, FindImplicitContentMember(topLevelControl), isInInitializer: true);
BuildMergedDictionaries(writer, topLevelControl.Members.FirstOrDefault(m => m.Member.Name == "MergedDictionaries"), isInInitializer: true);
BuildThemeDictionaries(writer, topLevelControl.Members.FirstOrDefault(m => m.Member.Name == "ThemeDictionaries"), isInInitializer: true);
writer.AppendLineInvariant("}}");
}

Expand Down Expand Up @@ -2054,6 +2055,12 @@ private void RegisterAndBuildResources(IIndentedStringBuilder writer, XamlObject
.Where(m => m.Member.Name == "MergedDictionaries")
.FirstOrDefault()
: null;
var themeDictionaries = isExplicitResDictionary ?
resourcesMember.Objects
.First().Members
.Where(m => m.Member.Name == "ThemeDictionaries")
.FirstOrDefault()
: null;

if (resourcesRoot != null || mergedDictionaries != null)
{
Expand All @@ -2063,8 +2070,8 @@ private void RegisterAndBuildResources(IIndentedStringBuilder writer, XamlObject
}

BuildResourceDictionary(writer, resourcesRoot, isInInitializer);

BuildMergedDictionaries(writer, mergedDictionaries, isInInitializer);
BuildThemeDictionaries(writer, themeDictionaries, isInInitializer);

if (isInInitializer)
{
Expand Down Expand Up @@ -2139,6 +2146,23 @@ private void BuildResourceDictionary(IIndentedStringBuilder writer, XamlMemberDe
/// Populate MergedDictionaries property of a ResourceDictionary.
/// </summary>
private void BuildMergedDictionaries(IIndentedStringBuilder writer, XamlMemberDefinition mergedDictionaries, bool isInInitializer)
{
var propertyName = "MergedDictionaries";
BuildDictionaryCollection(writer, mergedDictionaries, isInInitializer, propertyName, isDict: false);
}

/// <summary>
/// Populate ThemeDictionaries property of a ResourceDictionary.
/// </summary>
private void BuildThemeDictionaries(IIndentedStringBuilder writer, XamlMemberDefinition themeDictionaries, bool isInInitializer)
{
BuildDictionaryCollection(writer, themeDictionaries, isInInitializer, "ThemeDictionaries", isDict: true);
}

/// <summary>
/// Build a collection of ResourceDictionaries.
/// </summary>
private void BuildDictionaryCollection(IIndentedStringBuilder writer, XamlMemberDefinition mergedDictionaries, bool isInInitializer, string propertyName, bool isDict)
{
if (mergedDictionaries == null)
{
Expand All @@ -2147,11 +2171,11 @@ private void BuildMergedDictionaries(IIndentedStringBuilder writer, XamlMemberDe

if (isInInitializer)
{
writer.AppendLineInvariant("MergedDictionaries = {{");
writer.AppendLineInvariant("{0} = {{", propertyName);
}
else
{
writer.AppendLineInvariant("// MergedDictionaries");
writer.AppendLineInvariant("// {0}", propertyName);
}
foreach (var dictObject in mergedDictionaries.Objects)
{
Expand All @@ -2161,18 +2185,33 @@ private void BuildMergedDictionaries(IIndentedStringBuilder writer, XamlMemberDe
}

var source = dictObject.Members.FirstOrDefault(m => m.Member.Name == "Source");
if (source != null && dictObject.Members.Count > 1)
if (source != null && dictObject.Members.Any(m => m.Member.Name == "_UnknownContent"))
{
throw new Exception("Local values are not allowed in resource dictionary with Source set");
}

if (!isInInitializer)
var key = dictObject.Members.FirstOrDefault(m => m.Member.Name == "Key")?.Value as string;
if (isDict && key == null)
{
throw new Exception("Each dictionary entry must have an associated key.");
}

if (!isInInitializer && !isDict)
{
writer.AppendLineInvariant("Resources.MergedDictionaries.Add(");
writer.AppendLineInvariant("Resources.{0}.Add(", propertyName);
}
else if (!isInInitializer && isDict)
{
writer.AppendLineInvariant("Resources.{0}[\"{1}\"] = ", propertyName, key);
}
else if (isInInitializer && isDict)
{
writer.AppendLineInvariant("[\"{0}\"] = ", key);
}

if (source != null)
{
BuildMergedDictionaryFromSource(writer, source, isInInitializer);
BuildDictionaryFromSource(writer, source, isInInitializer);
}
else
{
Expand All @@ -2182,10 +2221,14 @@ private void BuildMergedDictionaries(IIndentedStringBuilder writer, XamlMemberDe
{
writer.AppendLineInvariant(",");
}
else
else if (!isDict)
{
writer.AppendLineInvariant(");");
}
else
{
writer.AppendLineInvariant(";");
}
}

if (isInInitializer)
Expand All @@ -2195,9 +2238,9 @@ private void BuildMergedDictionaries(IIndentedStringBuilder writer, XamlMemberDe
}

/// <summary>
/// Try to create a MergedDictionary entry from supplied Source property.
/// Try to create a ResourceDictionary assignment from supplied Source property.
/// </summary>
private void BuildMergedDictionaryFromSource(IIndentedStringBuilder writer, XamlMemberDefinition sourceDef, bool isInInitializer)
private void BuildDictionaryFromSource(IIndentedStringBuilder writer, XamlMemberDefinition sourceDef, bool isInInitializer)
{
var source = (sourceDef?.Value as string)?.Replace('\\', '/');
if (source == null)
Expand Down
6 changes: 6 additions & 0 deletions src/Uno.UI.Tests/App/App.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
Color="Magenta" />
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<SolidColorBrush x:Key="LucrativeColorBrush"
Color="Azure" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Application.Resources>

Expand Down
1 change: 1 addition & 0 deletions src/Uno.UI.Tests/App/Xaml/Test_Dictionary.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<SolidColorBrush x:Key="PlayfulColorBrush"
Color="RosyBrown" />
</ResourceDictionary>
<ResourceDictionary x:Key="Dark" Source="Test_Dictionary_Theme.xaml" />
</ResourceDictionary.ThemeDictionaries>

<x:String x:Key="GlobalCoordinates">11.22, 33</x:String>
Expand Down
5 changes: 5 additions & 0 deletions src/Uno.UI.Tests/App/Xaml/Test_Dictionary_Theme.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<SolidColorBrush x:Key="MoodyColorBrush"
Color="DarkKhaki" />
</ResourceDictionary>
3 changes: 2 additions & 1 deletion src/Uno.UI.Tests/Uno.UI.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@
<Page Include="App\Xaml\Test_CreateFromString.xaml" />
<Page Include="App\Xaml\Test_Dictionary.xaml" />
<Page Include="App\Xaml\Test_Dictionary_Inner.xaml" />
<Page Include="..\SamplesApp\UITests.Shared\Windows_UI_Xaml\Resources\Test_Dictionary_Linked.xaml" Link="App/Linked/Test_Dictionary_Linked.xaml"/>
<Page Include="App\Xaml\Test_Dictionary_Theme.xaml" />
<Page Include="..\SamplesApp\UITests.Shared\Windows_UI_Xaml\Resources\Test_Dictionary_Linked.xaml" Link="App/Linked/Test_Dictionary_Linked.xaml" />
<Page Include="App\Xaml\Test_Control.xaml" />
<Page Include="App\Xaml\Test_MarkupExtension.xaml" />
</ItemGroup>
Expand Down
21 changes: 21 additions & 0 deletions src/Uno.UI.Tests/Windows_UI_Xaml/Given_ResourceDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -374,8 +374,29 @@ public void When_Resource_In_Merged_Inline_Xaml()
AssertContainsColorBrushResource(app.Resources, "HangingOutInRecursiveMergedColorBrush", Colors.DarkMagenta);
}

[TestMethod]
public void When_Has_Themes_Inline_Xaml()
{
var app = UnitTestsApp.App.EnsureApplication();

AssertContainsColorBrushResource(app.Resources, "PlayfulColorBrush", Colors.RosyBrown);
AssertContainsColorBrushResource(app.Resources, "LucrativeColorBrush", Colors.Azure);
}

[TestMethod]
public void When_Has_Themes_Merged_Xaml()
{
var app = UnitTestsApp.App.EnsureApplication();

var dark = app.Resources.MergedDictionaries.First().ThemeDictionaries["Dark"] as ResourceDictionary;

AssertContainsColorBrushResource(dark, "MoodyColorBrush", Colors.DarkKhaki);
}

private void AssertContainsColorBrushResource(ResourceDictionary resources, string key, Color expected)
{
Assert.IsNotNull(resources);

var brush = resources[key] as SolidColorBrush;
Assert.IsNotNull(brush);
Assert.AreEqual(expected, brush.Color);
Expand Down

0 comments on commit 18240f7

Please sign in to comment.