Browse Source

Merge pull request #1622 from jkoritzinsky/RemoveLegacyDesigner

Remove legacy designer
pull/1633/head
Jeremy Koritzinsky 8 years ago
committed by GitHub
parent
commit
82cd66c678
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 44
      Avalonia.sln
  2. 30
      build.cake
  3. 2
      build/XUnit.props
  4. 2
      parameters.cake
  5. 92
      src/Avalonia.DesignerSupport/DesignerApi.cs
  6. 100
      src/Avalonia.DesignerSupport/DesignerAssist.cs
  7. 6
      src/Windows/Avalonia.Designer/App.config
  8. 8
      src/Windows/Avalonia.Designer/App.xaml
  9. 28
      src/Windows/Avalonia.Designer/App.xaml.cs
  10. 225
      src/Windows/Avalonia.Designer/AppHost/AvaloniaAppHost.cs
  11. 99
      src/Windows/Avalonia.Designer/AppHost/HostedAppModel.cs
  12. 143
      src/Windows/Avalonia.Designer/AppHost/WindowHost.cs
  13. 126
      src/Windows/Avalonia.Designer/Avalonia.Designer.csproj
  14. 17
      src/Windows/Avalonia.Designer/AvaloniaDesigner.xaml
  15. 142
      src/Windows/Avalonia.Designer/AvaloniaDesigner.xaml.cs
  16. 137
      src/Windows/Avalonia.Designer/Comm/CommChannel.cs
  17. 18
      src/Windows/Avalonia.Designer/Comm/InitMessage.cs
  18. 166
      src/Windows/Avalonia.Designer/Comm/ProcessHost.cs
  19. 19
      src/Windows/Avalonia.Designer/Comm/StateMessage.cs
  20. 21
      src/Windows/Avalonia.Designer/Comm/UpdateXamlMessage.cs
  21. 19
      src/Windows/Avalonia.Designer/Comm/WindowCreatedMessage.cs
  22. 30
      src/Windows/Avalonia.Designer/DemoWindow.xaml
  23. 66
      src/Windows/Avalonia.Designer/DemoWindow.xaml.cs
  24. 34
      src/Windows/Avalonia.Designer/InProcDesigner/InProcDesignerView.xaml
  25. 98
      src/Windows/Avalonia.Designer/InProcDesigner/InProcDesignerView.xaml.cs
  26. 69
      src/Windows/Avalonia.Designer/Program.cs
  27. 36
      src/Windows/Avalonia.Designer/Properties/AssemblyInfo.cs
  28. 3
      src/Windows/Avalonia.Designer/README.txt
  29. 19
      src/Windows/Avalonia.Designer/Settings.cs
  30. 33
      src/Windows/Avalonia.Designer/WinApi.cs
  31. BIN
      src/Windows/Avalonia.Designer/avalonia.designer.snk
  32. 18
      tests/Avalonia.DesignerSupport.TestApp/App.config
  33. 164
      tests/Avalonia.DesignerSupport.TestApp/Avalonia.DesignerSupport.TestApp.csproj
  34. 9
      tests/Avalonia.DesignerSupport.TestApp/Program.cs
  35. 36
      tests/Avalonia.DesignerSupport.TestApp/Properties/AssemblyInfo.cs
  36. 63
      tests/Avalonia.DesignerSupport.TestApp/Properties/Resources.Designer.cs
  37. 117
      tests/Avalonia.DesignerSupport.TestApp/Properties/Resources.resx
  38. 26
      tests/Avalonia.DesignerSupport.TestApp/Properties/Settings.Designer.cs
  39. 7
      tests/Avalonia.DesignerSupport.TestApp/Properties/Settings.settings
  40. 62
      tests/Avalonia.DesignerSupport.Tests/Avalonia.DesignerSupport.Tests.csproj
  41. 89
      tests/Avalonia.DesignerSupport.Tests/Checker.cs
  42. 108
      tests/Avalonia.DesignerSupport.Tests/DesignerSupportTests.cs
  43. 36
      tests/Avalonia.DesignerSupport.Tests/Properties/AssemblyInfo.cs

44
Avalonia.sln

