Add WinUI 2.6 animated icon support. (#412)

* Add support for WinUI 2.6 animated icon.

This also removes the ability to set a custom interface in place of the WinUI
interface, because nobody seems to need it now, and it adds a bunch of
complexity.
This commit is contained in:
Simeon 2021-01-25 10:43:29 -08:00 коммит произвёл GitHub
Родитель fe7369a6e1
Коммит 0b69c0ce95
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
12 изменённых файлов: 336 добавлений и 271 удалений

Просмотреть файл

@ -6,28 +6,12 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
internal enum Lang
{
// Language wasn't recognized.
Unknown,
// Language specified was ambigious.
Ambiguous,
CSharp,
Cx,
Cppwinrt,
LottieYaml,
WinCompDgml,
Stats,
}
using Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.CSharp;
sealed class CommandLineOptions
{
readonly List<string> _additionalInterfaces = new List<string>();
readonly List<string> _languageStrings = new List<string>();
string? _interfaceBaseName;
Version? _winUIVersion;
internal IReadOnlyList<string> AdditionalInterfaces => _additionalInterfaces;
@ -48,9 +32,7 @@ sealed class CommandLineOptions
internal string? InputFile { get; private set; }
internal string InterfaceBaseName => _interfaceBaseName ?? "Microsoft.UI.Xaml.Controls.IAnimatedVisual";
internal IReadOnlyList<Lang> Languages { get; private set; } = Array.Empty<Lang>();
internal IReadOnlyList<Language> Languages { get; private set; } = Array.Empty<Language>();
internal uint? MinimumUapVersion { get; private set; }
@ -84,7 +66,7 @@ sealed class CommandLineOptions
// for adding to generated code so that users can regenerate the code and know that
// they got the set of options the same as a previous run. It does not include the
// InputFile, OutputFolder, or Language options.
internal string ToConfigurationCommandLine(string languageSwitch)
internal string ToConfigurationCommandLine(Language languageSwitch)
{
var sb = new StringBuilder();
sb.Append(ThisAssembly.AssemblyName);
@ -117,8 +99,6 @@ sealed class CommandLineOptions
sb.Append($" -{nameof(GenerateDependencyObject)}");
}
sb.Append($" -{nameof(InterfaceBaseName)} {InterfaceBaseName}");
sb.Append($" -Language {languageSwitch}");
if (MinimumUapVersion.HasValue)
@ -131,18 +111,28 @@ sealed class CommandLineOptions
sb.Append($" -{nameof(Namespace)} {Namespace}");
}
// The -Public switch is ignored for c++.
if (Public &&
!(languageSwitch.Equals("cppwinrt", StringComparison.OrdinalIgnoreCase) ||
languageSwitch.Equals("cx", StringComparison.OrdinalIgnoreCase)))
switch (languageSwitch)
{
sb.Append($" -{nameof(Public)}");
case Language.Cx:
case Language.Cppwinrt:
// The -Public switch is ignored for c++.
break;
default:
sb.Append($" -{nameof(Public)}");
break;
}
// The -RootNamespace parameter is only used for cppwinrt.
if (!string.IsNullOrWhiteSpace(RootNamespace) && languageSwitch.Equals("cppwinrt", StringComparison.OrdinalIgnoreCase))
switch (languageSwitch)
{
sb.Append($" -{nameof(RootNamespace)} {RootNamespace}");
case Language.Cppwinrt:
// The -RootNamespace parameter is only used for cppwinrt.
if (!string.IsNullOrWhiteSpace(RootNamespace))
{
sb.Append($" -{nameof(RootNamespace)} {RootNamespace}");
}
break;
}
if (StrictMode)
@ -201,17 +191,17 @@ sealed class CommandLineOptions
result.ParseCommandLineStrings(args);
// Convert the language strings to language values.
var languageTokenizer = new CommandlineTokenizer<Lang>(Lang.Ambiguous)
.AddKeyword(Lang.CSharp)
.AddKeyword(Lang.Cx, "cppcx")
.AddKeyword(Lang.Cx)
.AddKeyword(Lang.Cppwinrt)
.AddKeyword(Lang.Cppwinrt, "winrtcpp")
.AddKeyword(Lang.LottieYaml)
.AddKeyword(Lang.WinCompDgml, "dgml")
.AddKeyword(Lang.Stats);
var languageTokenizer = new CommandlineTokenizer<Language>(Language.Ambiguous)
.AddKeyword(Language.CSharp)
.AddKeyword(Language.Cx, "cppcx")
.AddKeyword(Language.Cx)
.AddKeyword(Language.Cppwinrt)
.AddKeyword(Language.Cppwinrt, "winrtcpp")
.AddKeyword(Language.LottieYaml)
.AddKeyword(Language.WinCompDgml, "dgml")
.AddKeyword(Language.Stats);
var languages = new List<Lang>();
var languages = new List<Language>();
// Parse the language string.
foreach (var languageString in result._languageStrings)
@ -220,10 +210,10 @@ sealed class CommandLineOptions
languages.Add(language);
switch (language)
{
case Lang.Unknown:
case Language.Unknown:
result.ErrorDescription = $"Unrecognized language: {languageString}";
break;
case Lang.Ambiguous:
case Language.Ambiguous:
result.ErrorDescription = $"Ambiguous language: {languageString}";
break;
}
@ -342,16 +332,6 @@ sealed class CommandLineOptions
InputFile = arg;
previousKeyword = Keyword.None;
break;
case Keyword.Interface:
if (_interfaceBaseName != null)
{
ErrorDescription = ArgumentSpecifiedMoreThanOnce("Interface base name");
return;
}
_interfaceBaseName = arg;
previousKeyword = Keyword.None;
break;
case Keyword.Language:
_languageStrings.Add(arg);
previousKeyword = Keyword.None;
@ -424,6 +404,7 @@ sealed class CommandLineOptions
previousKeyword = Keyword.None;
break;
case Keyword.WinUIVersion:
if (_winUIVersion != null)
{

19
LottieGen/Language.cs Normal file
Просмотреть файл

@ -0,0 +1,19 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
enum Language
{
// Language wasn't recognized.
Unknown,
// Language specified was ambigious.
Ambiguous,
CSharp,
Cx,
Cppwinrt,
LottieYaml,
WinCompDgml,
Stats,
}

Просмотреть файл

@ -144,18 +144,18 @@ sealed class LottieJsonFileProcessor
var codeGenSucceeded = true;
var areBothCppwinrtAndCxRequested = _options.Languages.Where(l => l == Lang.Cppwinrt || l == Lang.Cx).Count() == 2;
var areBothCppwinrtAndCxRequested = _options.Languages.Where(l => l == Language.Cppwinrt || l == Language.Cx).Count() == 2;
foreach (var lang in _options.Languages)
{
switch (lang)
{
case Lang.CSharp:
case Language.CSharp:
codeGenSucceeded &= TryGenerateCSharpCode(lottieComposition, $"{outputFileBase}.cs");
_profiler.OnCodeGenFinished();
break;
case Lang.Cx:
case Language.Cx:
{
// If both cppwinrt and cx files were requested, add a differentiator to
// the folder name for the cx files to make their names distinct from the
@ -176,22 +176,22 @@ sealed class LottieJsonFileProcessor
break;
}
case Lang.Cppwinrt:
case Language.Cppwinrt:
codeGenSucceeded &= TryGenerateCppwinrtCode(lottieComposition, _outputFolder);
_profiler.OnCodeGenFinished();
break;
case Lang.LottieYaml:
case Language.LottieYaml:
codeGenSucceeded &= TryGenerateLottieYaml(lottieComposition, $"{outputFileBase}-Lottie.yaml");
_profiler.OnSerializationFinished();
break;
case Lang.WinCompDgml:
case Language.WinCompDgml:
codeGenSucceeded &= TryGenerateWincompDgml(lottieComposition, $"{outputFileBase}.dgml");
_profiler.OnSerializationFinished();
break;
case Lang.Stats:
case Language.Stats:
codeGenSucceeded &= TryGenerateStats(lottieComposition);
break;
@ -434,7 +434,9 @@ sealed class LottieJsonFileProcessor
return result;
}
bool TryGenerateCSharpCode(LottieComposition lottieComposition, string outputFilePath)
bool TryGenerateCSharpCode(
LottieComposition lottieComposition,
string outputFilePath)
{
if (!TryEnsureTranslated(lottieComposition))
{
@ -442,7 +444,8 @@ sealed class LottieJsonFileProcessor
}
var codegenResult =
CSharpInstantiatorGenerator.CreateFactoryCode(CreateCodeGenConfiguration(lottieComposition, "CSharp"));
CSharpInstantiatorGenerator.CreateFactoryCode(
CreateCodeGenConfiguration(lottieComposition, Language.CSharp));
if (string.IsNullOrWhiteSpace(codegenResult.CsText))
{
@ -478,7 +481,7 @@ sealed class LottieJsonFileProcessor
}
var codegenResult =
CppwinrtInstantiatorGenerator.CreateFactoryCode(CreateCodeGenConfiguration(lottieComposition, "Cppwinrt"));
CppwinrtInstantiatorGenerator.CreateFactoryCode(CreateCodeGenConfiguration(lottieComposition, Language.Cppwinrt));
if (string.IsNullOrWhiteSpace(codegenResult.CppText))
{
@ -532,7 +535,7 @@ sealed class LottieJsonFileProcessor
}
var codegenResult =
CxInstantiatorGenerator.CreateFactoryCode(CreateCodeGenConfiguration(lottieComposition, "CX"));
CxInstantiatorGenerator.CreateFactoryCode(CreateCodeGenConfiguration(lottieComposition, Language.Cx));
if (string.IsNullOrWhiteSpace(codegenResult.CppText))
{
@ -635,7 +638,7 @@ sealed class LottieJsonFileProcessor
CodegenConfiguration CreateCodeGenConfiguration(
LottieComposition lottieComposition,
string languageSwitch)
Language languageSwitch)
{
if (_translationResults is null)
{
@ -644,7 +647,6 @@ sealed class LottieJsonFileProcessor
var result = new CodegenConfiguration(
className: _className,
interfaceType: _options.InterfaceBaseName,
additionalInterfaces: _options.AdditionalInterfaces,
objectGraphs: _translationResults.Select(
tr => ((CompositionObject?)tr.RootVisual!, tr.MinimumRequiredUapVersion)).ToArray(),
@ -674,7 +676,7 @@ sealed class LottieJsonFileProcessor
// Returns lines that describe the invocation of this tool.
// This information is passed to the code generator so that it can
// be included in the generated output.
IEnumerable<string> GetToolInvocationInfo(string languageSwitch)
IEnumerable<string> GetToolInvocationInfo(Language languageSwitch)
{
var inputFile = new FileInfo(_sourceFilePath);

Просмотреть файл

@ -117,7 +117,7 @@ sealed class Program
foreach (var language in _options.Languages)
{
if (language == Lang.Unknown)
if (language == Language.Unknown)
{
_reporter.WriteError("Invalid language.");
return RunResult.InvalidUsage;
@ -168,7 +168,7 @@ sealed class Program
return RunResult.Failure;
}
if (_options.Languages.Contains(Lang.Stats))
if (_options.Languages.Contains(Language.Stats))
{
// Write the stats. Stats are collected by the Reporter from each FileProcessor
// then written to files here after all of the FileProcessors have finished.
@ -219,84 +219,5 @@ sealed class Program
}
static void ShowUsage(Reporter.Writer writer)
{
writer.WriteLine(Usage);
}
static string Usage => string.Format(
@"
Usage: {0} -InputFile LOTTIEFILE -Language LANG [Other options]
OVERVIEW:
Generates source code from Lottie files for playing in the AnimatedVisualPlayer.
LOTTIEFILE is a Lottie .json file or .lottie file. LOTTIEFILE may contain wildcards.
LANG is one of cs, cppcx, cppwinrt, lottieyaml, dgml, or stats.
-Language LANG may be specified multiple times.
[Other options]
-Help Print this help message and exit.
-AdditionalInterface
Specifies an additional interface that the generated code
will claim to implement. May be specified multiple times.
-DisableTranslationOptimizer
Disables optimization of the translation from Lottie to
Windows code. Mainly used to detect bugs in the optimizer.
-DisableCodeGenOptimizer
Disables optimization done by the code generator. This is
useful when the generated code is going to be hacked on.
-GenerateColorBindings
Generates properties for each distinct color of fills and
strokes so that the colors in the animation can be modified
at runtime.
-GenerateDependencyObject
Generates code that extends DependencyObject. This is useful
to allow XAML binding to properties in the Lottie source.
-InterfaceBaseName
Specifies the name of the interface to implement in the generated
code. Overrides the default interface base name. The default
is determined by the -WinUIVersion value.
-MinimumUapVersion
The lowest UAP version on which the result must run. Defaults
to 7. Must be 7 or higher. Code will be generated that will
run down to this version. If less than TargetUapVersion,
extra code will be generated if necessary to support the
lower versions.
-Namespace Specifies the namespace for the generated code. Defaults to
AnimatedVisuals.
-OutputFolder Specifies the output folder for the generated files. If not
specified the files will be written to the current directory.
-Public Makes the generated class public rather than internal. Ignored
for c++.
-RootNamespace
Cppwinrt only, specifies the root namespace of the consuming
project. Affects the names used to reference files generated
by cppwinrt.exe.
-StrictMode Fails on any parsing or translation issue. If not specified,
a best effort will be made to create valid output, and any
issues will be reported to STDOUT.
-TargetUapVersion
The target UAP version on which the result will run. Must be 7
or higher and >= MinimumUapVersion. This value determines the
minimum SDK version required to compile the generated code.
If not specified, defaults to the latest UAP version.
-TestMode Prevents any information from being included that could change
from run to run with the same inputs, for example tool version
numbers, file paths, and dates. This is designed to enable
testing of the tool by diffing the outputs.
-WinUIVersion Generates code for a particular WinUI version. Defaults to 2.4.
EXAMPLES:
Generate Foo.cpp and Foo.h cppwinrt files in the current directory from the
Lottie file Foo.json:
{0} -InputFile Foo.json -Language cppwinrt
Keywords can be abbreviated and are case insensitive.
Generate Bar.cs in the C:\temp directory from the Lottie file Bar.json:
{0} -inp Bar.json -L cs -o C:\temp",
Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly()?.ManifestModule.Name ?? "LottieGen"));
=> writer.WriteLine(Usage.Text);
}

91
LottieGen/Usage.cs Normal file
Просмотреть файл

@ -0,0 +1,91 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.IO;
using System.Reflection;
using Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.CSharp;
sealed class Usage
{
internal static string Text
{
get
{
var exeName =
Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly()?.ManifestModule.Name ?? "LottieGen");
return
@$"
Usage: {exeName} -InputFile LOTTIEFILE -Language LANG [Other options]
OVERVIEW:
Generates source code from Lottie files for playing in the AnimatedVisualPlayer.
LOTTIEFILE is a Lottie .json file or .lottie file. LOTTIEFILE may contain wildcards.
LANG is one of cs, cppcx, cppwinrt, lottieyaml, dgml, or stats.
-Language LANG may be specified multiple times.
[Other options]
-Help Print this help message and exit.
-AdditionalInterface
Specifies an additional interface that the generated code
will claim to implement. May be specified multiple times.
-DisableTranslationOptimizer
Disables optimization of the translation from Lottie to
Windows code. Mainly used to detect bugs in the optimizer.
-DisableCodeGenOptimizer
Disables optimization done by the code generator. This is
useful when the generated code is going to be hacked on.
-GenerateColorBindings
Generates properties for each distinct color of fills and
strokes so that the colors in the animation can be modified
at runtime.
-GenerateDependencyObject
Generates code that extends DependencyObject. This is useful
to allow XAML binding to properties in the Lottie source.
-MinimumUapVersion
The lowest UAP version on which the result must run. Defaults
to 7. Must be 7 or higher. Code will be generated that will
run down to this version. If less than TargetUapVersion,
extra code will be generated if necessary to support the
lower versions.
-Namespace Specifies the namespace for the generated code. Defaults to
AnimatedVisuals.
-OutputFolder Specifies the output folder for the generated files. If not
specified the files will be written to the current directory.
-Public Makes the generated class public rather than internal. Ignored
for c++.
-RootNamespace
Cppwinrt only, specifies the root namespace of the consuming
project. Affects the names used to reference files generated
by cppwinrt.exe.
-StrictMode Fails on any parsing or translation issue. If not specified,
a best effort will be made to create valid output, and any
issues will be reported to STDOUT.
-TargetUapVersion
The target UAP version on which the result will run. Must be 7
or higher and >= MinimumUapVersion. This value determines the
minimum SDK version required to compile the generated code.
If not specified, defaults to the latest UAP version.
-TestMode Prevents any information from being included that could change
from run to run with the same inputs, for example tool version
numbers, file paths, and dates. This is designed to enable
testing of the tool by diffing the outputs.
-WinUIVersion Generates code for a particular WinUI version. Defaults to 2.4.
EXAMPLES:
Generate Foo.cpp and Foo.h cppwinrt files in the current directory from the
Lottie file Foo.json:
{exeName} -InputFile Foo.json -Language cppwinrt
Keywords can be abbreviated and are case insensitive.
Generate Bar.cs in the C:\temp directory from the Lottie file Bar.json:
{exeName} -inp Bar.json -L cs -o C:\temp";
}
}
}

Просмотреть файл

@ -25,25 +25,32 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.CSharp
sealed class CSharpInstantiatorGenerator : InstantiatorGeneratorBase
{
readonly Stringifier _s;
readonly string _interface;
readonly string _sourceInterface;
readonly string _winUiNamespace;
readonly string _winUi3CastHack;
CSharpInstantiatorGenerator(CodegenConfiguration configuration, Stringifier stringifier)
CSharpInstantiatorGenerator(
CodegenConfiguration configuration,
Stringifier stringifier)
: base(
configuration,
setCommentProperties: false,
stringifier: stringifier)
{
_s = stringifier;
_interface = AnimatedVisualSourceInfo.InterfaceType.GetQualifiedName(stringifier);
_sourceInterface = _interface + "Source";
_winUiNamespace = AnimatedVisualSourceInfo.WinUi3 ? "Microsoft.UI" : "Windows.UI";
// This is a hack that is required to use Win2D with WinUI3 as of August 2020. It
// will not be necessary when an official Win2D for WinUI3 is released.
_winUi3CastHack = AnimatedVisualSourceInfo.WinUi3 ? "(IGeometrySource2D)(object)" : string.Empty;
if (AnimatedVisualSourceInfo.WinUIVersion.Major >= 3)
{
_winUiNamespace = "Microsoft.UI";
// This is a hack that is required to use Win2D with WinUI3 as of August 2020. It
// will not be necessary when an official Win2D for WinUI3 is released.
_winUi3CastHack = "(IGeometrySource2D)(object)";
}
else
{
_winUiNamespace = "Windows.UI";
_winUi3CastHack = string.Empty;
}
}
IAnimatedVisualSourceInfo SourceInfo => AnimatedVisualSourceInfo;
@ -53,7 +60,8 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.CSharp
/// Windows.UI.Composition Visual.
/// </summary>
/// <returns>A tuple containing the C# code and list of referenced asset files.</returns>
public static CSharpCodegenResult CreateFactoryCode(CodegenConfiguration configuration)
public static CSharpCodegenResult CreateFactoryCode(
CodegenConfiguration configuration)
{
var generator = new CSharpInstantiatorGenerator(
configuration: configuration,
@ -252,21 +260,29 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.CSharp
builder.WriteLine($"{visibility}sealed class {SourceInfo.ClassName}");
builder.Indent();
if (SourceInfo.GenerateDependencyObject)
{
builder.WriteLine($" : DependencyObject");
builder.WriteLine($" , {_sourceInterface}");
builder.WriteLine($": DependencyObject");
builder.WriteLine($", {Interface_IAnimatedVisualSource.GetQualifiedName(_s)}");
}
else
{
builder.WriteLine($" : {_sourceInterface}");
builder.WriteLine($": {Interface_IAnimatedVisualSource.GetQualifiedName(_s)}");
}
if (SourceInfo.WinUIVersion >= new Version(2, 6) && SourceInfo.WinUIVersion.Major < 3)
{
builder.WriteLine($", {Interface_IAnimatedVisualSource2.GetQualifiedName(_s)}");
}
foreach (var additionalInterface in SourceInfo.AdditionalInterfaces)
{
builder.WriteLine($" , {additionalInterface.GetQualifiedName(_s)}");
builder.WriteLine($", {additionalInterface.GetQualifiedName(_s)}");
}
builder.UnIndent();
builder.OpenScope();
// Add any internal constants.
@ -295,8 +311,16 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.CSharp
// Add the methods and fields needed for theming.
WriteThemeMethodsAndFields(builder);
// Generate the overload of TryCreateAnimatedVisual that doesn't return diagnostics.
builder.WriteLine($"public {Interface_IAnimatedVisual.GetQualifiedName(_s)} TryCreateAnimatedVisual(Compositor compositor)");
builder.OpenScope();
builder.WriteLine("object ignored = null;");
builder.WriteLine($"return TryCreateAnimatedVisual(compositor, out ignored);");
builder.CloseScope();
builder.WriteLine();
// Generate the method that creates an instance of the animated visual.
builder.WriteLine($"public {_interface} TryCreateAnimatedVisual(Compositor compositor, out object diagnostics)");
builder.WriteLine($"public {Interface_IAnimatedVisual.GetQualifiedName(_s)} TryCreateAnimatedVisual(Compositor compositor, out object diagnostics)");
builder.OpenScope();
builder.WriteLine("diagnostics = null;");
if (SourceInfo.IsThemed)
@ -308,7 +332,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.CSharp
// WinUI3 doesn't ever do a version check. It's up to the user to make sure
// the version they're using is compatible.
if (SourceInfo.WinUi3)
if (SourceInfo.WinUIVersion.Major >= 3)
{
WriteInstantiateAndReturnAnimatedVisual(builder, SourceInfo.AnimatedVisualInfos.First());
}
@ -484,7 +508,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.CSharp
builder.WriteLine();
// Generate the method that creates an instance of the animated visual.
builder.WriteLine($"public {_interface} TryCreateAnimatedVisual(Compositor compositor, out object diagnostics)");
builder.WriteLine($"public {Interface_IAnimatedVisual.GetQualifiedName(_s)} TryCreateAnimatedVisual(Compositor compositor, out object diagnostics)");
builder.OpenScope();
builder.WriteLine("_isTryCreateAnimatedVisualCalled = true;");
builder.WriteLine("diagnostics = null;");
@ -494,7 +518,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.CSharp
// WinUI3 doesn't ever do a version check. It's up to the user to make sure
// the version they're using is compatible.
if (!SourceInfo.WinUi3)
if (SourceInfo.WinUIVersion.Major < 3)
{
// Check whether the runtime will support the lowest UAP version required.
builder.WriteLine($"if (!{animatedVisualInfos[^1].ClassName}.IsRuntimeCompatible())");
@ -667,7 +691,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.CSharp
protected override void WriteAnimatedVisualStart(CodeBuilder builder, IAnimatedVisualInfo info)
{
// Start the instantiator class.
builder.WriteLine($"sealed class {info.ClassName} : {_interface}");
builder.WriteLine($"sealed class {info.ClassName} : {Interface_IAnimatedVisual.GetQualifiedName(_s)}");
builder.OpenScope();
}
@ -729,7 +753,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.CSharp
// WinUI3 doesn't ever do a version check. It's up to the user to make sure
// the version they're using is compatible.
if (!SourceInfo.WinUi3)
if (SourceInfo.WinUIVersion.Major < 3)
{
// Write the IsRuntimeCompatible static method.
builder.WriteLine("internal static bool IsRuntimeCompatible()");

Просмотреть файл

@ -18,7 +18,6 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
{
public CodegenConfiguration(
string className,
string interfaceType,
IReadOnlyList<string> additionalInterfaces,
IReadOnlyList<(CompositionObject graphRoot, uint requiredUapVersion)> objectGraphs,
string nameSpace,
@ -29,7 +28,6 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
)
{
ClassName = className;
InterfaceType = interfaceType;
AdditionalInterfaces = additionalInterfaces;
ObjectGraphs = objectGraphs;
Namespace = nameSpace;
@ -78,13 +76,6 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
/// </summary>
public bool GenerateDependencyObject { get; set; }
/// <summary>
/// Defines the interface used in the generated code. Setting this to
/// "Microsoft.UI.Xaml.Controls.IAnimatedVisual" will cause the generation
/// of code for IAnimatedVisualSource and IAnimatedVisual.
/// </summary>
public string InterfaceType { get; }
/// <summary>
/// 0 or more additional interfaces that the generated class will claim
/// to implement.

Просмотреть файл

@ -11,7 +11,6 @@ using Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.MetaData;
using Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Mgce;
using Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Mgcg;
using Microsoft.Toolkit.Uwp.UI.Lottie.WinUIXamlMediaData;
using Mgce = Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Mgce;
namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cppwinrt
{
@ -95,10 +94,11 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cppwinrt
_isIDynamic = SourceInfo.LoadedImageSurfaces.Any();
_winUINamespace = SourceInfo.WinUi3 ? "Microsoft::UI" : "Windows::UI";
_winUINamespace = SourceInfo.WinUIVersion.Major >= 3 ? "Microsoft::UI" : "Windows::UI";
_wuc = $"{_winUINamespace}::Composition";
_sourceClassName = SourceInfo.ClassName;
_animatedVisualTypeName = SourceInfo.InterfaceType.GetQualifiedName(_s);
_animatedVisualTypeName = Interface_IAnimatedVisual.GetQualifiedName(_s);
}
static string FieldAssignment(string fieldName) => fieldName != null ? $"{fieldName} = " : string.Empty;
@ -115,11 +115,6 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cppwinrt
builder.WriteLine(string.Join("\r\n", AutoGeneratedHeaderText));
var idlImports = new List<string>();
if (SourceInfo.IsInterfaceCustom)
{
idlImports.Add(SourceInfo.InterfaceType.NormalizedQualifiedName);
}
idlImports.AddRange(SourceInfo.AdditionalInterfaces.Select(n => n.NormalizedQualifiedName));
if (idlImports.Any())
@ -134,26 +129,20 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cppwinrt
builder.WriteLine($"namespace {SourceInfo.Namespace}");
builder.OpenScope();
if (SourceInfo.IsInterfaceCustom)
{
builder.WriteLine("[contract(InternalContract, 1)]");
}
builder.WriteLine($"runtimeclass {_sourceClassName}");
builder.Indent();
if (SourceInfo.IsInterfaceCustom)
if (_isIDynamic)
{
builder.WriteLine($": [default] {SourceInfo.InterfaceType.NormalizedQualifiedName}Source");
builder.WriteLine($": [default] {Interface_IDynamicAnimatedVisualSource.NormalizedQualifiedName}");
}
else
{
if (_isIDynamic)
builder.WriteLine($": [default] {Interface_IAnimatedVisualSource.NormalizedQualifiedName}");
if (SourceInfo.WinUIVersion >= new Version(2, 6) && SourceInfo.WinUIVersion.Major < 3)
{
builder.WriteLine(": [default] Microsoft.UI.Xaml.Controls.IDynamicAnimatedVisualSource");
}
else
{
builder.WriteLine(": [default] Microsoft.UI.Xaml.Controls.IAnimatedVisualSource");
builder.WriteLine($", {Interface_IAnimatedVisualSource2.NormalizedQualifiedName}");
}
}
@ -315,6 +304,12 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cppwinrt
void WriteTryCreateAnimatedVisualDecl(CodeBuilder builder)
{
builder.WriteLine($"winrt::{_animatedVisualTypeName} TryCreateAnimatedVisual(");
builder.Indent();
builder.WriteLine($"winrt::{_wuc}::Compositor const& compositor);");
builder.UnIndent();
builder.WriteLine();
builder.WriteLine($"winrt::{_animatedVisualTypeName} TryCreateAnimatedVisual(");
builder.Indent();
builder.WriteLine($"winrt::{_wuc}::Compositor const& compositor,");
@ -506,7 +501,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cppwinrt
void AddUsingsForTypeAliases(CodeBuilder builder)
{
// Add usings for type aliases.
if (SourceInfo.WinUi3)
if (SourceInfo.WinUIVersion.Major >= 3)
{
builder.WriteLine($"using Color = winrt::Windows::UI::Color;");
builder.WriteLine($"using CompositionPropertySet = winrt::Microsoft::UI::Composition::CompositionPropertySet;");
@ -557,7 +552,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cppwinrt
builder.WriteLine("#include <winrt/Windows.Foundation.Metadata.h>");
builder.WriteLine("#include <winrt/Windows.Foundation.Collections.h>");
if (SourceInfo.WinUi3)
if (SourceInfo.WinUIVersion.Major >= 3)
{
builder.WriteLine("#include <winrt/Microsoft.UI.Composition.h>");
}
@ -637,11 +632,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cppwinrt
namespaces.Add($"winrt::{_winUINamespace}");
namespaces.Add($"winrt::{_wuc}");
namespaces.Add("winrt::Windows::Graphics");
if (SourceInfo.InterfaceType is null)
{
namespaces.Add(Muxc);
}
namespaces.Add(Muxc);
if (SourceInfo.UsesNamespaceWindowsUIXamlMedia)
{
@ -799,6 +790,17 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cppwinrt
WriteThemePropertyImpls(builder);
}
// Generate the overload of TryCreateAnimatedVisual that doesn't have diagnostics;
builder.WriteLine($"winrt::{_animatedVisualTypeName} {_sourceClassName}::TryCreateAnimatedVisual(");
builder.Indent();
builder.WriteLine("Compositor const& compositor)");
builder.UnIndent();
builder.OpenScope();
builder.WriteLine("IInspectable diagnostics = nullptr;");
builder.WriteLine("return TryCreateAnimatedVisual(compositor, diagnostics);");
builder.CloseScope();
builder.WriteLine();
// Generate the method that creates an instance of the composition on the IAnimatedVisualSource.
builder.WriteLine($"winrt::{_animatedVisualTypeName} {_sourceClassName}::TryCreateAnimatedVisual(");
builder.Indent();
@ -981,7 +983,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cppwinrt
{
// WinUI3 doesn't ever do a version check. It's up to the user to make sure
// the version they're using is compatible.
if (SourceInfo.WinUi3)
if (SourceInfo.WinUIVersion.Major >= 3)
{
var info = animatedVisualInfos.First();
builder.WriteBreakableLine($"return winrt::make<{info.ClassName}>(", CommaSeparate(GetConstructorArguments(info)), ");");
@ -1016,7 +1018,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cppwinrt
// WinUI3 doesn't ever do a version check. It's up to the user to make sure
// the version they're using is compatible.
if (!SourceInfo.WinUi3)
if (SourceInfo.WinUIVersion.Major < 3)
{
builder.WriteLine($"if (!{animatedVisualInfos[^1].ClassName}::IsRuntimeCompatible())");
builder.OpenScope();
@ -1166,7 +1168,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cppwinrt
{
// WinUI3 doesn't ever do a version check. It's up to the user to make sure
// the version they're using is compatible.
if (!SourceInfo.WinUi3)
if (SourceInfo.WinUIVersion.Major < 3)
{
// Write the IsRuntimeCompatible static method.
builder.WriteLine("static bool IsRuntimeCompatible()");

Просмотреть файл

@ -24,6 +24,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cx
readonly string _fileBaseName;
readonly string _headerFileName;
readonly string _cppFileName;
readonly bool _isAnimatedIcon;
// The name of the source class i.e. the class
// that contains the TryCreateAnimatedVisual method.
@ -63,10 +64,13 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cx
_fileBaseName = $"{SourceInfo.Namespace}.{SourceInfo.ClassName}";
_cppFileName = $"{_fileBaseName}.cpp";
_headerFileName = $"{_fileBaseName}.h";
_winUINamespace = SourceInfo.WinUi3 ? "Microsoft::UI" : "Windows::UI";
_winUINamespace = SourceInfo.WinUIVersion.Major >= 3 ? "Microsoft::UI" : "Windows::UI";
_wuc = $"{_winUINamespace}::Composition";
_sourceClassName = SourceInfo.ClassName;
_animatedVisualTypeName = SourceInfo.InterfaceType.GetQualifiedName(_s);
_animatedVisualTypeName = Interface_IAnimatedVisual.GetQualifiedName(_s);
// Temporary until IAnimatedVisualSource2 makes it into WinUI3.
_isAnimatedIcon = SourceInfo.WinUIVersion >= new Version(2, 6) && SourceInfo.WinUIVersion.Major < 3;
}
static string FieldAssignment(string fieldName) => fieldName != null ? $"{fieldName} = " : string.Empty;
@ -83,14 +87,6 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cx
builder.Preamble.WriteLine("#pragma once");
builder.Preamble.WriteLine(string.Join("\r\n", AutoGeneratedHeaderText));
// If a non-standard interface has been specified, include a header file for it.
// The user is expected to provide this header file. If the standard interface
// was specified, the definitions come from WinUI.
if (SourceInfo.IsInterfaceCustom)
{
builder.Preamble.WriteLine($"#include \"{_headerFileName}\"");
}
builder.Internal.Indent();
builder.Internal.WriteLine("internal:");
builder.Internal.Indent();
@ -134,7 +130,13 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cx
inherits.Add($"{_winUINamespace}::Xaml::DependencyObject");
}
inherits.Add($"{_animatedVisualTypeName}Source");
inherits.Add(Interface_IAnimatedVisualSource.GetQualifiedName(_s));
if (SourceInfo.WinUIVersion >= new Version(2, 6) && SourceInfo.WinUIVersion.Major < 3)
{
inherits.Add(Interface_IAnimatedVisualSource2.GetQualifiedName(_s));
}
inherits.AddRange(SourceInfo.AdditionalInterfaces.Select(n => n.GetQualifiedName(_s)));
WriteHeaderClassStart(builder.Preamble, inherits);
@ -146,11 +148,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cx
WriteThemeHeader(builder);
}
builder.Public.WriteLine($"virtual {_animatedVisualTypeName}^ TryCreateAnimatedVisual(");
builder.Public.Indent();
builder.Public.WriteLine($"{_wuc}::Compositor^ compositor,");
builder.Public.WriteLine($"Object^* diagnostics);");
builder.Public.UnIndent();
WriteTryCreateAnimatedVisualDecl(builder.Public);
builder.Public.WriteLine();
WriteMarkersPropertyDecl(builder.Public);
@ -221,7 +219,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cx
if (hasColorProperty)
{
var b = SourceInfo.IsInterfaceCustom ? builder.Internal : builder.Private;
var b = builder.Internal;
b.WriteLine($"static Windows::Foundation::Numerics::float4 ColorAsVector4(Windows::UI::Color color);");
b.WriteLine();
}
@ -363,6 +361,12 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cx
}
inherits.Add("IDynamicAnimatedVisualSourceSource");
if (SourceInfo.WinUIVersion >= new Version(2, 6) && SourceInfo.WinUIVersion.Major < 3)
{
inherits.Add(Interface_IAnimatedVisualSource2.GetQualifiedName(_s));
}
inherits.Add("INotifyPropertyChanged");
inherits.AddRange(SourceInfo.AdditionalInterfaces.Select(n => n.GetQualifiedName(_s)));
@ -380,11 +384,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cx
pub.WriteLine("virtual event Windows::Foundation::TypedEventHandler<IDynamicAnimatedVisualSource^, Object^>^ AnimatedVisualInvalidated;");
pub.WriteLine();
pub.WriteLine($"virtual {_animatedVisualTypeName}^ TryCreateAnimatedVisual(");
pub.Indent();
pub.WriteLine($"{_wuc}::Compositor^ compositor,");
pub.WriteLine($"Object^* diagnostics);");
pub.UnIndent();
WriteTryCreateAnimatedVisualDecl(pub);
pub.WriteLine();
WriteFrameToProgressDecl(pub);
@ -543,11 +543,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cx
namespaces.Add($"{_winUINamespace}");
namespaces.Add(_wuc);
namespaces.Add("Windows::Graphics");
if (SourceInfo.InterfaceType is null)
{
namespaces.Add(Muxc);
}
namespaces.Add(Muxc);
if (SourceInfo.UsesCanvas ||
SourceInfo.UsesCanvasEffects ||
@ -668,6 +664,16 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cx
WriteThemePropertyImpls(builder);
}
// Generate the overload of TryCreateAnimatedVisual that doesn't have diagnostics.
builder.WriteLine($"{_animatedVisualTypeName}^ {_s.Namespace(SourceInfo.Namespace)}::{_sourceClassName}::TryCreateAnimatedVisual(");
builder.Indent();
builder.WriteLine($"Compositor^ compositor)");
builder.UnIndent();
builder.OpenScope();
builder.WriteLine("return TryCreateAnimatedVisual(compositor, nullptr);");
builder.CloseScope();
builder.WriteLine();
// Generate the method that creates an instance of the composition on the IAnimatedVisualSource.
builder.WriteLine($"{_animatedVisualTypeName}^ {_s.Namespace(SourceInfo.Namespace)}::{_sourceClassName}::TryCreateAnimatedVisual(");
builder.Indent();
@ -725,13 +731,26 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cx
builder.CloseScope();
}
void WriteTryCreateAnimatedVisualDecl(CodeBuilder builder)
{
builder.WriteLine("[Windows::Foundation::Metadata::DefaultOverload]");
builder.WriteLine($"{(_isAnimatedIcon ? "virtual " : string.Empty)}{_animatedVisualTypeName}^ TryCreateAnimatedVisual({_wuc}::Compositor^ compositor);");
builder.WriteLine();
builder.WriteLine($"virtual {_animatedVisualTypeName}^ TryCreateAnimatedVisual(");
builder.Indent();
builder.WriteLine($"{_wuc}::Compositor^ compositor,");
builder.WriteLine($"Object^* diagnostics);");
builder.UnIndent();
}
/// <summary>
/// Generates the GetMarkerAsProgress(...) declaration.
/// Generates the Markers property declaration.
/// </summary>
void WriteMarkersPropertyDecl(CodeBuilder builder)
{
builder.WriteComment("Returns a map from marker names to corresponding progress values.");
builder.WriteLine($"property Windows::Foundation::Collections::IMapView<Platform::String^, double>^ Markers");
builder.WriteLine($"{(_isAnimatedIcon ? "virtual " : string.Empty)}property Windows::Foundation::Collections::IMapView<Platform::String^, double>^ Markers");
builder.OpenScope();
builder.WriteLine("Windows::Foundation::Collections::IMapView<Platform::String^, double>^ get();");
builder.CloseScope();
@ -762,7 +781,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cx
void WriteSetColorPropertyDecl(CodeBuilder builder)
{
builder.WriteComment("Sets the color property with the given name, or does nothing if no such property exists.");
builder.WriteLine("void SetColorProperty(Platform::String^ propertyName, Windows::UI::Color value);");
builder.WriteLine($"{(_isAnimatedIcon ? "virtual " : string.Empty)}void SetColorProperty(Platform::String^ propertyName, Windows::UI::Color value);");
}
void WriteSetScalarPropertyDecl(CodeBuilder builder)
@ -830,7 +849,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cx
/// </summary>
void WriteIAnimatedVisualSource(CodeBuilder builder)
{
builder.WriteLine("diagnostics = nullptr;");
builder.WriteLine("if (diagnostics != nullptr) { diagnostics = nullptr; }");
// Check the runtime version and instantiate the highest compatible IAnimatedVisual class.
WriteInstantiateHighestCompatibleAnimatedVisual(builder, SourceInfo.AnimatedVisualInfos);
@ -885,7 +904,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cx
{
// WinUI3 doesn't ever do a version check. It's up to the user to make sure
// the version they're using is compatible.
if (SourceInfo.WinUi3)
if (SourceInfo.WinUIVersion.Major >= 3)
{
var info = animatedVisualInfos.First();
builder.WriteBreakableLine($"return {_s.New(info.ClassName)}(", CommaSeparate(GetConstructorArguments(info)), ");");
@ -912,7 +931,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cx
void WriteIDynamicAnimatedVisualSource(CodeBuilder builder)
{
builder.WriteLine("m_isTryCreateAnimatedVisualCalled = true;");
builder.WriteLine("diagnostics = nullptr;");
builder.WriteLine("if (diagnostics != nullptr) { *diagnostics = nullptr; }");
builder.WriteLine();
// Check whether the runtime will support the lowest UAP version required.
@ -920,7 +939,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cx
// WinUI3 doesn't ever do a version check. It's up to the user to make sure
// the version they're using is compatible.
if (!SourceInfo.WinUi3)
if (SourceInfo.WinUIVersion.Major < 3)
{
builder.WriteLine($"if (!{animatedVisualInfos[^1].ClassName}::IsRuntimeCompatible())");
builder.OpenScope();
@ -1037,7 +1056,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.Cx
{
// WinUI3 doesn't ever do a version check. It's up to the user to make sure
// the version they're using is compatible.
if (!SourceInfo.WinUi3)
if (SourceInfo.WinUIVersion.Major < 3)
{
// Write the IsRuntimeCompatible static method.
builder.WriteLine("static bool IsRuntimeCompatible()");

Просмотреть файл

@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Numerics;
@ -25,21 +26,11 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
/// </summary>
string Namespace { get; }
/// <summary>
/// Gets the name of the interface for the generated code.
/// </summary>
TypeName InterfaceType { get; }
/// <summary>
/// 0 or more additional interfaces that the class will claim to implement.
/// </summary>
IReadOnlyList<TypeName> AdditionalInterfaces { get; }
/// <summary>
/// True iff the interface type is not the default Microsoft.UI.Xaml interface.
/// </summary>
bool IsInterfaceCustom { get; }
/// <summary>
/// Gets the name of the field in the instantiator class that holds the reusable ExpressionAnimation.
/// </summary>
@ -51,7 +42,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
string DurationTicksFieldName { get; }
/// <summary>
/// True if the IAnimatedVisualSource should be a DependencyObject.
/// <c>true</c> if the IAnimatedVisualSource should be a DependencyObject.
/// </summary>
bool GenerateDependencyObject { get; }
@ -71,7 +62,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
Vector2 CompositionDeclaredSize { get; }
/// <summary>
/// True if the IAnimatedVisualSource should be public.
/// <c>true</c> if the IAnimatedVisualSource should be public.
/// </summary>
bool Public { get; }
@ -141,9 +132,8 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
SourceMetadata SourceMetadata { get; }
/// <summary>
/// Gets a value indicating whether the generated code should target WinUI3. This
/// is an experimental feature.
/// The version of WinUI to generate code for.
/// </summary>
bool WinUi3 { get; }
Version WinUIVersion { get; }
}
}

Просмотреть файл

@ -49,7 +49,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
readonly bool _disableFieldOptimization;
readonly bool _generateDependencyObject;
readonly bool _generatePublicClass;
readonly bool _generateForWinui3;
readonly Version _winUIVersion;
readonly Stringifier _s;
readonly IReadOnlyList<AnimatedVisualGenerator> _animatedVisualGenerators;
readonly LoadedImageSurfaceInfo[] _loadedImageSurfaceInfos;
@ -57,9 +57,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
readonly SourceMetadata _sourceMetadata;
readonly bool _isThemed;
readonly IReadOnlyList<string> _toolInfo;
readonly TypeName _interfaceType;
readonly IReadOnlyList<TypeName> _additionalInterfaces;
readonly bool _isInterfaceCustom;
readonly IReadOnlyList<MarkerInfo> _markers;
readonly IReadOnlyList<NamedConstant> _internalConstants;
@ -79,11 +77,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
_disableFieldOptimization = configuration.DisableOptimization;
_generateDependencyObject = configuration.GenerateDependencyObject;
_generatePublicClass = configuration.Public;
_generateForWinui3 = configuration.WinUIVersion.Major >= 3;
_winUIVersion = configuration.WinUIVersion;
_s = stringifier;
_toolInfo = configuration.ToolInfo;
_interfaceType = new TypeName(configuration.InterfaceType);
_isInterfaceCustom = _interfaceType.NormalizedQualifiedName != "Microsoft.UI.Xaml.Controls.IAnimatedVisual";
_additionalInterfaces = configuration.AdditionalInterfaces.Select(n => new TypeName(n)).ToArray();
_markers = MarkerInfo.GetMarkerInfos(_sourceMetadata.LottieMetadata.FilteredMarkers).ToArray();
_internalConstants = GetInternalConstants().ToArray();
@ -156,6 +152,26 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
_loadedImageSurfaceInfosByNode = sharedLoadedImageSurfaceInfos.ToDictionary(n => n.node, n => n.loadedImageSurfaceNode);
}
/// <summary>
/// Well-known interface type.
/// </summary>
protected TypeName Interface_IAnimatedVisual { get; } = new TypeName("Microsoft.UI.Xaml.Controls.IAnimatedVisual");
/// <summary>
/// Well-known interface type.
/// </summary>
protected TypeName Interface_IAnimatedVisualSource { get; } = new TypeName("Microsoft.UI.Xaml.Controls.IAnimatedVisualSource");
/// <summary>
/// Well-known interface type.
/// </summary>
protected TypeName Interface_IDynamicAnimatedVisualSource { get; } = new TypeName("Microsoft.UI.Xaml.Controls.IDynamicAnimatedVisualSource");
/// <summary>
/// Well-known interface type.
/// </summary>
protected TypeName Interface_IAnimatedVisualSource2 { get; } = new TypeName("Microsoft.UI.Xaml.Controls.IAnimatedVisualSource2");
/// <summary>
/// Information about the IAnimatedVisualSourceInfo implementation.
/// </summary>
@ -686,12 +702,8 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
string IAnimatedVisualSourceInfo.Namespace => _namespace;
TypeName IAnimatedVisualSourceInfo.InterfaceType => _interfaceType;
IReadOnlyList<TypeName> IAnimatedVisualSourceInfo.AdditionalInterfaces => _additionalInterfaces;
bool IAnimatedVisualSourceInfo.IsInterfaceCustom => _isInterfaceCustom;
string IAnimatedVisualSourceInfo.ReusableExpressionAnimationFieldName => SingletonExpressionAnimationName;
string IAnimatedVisualSourceInfo.DurationTicksFieldName => DurationTicksFieldName;
@ -700,7 +712,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
bool IAnimatedVisualSourceInfo.Public => _generatePublicClass;
bool IAnimatedVisualSourceInfo.WinUi3 => _generateForWinui3;
Version IAnimatedVisualSourceInfo.WinUIVersion => _winUIVersion;
string IAnimatedVisualSourceInfo.ThemePropertiesFieldName => ThemePropertiesFieldName;

Просмотреть файл

@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics.CodeAnalysis;
namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
{
@ -12,7 +13,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
#if PUBLIC_UIDataCodeGen
public
#endif
sealed class TypeName
sealed class TypeName : IEquatable<TypeName>
{
internal TypeName(string namespaceName, string unqualifiedName)
{
@ -63,5 +64,17 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
/// and comparison.
/// </summary>
public string NormalizedNamespace { get; }
public override bool Equals(object? obj)
=> obj is TypeName other && Equals(other);
public override int GetHashCode() => UnqualifiedName.GetHashCode();
public override string ToString() => NormalizedQualifiedName;
public bool Equals([AllowNull] TypeName other)
=> !(other is null) &&
other.NormalizedNamespace == NormalizedNamespace &&
other.UnqualifiedName == UnqualifiedName;
}
}