Browse Source

Add program to merge XAML style files.

experiment/merged-fluent-theme
Steven Kirk 5 years ago
parent
commit
399bbca153
  1. 33
      Avalonia.sln
  2. 8
      samples/Sandbox/MainWindow.axaml.cs
  3. 6
      samples/Sandbox/Program.cs
  4. 3
      src/Avalonia.Styling/Avalonia.Styling.csproj
  5. 8
      src/Avalonia.Styling/Styling/Styles.cs
  6. 138
      src/tools/XamlStyleMerge/Program.cs
  7. 8
      src/tools/XamlStyleMerge/Properties/launchSettings.json
  8. 9
      src/tools/XamlStyleMerge/XamlStyleMerge.csproj

33
Avalonia.sln

@ -226,11 +226,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.ReactiveUI.Events"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sandbox", "samples\Sandbox\Sandbox.csproj", "{11BE52AF-E2DD-4CF0-B19A-05285ACAF571}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MicroComGenerator", "src\tools\MicroComGenerator\MicroComGenerator.csproj", "{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MicroComGenerator", "src\tools\MicroComGenerator\MicroComGenerator.csproj", "{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.MicroCom", "src\Avalonia.MicroCom\Avalonia.MicroCom.csproj", "{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.MicroCom", "src\Avalonia.MicroCom\Avalonia.MicroCom.csproj", "{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MiniMvvm", "samples\MiniMvvm\MiniMvvm.csproj", "{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MiniMvvm", "samples\MiniMvvm\MiniMvvm.csproj", "{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XamlStyleMerge", "src\tools\XamlStyleMerge\XamlStyleMerge.csproj", "{740C248D-C44F-44D5-90E0-89B7536CDDC7}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
@ -2142,6 +2144,30 @@ Global
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Release|iPhone.Build.0 = Release|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{740C248D-C44F-44D5-90E0-89B7536CDDC7}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{740C248D-C44F-44D5-90E0-89B7536CDDC7}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{740C248D-C44F-44D5-90E0-89B7536CDDC7}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{740C248D-C44F-44D5-90E0-89B7536CDDC7}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{740C248D-C44F-44D5-90E0-89B7536CDDC7}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{740C248D-C44F-44D5-90E0-89B7536CDDC7}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{740C248D-C44F-44D5-90E0-89B7536CDDC7}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{740C248D-C44F-44D5-90E0-89B7536CDDC7}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{740C248D-C44F-44D5-90E0-89B7536CDDC7}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{740C248D-C44F-44D5-90E0-89B7536CDDC7}.AppStore|iPhone.Build.0 = Debug|Any CPU
{740C248D-C44F-44D5-90E0-89B7536CDDC7}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{740C248D-C44F-44D5-90E0-89B7536CDDC7}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{740C248D-C44F-44D5-90E0-89B7536CDDC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{740C248D-C44F-44D5-90E0-89B7536CDDC7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{740C248D-C44F-44D5-90E0-89B7536CDDC7}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{740C248D-C44F-44D5-90E0-89B7536CDDC7}.Debug|iPhone.Build.0 = Debug|Any CPU
{740C248D-C44F-44D5-90E0-89B7536CDDC7}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{740C248D-C44F-44D5-90E0-89B7536CDDC7}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{740C248D-C44F-44D5-90E0-89B7536CDDC7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{740C248D-C44F-44D5-90E0-89B7536CDDC7}.Release|Any CPU.Build.0 = Release|Any CPU
{740C248D-C44F-44D5-90E0-89B7536CDDC7}.Release|iPhone.ActiveCfg = Release|Any CPU
{740C248D-C44F-44D5-90E0-89B7536CDDC7}.Release|iPhone.Build.0 = Release|Any CPU
{740C248D-C44F-44D5-90E0-89B7536CDDC7}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{740C248D-C44F-44D5-90E0-89B7536CDDC7}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -2203,6 +2229,7 @@ Global
{11BE52AF-E2DD-4CF0-B19A-05285ACAF571} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637}
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{740C248D-C44F-44D5-90E0-89B7536CDDC7} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {87366D66-1391-4D90-8999-95A620AD786A}

8
samples/Sandbox/MainWindow.axaml.cs

@ -1,7 +1,6 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.Win32.WinRT.Composition;
namespace Sandbox
{
@ -11,6 +10,13 @@ namespace Sandbox
{
this.InitializeComponent();
this.AttachDevTools();
this.Activated += MainWindow_Activated;
}
private void MainWindow_Activated(object sender, System.EventArgs e)
{
Program.sw.Stop();
Title = Program.sw.Elapsed.ToString();
}
private void InitializeComponent()

6
samples/Sandbox/Program.cs

@ -1,4 +1,5 @@
using Avalonia;
using System.Diagnostics;
using Avalonia;
namespace Sandbox
{
@ -6,10 +7,13 @@ namespace Sandbox
{
static void Main(string[] args)
{
sw.Start();
AppBuilder.Configure<App>()
.UsePlatformDetect()
.LogToTrace()
.StartWithClassicDesktopLifetime(args);
}
public static Stopwatch sw = new Stopwatch();
}
}

3
src/Avalonia.Styling/Avalonia.Styling.csproj

@ -4,6 +4,9 @@
<AssemblyName>Avalonia.Styling</AssemblyName>
<RootNamespace>Avalonia</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="JetBrains.Profiler.Api" Version="1.1.7" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Avalonia.Animation\Avalonia.Animation.csproj" />
<ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj" />

8
src/Avalonia.Styling/Styling/Styles.cs

@ -286,7 +286,15 @@ namespace Avalonia.Styling
if (Owner is object && style is IResourceProvider resourceProvider)
{
var profile = Owner.GetType().Name == "App";
if (profile)
JetBrains.Profiler.Api.MeasureProfiler.StartCollectingData();
resourceProvider.AddOwner(Owner);
if (profile)
JetBrains.Profiler.Api.MeasureProfiler.SaveData();
}
_cache = null;

138
src/tools/XamlStyleMerge/Program.cs

@ -0,0 +1,138 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Xml.Linq;
namespace XamlStyleMerge
{
class Program
{
private static readonly XNamespace s_ns = "https://github.com/avaloniaui";
private static readonly XNamespace s_xns = "http://schemas.microsoft.com/winfx/2006/xaml";
private static readonly List<XAttribute> s_namespaces = new List<XAttribute>();
private static readonly OrderedDictionary s_resources = new OrderedDictionary();
private static readonly List<XElement> s_styles = new List<XElement>();
private static string s_basePath = null!;
static void Main(string[] args)
{
if (args.Length == 0)
Console.WriteLine("Usage: XamlStyleMerge <input> [output]");
if (!UriParser.IsKnownScheme("avares"))
UriParser.Register(new GenericUriParser(
GenericUriParserOptions.GenericAuthority |
GenericUriParserOptions.NoUserInfo |
GenericUriParserOptions.NoPort |
GenericUriParserOptions.NoQuery |
GenericUriParserOptions.NoFragment), "avares", -1);
s_basePath = Path.GetDirectoryName(args[0])!;
var f = File.ReadAllText(args[0]);
var d = XDocument.Parse(f);
if (d.Root.Name != s_ns + "Styles")
{
throw new InvalidOperationException("File is not an Avalonia Styles document.");
}
ProcessStyles(d.Root);
foreach (var ns in s_namespaces)
{
if (d.Root.Attribute(ns.Name) is null)
d.Root.Add(ns);
}
d.Root.RemoveNodes();
d.Root.Add(new XElement(s_ns + "Styles.Resources", s_resources.Values));
d.Root.Add(s_styles);
var outFile = args.Length > 1 ? args[1] : "out.xaml";
d.Save(outFile);
}
private static void Process(string fileName)
{
var f = File.ReadAllText(fileName);
var d = XDocument.Parse(f);
if (d.Root.Name == s_ns + "Style")
ProcessStyle(d.Root);
else
ProcessStyles(d.Root);
}
private static void ProcessStyle(XElement element)
{
ProcessAttributes(element);
ProcessResources(element);
RemoveDesignTimeElements(element);
var selector = element.Attribute("Selector");
if (selector is object)
{
s_styles.Add(element);
}
}
private static void ProcessStyles(XElement element)
{
ProcessAttributes(element);
ProcessResources(element);
RemoveDesignTimeElements(element);
foreach (var child in element.Elements(s_ns + "StyleInclude"))
{
var source = new Uri(child.Attribute("Source").Value);
var fileName = Path.Combine(s_basePath, source.LocalPath.TrimStart('/'));
Process(fileName);
}
foreach (var child in element.Elements(s_ns + "Style"))
{
ProcessStyle(child);
}
}
private static void ProcessAttributes(XElement element)
{
foreach (var attr in element.Attributes().ToList())
{
if (attr.IsNamespaceDeclaration)
{
s_namespaces.Add(attr);
attr.Remove();
}
}
}
private static void ProcessResources(XElement element)
{
var resources = element.Element(s_ns + "Style.Resources") ??
element.Element(s_ns + "Styles.Resources");
if (resources is object)
{
foreach (var r in resources.Elements())
{
var key = r.Attribute(s_xns + "Key").Value;
s_resources[key] = r;
}
resources.ReplaceWith(null);
}
}
private static void RemoveDesignTimeElements(XElement element)
{
foreach (var e in element.Elements(s_ns + "Design.PreviewWith"))
e.Remove();
}
}
}

8
src/tools/XamlStyleMerge/Properties/launchSettings.json

@ -0,0 +1,8 @@
{
"profiles": {
"XamlStyleMerge": {
"commandName": "Project",
"commandLineArgs": "\"D:\\projects\\AvaloniaUI\\Avalonia\\src\\Avalonia.Themes.Fluent\\FluentDark.xaml\""
}
}
}

9
src/tools/XamlStyleMerge/XamlStyleMerge.csproj

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
Loading…
Cancel
Save