@ -1,4 +1,3 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2027
@ -15,8 +14,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Win32", "src\Windo
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Direct2D1", "src\Windows\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj", "{3E908F67-5543-4879-A1DC-08EACE79B3CD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Designer", "src\Windows\Avalonia.Designer\Avalonia.Designer.csproj", "{EC42600F-049B-43FF-AED1-8314D61B2749}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Input", "src\Avalonia.Input\Avalonia.Input.csproj", "{62024B2D-53EB-4638-B26B-85EEAA54866E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Interactivity", "src\Avalonia.Interactivity\Avalonia.Interactivity.csproj", "{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}"
@ -104,7 +101,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.DesignerSupport",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog", "samples\ControlCatalog\ControlCatalog.csproj", "{D0A739B9-3C68-4BA6-A328-41606954B6BD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog.Desktop", "samples\ControlCatalog.Desktop\ControlCatalog.Desktop.csproj", "{2B888490-D14A-4BCA-AB4B-48676FA93C9B}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.Desktop", "samples\ControlCatalog.Desktop\ControlCatalog.Desktop.csproj", "{2B888490-D14A-4BCA-AB4B-48676FA93C9B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog.iOS", "samples\ControlCatalog.iOS\ControlCatalog.iOS.csproj", "{57E0455D-D565-44BB-B069-EE1AA20F8337}"
EndProject
@ -410,38 +407,6 @@ Global
{3E908F67-5543-4879-A1DC-08EACE79B3CD}.Release|NetCoreOnly.ActiveCfg = Release|Any CPU
{3E908F67-5543-4879-A1DC-08EACE79B3CD}.Release|x86.ActiveCfg = Release|Any CPU
{3E908F67-5543-4879-A1DC-08EACE79B3CD}.Release|x86.Build.0 = Release|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.Ad-Hoc|NetCoreOnly.ActiveCfg = Debug|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.AppStore|Any CPU.Build.0 = Release|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.AppStore|iPhone.Build.0 = Release|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.AppStore|NetCoreOnly.ActiveCfg = Debug|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.AppStore|x86.ActiveCfg = Debug|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.Debug|iPhone.Build.0 = Debug|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.Debug|NetCoreOnly.ActiveCfg = Debug|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.Debug|x86.ActiveCfg = Debug|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.Release|Any CPU.Build.0 = Release|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.Release|iPhone.ActiveCfg = Release|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.Release|iPhone.Build.0 = Release|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.Release|NetCoreOnly.ActiveCfg = Release|Any CPU
{EC42600F-049B-43FF-AED1-8314D61B2749}.Release|x86.ActiveCfg = Release|Any CPU
{62024B2D-53EB-4638-B26B-85EEAA54866E}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{62024B2D-53EB-4638-B26B-85EEAA54866E}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{62024B2D-53EB-4638-B26B-85EEAA54866E}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
@ -1699,6 +1664,7 @@ Global
{52F55355-D120-42AC-8116-8410A7D602FA}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{52F55355-D120-42AC-8116-8410A7D602FA}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{52F55355-D120-42AC-8116-8410A7D602FA}.Debug|NetCoreOnly.ActiveCfg = Debug|Any CPU
{52F55355-D120-42AC-8116-8410A7D602FA}.Debug|NetCoreOnly.Build.0 = Debug|Any CPU
{52F55355-D120-42AC-8116-8410A7D602FA}.Debug|x86.ActiveCfg = Debug|Any CPU
{52F55355-D120-42AC-8116-8410A7D602FA}.Debug|x86.Build.0 = Debug|Any CPU
{52F55355-D120-42AC-8116-8410A7D602FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -1708,6 +1674,7 @@ Global
{52F55355-D120-42AC-8116-8410A7D602FA}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{52F55355-D120-42AC-8116-8410A7D602FA}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{52F55355-D120-42AC-8116-8410A7D602FA}.Release|NetCoreOnly.ActiveCfg = Release|Any CPU
{52F55355-D120-42AC-8116-8410A7D602FA}.Release|NetCoreOnly.Build.0 = Release|Any CPU
{52F55355-D120-42AC-8116-8410A7D602FA}.Release|x86.ActiveCfg = Release|Any CPU
{52F55355-D120-42AC-8116-8410A7D602FA}.Release|x86.Build.0 = Release|Any CPU
{F1381F98-4D24-409A-A6C5-1C5B1E08BB08}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
@ -1735,6 +1702,7 @@ Global
{F1381F98-4D24-409A-A6C5-1C5B1E08BB08}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{F1381F98-4D24-409A-A6C5-1C5B1E08BB08}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{F1381F98-4D24-409A-A6C5-1C5B1E08BB08}.Debug|NetCoreOnly.ActiveCfg = Debug|Any CPU
{F1381F98-4D24-409A-A6C5-1C5B1E08BB08}.Debug|NetCoreOnly.Build.0 = Debug|Any CPU
{F1381F98-4D24-409A-A6C5-1C5B1E08BB08}.Debug|x86.ActiveCfg = Debug|Any CPU
{F1381F98-4D24-409A-A6C5-1C5B1E08BB08}.Debug|x86.Build.0 = Debug|Any CPU
{F1381F98-4D24-409A-A6C5-1C5B1E08BB08}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -1744,6 +1712,7 @@ Global
{F1381F98-4D24-409A-A6C5-1C5B1E08BB08}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{F1381F98-4D24-409A-A6C5-1C5B1E08BB08}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{F1381F98-4D24-409A-A6C5-1C5B1E08BB08}.Release|NetCoreOnly.ActiveCfg = Release|Any CPU
{F1381F98-4D24-409A-A6C5-1C5B1E08BB08}.Release|NetCoreOnly.Build.0 = Release|Any CPU
{F1381F98-4D24-409A-A6C5-1C5B1E08BB08}.Release|x86.ActiveCfg = Release|Any CPU
{F1381F98-4D24-409A-A6C5-1C5B1E08BB08}.Release|x86.Build.0 = Release|Any CPU
{FBCAF3D0-2808-4934-8E96-3F607594517B}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
@ -2371,6 +2340,7 @@ Global
{050CC912-FF49-4A8B-B534-9544017446DD}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{050CC912-FF49-4A8B-B534-9544017446DD}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{050CC912-FF49-4A8B-B534-9544017446DD}.Debug|NetCoreOnly.ActiveCfg = Debug|Any CPU
{050CC912-FF49-4A8B-B534-9544017446DD}.Debug|NetCoreOnly.Build.0 = Debug|Any CPU
{050CC912-FF49-4A8B-B534-9544017446DD}.Debug|x86.ActiveCfg = Debug|Any CPU
{050CC912-FF49-4A8B-B534-9544017446DD}.Debug|x86.Build.0 = Debug|Any CPU
{050CC912-FF49-4A8B-B534-9544017446DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -2380,6 +2350,7 @@ Global
{050CC912-FF49-4A8B-B534-9544017446DD}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{050CC912-FF49-4A8B-B534-9544017446DD}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{050CC912-FF49-4A8B-B534-9544017446DD}.Release|NetCoreOnly.ActiveCfg = Release|Any CPU
{050CC912-FF49-4A8B-B534-9544017446DD}.Release|NetCoreOnly.Build.0 = Release|Any CPU
{050CC912-FF49-4A8B-B534-9544017446DD}.Release|x86.ActiveCfg = Release|Any CPU
{050CC912-FF49-4A8B-B534-9544017446DD}.Release|x86.Build.0 = Release|Any CPU
{F40FC0A2-1BC3-401C-BFC1-928EC4D4A9CE}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
@ -2505,7 +2476,6 @@ Global
GlobalSection(NestedProjects) = preSolution
{811A76CF-1CF6-440F-963B-BBE31BD72A82} = {B39A8919-9F95-48FE-AD7B-76E08B509888}
{3E908F67-5543-4879-A1DC-08EACE79B3CD} = {B39A8919-9F95-48FE-AD7B-76E08B509888}
{EC42600F-049B-43FF-AED1-8314D61B2749} = {B39A8919-9F95-48FE-AD7B-76E08B509888}
{47ECDF59-DEF8-4C53-87B1-2098A3429059} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{5CCB5571-7C30-4E7D-967D-0E2158EBD91F} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{76716382-3159-460E-BDA6-C5715CF606D7} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}

30
build.cake

@ -93,7 +93,6 @@ Task("Clean")
CleanDirectory(parameters.NugetRoot);
CleanDirectory(parameters.ZipRoot);
CleanDirectory(parameters.BinRoot);
CleanDirectory(parameters.DesignerTestsRoot);
});
Task("Restore-NuGet-Packages")
@ -183,7 +182,7 @@ void RunCoreTest(string project, Parameters parameters, bool coreOnly = false)
Task("Run-Unit-Tests")
.IsDependentOn("Build")
.IsDependentOn("Run-Designer-Unit-Tests")
.IsDependentOn("Run-Designer-Tests")
.IsDependentOn("Run-Render-Tests")
.WithCriteria(() => !parameters.SkipTests)
.Does(() => {
@ -202,6 +201,13 @@ Task("Run-Unit-Tests")
}
});
Task("Run-Designer-Tests")
.IsDependentOn("Build")
.WithCriteria(() => !parameters.SkipTests)
.Does(() => {
RunCoreTest("./tests/Avalonia.DesignerSupport.Tests", parameters, false);
});
Task("Run-Render-Tests")
.IsDependentOn("Build")
.WithCriteria(() => !parameters.SkipTests && parameters.IsRunningOnWindows)
@ -210,25 +216,6 @@ Task("Run-Render-Tests")
RunCoreTest("./tests/Avalonia.Direct2D1.RenderTests/Avalonia.Direct2D1.RenderTests.csproj", parameters, true);
});
Task("Run-Designer-Unit-Tests")
.IsDependentOn("Build")
.WithCriteria(() => !parameters.SkipTests && parameters.IsRunningOnWindows)
.Does(() =>
{
var toolPath = (parameters.IsPlatformAnyCPU || parameters.IsPlatformX86) ?
Context.Tools.Resolve("xunit.console.x86.exe") :
Context.Tools.Resolve("xunit.console.exe");
var xUnitSettings = new XUnit2Settings
{
ToolPath = toolPath,
Parallelism = ParallelismOption.None,
ShadowCopy = false,
};
XUnit2("./artifacts/designer-tests/Avalonia.DesignerSupport.Tests.dll", xUnitSettings);
});
Task("Copy-Files")
.IsDependentOn("Run-Unit-Tests")
.Does(() =>
@ -376,7 +363,6 @@ Task("Inspect")
{
var badIssues = new []{"PossibleNullReferenceException"};
var whitelist = new []{"tests", "src\\android", "src\\ios",
"src\\windows\\avalonia.designer",
"src\\markup\\avalonia.markup.xaml\\portablexaml\\portable.xaml.github"};
Information("Running code inspections");

2
build/XUnit.props

@ -8,7 +8,7 @@
<PackageReference Include="xunit.extensibility.execution" Version="2.3.0" />
<PackageReference Include="xunit.runner.console" Version="2.3.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.0" />
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.0" />
<PackageReference Include="Xunit.SkippableFact" Version="1.3.6" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp2.0'">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />

2
parameters.cake

@ -30,7 +30,6 @@ public class Parameters
public DirectoryPath NugetRoot { get; private set; }
public DirectoryPath ZipRoot { get; private set; }
public DirectoryPath BinRoot { get; private set; }
public DirectoryPath DesignerTestsRoot { get; private set; }
public string DirSuffix { get; private set; }
public string DirSuffixIOS { get; private set; }
public DirectoryPathCollection BuildDirs { get; private set; }
@ -106,7 +105,6 @@ public class Parameters
NugetRoot = ArtifactsDir.Combine("nuget");
ZipRoot = ArtifactsDir.Combine("zip");
BinRoot = ArtifactsDir.Combine("bin");
DesignerTestsRoot = ArtifactsDir.Combine("designer-tests");
BuildDirs = context.GetDirectories("**/bin") + context.GetDirectories("**/obj");

92
src/Avalonia.DesignerSupport/DesignerApi.cs

@ -1,92 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace Avalonia.DesignerSupport
{
class DesignerApiDictionary
{
public Dictionary<string, object> Dictionary { get; set; }
public DesignerApiDictionary(Dictionary<string, object> dictionary)
{
Dictionary = dictionary;
}
protected object Get([CallerMemberName] string name = null)
{
object rv;
Dictionary.TryGetValue(name, out rv);
return rv;
}
protected void Set(object value, [CallerMemberName] string name = null)
{
Dictionary[name] = value;
}
}
class DesignerApi : DesignerApiDictionary
{
public Action<string> UpdateXaml
{
get { return (Action<string>) Get(); }
set {Set(value); }
}
public Action<Dictionary<string, object>> UpdateXaml2
{
get { return (Action<Dictionary<string, object>>)Get(); }
set { Set(value); }
}
public Action OnResize
{
get { return (Action) Get(); }
set { Set(value);}
}
public Action<IntPtr> OnWindowCreated
{
set { Set(value); }
get { return (Action<IntPtr>) Get(); }
}
public Action<double> SetScalingFactor
{
set { Set(value);}
get { return (Action<double>) Get(); }
}
public DesignerApi(Dictionary<string, object> dictionary) : base(dictionary)
{
}
}
class DesignerApiXamlFileInfo : DesignerApiDictionary
{
public string Xaml
{
get { return (string)Get(); }
set { Set(value); }
}
public string AssemblyPath
{
get { return (string) Get(); }
set { Set(value); }
}
public DesignerApiXamlFileInfo(Dictionary<string, object> dictionary) : base(dictionary)
{
}
public DesignerApiXamlFileInfo(): base(new Dictionary<string, object>())
{
}
}
}

100
src/Avalonia.DesignerSupport/DesignerAssist.cs

@ -1,100 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using Avalonia.Controls;
using Avalonia.Controls.Platform;
using Avalonia.Markup.Xaml;
using Avalonia.Platform;
using Avalonia.Styling;
using Avalonia.Themes.Default;
namespace Avalonia.DesignerSupport
{
class DesignerAssist
{
class DesignerApp : Application
{
public override void Initialize()
{
Styles.Add(new DefaultTheme());
var loader = new AvaloniaXamlLoader();
var baseLight = (IStyle)loader.Load(
new Uri("resm:Avalonia.Themes.Default.Accents.BaseLight.xaml?assembly=Avalonia.Themes.Default"), null);
Styles.Add(baseLight);
}
}
public static DesignerApi Api { get; set; }
public static void Init(Dictionary<string, object> shared)
{
Design.IsDesignMode = true;
Api = new DesignerApi(shared) {UpdateXaml = UpdateXaml, UpdateXaml2 = UpdateXaml2, SetScalingFactor = SetScalingFactor};
var runtimeAssembly = Assembly.Load(new AssemblyName("Avalonia.DotNetFrameworkRuntime"));
var plat = (IRuntimePlatform) Activator.CreateInstance(runtimeAssembly
.DefinedTypes.First(typeof (IRuntimePlatform).GetTypeInfo().IsAssignableFrom).AsType());
TypeInfo app = null;
var asms = plat.GetLoadedAssemblies();
foreach (var asm in asms)
{
if(Equals(asm, typeof(Application).GetTypeInfo().Assembly) || Equals(asm, typeof(DesignerApp).GetTypeInfo().Assembly))
continue;
try
{
app = asm.DefinedTypes.Where(typeof (Application).GetTypeInfo().IsAssignableFrom).FirstOrDefault();
if (app != null)
break;
}
catch
{
//Ignore, Assembly.DefinedTypes threw an exception, we can't do anything about that
}
}
var builderType = runtimeAssembly.GetType("Avalonia.AppBuilder");
var builder = (dynamic)Activator.CreateInstance(builderType,
app == null ? new DesignerApp() : (Application) Activator.CreateInstance(app.AsType()));
builder
.UseWindowingSubsystem("Avalonia.Win32")
.UseRenderingSubsystem("Avalonia.Direct2D1")
.SetupWithoutStarting();
}
private static void SetScalingFactor(double factor)
{
PlatformManager.SetDesignerScalingFactor(factor);
s_currentWindow?.PlatformImpl?.Resize(s_currentWindow.ClientSize);
}
static Window s_currentWindow;
private static void UpdateXaml(string xaml) => UpdateXaml2(new DesignerApiXamlFileInfo
{
Xaml = xaml
}.Dictionary);
private static void UpdateXaml2(Dictionary<string, object> dic)
{
var xamlInfo = new DesignerApiXamlFileInfo(dic);
Window window = DesignWindowLoader.LoadDesignerWindow(xamlInfo.Xaml, xamlInfo.AssemblyPath);
s_currentWindow?.Close();
s_currentWindow = window;
// ReSharper disable once PossibleNullReferenceException
// Always not null at this point
Api.OnWindowCreated?.Invoke(window.PlatformImpl.Handle.Handle);
Api.OnResize?.Invoke();
}
}
}

6
src/Windows/Avalonia.Designer/App.config

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
</startup>
</configuration>

8
src/Windows/Avalonia.Designer/App.xaml

@ -1,8 +0,0 @@
<Application x:Class="Avalonia.Designer.App" x:ClassModifier="internal"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" >
</Application>

28
src/Windows/Avalonia.Designer/App.xaml.cs

@ -1,28 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Avalonia.Designer
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
internal partial class App
{
public App()
{
InitializeComponent();
}
}
}

225
src/Windows/Avalonia.Designer/AppHost/AvaloniaAppHost.cs

@ -1,225 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Windows.Forms.Integration;
using System.Xml;
using Avalonia.Designer.Comm;
using Avalonia.Designer.InProcDesigner;
using Timer = System.Windows.Forms.Timer;
using Avalonia.DesignerSupport;
namespace Avalonia.Designer.AppHost
{
class AvaloniaAppHost
{
private string _appDir;
private readonly CommChannel _comm;
private string _lastXaml;
private string _currentXaml;
private string _currentSourceAssembly;
private bool _initSuccess;
private readonly HostedAppModel _appModel;
private Control _window;
public AvaloniaAppHost(CommChannel channel)
{
_comm = channel;
_appModel = new HostedAppModel(this);
}
public void Start()
{
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
_comm.OnMessage += Channel_OnMessage;
_comm.Start();
}
private void Channel_OnMessage(object obj)
{
var init = obj as InitMessage;
if (init != null)
{
Init(init.TargetExe);
}
var updateXaml = obj as UpdateXamlMessage;
if (updateXaml != null)
{
_currentXaml = updateXaml.Xaml;
_currentSourceAssembly = updateXaml.AssemblyPath;
}
}
void UpdateState(string state)
{
_comm.SendMessage(new StateMessage(state));
}
Type LookupType(params string[] names)
{
var asms = AppDomain.CurrentDomain.GetAssemblies();
foreach (var asm in asms)
{
foreach (var name in names)
{
var found = asm.GetType(name, false, true);
if (found != null)
return found;
}
}
throw new TypeLoadException("Unable to find any of types: " + string.Join(",", names));
}
private MethodInfo LookupStaticMethod(string typeName, string method)
{
var type = LookupType(typeName);
var methods = type.GetMethods();
return methods.First(m => m.Name == method);
}
private void Init(string targetExe)
{
var log = new StringBuilder();
try
{
DoInit(targetExe, log);
}
catch (Exception e)
{
UpdateState("Unable to load Avalonia:\n\n" + e + "\n\n" + log);
}
}
private void DoInit(string targetExe, StringBuilder logger)
{
_appDir = Path.GetFullPath(Path.GetDirectoryName(targetExe));
Directory.SetCurrentDirectory(_appDir);
Action<string> log = s =>
{
UpdateState(s);
logger.AppendLine(s);
};
log("Loading assemblies from " + _appDir);
var asms = new List<Assembly>();
foreach(var asm in Directory.GetFiles(_appDir).Where(f=>f.ToLower().EndsWith(".dll")||f.ToLower().EndsWith(".exe")))
try
{
log("Trying to load " + asm);
asms.Add(Assembly.LoadFrom(asm));
}
catch (Exception e)
{
logger.AppendLine(e.ToString());
}
log("Initializing built-in designer");
var dic = new Dictionary<string, object>();
Api = new DesignerApi(dic) {OnResize = OnResize, OnWindowCreated = OnWindowCreated};
LookupStaticMethod("Avalonia.DesignerSupport.DesignerAssist", "Init").Invoke(null, new object[] {dic});
_window = new Control
{
Controls =
{
new ElementHost()
{
Child = new InProcDesignerView(_appModel),
Dock = DockStyle.Fill
}
}
};
_window.CreateControl();
new Timer {Interval = 200, Enabled = true}.Tick += delegate { XamlUpdater(); };
_comm.SendMessage(new WindowCreatedMessage(_window.Handle));
_initSuccess = true;
}
private void OnWindowCreated(IntPtr hWnd)
{
_appModel.NativeWindowHandle = hWnd;
}
public DesignerApi Api { get; set; }
bool ValidateXml(string xml)
{
try
{
var rdr = new XmlTextReader(new StringReader(xml));
while (rdr.Read())
{
}
}
catch
{
return false;
}
return true;
}
private void OnResize()
{
}
void XamlUpdater()
{
if (!_initSuccess)
return;
if(_lastXaml == _currentXaml)
return;
_lastXaml = _currentXaml;
if (!ValidateXml(_currentXaml))
{
_appModel.SetError("Invalid markup");
return;
}
try
{
if (Api.UpdateXaml2 != null)
{
Api.UpdateXaml2(new DesignerApiXamlFileInfo
{
AssemblyPath = _currentSourceAssembly,
Xaml = _currentXaml
}.Dictionary);
}
else
Api.UpdateXaml(_currentXaml);
_appModel.SetError(null);
}
catch (Exception e)
{
_appModel.SetError("XAML load error", e.ToString());
}
}
private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
string assemblyPath = Path.Combine(_appDir, new AssemblyName(args.Name).Name + ".dll");
if (File.Exists(assemblyPath) == false) return null;
Assembly assembly = Assembly.LoadFrom(assemblyPath);
return assembly;
}
}
static class Helper
{
public static object Prop(this object obj, string name) => obj.GetType().GetProperty(name).GetValue(obj);
}
}

99
src/Windows/Avalonia.Designer/AppHost/HostedAppModel.cs

@ -1,99 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using JetBrains.Annotations;
namespace Avalonia.Designer.AppHost
{
public class HostedAppModel : INotifyPropertyChanged
{
private readonly AvaloniaAppHost _host;
private IntPtr _nativeWindowHandle;
private string _error;
private string _errorDetails;
internal HostedAppModel(AvaloniaAppHost host)
{
_host = host;
Background = Settings.Background;
}
public IntPtr NativeWindowHandle
{
get { return _nativeWindowHandle; }
set
{
if (value.Equals(_nativeWindowHandle)) return;
_nativeWindowHandle = value;
OnPropertyChanged();
}
}
public string Error
{
get { return _error; }
private set
{
if (value == _error) return;
_error = value;
OnPropertyChanged();
}
}
public string ErrorDetails
{
get { return _errorDetails; }
private set
{
if (value == _errorDetails) return;
_errorDetails = value;
OnPropertyChanged();
}
}
public string Background
{
get { return _background; }
set
{
if (value == _background) return;
_background = value;
OnPropertyChanged();
}
}
public IReadOnlyList<double> AvailableScalingFactors => new List<double>() {1, 2, 4, 8};
public double CurrentScalingFactor
{
get { return _currentScalingFactor; }
set
{
_currentScalingFactor = value;
_host.Api.SetScalingFactor(value);
}
}
public void SetError(string error, string details = null)
{
Error = error;
ErrorDetails = details;
}
double _currentScalingFactor = 1;
private string _background;
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

143
src/Windows/Avalonia.Designer/AppHost/WindowHost.cs

@ -1,143 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Avalonia.Designer.AppHost
{
class WindowHost : UserControl
{
private readonly bool _supportScroll;
public WindowHost(bool supportScroll)
{
_supportScroll = supportScroll;
if (_supportScroll)
{
AutoScroll = true;
VerticalScroll.Enabled = true;
HorizontalScroll.Enabled = true;
}
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
Controls.Add(_windowHost);
_windowHost.Anchor = AnchorStyles.None;
if (!supportScroll)
_windowHost.Visible = false;
_timer.Tick += delegate
{
ReloadSettings();
FixWindow();
};
}
private void ReloadSettings()
{
var bkg = Settings.Background;
var color = System.Drawing.ColorTranslator.FromHtml(bkg);
if (BackColor != color)
BackColor = color;
}
private readonly Control _windowHost = new Control() {Text = "WindowWrapper"};
private readonly Timer _timer = new Timer {Enabled = true, Interval = 50};
private IntPtr _hWnd;
private int _desiredWidth;
private int _desiredHeight;
private const int WM_HSCROLL = 0x114;
private const int WM_VSCROLL = 0x115;
protected override void WndProc(ref Message m)
{
if ((m.Msg == WM_HSCROLL || m.Msg == WM_VSCROLL)
&& (((int) m.WParam & 0xFFFF) == 5))
{
// Change SB_THUMBTRACK to SB_THUMBPOSITION
m.WParam = (IntPtr) (((int) m.WParam & ~0xFFFF) | 4);
}
base.WndProc(ref m);
}
protected override void OnPaint(PaintEventArgs e)
{
using (var b = new SolidBrush(BackColor))
e.Graphics.FillRectangle(b, e.ClipRectangle);
}
void FixPosition()
{
var newScrollSize = new Size(_desiredWidth, _desiredHeight);
if (AutoScrollMinSize != newScrollSize)
AutoScrollMinSize = newScrollSize;
var width = Width - AutoScrollMargin.Width;
var height = Height - AutoScrollMargin.Height;
var x = Math.Max(0, (width - _windowHost.Width)/2);
var y = Math.Max(0, (height - _windowHost.Height)/2);
var newLoc = new Point(x - HorizontalScroll.Value, y - VerticalScroll.Value);
if(_windowHost.Location != newLoc)
_windowHost.Location = newLoc;
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
_timer.Dispose();
}
base.Dispose(disposing);
}
public void SetWindow(IntPtr hWnd)
{
if (_hWnd != IntPtr.Zero)
WinApi.SendMessage(_hWnd, WinApi.WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
_hWnd = hWnd;
if (_hWnd != IntPtr.Zero)
{
WinApi.SetParent(hWnd, _supportScroll ? _windowHost.Handle : Handle);
FixWindow();
}
}
void FixWindow()
{
if (_hWnd != IntPtr.Zero)
{
if (_supportScroll)
{
WinApi.RECT rc;
WinApi.GetWindowRect(_hWnd, out rc);
_desiredWidth = rc.Right - rc.Left;
_desiredHeight = rc.Bottom - rc.Top;
var pt = _windowHost.PointToClient(new Point(rc.Left, rc.Top));
if (
!(pt.Y == 0 && pt.X == 0 && _desiredWidth == _windowHost.Width &&
_desiredHeight == _windowHost.Height))
{
_windowHost.Width = _desiredWidth;
_windowHost.Height = _desiredHeight;
WinApi.MoveWindow(_hWnd, 0, 0, _desiredWidth, _desiredHeight, true);
}
FixPosition();
}
else
{
WinApi.MoveWindow(_hWnd, 0, 0, Width, Height, true);
}
}
}
protected override void OnResize(EventArgs e)
{
FixWindow();
base.OnResize(e);
}
}
}

126
src/Windows/Avalonia.Designer/Avalonia.Designer.csproj

@ -1,126 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{EC42600F-049B-43FF-AED1-8314D61B2749}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Avalonia.Designer</RootNamespace>
<AssemblyName>Avalonia.Designer</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<UseVSHostingProcess>true</UseVSHostingProcess>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<SignAssembly>true</SignAssembly>
</PropertyGroup>
<PropertyGroup>
<AssemblyOriginatorKeyFile>avalonia.designer.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<ItemGroup>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
<Reference Include="WindowsFormsIntegration" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\Avalonia.DesignerSupport\DesignerApi.cs">
<Link>DesignerApi.cs</Link>
</Compile>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
</Compile>
<Compile Include="AppHost\HostedAppModel.cs" />
<Compile Include="AppHost\AvaloniaAppHost.cs" />
<Compile Include="AppHost\WindowHost.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Comm\CommChannel.cs" />
<Compile Include="Comm\InitMessage.cs" />
<Compile Include="Comm\ProcessHost.cs" />
<Compile Include="Comm\StateMessage.cs" />
<Compile Include="Comm\UpdateXamlMessage.cs" />
<Compile Include="Comm\WindowCreatedMessage.cs" />
<Compile Include="DemoWindow.xaml.cs">
<DependentUpon>DemoWindow.xaml</DependentUpon>
</Compile>
<Compile Include="InProcDesigner\InProcDesignerView.xaml.cs">
<DependentUpon>InProcDesignerView.xaml</DependentUpon>
</Compile>
<Compile Include="AvaloniaDesigner.xaml.cs">
<DependentUpon>AvaloniaDesigner.xaml</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Settings.cs" />
<Compile Include="WinApi.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="avalonia.designer.snk" />
</ItemGroup>
<ItemGroup>
<Page Include="App.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="DemoWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="InProcDesigner\InProcDesignerView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="AvaloniaDesigner.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Content Include="README.txt" />
</ItemGroup>
<ItemGroup>
<Folder Include="Metadata\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\..\build\JetBrains.Annotations.props" />
</Project>

17
src/Windows/Avalonia.Designer/AvaloniaDesigner.xaml

@ -1,17 +0,0 @@
<UserControl x:Class="Avalonia.Designer.AvaloniaDesigner"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<WindowsFormsHost Background="White" x:Name="NativeContainer" Panel.ZIndex="1"/>
<ScrollViewer VerticalScrollBarVisibility="Auto" Panel.ZIndex="0">
<TextBox IsReadOnly="True" TextWrapping="WrapWithOverflow" x:Name="State"/>
</ScrollViewer>
<StackPanel x:Name="ErrorContainer">
<TextBlock />
</StackPanel>
</Grid>
</UserControl>

142
src/Windows/Avalonia.Designer/AvaloniaDesigner.xaml.cs

@ -1,142 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms.Integration;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Avalonia.Designer.AppHost;
using Avalonia.Designer.Comm;
namespace Avalonia.Designer
{
/// <summary>
/// Interaction logic for PerpexDesigner.xaml
/// </summary>
public partial class AvaloniaDesigner
{
public static readonly DependencyProperty TargetExeProperty = DependencyProperty.Register(
"TargetExe", typeof (string), typeof (AvaloniaDesigner), new FrameworkPropertyMetadata(TargetExeChanged));
private static void TargetExeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((AvaloniaDesigner) d).RestartProcess();
}
public string TargetExe
{
get { return (string) GetValue(TargetExeProperty); }
set { SetValue(TargetExeProperty, value); }
}
public static readonly DependencyProperty XamlProperty = DependencyProperty.Register(
"Xaml", typeof (string), typeof (AvaloniaDesigner), new FrameworkPropertyMetadata(XamlChanged));
private static void XamlChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((AvaloniaDesigner) d).OnXamlChanged();
}
public string Xaml
{
get { return (string) GetValue(XamlProperty); }
set { SetValue(XamlProperty, value); }
}
public static readonly DependencyProperty SourceAssemblyProperty = DependencyProperty.Register(
"SourceAssembly", typeof (string), typeof (AvaloniaDesigner), new FrameworkPropertyMetadata(XamlChanged));
public string SourceAssembly
{
get { return (string) GetValue(SourceAssemblyProperty); }
set { SetValue(SourceAssemblyProperty, value); }
}
private readonly ProcessHost _host = new ProcessHost();
public AvaloniaDesigner()
{
InitializeComponent();
BindingOperations.SetBinding(State, TextBox.TextProperty,
new Binding(nameof(ProcessHost.State)) {Source = _host, Mode = BindingMode.OneWay});
_host.PropertyChanged += _host_PropertyChanged;
}
private void _host_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(ProcessHost.WindowHandle))
{
ResetNativeContainer();
if(_host.WindowHandle == IntPtr.Zero)
return;
NativeContainer.Child = new WindowHost(false);
var wndHost = ((WindowHost) NativeContainer.Child);
wndHost.SetWindow(_host.WindowHandle);
}
}
void ResetNativeContainer()
{
if (NativeContainer.Child != null)
{
var child = NativeContainer.Child;
NativeContainer.Child = null;
child.Dispose();
}
}
public void KillProcess()
{
_host.Kill();
ResetNativeContainer();
}
bool CheckTargetExeOrSetError()
{
if (string.IsNullOrEmpty(TargetExe))
{
_host.State = "No target exe found";
return false;
}
if (File.Exists(TargetExe ?? ""))
return true;
_host.State = "No target binary found, build your project";
return false;
}
public void RestartProcess()
{
KillProcess();
if(!CheckTargetExeOrSetError())
return;
if(string.IsNullOrEmpty(Xaml))
return;
_host.Start(TargetExe, Xaml, SourceAssembly);
}
private void OnXamlChanged()
{
if (!CheckTargetExeOrSetError())
return;
if (!_host.IsAlive)
_host.Start(TargetExe, Xaml, SourceAssembly);
else
_host.UpdateXaml(Xaml ?? "", SourceAssembly);
}
}
}

137
src/Windows/Avalonia.Designer/Comm/CommChannel.cs

@ -1,137 +0,0 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Threading;
namespace Avalonia.Designer.Comm
{
class CommChannel : IDisposable
{
private readonly BinaryReader _input;
private readonly BinaryWriter _output;
private readonly SynchronizationContext _dispatcher;
readonly TaskCompletionSource<bool> _terminating = new TaskCompletionSource<bool>();
private readonly BlockingCollection<byte[]> _outputQueue = new BlockingCollection<byte[]>();
public event Action<object> OnMessage;
public event Action Disposed;
public event Action<Exception> Exception;
public CommChannel(Stream input, Stream output)
{
_input = new BinaryReader(input);
_output = new BinaryWriter(output);
_dispatcher = SynchronizationContext.Current;
}
public void Start()
{
new Thread(WriterThread) { IsBackground = true }.Start();
new Thread(ReaderThread) { IsBackground = true }.Start();
}
public void SendMessage(object message)
{
var fmt = GetFormatter();
var ms = new MemoryStream();
fmt.Serialize(ms, message);
_outputQueue.Add(ms.ToArray());
}
void WriterThread()
{
while (!_terminating.Task.IsCompleted)
{
var item = _outputQueue.Take();
if(_terminating.Task.IsCompleted)
return;
try
{
_output.Write(item.Length);
_output.Write(item);
_output.Flush();
}
catch (Exception e)
{
Exception?.Invoke(e);
Dispose();
}
}
}
private async Task<byte[]> ReadAsyncOrNull(int count)
{
var readTask = Task.Factory.StartNew(() => _input.ReadBytes(count));
await Task.WhenAny(readTask, _terminating.Task);
if (_terminating.Task.IsCompleted)
return null;
return await readTask;
}
async void ReaderThread()
{
await Task.Delay(10).ConfigureAwait(false);
var fmt = GetFormatter();
while (!_terminating.Task.IsCompleted)
{
try
{
var lenb = await ReadAsyncOrNull(4);
if (lenb == null)
return;
var data = await ReadAsyncOrNull(BitConverter.ToInt32(lenb, 0));
if (data == null)
return;
var message = fmt.Deserialize(new MemoryStream(data));
_dispatcher.Post(_ => OnMessage?.Invoke(message), null);
}
catch(Exception e)
{
Dispose();
Exception?.Invoke(e);
return;
}
}
}
sealed class BinderFix : SerializationBinder
{
private const string ListNamePrefix = "System.Collections.Generic.List`1[[";
public override Type BindToType(string assemblyName, string typeName)
{
if (typeName.StartsWith(ListNamePrefix))
{
typeName = typeName.Substring(ListNamePrefix.Length);
typeName = typeName.Substring(0, typeName.IndexOf(","));
return typeof (List<>).MakeGenericType(BindToType(assemblyName, typeName));
}
return typeof (CommChannel).Assembly.GetType(typeName, false, true);
}
}
BinaryFormatter GetFormatter()
{
return new BinaryFormatter() {Binder = new BinderFix()};
}
public void Dispose()
{
if(_terminating.Task.IsCompleted)
return;
_terminating.TrySetResult(true);
_outputQueue.Add(null);
Disposed?.Invoke();
}
}
}

18
src/Windows/Avalonia.Designer/Comm/InitMessage.cs

@ -1,18 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Avalonia.Designer.Comm
{
[Serializable]
class InitMessage : UpdateXamlMessage
{
public string TargetExe { get; private set; }
public InitMessage(string targetExe, string xaml, string sourceAssembly) : base(xaml, sourceAssembly)
{
TargetExe = targetExe;
}
}
}

166
src/Windows/Avalonia.Designer/Comm/ProcessHost.cs

@ -1,166 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
namespace Avalonia.Designer.Comm
{
class ProcessHost : INotifyPropertyChanged
{
private CommChannel _comm;
private string _state;
public string State
{
get { return _state; }
set
{
if (_state == value)
return;
_state = value;
OnPropertyChanged();
}
}
private bool _isAlive;
private readonly SynchronizationContext _dispatcher;
private Process _proc;
public bool IsAlive
{
get { return _isAlive; }
set
{
if (_isAlive == value)
return;
_isAlive = value;
OnPropertyChanged();
}
}
private IntPtr _windowHandle;
public IntPtr WindowHandle
{
get { return _windowHandle; }
set
{
if (_windowHandle == value)
return;
_windowHandle = value;
OnPropertyChanged();
}
}
public ProcessHost()
{
_dispatcher = SynchronizationContext.Current;
}
void OnExited(object sender, EventArgs eventArgs)
{
if(_proc != sender)
return;
_proc = null;
_dispatcher.Post(_ =>
{
HandleExited();
}, null);
}
void HandleExited()
{
_comm.Dispose();
IsAlive = false;
WindowHandle = IntPtr.Zero;
State = "Designer process crashed";
}
public void Start(string targetExe, string initialXaml, string sourceAssembly)
{
if (_proc != null)
{
_proc.Exited -= OnExited;
try
{
_comm?.Dispose();
_proc.Kill();
}
catch { }
HandleExited();
State = "Restarting...";
}
var msg = new InitMessage(Path.GetFullPath(targetExe), initialXaml, sourceAssembly);
var exe = typeof (ProcessHost).Assembly.GetModules()[0].FullyQualifiedName;
_proc = new Process()
{
StartInfo = new ProcessStartInfo(exe, "--hosted")
{
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
},
EnableRaisingEvents = true
};
_proc.Exited += OnExited;
try
{
_proc.Start();
State = "Launching designer process...";
_comm = new CommChannel(_proc.StandardOutput.BaseStream, _proc.StandardInput.BaseStream);
_comm.OnMessage += OnMessage;
_comm.Start();
_comm.SendMessage(msg);
}
catch (Exception e)
{
State = e.ToString();
HandleExited();
}
IsAlive = true;
}
public void UpdateXaml(string xaml, string sourceAssembly)
{
_comm?.SendMessage(new UpdateXamlMessage(xaml, sourceAssembly));
}
private void OnMessage(object obj)
{
var stateMessage = obj as StateMessage;
if (stateMessage != null)
State = stateMessage.State;
var windowMessage = obj as WindowCreatedMessage;
if (windowMessage != null)
WindowHandle = windowMessage.Handle;
}
public void Kill()
{
try
{
_proc?.Kill();
_proc = null;
}
catch
{
//
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

19
src/Windows/Avalonia.Designer/Comm/StateMessage.cs

@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Avalonia.Designer.Comm
{
[Serializable]
class StateMessage
{
public StateMessage(string state)
{
State = state;
}
public string State { get; private set; }
}
}

21
src/Windows/Avalonia.Designer/Comm/UpdateXamlMessage.cs

@ -1,21 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Avalonia.Designer.Comm
{
[Serializable]
class UpdateXamlMessage
{
public UpdateXamlMessage(string xaml, string assemblyPath)
{
Xaml = xaml;
AssemblyPath = assemblyPath;
}
public string Xaml { get; private set; }
public string AssemblyPath { get; private set; }
}
}

19
src/Windows/Avalonia.Designer/Comm/WindowCreatedMessage.cs

@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Avalonia.Designer.Comm
{
[Serializable]
class WindowCreatedMessage
{
public WindowCreatedMessage(IntPtr handle)
{
Handle = handle;
}
public IntPtr Handle { get; private set; }
}
}

30
src/Windows/Avalonia.Designer/DemoWindow.xaml

@ -1,30 +0,0 @@
<Window x:Class="Avalonia.Designer.DemoWindow" x:ClassModifier="internal"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Avalonia.Designer"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<DockPanel LastChildFill="True">
<DockPanel Dock="Bottom" LastChildFill="True">
<TextBlock Margin="5,0">Target Exe: </TextBlock>
<Button DockPanel.Dock="Right">Load XAML</Button>
<Button Margin="5,0" DockPanel.Dock="Right" Click="SelectExeClicked">Select EXE</Button>
<Button Margin="5,0" DockPanel.Dock="Right" Click="RestartClicked">Restart</Button>
<TextBlock x:Name="TargetExe"/>
</DockPanel>
<DockPanel Dock="Bottom" LastChildFill="True" Margin="0,5">
<TextBlock Margin="5,0">Source Assembly:</TextBlock>
<Button DockPanel.Dock="Right" Click="SelectSourceClicked">Select Source Assembly</Button>
<TextBlock x:Name="SourceAssembly"/>
</DockPanel>
<UniformGrid Columns="1" Rows="2">
<local:AvaloniaDesigner x:Name="Designer"
TargetExe="{Binding ElementName=TargetExe, Path=Text, Mode=OneWay}"
Xaml="{Binding ElementName=Xaml, Path=Text, Mode=OneWay}"
SourceAssembly="{Binding ElementName=SourceAssembly, Path=Text, Mode=OneWay}"/>
<TextBox x:Name="Xaml"/>
</UniformGrid>
</DockPanel>
</Window>

66
src/Windows/Avalonia.Designer/DemoWindow.xaml.cs

@ -1,66 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Win32;
namespace Avalonia.Designer
{
internal partial class DemoWindow
{
public DemoWindow()
{
InitializeComponent();
}
public DemoWindow(string targetExe, string targetPath, string sourceAssembly) : this()
{
if (targetPath != null)
{
Xaml.Text = File.ReadAllText(targetPath);
}
SourceAssembly.Text = sourceAssembly ?? targetExe;
TargetExe.Text = targetExe;
}
static string OpenFile(string filter)
{
var dlg = new OpenFileDialog {Filter = filter};
if (dlg.ShowDialog() == true)
return dlg.FileName;
return null;
}
private void SelectExeClicked(object sender, RoutedEventArgs e)
{
var exe = OpenFile("exe|*.exe");
if (exe != null)
TargetExe.Text = exe;
}
private void RestartClicked(object sender, RoutedEventArgs e)
{
Designer.RestartProcess();
}
private void SelectSourceClicked(object sender, RoutedEventArgs e)
{
var exe = OpenFile("assembly|*.exe,*.dll");
if (exe != null)
SourceAssembly.Text = exe;
}
}
}

34
src/Windows/Avalonia.Designer/InProcDesigner/InProcDesignerView.xaml

@ -1,34 +0,0 @@
<UserControl x:Class="Avalonia.Designer.InProcDesigner.InProcDesignerView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:appHost="clr-namespace:Avalonia.Designer.AppHost"
xmlns:system="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" d:DataContext="{d:DesignInstance appHost:HostedAppModel}">
<DockPanel>
<StackPanel Orientation="Horizontal" DockPanel.Dock="Bottom">
<ComboBox ItemsSource="{Binding AvailableScalingFactors}" SelectedItem="{Binding CurrentScalingFactor, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type system:Double}">
<TextBlock><Run Text="{Binding .}"/>00%</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Rectangle Cursor="Hand" Stroke="Black" Width="{Binding RelativeSource={RelativeSource Self}, Path=ActualHeight}" Fill="{Binding Background}"
Margin="3" MouseDown="ColorPicker_OnClick"/>
<Border x:Name="ErrorPanel" BorderBrush="Red" BorderThickness="3" Padding="3">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Error}" FontSize="16"/>
<TextBlock x:Name="DetailsBlock" FontSize="16">
<Run> (</Run><Hyperlink Click="Hyperlink_OnClick">View details</Hyperlink><Run>)</Run>
</TextBlock>
</StackPanel>
</Border>
</StackPanel>
<WindowsFormsHost x:Name="WindowHostControl"/>
</DockPanel>
</UserControl>

98
src/Windows/Avalonia.Designer/InProcDesigner/InProcDesignerView.xaml.cs

@ -1,98 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Avalonia.Designer.AppHost;
using TextBox = System.Windows.Controls.TextBox;
using UserControl = System.Windows.Controls.UserControl;
namespace Avalonia.Designer.InProcDesigner
{
/// <summary>
/// Interaction logic for InProcDesignerView.xaml
/// </summary>
public partial class InProcDesignerView : UserControl
{
private readonly HostedAppModel _appModel;
private readonly WindowHost _host;
public InProcDesignerView(HostedAppModel appModel)
{
_appModel = appModel;
InitializeComponent();
DataContext = _appModel;
_appModel.PropertyChanged += ModelPropertyChanged;
WindowHostControl.Child = _host = new WindowHost(true);
HandleVisibility();
HandleWindow();
}
private void ModelPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(HostedAppModel.Error) || e.PropertyName == nameof(HostedAppModel.ErrorDetails))
HandleVisibility();
if (e.PropertyName == nameof(HostedAppModel.NativeWindowHandle))
HandleWindow();
}
private void HandleWindow()
{
_host.SetWindow(_appModel.NativeWindowHandle);
}
private void HandleVisibility()
{
ErrorPanel.Visibility = string.IsNullOrEmpty(_appModel.Error)
? Visibility.Collapsed
: Visibility.Visible;
DetailsBlock.Visibility = string.IsNullOrWhiteSpace(_appModel.ErrorDetails)
? Visibility.Collapsed
: Visibility.Visible;
}
public InProcDesignerView()
{
}
private void Hyperlink_OnClick(object sender, RoutedEventArgs e)
{
var wnd = new Window()
{
Content = new TextBox()
{
IsReadOnly = true,
AcceptsReturn = true,
TextWrapping = TextWrapping.Wrap,
Text = _appModel.ErrorDetails
}
};
wnd.ShowDialog();
}
private void ColorPicker_OnClick(object sender, MouseButtonEventArgs e)
{
var dlg = new ColorDialog() {Color = ColorTranslator.FromHtml(Settings.Background)};
if (dlg.ShowDialog(_host) == DialogResult.OK)
{
var color = ColorTranslator.ToHtml(dlg.Color);
_appModel.Background = color;
Settings.Background = color;
}
}
}
}

69
src/Windows/Avalonia.Designer/Program.cs

@ -1,69 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Threading;
using Avalonia.Designer.AppHost;
using Avalonia.Designer.Comm;
namespace Avalonia.Designer
{
class Program
{
[STAThread]
static void Main(string[] args)
{
if (!args.Contains("--hosted"))
DemoMain(args);
else
HostedMain();
}
static void HostedMain()
{
//Initialize sync context
SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext());
var comm = new CommChannel(Console.OpenStandardInput(), Console.OpenStandardOutput());
Console.SetOut(new NullTextWriter());
Console.SetError(new NullTextWriter());
comm.Disposed += () => Process.GetCurrentProcess().Kill();
comm.SendMessage(new StateMessage("Staying awhile and listening..."));
var service = new AvaloniaAppHost(comm);
service.Start();
Application.Run();
}
class NullTextWriter : TextWriter
{
public override Encoding Encoding => Encoding.UTF8;
public override void Write(char[] buffer, int index, int count)
{
}
public override void Write(char value)
{
}
}
private static void DemoMain(string[] args)
{
SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext());
var app = new App();
const string targetExe = "--exe=";
const string xaml = "--xaml=";
const string source = "--source=";
app.Run(new DemoWindow(
args.Where(a => a.StartsWith(targetExe)).Select(a => a.Substring(targetExe.Length)).FirstOrDefault(),
args.Where(a => a.StartsWith(xaml)).Select(a => a.Substring(xaml.Length)).FirstOrDefault(),
args.Where(a => a.StartsWith(source)).Select(a => a.Substring(source.Length)).FirstOrDefault()));
}
}
}

36
src/Windows/Avalonia.Designer/Properties/AssemblyInfo.cs

@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Avalonia.Designer")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Avalonia.Designer")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("ec42600f-049b-43ff-aed1-8314d61b2749")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

3
src/Windows/Avalonia.Designer/README.txt

@ -1,3 +0,0 @@
To load data from XamlTestApplication run with:
--exe=..\..\..\..\..\samples\XamlTestApplication\bin\Debug\XamlTestApplication.exe --xaml=..\..\..\..\..\samples\XamlTestApplication\Views\MainWindow.xaml

19
src/Windows/Avalonia.Designer/Settings.cs

@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Win32;
namespace Avalonia.Designer
{
static class Settings
{
static readonly string Root = @"HKEY_CURRENT_USER\Software\AvaloniaUI\Designer";
public static string Background
{
get { return Registry.GetValue(Root, "Background", "#f3f3f3")?.ToString() ?? "#f3f3f3"; }
set { Registry.SetValue(Root, "Background", value); }
}
}
}

33
src/Windows/Avalonia.Designer/WinApi.cs

@ -1,33 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace Avalonia.Designer
{
class WinApi
{
[DllImport("user32.dll", SetLastError = true)]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
[DllImport("user32.dll")]
public static extern bool SetParent(IntPtr hWnd, IntPtr hWndNewParent);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
public const uint WM_CLOSE = 0x0010;
[DllImport("user32.dll", SetLastError = true)]
public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left; // x position of upper-left corner
public int Top; // y position of upper-left corner
public int Right; // x position of lower-right corner
public int Bottom; // y position of lower-right corner
}
}
}

BIN
src/Windows/Avalonia.Designer/avalonia.designer.snk

Binary file not shown.

18
tests/Avalonia.DesignerSupport.TestApp/App.config

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7"/>
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="SharpDX" publicKeyToken="b4dcf0f35e5521f1" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-3.1.1.0" newVersion="3.1.1.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="SharpDX.DXGI" publicKeyToken="b4dcf0f35e5521f1" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-3.1.1.0" newVersion="3.1.1.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

164
tests/Avalonia.DesignerSupport.TestApp/Avalonia.DesignerSupport.TestApp.csproj

@ -1,151 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{F1381F98-4D24-409A-A6C5-1C5B1E08BB08}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Avalonia.DesignerSupport.TestApp</RootNamespace>
<AssemblyName>Avalonia.DesignerSupport.TestApp</AssemblyName>
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFrameworkProfile />
<OutputPath>..\..\artifacts\designer-tests\</OutputPath>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
</Compile>
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<EmbeddedResource Include="App.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<Compile Update="**\*.xaml.cs">
<DependentUpon>%(Filename)</DependentUpon>
</Compile>
<EmbeddedResource Include="MainWindow.xaml">
<EmbeddedResource Include="**\*.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<ProjectReference Include="..\..\src\Avalonia.DesignerSupport\Avalonia.DesignerSupport.csproj" />
<ProjectReference Include="..\..\src\Avalonia.DotNetCoreRuntime\Avalonia.DotNetCoreRuntime.csproj" />
<ProjectReference Include="..\..\src\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj" />
<ProjectReference Include="..\..\src\Markup\Avalonia.Markup\Avalonia.Markup.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Animation\Avalonia.Animation.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Base\Avalonia.Base.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Controls\Avalonia.Controls.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Input\Avalonia.Input.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Interactivity\Avalonia.Interactivity.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Layout\Avalonia.Layout.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Visuals\Avalonia.Visuals.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Styling\Avalonia.Styling.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Avalonia.Animation\Avalonia.Animation.csproj">
<Project>{d211e587-d8bc-45b9-95a4-f297c8fa5200}</Project>
<Name>Avalonia.Animation</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Base\Avalonia.Base.csproj">
<Project>{b09b78d8-9b26-48b0-9149-d64a2f120f3f}</Project>
<Name>Avalonia.Base</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Controls\Avalonia.Controls.csproj">
<Project>{d2221c82-4a25-4583-9b43-d791e3f6820c}</Project>
<Name>Avalonia.Controls</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.DesignerSupport\Avalonia.DesignerSupport.csproj">
<Project>{799a7bb5-3c2c-48b6-85a7-406a12c420da}</Project>
<Name>Avalonia.DesignerSupport</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.DotNetFrameworkRuntime\Avalonia.DotNetFrameworkRuntime.csproj">
<Project>{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}</Project>
<Name>Avalonia.DotNetFrameworkRuntime</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Input\Avalonia.Input.csproj">
<Project>{62024b2d-53eb-4638-b26b-85eeaa54866e}</Project>
<Name>Avalonia.Input</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Interactivity\Avalonia.Interactivity.csproj">
<Project>{6b0ed19d-a08b-461c-a9d9-a9ee40b0c06b}</Project>
<Name>Avalonia.Interactivity</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Layout\Avalonia.Layout.csproj">
<Project>{42472427-4774-4c81-8aff-9f27b8e31721}</Project>
<Name>Avalonia.Layout</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Visuals\Avalonia.Visuals.csproj">
<Project>{eb582467-6abb-43a1-b052-e981ba910e3a}</Project>
<Name>Avalonia.Visuals</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Styling\Avalonia.Styling.csproj">
<Project>{f1baa01a-f176-4c6a-b39d-5b40bb1b148f}</Project>
<Name>Avalonia.Styling</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj">
<Project>{3e10a5fa-e8da-48b1-ad44-6a5b6cb7750f}</Project>
<Name>Avalonia.Themes.Default</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj">
<Project>{3e53a01a-b331-47f3-b828-4a5717e77a24}</Project>
<Name>Avalonia.Markup.Xaml</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Markup\Avalonia.Markup\Avalonia.Markup.csproj">
<Project>{6417e941-21bc-467b-a771-0de389353ce6}</Project>
<Name>Avalonia.Markup</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Windows\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj">
<Project>{3e908f67-5543-4879-a1dc-08eace79b3cd}</Project>
<Name>Avalonia.Direct2D1</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Windows\Avalonia.Win32\Avalonia.Win32.csproj">
<Project>{811a76cf-1cf6-440f-963b-bbe31bd72a82}</Project>
<Name>Avalonia.Win32</Name>
</ProjectReference>
<Folder Include="Properties\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\build\Serilog.props" />
</Project>

9
tests/Avalonia.DesignerSupport.TestApp/Program.cs

@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using Avalonia.Controls;
namespace Avalonia.DesignerSupport.TestApp
@ -12,10 +11,14 @@ namespace Avalonia.DesignerSupport.TestApp
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
AppBuilder.Configure<App>().UseDirect2D1().UseWin32().Start<MainWindow>();
BuildAvaloniaApp().Start<MainWindow>();
}
private static AppBuilder BuildAvaloniaApp()
{
return AppBuilder.Configure<App>().UsePlatformDetect();
}
}
}

36
tests/Avalonia.DesignerSupport.TestApp/Properties/AssemblyInfo.cs

@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Avalonia.DesignerSupport.TestApp")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Avalonia.DesignerSupport.TestApp")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("f1381f98-4d24-409a-a6c5-1c5b1e08bb08")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

63
tests/Avalonia.DesignerSupport.TestApp/Properties/Resources.Designer.cs

@ -1,63 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Avalonia.DesignerSupport.TestApp.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Avalonia.DesignerSupport.TestApp.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

117
tests/Avalonia.DesignerSupport.TestApp/Properties/Resources.resx

@ -1,117 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

26
tests/Avalonia.DesignerSupport.TestApp/Properties/Settings.Designer.cs

@ -1,26 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Avalonia.DesignerSupport.TestApp.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.5.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

7
tests/Avalonia.DesignerSupport.TestApp/Properties/Settings.settings

@ -1,7 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

62
tests/Avalonia.DesignerSupport.Tests/Avalonia.DesignerSupport.Tests.csproj

@ -1,61 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{52F55355-D120-42AC-8116-8410A7D602FA}</ProjectGuid>
<TargetFrameworks>netcoreapp2.0</TargetFrameworks>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Avalonia.DesignerSupport.Tests</RootNamespace>
<AssemblyName>Avalonia.DesignerSupport.Tests</AssemblyName>
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
<OutputPath>..\..\artifacts\designer-tests\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<Import Project="..\..\build\UnitTests.NetCore.targets" />
<Import Project="..\..\build\Moq.props" />
<Import Project="..\..\build\XUnit.props" />
<Import Project="..\..\build\Rx.props" />
<Import Project="..\..\build\Microsoft.Reactive.Testing.props" />
<ItemGroup>
<Compile Include="..\..\src\Avalonia.DesignerSupport\DesignerApi.cs">
<Link>DesignerApi.cs</Link>
</Compile>
<Compile Include="Checker.cs" />
<Compile Include="DesignerSupportTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<ProjectReference Include="..\..\src\Avalonia.Controls\Avalonia.Controls.csproj" />
<ProjectReference Include="..\..\src\Avalonia.DesignerSupport\Avalonia.DesignerSupport.csproj" />
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Avalonia.DesignerSupport.TestApp\Avalonia.DesignerSupport.TestApp.csproj">
<Project>{f1381f98-4d24-409a-a6c5-1c5b1e08bb08}</Project>
<Name>Avalonia.DesignerSupport.TestApp</Name>
</ProjectReference>
<Folder Include="Properties\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\build\XUnit.props" />
</Project>

89
tests/Avalonia.DesignerSupport.Tests/Checker.cs

@ -1,89 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace Avalonia.DesignerSupport.Tests
{
public class Checker : MarshalByRefObject
{
private string _appDir;
private IntPtr _window;
public void DoCheck(string baseAsset, string xamlText)
{
_appDir = new FileInfo(baseAsset).Directory.FullName;
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
foreach (var asm in Directory.GetFiles(_appDir).Where(f => f.ToLower().EndsWith(".dll") || f.ToLower().EndsWith(".exe")))
try
{
Assembly.LoadFrom(asm);
}
catch (Exception)
{
}
var dic = new Dictionary<string, object>();
var api = new DesignerApi(dic) { OnResize = OnResize, OnWindowCreated = OnWindowCreated };
LookupStaticMethod("Avalonia.DesignerSupport.DesignerAssist", "Init").Invoke(null, new object[] { dic });
api.UpdateXaml2(new DesignerApiXamlFileInfo
{
Xaml = xamlText,
AssemblyPath = baseAsset
}.Dictionary);
if (_window == IntPtr.Zero)
throw new Exception("Something went wrong");
SendMessage(_window, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
}
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
public const uint WM_CLOSE = 0x0010;
private void OnWindowCreated(IntPtr lastIntPtr)
{
_window = lastIntPtr;
}
private void OnResize()
{
}
static Type LookupType(params string[] names)
{
var asms = AppDomain.CurrentDomain.GetAssemblies();
foreach (var asm in asms)
{
foreach (var name in names)
{
var found = asm.GetType(name, false, true);
if (found != null)
return found;
}
}
throw new TypeLoadException("Unable to find any of types: " + string.Join(",", names));
}
static MethodInfo LookupStaticMethod(string typeName, string method)
{
var type = LookupType(typeName);
var methods = type.GetMethods();
return methods.First(m => m.Name == method);
}
private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
string assemblyPath = Path.Combine(_appDir, new AssemblyName(args.Name).Name + ".dll");
if (File.Exists(assemblyPath) == false) return null;
Assembly assembly = Assembly.LoadFrom(assemblyPath);
return assembly;
}
}
}

108
tests/Avalonia.DesignerSupport.Tests/DesignerSupportTests.cs

@ -1,9 +1,16 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Avalonia.Remote.Protocol;
using Avalonia.Remote.Protocol.Designer;
using Xunit;
using Xunit.Extensions;
@ -11,23 +18,102 @@ namespace Avalonia.DesignerSupport.Tests
{
public class DesignerSupportTests
{
[Theory,
InlineData(@"Avalonia.DesignerSupport.TestApp.exe", @"..\..\tests\Avalonia.DesignerSupport.TestApp\MainWindow.xaml"),
InlineData(@"..\..\samples\ControlCatalog.Desktop\bin\$BUILD\net461\ControlCatalog.dll", @"..\..\samples\ControlCatalog\MainWindow.xaml")]
public void DesignerApiShoudBeOperational(string outputDir, string xamlFile)
private const string DesignerAppPath = "../../../../../src/tools/Avalonia.Designer.HostApp/bin/$BUILD/netcoreapp2.0/Avalonia.Designer.HostApp.dll";
[SkippableTheory,
InlineData(
@"..\..\..\..\..\tests/Avalonia.DesignerSupport.TestApp/bin/$BUILD/netcoreapp2.0/",
"Avalonia.DesignerSupport.TestApp",
"Avalonia.DesignerSupport.TestApp.dll",
@"..\..\..\..\..\tests\Avalonia.DesignerSupport.TestApp\MainWindow.xaml"),
InlineData(
@"..\..\..\..\..\samples\ControlCatalog.NetCore\bin\$BUILD\netcoreapp2.0\",
"ControlCatalog.NetCore",
"ControlCatalog.dll",
@"..\..\..\..\..\samples\ControlCatalog\MainWindow.xaml")]
public async Task Designer_In_Win32_Mode_Should_Provide_Valid_Hwnd(
string outputDir,
string executableName,
string assemblyName,
string xamlFile)
{
Skip.IfNot(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
var xaml = File.ReadAllText(xamlFile);
string buildType;
#if DEBUG
outputDir = outputDir.Replace("$BUILD", "Debug");
buildType = "Debug";
#else
outputDir = outputDir.Replace("$BUILD", "Release");
buildType = "Release";
#endif
var domain = AppDomain.CreateDomain("TESTDOMAIN" + Guid.NewGuid());
var checker = (Checker)domain.CreateInstanceFromAndUnwrap(typeof (Checker).Assembly.GetModules()[0].FullyQualifiedName,
"Avalonia.DesignerSupport.Tests.Checker");
checker.DoCheck(outputDir, xaml);
outputDir = outputDir.Replace("$BUILD", buildType);
var sessionId = Guid.NewGuid();
long handle = 0;
var resultMessageReceivedToken = new CancellationTokenSource();
var tcpListener = new TcpListener(IPAddress.Loopback, 0);
tcpListener.Start();
var port = ((IPEndPoint)tcpListener.LocalEndpoint).Port;
tcpListener.Stop();
var transport = new BsonTcpTransport();
transport.Listen(IPAddress.Loopback, port, conn =>
{
conn.OnMessage += async (_, msg) =>
{
if (msg is StartDesignerSessionMessage start)
{
Assert.Equal(sessionId, Guid.Parse(start.SessionId));
await conn.Send(new UpdateXamlMessage
{
AssemblyPath = Path.Combine(outputDir, assemblyName),
Xaml = xaml
});
}
else if (msg is UpdateXamlResultMessage result)
{
handle = result.Handle != null ? long.Parse(result.Handle) : 0;
resultMessageReceivedToken.Cancel();
conn.Dispose();
}
};
});
var cmdline =
$"exec --runtimeconfig \"{outputDir}{executableName}.runtimeconfig.json\" --depsfile \"{outputDir}{executableName}.deps.json\" "
+ $" \"{DesignerAppPath.Replace("$BUILD", buildType)}\" "
+ $"--transport tcp-bson://127.0.0.1:{port}/ --session-id {sessionId} --method win32 \"{outputDir}{executableName}.dll\"";
using (var proc = new Process
{
StartInfo = new ProcessStartInfo("dotnet", cmdline)
{
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
},
EnableRaisingEvents = true
})
{
proc.Start();
var cancelled = false;
try
{
await Task.Delay(10000, resultMessageReceivedToken.Token);
}
catch (TaskCanceledException)
{
cancelled = true;
}
Assert.True(cancelled);
Assert.NotEqual(0, handle);
proc.Kill();
proc.WaitForExit();
}
}
}
}

36
tests/Avalonia.DesignerSupport.Tests/Properties/AssemblyInfo.cs

@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Avalonia.DesignerSupport.Tests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Avalonia.DesignerSupport.Tests")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("52f55355-d120-42ac-8116-8410a7d602fa")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
Loading…
Cancel
Save