diff --git a/.gitignore b/.gitignore index 5917c0f2ba..6ee6057d5f 100644 --- a/.gitignore +++ b/.gitignore @@ -94,10 +94,6 @@ publish/ *.Publish.xml *.pubxml -# NuGet Packages Directory -## TODO: If you have NuGet Package Restore enabled, uncomment the next line -packages/ - # Windows Azure Build Output csx *.build.csdef @@ -189,3 +185,13 @@ project.lock.json BenchmarkDotNet.Artifacts/ dirs.sln + + +################## +# XCode +################## +Index/ +Logs/ +ModuleCache.noindex/ +Build/Intermediates.noindex/ +info.plist diff --git a/.ncrunch/Avalonia.DotNetCoreRuntime.v3.ncrunchproject b/.ncrunch/Avalonia.DesktopRuntime.v3.ncrunchproject similarity index 100% rename from .ncrunch/Avalonia.DotNetCoreRuntime.v3.ncrunchproject rename to .ncrunch/Avalonia.DesktopRuntime.v3.ncrunchproject diff --git a/.ncrunch/Avalonia.DotNetFrameworkRuntime.v3.ncrunchproject b/.ncrunch/Avalonia.DotNetFrameworkRuntime.v3.ncrunchproject deleted file mode 100644 index 3cd9a982c9..0000000000 --- a/.ncrunch/Avalonia.DotNetFrameworkRuntime.v3.ncrunchproject +++ /dev/null @@ -1,6 +0,0 @@ - - - False - True - - \ No newline at end of file diff --git a/.ncrunch/Avalonia.Gtk.v3.ncrunchproject b/.ncrunch/Avalonia.Gtk.v3.ncrunchproject deleted file mode 100644 index 6800b4a3fe..0000000000 --- a/.ncrunch/Avalonia.Gtk.v3.ncrunchproject +++ /dev/null @@ -1,5 +0,0 @@ - - - True - - \ No newline at end of file diff --git a/.ncrunch/Avalonia.HtmlRenderer.v3.ncrunchproject b/.ncrunch/Avalonia.HtmlRenderer.v3.ncrunchproject deleted file mode 100644 index 6800b4a3fe..0000000000 --- a/.ncrunch/Avalonia.HtmlRenderer.v3.ncrunchproject +++ /dev/null @@ -1,5 +0,0 @@ - - - True - - \ No newline at end of file diff --git a/.ncrunch/Avalonia.Win32.NetStandard.v3.ncrunchproject b/.ncrunch/Avalonia.Win32.NetStandard.v3.ncrunchproject deleted file mode 100644 index 95a483b433..0000000000 --- a/.ncrunch/Avalonia.Win32.NetStandard.v3.ncrunchproject +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/.ncrunch/Avalonia.Win32.Shared.v3.ncrunchproject b/.ncrunch/Avalonia.Win32.Shared.v3.ncrunchproject deleted file mode 100644 index 95a483b433..0000000000 --- a/.ncrunch/Avalonia.Win32.Shared.v3.ncrunchproject +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/.ncrunch/BindingTest.v3.ncrunchproject b/.ncrunch/BindingTest.v3.ncrunchproject deleted file mode 100644 index a4953e14f9..0000000000 --- a/.ncrunch/BindingTest.v3.ncrunchproject +++ /dev/null @@ -1,6 +0,0 @@ - - - True - True - - \ No newline at end of file diff --git a/.ncrunch/RemoteTest.v3.ncrunchproject b/.ncrunch/RemoteTest.v3.ncrunchproject deleted file mode 100644 index 319cd523ce..0000000000 --- a/.ncrunch/RemoteTest.v3.ncrunchproject +++ /dev/null @@ -1,5 +0,0 @@ - - - True - - \ No newline at end of file diff --git a/.ncrunch/RenderTest.v3.ncrunchproject b/.ncrunch/RenderTest.v3.ncrunchproject deleted file mode 100644 index e12537d535..0000000000 --- a/.ncrunch/RenderTest.v3.ncrunchproject +++ /dev/null @@ -1,8 +0,0 @@ - - - - MissingOrIgnoredProjectReference - - True - - \ No newline at end of file diff --git a/.ncrunch/VirtualizationTest.v3.ncrunchproject b/.ncrunch/VirtualizationTest.v3.ncrunchproject deleted file mode 100644 index a4953e14f9..0000000000 --- a/.ncrunch/VirtualizationTest.v3.ncrunchproject +++ /dev/null @@ -1,6 +0,0 @@ - - - True - True - - \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index d80d24f32c..b0c0c807cb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,8 @@ mono: - 5.2.0 dotnet: 2.1.200 script: + - sudo apt-get update + - sudo apt-get install castxml - ./build.sh --target "Travis" --configuration "Release" notifications: email: false diff --git a/Avalonia.sln b/Avalonia.sln index 76d8a14524..7fa5f7736a 100644 --- a/Avalonia.sln +++ b/Avalonia.sln @@ -80,13 +80,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Skia", "Skia", "{3743B0F2-C EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Android", "Android", "{7CF9789C-F1D3-4D0E-90E5-F1DF67A2753F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Android", "src\Android\Avalonia.Android\Avalonia.Android.csproj", "{7B92AF71-6287-4693-9DCB-BD5B6E927E23}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Android", "src\Android\Avalonia.Android\Avalonia.Android.csproj", "{7B92AF71-6287-4693-9DCB-BD5B6E927E23}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.AndroidTestApplication", "src\Android\Avalonia.AndroidTestApplication\Avalonia.AndroidTestApplication.csproj", "{FF69B927-C545-49AE-8E16-3D14D621AA12}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "iOS", "iOS", "{0CB0B92E-6CFF-4240-80A5-CCAFE75D91E1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.iOS", "src\iOS\Avalonia.iOS\Avalonia.iOS.csproj", "{4488AD85-1495-4809-9AA4-DDFE0A48527E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.iOS", "src\iOS\Avalonia.iOS\Avalonia.iOS.csproj", "{4488AD85-1495-4809-9AA4-DDFE0A48527E}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.iOSTestApplication", "src\iOS\Avalonia.iOSTestApplication\Avalonia.iOSTestApplication.csproj", "{8C923867-8A8F-4F6B-8B80-47D9E8436166}" EndProject @@ -116,14 +116,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Interop", "Interop", "{A0CC EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsInteropTest", "samples\interop\WindowsInteropTest\WindowsInteropTest.csproj", "{C7A69145-60B6-4882-97D6-A3921DD43978}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.DotNetFrameworkRuntime", "src\Avalonia.DotNetFrameworkRuntime\Avalonia.DotNetFrameworkRuntime.csproj", "{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RenderDemo", "samples\RenderDemo\RenderDemo.csproj", "{F1FDC5B0-4654-416F-AE69-E3E9BBD87801}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog.Android", "samples\ControlCatalog.Android\ControlCatalog.Android.csproj", "{29132311-1848-4FD6-AE0C-4FF841151BD3}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.DotNetCoreRuntime", "src\Avalonia.DotNetCoreRuntime\Avalonia.DotNetCoreRuntime.csproj", "{7863EA94-F0FB-4386-BF8C-E5BFA761560A}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Skia", "src\Skia\Avalonia.Skia\Avalonia.Skia.csproj", "{7D2D3083-71DD-4CC9-8907-39A0D86FB322}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Gtk3", "src\Gtk\Avalonia.Gtk3\Avalonia.Gtk3.csproj", "{BB1F7BB5-6AD4-4776-94D9-C09D0A972658}" @@ -164,7 +160,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.LinuxFramebuffer", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Direct3DInteropSample", "samples\interop\Direct3DInteropSample\Direct3DInteropSample.csproj", "{638580B0-7910-40EF-B674-DCB34DA308CD}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Win32.Interop", "src\Windows\Avalonia.Win32.Interop\Avalonia.Win32.Interop.csproj", "{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Win32.Interop", "src\Windows\Avalonia.Win32.Interop\Avalonia.Win32.Interop.csproj", "{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Skia.RenderTests", "tests\Avalonia.Skia.RenderTests\Avalonia.Skia.RenderTests.csproj", "{E1582370-37B3-403C-917F-8209551B1634}" EndProject @@ -178,21 +174,25 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Designer.HostApp", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Previewer", "samples\Previewer\Previewer.csproj", "{F40FC0A2-1BC3-401C-BFC1-928EC4D4A9CE}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "OSX", "OSX", "{A59C4C0A-64DF-4621-B450-2BA00D6F61E2}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Skia.UnitTests", "tests\Avalonia.Skia.UnitTests\Avalonia.Skia.UnitTests.csproj", "{E1240B49-7B4B-4371-A00E-068778C5CF0B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.MonoMac", "src\OSX\Avalonia.MonoMac\Avalonia.MonoMac.csproj", "{CBFD5788-567D-401B-9DFA-74E4224025A0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.OpenGL", "src\Avalonia.OpenGL\Avalonia.OpenGL.csproj", "{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Designer.HostApp.NetFX", "src\tools\Avalonia.Designer.HostApp.NetFX\Avalonia.Designer.HostApp.NetFX.csproj", "{4ADA61C8-D191-428D-9066-EF4F0D86520F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Native", "src\Avalonia.Native\Avalonia.Native.csproj", "{12A91A62-C064-42CA-9A8C-A1272F354388}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Skia.UnitTests", "tests\Avalonia.Skia.UnitTests\Avalonia.Skia.UnitTests.csproj", "{E1240B49-7B4B-4371-A00E-068778C5CF0B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.DesktopRuntime", "src\Avalonia.DesktopRuntime\Avalonia.DesktopRuntime.csproj", "{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Packages", "Packages", "{E870DCD7-F46A-498D-83FC-D0FD13E0A11C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia", "packages\Avalonia\Avalonia.csproj", "{D49233F8-F29C-47DD-9975-C4C9E4502720}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Desktop", "src\Avalonia.Desktop\Avalonia.Desktop.csproj", "{3C471044-3640-45E3-B1B2-16D2FF8399EE}" EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution src\Shared\RenderHelpers\RenderHelpers.projitems*{3c4c0cb4-0c0f-4450-a37b-148c84ff905f}*SharedItemsImports = 13 src\Shared\RenderHelpers\RenderHelpers.projitems*{3e908f67-5543-4879-a1dc-08eace79b3cd}*SharedItemsImports = 4 src\Shared\PlatformSupport\PlatformSupport.projitems*{4488ad85-1495-4809-9aa4-ddfe0a48527e}*SharedItemsImports = 4 - src\Shared\PlatformSupport\PlatformSupport.projitems*{4a1abb09-9047-4bd5-a4ad-a055e52c5ee0}*SharedItemsImports = 4 - src\Shared\PlatformSupport\PlatformSupport.projitems*{7863ea94-f0fb-4386-bf8c-e5bfa761560a}*SharedItemsImports = 4 src\Shared\PlatformSupport\PlatformSupport.projitems*{7b92af71-6287-4693-9dcb-bd5b6e927e23}*SharedItemsImports = 4 src\Shared\RenderHelpers\RenderHelpers.projitems*{7d2d3083-71dd-4cc9-8907-39a0d86fb322}*SharedItemsImports = 4 tests\Avalonia.RenderTests\Avalonia.RenderTests.projitems*{dabfd304-d6a4-4752-8123-c2ccf7ac7831}*SharedItemsImports = 4 @@ -1219,30 +1219,6 @@ Global {C7A69145-60B6-4882-97D6-A3921DD43978}.Release|iPhone.Build.0 = Release|Any CPU {C7A69145-60B6-4882-97D6-A3921DD43978}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU {C7A69145-60B6-4882-97D6-A3921DD43978}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|Any CPU.Build.0 = Release|Any CPU - {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|iPhone.Build.0 = Release|Any CPU - {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU - {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|iPhone.Build.0 = Debug|Any CPU - {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|Any CPU.Build.0 = Release|Any CPU - {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|iPhone.ActiveCfg = Release|Any CPU - {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|iPhone.Build.0 = Release|Any CPU - {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|iPhoneSimulator.Build.0 = Release|Any CPU {F1FDC5B0-4654-416F-AE69-E3E9BBD87801}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU {F1FDC5B0-4654-416F-AE69-E3E9BBD87801}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU {F1FDC5B0-4654-416F-AE69-E3E9BBD87801}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU @@ -1303,30 +1279,6 @@ Global {29132311-1848-4FD6-AE0C-4FF841151BD3}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU {29132311-1848-4FD6-AE0C-4FF841151BD3}.Release|iPhoneSimulator.Build.0 = Release|Any CPU {29132311-1848-4FD6-AE0C-4FF841151BD3}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU - {7863EA94-F0FB-4386-BF8C-E5BFA761560A}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {7863EA94-F0FB-4386-BF8C-E5BFA761560A}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {7863EA94-F0FB-4386-BF8C-E5BFA761560A}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {7863EA94-F0FB-4386-BF8C-E5BFA761560A}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {7863EA94-F0FB-4386-BF8C-E5BFA761560A}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {7863EA94-F0FB-4386-BF8C-E5BFA761560A}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {7863EA94-F0FB-4386-BF8C-E5BFA761560A}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {7863EA94-F0FB-4386-BF8C-E5BFA761560A}.AppStore|Any CPU.Build.0 = Release|Any CPU - {7863EA94-F0FB-4386-BF8C-E5BFA761560A}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {7863EA94-F0FB-4386-BF8C-E5BFA761560A}.AppStore|iPhone.Build.0 = Release|Any CPU - {7863EA94-F0FB-4386-BF8C-E5BFA761560A}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {7863EA94-F0FB-4386-BF8C-E5BFA761560A}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU - {7863EA94-F0FB-4386-BF8C-E5BFA761560A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7863EA94-F0FB-4386-BF8C-E5BFA761560A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7863EA94-F0FB-4386-BF8C-E5BFA761560A}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {7863EA94-F0FB-4386-BF8C-E5BFA761560A}.Debug|iPhone.Build.0 = Debug|Any CPU - {7863EA94-F0FB-4386-BF8C-E5BFA761560A}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {7863EA94-F0FB-4386-BF8C-E5BFA761560A}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {7863EA94-F0FB-4386-BF8C-E5BFA761560A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7863EA94-F0FB-4386-BF8C-E5BFA761560A}.Release|Any CPU.Build.0 = Release|Any CPU - {7863EA94-F0FB-4386-BF8C-E5BFA761560A}.Release|iPhone.ActiveCfg = Release|Any CPU - {7863EA94-F0FB-4386-BF8C-E5BFA761560A}.Release|iPhone.Build.0 = Release|Any CPU - {7863EA94-F0FB-4386-BF8C-E5BFA761560A}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {7863EA94-F0FB-4386-BF8C-E5BFA761560A}.Release|iPhoneSimulator.Build.0 = Release|Any CPU {7D2D3083-71DD-4CC9-8907-39A0D86FB322}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU {7D2D3083-71DD-4CC9-8907-39A0D86FB322}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU {7D2D3083-71DD-4CC9-8907-39A0D86FB322}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU @@ -1591,54 +1543,6 @@ Global {F40FC0A2-1BC3-401C-BFC1-928EC4D4A9CE}.Release|iPhone.Build.0 = Release|Any CPU {F40FC0A2-1BC3-401C-BFC1-928EC4D4A9CE}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU {F40FC0A2-1BC3-401C-BFC1-928EC4D4A9CE}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {CBFD5788-567D-401B-9DFA-74E4224025A0}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {CBFD5788-567D-401B-9DFA-74E4224025A0}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {CBFD5788-567D-401B-9DFA-74E4224025A0}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {CBFD5788-567D-401B-9DFA-74E4224025A0}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {CBFD5788-567D-401B-9DFA-74E4224025A0}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {CBFD5788-567D-401B-9DFA-74E4224025A0}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {CBFD5788-567D-401B-9DFA-74E4224025A0}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {CBFD5788-567D-401B-9DFA-74E4224025A0}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {CBFD5788-567D-401B-9DFA-74E4224025A0}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {CBFD5788-567D-401B-9DFA-74E4224025A0}.AppStore|iPhone.Build.0 = Debug|Any CPU - {CBFD5788-567D-401B-9DFA-74E4224025A0}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {CBFD5788-567D-401B-9DFA-74E4224025A0}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {CBFD5788-567D-401B-9DFA-74E4224025A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CBFD5788-567D-401B-9DFA-74E4224025A0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CBFD5788-567D-401B-9DFA-74E4224025A0}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {CBFD5788-567D-401B-9DFA-74E4224025A0}.Debug|iPhone.Build.0 = Debug|Any CPU - {CBFD5788-567D-401B-9DFA-74E4224025A0}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {CBFD5788-567D-401B-9DFA-74E4224025A0}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {CBFD5788-567D-401B-9DFA-74E4224025A0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CBFD5788-567D-401B-9DFA-74E4224025A0}.Release|Any CPU.Build.0 = Release|Any CPU - {CBFD5788-567D-401B-9DFA-74E4224025A0}.Release|iPhone.ActiveCfg = Release|Any CPU - {CBFD5788-567D-401B-9DFA-74E4224025A0}.Release|iPhone.Build.0 = Release|Any CPU - {CBFD5788-567D-401B-9DFA-74E4224025A0}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {CBFD5788-567D-401B-9DFA-74E4224025A0}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {4ADA61C8-D191-428D-9066-EF4F0D86520F}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {4ADA61C8-D191-428D-9066-EF4F0D86520F}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {4ADA61C8-D191-428D-9066-EF4F0D86520F}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {4ADA61C8-D191-428D-9066-EF4F0D86520F}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {4ADA61C8-D191-428D-9066-EF4F0D86520F}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {4ADA61C8-D191-428D-9066-EF4F0D86520F}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {4ADA61C8-D191-428D-9066-EF4F0D86520F}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {4ADA61C8-D191-428D-9066-EF4F0D86520F}.AppStore|Any CPU.Build.0 = Release|Any CPU - {4ADA61C8-D191-428D-9066-EF4F0D86520F}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {4ADA61C8-D191-428D-9066-EF4F0D86520F}.AppStore|iPhone.Build.0 = Release|Any CPU - {4ADA61C8-D191-428D-9066-EF4F0D86520F}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {4ADA61C8-D191-428D-9066-EF4F0D86520F}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU - {4ADA61C8-D191-428D-9066-EF4F0D86520F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4ADA61C8-D191-428D-9066-EF4F0D86520F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4ADA61C8-D191-428D-9066-EF4F0D86520F}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {4ADA61C8-D191-428D-9066-EF4F0D86520F}.Debug|iPhone.Build.0 = Debug|Any CPU - {4ADA61C8-D191-428D-9066-EF4F0D86520F}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {4ADA61C8-D191-428D-9066-EF4F0D86520F}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {4ADA61C8-D191-428D-9066-EF4F0D86520F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4ADA61C8-D191-428D-9066-EF4F0D86520F}.Release|Any CPU.Build.0 = Release|Any CPU - {4ADA61C8-D191-428D-9066-EF4F0D86520F}.Release|iPhone.ActiveCfg = Release|Any CPU - {4ADA61C8-D191-428D-9066-EF4F0D86520F}.Release|iPhone.Build.0 = Release|Any CPU - {4ADA61C8-D191-428D-9066-EF4F0D86520F}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {4ADA61C8-D191-428D-9066-EF4F0D86520F}.Release|iPhoneSimulator.Build.0 = Release|Any CPU {E1240B49-7B4B-4371-A00E-068778C5CF0B}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU {E1240B49-7B4B-4371-A00E-068778C5CF0B}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU {E1240B49-7B4B-4371-A00E-068778C5CF0B}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU @@ -1663,6 +1567,126 @@ Global {E1240B49-7B4B-4371-A00E-068778C5CF0B}.Release|iPhone.Build.0 = Release|Any CPU {E1240B49-7B4B-4371-A00E-068778C5CF0B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU {E1240B49-7B4B-4371-A00E-068778C5CF0B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.AppStore|iPhone.Build.0 = Debug|Any CPU + {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Debug|iPhone.Build.0 = Debug|Any CPU + {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Release|Any CPU.Build.0 = Release|Any CPU + {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Release|iPhone.ActiveCfg = Release|Any CPU + {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Release|iPhone.Build.0 = Release|Any CPU + {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {12A91A62-C064-42CA-9A8C-A1272F354388}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {12A91A62-C064-42CA-9A8C-A1272F354388}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {12A91A62-C064-42CA-9A8C-A1272F354388}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {12A91A62-C064-42CA-9A8C-A1272F354388}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {12A91A62-C064-42CA-9A8C-A1272F354388}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {12A91A62-C064-42CA-9A8C-A1272F354388}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {12A91A62-C064-42CA-9A8C-A1272F354388}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {12A91A62-C064-42CA-9A8C-A1272F354388}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {12A91A62-C064-42CA-9A8C-A1272F354388}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {12A91A62-C064-42CA-9A8C-A1272F354388}.AppStore|iPhone.Build.0 = Debug|Any CPU + {12A91A62-C064-42CA-9A8C-A1272F354388}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {12A91A62-C064-42CA-9A8C-A1272F354388}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {12A91A62-C064-42CA-9A8C-A1272F354388}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {12A91A62-C064-42CA-9A8C-A1272F354388}.Debug|Any CPU.Build.0 = Debug|Any CPU + {12A91A62-C064-42CA-9A8C-A1272F354388}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {12A91A62-C064-42CA-9A8C-A1272F354388}.Debug|iPhone.Build.0 = Debug|Any CPU + {12A91A62-C064-42CA-9A8C-A1272F354388}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {12A91A62-C064-42CA-9A8C-A1272F354388}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {12A91A62-C064-42CA-9A8C-A1272F354388}.Release|Any CPU.ActiveCfg = Release|Any CPU + {12A91A62-C064-42CA-9A8C-A1272F354388}.Release|Any CPU.Build.0 = Release|Any CPU + {12A91A62-C064-42CA-9A8C-A1272F354388}.Release|iPhone.ActiveCfg = Release|Any CPU + {12A91A62-C064-42CA-9A8C-A1272F354388}.Release|iPhone.Build.0 = Release|Any CPU + {12A91A62-C064-42CA-9A8C-A1272F354388}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {12A91A62-C064-42CA-9A8C-A1272F354388}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.AppStore|iPhone.Build.0 = Debug|Any CPU + {878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Debug|Any CPU.Build.0 = Debug|Any CPU + {878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Debug|iPhone.Build.0 = Debug|Any CPU + {878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Release|Any CPU.ActiveCfg = Release|Any CPU + {878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Release|Any CPU.Build.0 = Release|Any CPU + {878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Release|iPhone.ActiveCfg = Release|Any CPU + {878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Release|iPhone.Build.0 = Release|Any CPU + {878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {D49233F8-F29C-47DD-9975-C4C9E4502720}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {D49233F8-F29C-47DD-9975-C4C9E4502720}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {D49233F8-F29C-47DD-9975-C4C9E4502720}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {D49233F8-F29C-47DD-9975-C4C9E4502720}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {D49233F8-F29C-47DD-9975-C4C9E4502720}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {D49233F8-F29C-47DD-9975-C4C9E4502720}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {D49233F8-F29C-47DD-9975-C4C9E4502720}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {D49233F8-F29C-47DD-9975-C4C9E4502720}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {D49233F8-F29C-47DD-9975-C4C9E4502720}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {D49233F8-F29C-47DD-9975-C4C9E4502720}.AppStore|iPhone.Build.0 = Debug|Any CPU + {D49233F8-F29C-47DD-9975-C4C9E4502720}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {D49233F8-F29C-47DD-9975-C4C9E4502720}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {D49233F8-F29C-47DD-9975-C4C9E4502720}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D49233F8-F29C-47DD-9975-C4C9E4502720}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D49233F8-F29C-47DD-9975-C4C9E4502720}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {D49233F8-F29C-47DD-9975-C4C9E4502720}.Debug|iPhone.Build.0 = Debug|Any CPU + {D49233F8-F29C-47DD-9975-C4C9E4502720}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {D49233F8-F29C-47DD-9975-C4C9E4502720}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {D49233F8-F29C-47DD-9975-C4C9E4502720}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D49233F8-F29C-47DD-9975-C4C9E4502720}.Release|Any CPU.Build.0 = Release|Any CPU + {D49233F8-F29C-47DD-9975-C4C9E4502720}.Release|iPhone.ActiveCfg = Release|Any CPU + {D49233F8-F29C-47DD-9975-C4C9E4502720}.Release|iPhone.Build.0 = Release|Any CPU + {D49233F8-F29C-47DD-9975-C4C9E4502720}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {D49233F8-F29C-47DD-9975-C4C9E4502720}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {3C471044-3640-45E3-B1B2-16D2FF8399EE}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {3C471044-3640-45E3-B1B2-16D2FF8399EE}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {3C471044-3640-45E3-B1B2-16D2FF8399EE}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {3C471044-3640-45E3-B1B2-16D2FF8399EE}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {3C471044-3640-45E3-B1B2-16D2FF8399EE}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {3C471044-3640-45E3-B1B2-16D2FF8399EE}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {3C471044-3640-45E3-B1B2-16D2FF8399EE}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {3C471044-3640-45E3-B1B2-16D2FF8399EE}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {3C471044-3640-45E3-B1B2-16D2FF8399EE}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {3C471044-3640-45E3-B1B2-16D2FF8399EE}.AppStore|iPhone.Build.0 = Debug|Any CPU + {3C471044-3640-45E3-B1B2-16D2FF8399EE}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {3C471044-3640-45E3-B1B2-16D2FF8399EE}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {3C471044-3640-45E3-B1B2-16D2FF8399EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3C471044-3640-45E3-B1B2-16D2FF8399EE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3C471044-3640-45E3-B1B2-16D2FF8399EE}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {3C471044-3640-45E3-B1B2-16D2FF8399EE}.Debug|iPhone.Build.0 = Debug|Any CPU + {3C471044-3640-45E3-B1B2-16D2FF8399EE}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {3C471044-3640-45E3-B1B2-16D2FF8399EE}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {3C471044-3640-45E3-B1B2-16D2FF8399EE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3C471044-3640-45E3-B1B2-16D2FF8399EE}.Release|Any CPU.Build.0 = Release|Any CPU + {3C471044-3640-45E3-B1B2-16D2FF8399EE}.Release|iPhone.ActiveCfg = Release|Any CPU + {3C471044-3640-45E3-B1B2-16D2FF8399EE}.Release|iPhone.Build.0 = Release|Any CPU + {3C471044-3640-45E3-B1B2-16D2FF8399EE}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {3C471044-3640-45E3-B1B2-16D2FF8399EE}.Release|iPhoneSimulator.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1713,9 +1737,9 @@ Global {E2999E4A-9086-401F-898C-AEB0AD38E676} = {9B9E3891-2366-4253-A952-D08BCEB71098} {050CC912-FF49-4A8B-B534-9544017446DD} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637} {F40FC0A2-1BC3-401C-BFC1-928EC4D4A9CE} = {9B9E3891-2366-4253-A952-D08BCEB71098} - {CBFD5788-567D-401B-9DFA-74E4224025A0} = {A59C4C0A-64DF-4621-B450-2BA00D6F61E2} - {4ADA61C8-D191-428D-9066-EF4F0D86520F} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637} {E1240B49-7B4B-4371-A00E-068778C5CF0B} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} + {D49233F8-F29C-47DD-9975-C4C9E4502720} = {E870DCD7-F46A-498D-83FC-D0FD13E0A11C} + {3C471044-3640-45E3-B1B2-16D2FF8399EE} = {E870DCD7-F46A-498D-83FC-D0FD13E0A11C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {87366D66-1391-4D90-8999-95A620AD786A} diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000000..50476c81f1 --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,5 @@ + + + $(MSBuildThisFileDirectory)artifacts/nuget + + diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 0000000000..f6929f8dee --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,128 @@ +jobs: +- job: Linux + pool: + vmImage: 'ubuntu-16.04' + steps: + - task: CmdLine@2 + displayName: 'Install CastXML' + inputs: + script: | + sudo apt-get update + sudo apt-get install castxml + + - task: CmdLine@2 + displayName: 'Install Cake' + inputs: + script: | + dotnet tool install -g Cake.Tool --version 0.30.0 + + - task: CmdLine@2 + displayName: 'Run Cake' + inputs: + script: | + export PATH="$PATH:$HOME/.dotnet/tools" + dotnet --info + printenv + dotnet cake build.cake -target="Azure-Linux" -configuration="Release" + + - task: PublishTestResults@2 + inputs: + testResultsFormat: 'VSTest' + testResultsFiles: '$(Build.SourcesDirectory)/artifacts/test-results/*.trx' + condition: not(canceled()) + +- job: macOS + pool: + vmImage: 'xcode9-macos10.13' + steps: + - task: DotNetCoreInstaller@0 + inputs: + version: '2.1.403' + + - task: Xcode@5 + inputs: + actions: 'build' + scheme: '' + sdk: 'macosx10.13' + configuration: 'Release' + xcWorkspacePath: '**/*.xcodeproj/project.xcworkspace' + xcodeVersion: 'default' # Options: 8, 9, default, specifyPath + args: '-derivedDataPath ./' + + - task: CmdLine@2 + displayName: 'Install CastXML' + inputs: + script: brew install castxml + + - task: CmdLine@2 + displayName: 'Install Cake' + inputs: + script: | + dotnet tool install -g Cake.Tool --version 0.30.0 + + - task: CmdLine@2 + displayName: 'Run Cake' + inputs: + script: | + export COREHOST_TRACE=0 + export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 + export DOTNET_CLI_TELEMETRY_OPTOUT=1 + which dotnet + dotnet --info + export PATH="$PATH:$HOME/.dotnet/tools" + dotnet --info + printenv + dotnet cake build.cake -target="Azure-OSX" -configuration="Release" + + - task: PublishTestResults@2 + inputs: + testResultsFormat: 'VSTest' + testResultsFiles: '$(Build.SourcesDirectory)/artifacts/test-results/*.trx' + condition: not(canceled()) + + - task: PublishBuildArtifacts@1 + inputs: + pathToPublish: '$(Build.SourcesDirectory)/Build/Products/Release/' + artifactName: 'Avalonia.Native.OSX' + condition: and(succeeded(), eq(variables['system.pullrequest.isfork'], false)) + + - task: PublishBuildArtifacts@1 + inputs: + pathtoPublish: '$(Build.SourcesDirectory)/artifacts/nuget' + artifactName: 'NuGetOSX' + condition: and(succeeded(), eq(variables['system.pullrequest.isfork'], false)) + +- job: Windows + pool: + vmImage: 'vs2017-win2016' + steps: + - task: CmdLine@2 + displayName: 'Install Cake' + inputs: + script: | + dotnet tool install -g Cake.Tool --version 0.30.0 + + - task: CmdLine@2 + displayName: 'Run Cake' + inputs: + script: | + set PATH=%PATH%;%USERPROFILE%\.dotnet\tools + dotnet cake build.cake -target="Azure-Windows" -configuration="Release" + + - task: PublishTestResults@2 + inputs: + testResultsFormat: 'VSTest' + testResultsFiles: '$(Build.SourcesDirectory)/artifacts/test-results/*.trx' + condition: not(canceled()) + + - task: PublishBuildArtifacts@1 + inputs: + pathtoPublish: '$(Build.SourcesDirectory)/artifacts/nuget' + artifactName: 'NuGet' + condition: and(succeeded(), eq(variables['system.pullrequest.isfork'], false)) + + - task: PublishBuildArtifacts@1 + inputs: + pathToPublish: '$(Build.SourcesDirectory)/artifacts/zip' + artifactName: 'Samples' + condition: and(succeeded(), eq(variables['system.pullrequest.isfork'], false)) diff --git a/build-native.sh b/build-native.sh new file mode 100644 index 0000000000..5983751dce --- /dev/null +++ b/build-native.sh @@ -0,0 +1,6 @@ +# /bin/sh + +mkdir native-build +cd native-build +cmake -DCMAKE_BUILD_TYPE=$1 ../native +cmake --build . --target install \ No newline at end of file diff --git a/build.cake b/build.cake index 24f529ee4a..f10a12c4e6 100644 --- a/build.cake +++ b/build.cake @@ -1,15 +1,9 @@ -/////////////////////////////////////////////////////////////////////////////// -// ADDINS -/////////////////////////////////////////////////////////////////////////////// - -#addin "nuget:?package=NuGet.Core&version=2.14.0" -#tool "nuget:?package=NuGet.CommandLine&version=4.3.0" -#tool "nuget:?package=JetBrains.ReSharper.CommandLineTools&version=2017.1.20170613.162720" - /////////////////////////////////////////////////////////////////////////////// // TOOLS /////////////////////////////////////////////////////////////////////////////// +#tool "nuget:?package=NuGet.CommandLine&version=4.7.1" +#tool "nuget:?package=JetBrains.ReSharper.CommandLineTools&version=2018.2.3" #tool "nuget:?package=xunit.runner.console&version=2.3.1" #tool "nuget:?package=JetBrains.dotMemoryUnit&version=3.0.20171219.105559" @@ -21,39 +15,20 @@ using System; using System.Collections; using System.Collections.Generic; using System.Linq; -using NuGet; /////////////////////////////////////////////////////////////////////////////// // SCRIPTS /////////////////////////////////////////////////////////////////////////////// #load "./parameters.cake" -#load "./packages.cake" - -////////////////////////////////////////////////////////////////////// -// PARAMETERS -////////////////////////////////////////////////////////////////////// - -class AvaloniaBuildData -{ - public AvaloniaBuildData(Parameters parameters, Packages packages) - { - Parameters = parameters; - Packages = packages; - } - - public Parameters Parameters { get; } - public Packages Packages { get; } -} /////////////////////////////////////////////////////////////////////////////// // SETUP /////////////////////////////////////////////////////////////////////////////// -Setup(context => +Setup(context => { var parameters = new Parameters(context); - var buildContext = new AvaloniaBuildData(parameters, new Packages(context, parameters)); Information("Building version {0} of Avalonia ({1}) using version {2} of Cake.", parameters.Version, @@ -71,22 +46,24 @@ Setup(context => Information("IsRunningOnUnix: " + parameters.IsRunningOnUnix); Information("IsRunningOnWindows: " + parameters.IsRunningOnWindows); Information("IsRunningOnAppVeyor: " + parameters.IsRunningOnAppVeyor); + Information("IsRunnongOnAzure:" + parameters.IsRunningOnAzure); Information("IsPullRequest: " + parameters.IsPullRequest); Information("IsMainRepo: " + parameters.IsMainRepo); Information("IsMasterBranch: " + parameters.IsMasterBranch); + Information("IsReleaseBranch: " + parameters.IsReleaseBranch); Information("IsTagged: " + parameters.IsTagged); Information("IsReleasable: " + parameters.IsReleasable); Information("IsMyGetRelease: " + parameters.IsMyGetRelease); Information("IsNuGetRelease: " + parameters.IsNuGetRelease); - return buildContext; + return parameters; }); /////////////////////////////////////////////////////////////////////////////// // TEARDOWN /////////////////////////////////////////////////////////////////////////////// -Teardown((context, buildContext) => +Teardown((context, buildContext) => { Information("Finished running tasks."); }); @@ -96,13 +73,13 @@ Teardown((context, buildContext) => /////////////////////////////////////////////////////////////////////////////// Task("Clean-Impl") - .Does(data => + .Does(data => { - CleanDirectories(data.Parameters.BuildDirs); - CleanDirectory(data.Parameters.ArtifactsDir); - CleanDirectory(data.Parameters.NugetRoot); - CleanDirectory(data.Parameters.ZipRoot); - CleanDirectory(data.Parameters.BinRoot); + CleanDirectories(data.BuildDirs); + CleanDirectory(data.ArtifactsDir); + CleanDirectory(data.NugetRoot); + CleanDirectory(data.ZipRoot); + CleanDirectory(data.TestResultsRoot); }); void DotNetCoreBuild(Parameters parameters) @@ -110,27 +87,35 @@ void DotNetCoreBuild(Parameters parameters) var settings = new DotNetCoreBuildSettings { Configuration = parameters.Configuration, + MSBuildSettings = new DotNetCoreMSBuildSettings + { + Properties = + { + { "PackageVersion", new [] { parameters.Version } } + } + } }; DotNetCoreBuild(parameters.MSBuildSolution, settings); } Task("Build-Impl") - .Does(data => + .Does(data => { - if(data.Parameters.IsRunningOnWindows) + if(data.IsRunningOnWindows) { - MSBuild(data.Parameters.MSBuildSolution, settings => { - settings.SetConfiguration(data.Parameters.Configuration); + MSBuild(data.MSBuildSolution, settings => { + settings.SetConfiguration(data.Configuration); settings.SetVerbosity(Verbosity.Minimal); settings.WithProperty("iOSRoslynPathHackRequired", "true"); + settings.WithProperty("PackageVersion", data.Version); settings.UseToolVersion(MSBuildToolVersion.VS2017); settings.WithRestore(); }); } else { - DotNetCoreBuild(data.Parameters); + DotNetCoreBuild(data); } }); @@ -146,55 +131,63 @@ void RunCoreTest(string project, Parameters parameters, bool coreOnly = false) continue; Information("Running for " + fw); - DotNetCoreTest(project, - new DotNetCoreTestSettings { - Configuration = parameters.Configuration, - Framework = fw, - NoBuild = true, - NoRestore = true - }); + var settings = new DotNetCoreTestSettings { + Configuration = parameters.Configuration, + Framework = fw, + NoBuild = true, + NoRestore = true + }; + + if (parameters.PublishTestResults) + { + settings.Logger = "trx"; + settings.ResultsDirectory = parameters.TestResultsRoot; + } + + DotNetCoreTest(project, settings); } } Task("Run-Unit-Tests-Impl") - .WithCriteria((context, data) => !data.Parameters.SkipTests) - .Does(data => + .WithCriteria((context, data) => !data.SkipTests) + .Does(data => { - RunCoreTest("./tests/Avalonia.Base.UnitTests", data.Parameters, false); - RunCoreTest("./tests/Avalonia.Controls.UnitTests", data.Parameters, false); - RunCoreTest("./tests/Avalonia.Input.UnitTests", data.Parameters, false); - RunCoreTest("./tests/Avalonia.Interactivity.UnitTests", data.Parameters, false); - RunCoreTest("./tests/Avalonia.Layout.UnitTests", data.Parameters, false); - RunCoreTest("./tests/Avalonia.Markup.UnitTests", data.Parameters, false); - RunCoreTest("./tests/Avalonia.Markup.Xaml.UnitTests", data.Parameters, false); - RunCoreTest("./tests/Avalonia.Styling.UnitTests", data.Parameters, false); - RunCoreTest("./tests/Avalonia.Visuals.UnitTests", data.Parameters, false); - RunCoreTest("./tests/Avalonia.Skia.UnitTests", data.Parameters, false); - if (data.Parameters.IsRunningOnWindows) + RunCoreTest("./tests/Avalonia.Base.UnitTests", data, false); + RunCoreTest("./tests/Avalonia.Controls.UnitTests", data, false); + RunCoreTest("./tests/Avalonia.Input.UnitTests", data, false); + RunCoreTest("./tests/Avalonia.Interactivity.UnitTests", data, false); + RunCoreTest("./tests/Avalonia.Layout.UnitTests", data, false); + RunCoreTest("./tests/Avalonia.Markup.UnitTests", data, false); + RunCoreTest("./tests/Avalonia.Markup.Xaml.UnitTests", data, false); + RunCoreTest("./tests/Avalonia.Styling.UnitTests", data, false); + RunCoreTest("./tests/Avalonia.Visuals.UnitTests", data, false); + RunCoreTest("./tests/Avalonia.Skia.UnitTests", data, false); + RunCoreTest("./tests/Avalonia.ReactiveUI.UnitTests", data, false); + if (data.IsRunningOnWindows) { - RunCoreTest("./tests/Avalonia.Direct2D1.UnitTests", data.Parameters, false); + RunCoreTest("./tests/Avalonia.Direct2D1.UnitTests", data, false); } }); Task("Run-Designer-Tests-Impl") - .WithCriteria((context, data) => !data.Parameters.SkipTests) - .Does(data => + .WithCriteria((context, data) => !data.SkipTests) + .Does(data => { - RunCoreTest("./tests/Avalonia.DesignerSupport.Tests", data.Parameters, false); + RunCoreTest("./tests/Avalonia.DesignerSupport.Tests", data, false); }); Task("Run-Render-Tests-Impl") - .WithCriteria((context, data) => !data.Parameters.SkipTests) - .WithCriteria((context, data) => data.Parameters.IsRunningOnWindows) - .Does(data => + .WithCriteria((context, data) => !data.SkipTests) + .WithCriteria((context, data) => data.IsRunningOnWindows) + .Does(data => { - RunCoreTest("./tests/Avalonia.Skia.RenderTests/Avalonia.Skia.RenderTests.csproj", data.Parameters, true); - RunCoreTest("./tests/Avalonia.Direct2D1.RenderTests/Avalonia.Direct2D1.RenderTests.csproj", data.Parameters, true); + RunCoreTest("./tests/Avalonia.Skia.RenderTests/Avalonia.Skia.RenderTests.csproj", data, true); + RunCoreTest("./tests/Avalonia.Direct2D1.RenderTests/Avalonia.Direct2D1.RenderTests.csproj", data, true); }); Task("Run-Leak-Tests-Impl") - .WithCriteria((context, data) => !data.Parameters.SkipTests) - .WithCriteria((context, data) => data.Parameters.IsRunningOnWindows) + .WithCriteria((context, data) => !data.SkipTests) + .WithCriteria((context, data) => data.IsRunningOnWindows) .Does(() => { var dotMemoryUnit = Context.Tools.Resolve("dotMemoryUnit.exe"); @@ -214,136 +207,58 @@ Task("Run-Leak-Tests-Impl") } }); -Task("Copy-Files-Impl") - .Does(data => -{ - CopyFiles(data.Packages.BinFiles, data.Parameters.BinRoot); -}); - Task("Zip-Files-Impl") - .Does(data => + .Does(data => { - Zip(data.Parameters.BinRoot, data.Parameters.ZipCoreArtifacts); + Zip(data.BinRoot, data.ZipCoreArtifacts); - Zip(data.Parameters.NugetRoot, data.Parameters.ZipNuGetArtifacts); + Zip(data.NugetRoot, data.ZipNuGetArtifacts); - Zip(data.Parameters.ZipSourceControlCatalogDesktopDirs, - data.Parameters.ZipTargetControlCatalogDesktopDirs, - GetFiles(data.Parameters.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.dll") + - GetFiles(data.Parameters.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.config") + - GetFiles(data.Parameters.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.so") + - GetFiles(data.Parameters.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.dylib") + - GetFiles(data.Parameters.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.exe")); + Zip(data.ZipSourceControlCatalogDesktopDirs, + data.ZipTargetControlCatalogDesktopDirs, + GetFiles(data.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.dll") + + GetFiles(data.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.config") + + GetFiles(data.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.so") + + GetFiles(data.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.dylib") + + GetFiles(data.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.exe")); }); -Task("Create-NuGet-Packages-Impl") - .Does(data => +void DotNetCorePack(Parameters parameters) { - foreach(var nuspec in data.Packages.NuspecNuGetSettings) + var settings = new DotNetCorePackSettings { - NuGetPack(nuspec); - } -}); - -Task("Publish-MyGet-Impl") - .WithCriteria((context, data) => !data.Parameters.IsLocalBuild) - .WithCriteria((context, data) => !data.Parameters.IsPullRequest) - .WithCriteria((context, data) => data.Parameters.IsMainRepo) - .WithCriteria((context, data) => data.Parameters.IsMasterBranch) - .WithCriteria((context, data) => data.Parameters.IsMyGetRelease) - .Does(data => -{ - var apiKey = EnvironmentVariable("MYGET_API_KEY"); - if(string.IsNullOrEmpty(apiKey)) - { - throw new InvalidOperationException("Could not resolve MyGet API key."); - } - - var apiUrl = EnvironmentVariable("MYGET_API_URL"); - if(string.IsNullOrEmpty(apiUrl)) - { - throw new InvalidOperationException("Could not resolve MyGet API url."); - } + Configuration = parameters.Configuration, + MSBuildSettings = new DotNetCoreMSBuildSettings + { + Properties = + { + { "PackageVersion", new [] { parameters.Version } } + } + } + }; - foreach(var nupkg in data.Packages.NugetPackages) - { - NuGetPush(nupkg, new NuGetPushSettings { - Source = apiUrl, - ApiKey = apiKey - }); - } -}) -.OnError(exception => -{ - Information("Publish-MyGet Task failed, but continuing with next Task..."); -}); + DotNetCorePack(parameters.MSBuildSolution, settings); +} -Task("Publish-NuGet-Impl") - .WithCriteria((context, data) => !data.Parameters.IsLocalBuild) - .WithCriteria((context, data) => !data.Parameters.IsPullRequest) - .WithCriteria((context, data) => data.Parameters.IsMainRepo) - .WithCriteria((context, data) => data.Parameters.IsNuGetRelease) - .Does(data => +Task("Create-NuGet-Packages-Impl") + .Does(data => { - var apiKey = EnvironmentVariable("NUGET_API_KEY"); - if(string.IsNullOrEmpty(apiKey)) - { - throw new InvalidOperationException("Could not resolve NuGet API key."); - } - - var apiUrl = EnvironmentVariable("NUGET_API_URL"); - if(string.IsNullOrEmpty(apiUrl)) + if(data.IsRunningOnWindows) { - throw new InvalidOperationException("Could not resolve NuGet API url."); - } - - foreach(var nupkg in data.Packages.NugetPackages) - { - NuGetPush(nupkg, new NuGetPushSettings { - ApiKey = apiKey, - Source = apiUrl + MSBuild(data.MSBuildSolution, settings => { + settings.SetConfiguration(data.Configuration); + settings.SetVerbosity(Verbosity.Minimal); + settings.WithProperty("iOSRoslynPathHackRequired", "true"); + settings.WithProperty("PackageVersion", data.Version); + settings.UseToolVersion(MSBuildToolVersion.VS2017); + settings.WithRestore(); + settings.WithTarget("Pack"); }); } -}) -.OnError(exception => -{ - Information("Publish-NuGet Task failed, but continuing with next Task..."); -}); - -Task("Inspect-Impl") - .WithCriteria((context, data) => data.Parameters.IsRunningOnWindows) - .Does(() => -{ - var badIssues = new []{"PossibleNullReferenceException"}; - var whitelist = new []{"tests", "src\\android", "src\\ios", - "src\\markup\\avalonia.markup.xaml\\portablexaml\\portable.xaml.github"}; - Information("Running code inspections"); - - var exitCode = StartProcess(Context.Tools.Resolve("inspectcode.exe"), - new ProcessSettings - { - Arguments = "--output=artifacts\\inspectcode.xml --profile=Avalonia.sln.DotSettings Avalonia.sln", - RedirectStandardOutput = true - }); - - Information("Analyzing report"); - var doc = XDocument.Parse(System.IO.File.ReadAllText("artifacts\\inspectcode.xml")); - var failBuild = false; - foreach(var xml in doc.Descendants("Issue")) + else { - var typeId = xml.Attribute("TypeId").Value.ToString(); - if(badIssues.Contains(typeId)) - { - var file = xml.Attribute("File").Value.ToString().ToLower(); - if(whitelist.Any(wh => file.StartsWith(wh))) - continue; - var line = xml.Attribute("Line").Value.ToString(); - Error(typeId + " - " + file + " on line " + line); - failBuild = true; - } + DotNetCorePack(data); } - if(failBuild) - throw new Exception("Issues found"); }); /////////////////////////////////////////////////////////////////////////////// @@ -363,19 +278,26 @@ Task("Run-Tests") Task("Package") .IsDependentOn("Run-Tests") - .IsDependentOn("Inspect-Impl") .IsDependentOn("Create-NuGet-Packages-Impl"); Task("AppVeyor") .IsDependentOn("Package") - .IsDependentOn("Copy-Files-Impl") - .IsDependentOn("Zip-Files-Impl") - .IsDependentOn("Publish-MyGet-Impl") - .IsDependentOn("Publish-NuGet-Impl"); + .IsDependentOn("Zip-Files-Impl"); Task("Travis") .IsDependentOn("Run-Tests"); +Task("Azure-Linux") + .IsDependentOn("Run-Tests"); + +Task("Azure-OSX") + .IsDependentOn("Package") + .IsDependentOn("Zip-Files-Impl"); + +Task("Azure-Windows") + .IsDependentOn("Package") + .IsDependentOn("Zip-Files-Impl"); + /////////////////////////////////////////////////////////////////////////////// // EXECUTE /////////////////////////////////////////////////////////////////////////////// diff --git a/build/CoreLibraries.props b/build/CoreLibraries.props new file mode 100644 index 0000000000..d989e643b8 --- /dev/null +++ b/build/CoreLibraries.props @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/build/LegacyProject.targets b/build/LegacyProject.targets new file mode 100644 index 0000000000..0e0d49b1c2 --- /dev/null +++ b/build/LegacyProject.targets @@ -0,0 +1,3 @@ + + + diff --git a/build/MonoMac.props b/build/MonoMac.props deleted file mode 100644 index 5cf19ef503..0000000000 --- a/build/MonoMac.props +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/build/ReactiveUI.props b/build/ReactiveUI.props index acdfdd215a..1208be34b8 100644 --- a/build/ReactiveUI.props +++ b/build/ReactiveUI.props @@ -1,5 +1,5 @@ - + diff --git a/build/ReferenceCoreLibraries.props b/build/ReferenceCoreLibraries.props new file mode 100644 index 0000000000..bd9d6ad843 --- /dev/null +++ b/build/ReferenceCoreLibraries.props @@ -0,0 +1,6 @@ + + + + + + diff --git a/build/Rx.props b/build/Rx.props index f4affcacac..359ce53a92 100644 --- a/build/Rx.props +++ b/build/Rx.props @@ -1,9 +1,5 @@  - - - - diff --git a/build/SampleApp.props b/build/SampleApp.props index 3b538e4029..5580a4c2c9 100644 --- a/build/SampleApp.props +++ b/build/SampleApp.props @@ -2,12 +2,7 @@ WinExe - - - - + - diff --git a/build/SharedVersion.props b/build/SharedVersion.props index 351583a106..b46ac16a79 100644 --- a/build/SharedVersion.props +++ b/build/SharedVersion.props @@ -2,8 +2,8 @@ xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> Avalonia - 0.6.2 - Copyright 2016 © The AvaloniaUI Project + 0.7.1 + Copyright 2018 © The AvaloniaUI Project https://github.com/AvaloniaUI/Avalonia/blob/master/licence.md https://github.com/AvaloniaUI/Avalonia/ https://github.com/AvaloniaUI/Avalonia/ diff --git a/build/System.Drawing.Common.props b/build/System.Drawing.Common.props index a568152bbd..2b3707d38a 100644 --- a/build/System.Drawing.Common.props +++ b/build/System.Drawing.Common.props @@ -1,5 +1,5 @@  - + diff --git a/dirs.proj b/dirs.proj index b655987aa4..0f24632b72 100644 --- a/dirs.proj +++ b/dirs.proj @@ -3,6 +3,7 @@ + diff --git a/global.json b/global.json index 38f403a701..d11e78bd7f 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,7 @@ { "msbuild-sdks": { - "Microsoft.Build.Traversal": "1.0.41", - "MSBuild.Sdk.Extras": "1.6.46" + "Microsoft.Build.Traversal": "1.0.43", + "MSBuild.Sdk.Extras": "1.6.46", + "AggregatePackage.NuGet.Sdk" : "0.1.12" } } diff --git a/native/Avalonia.Native/inc/avalonia-native-guids.h b/native/Avalonia.Native/inc/avalonia-native-guids.h new file mode 100644 index 0000000000..439008fd4b --- /dev/null +++ b/native/Avalonia.Native/inc/avalonia-native-guids.h @@ -0,0 +1,5 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +#define COM_GUIDS_MATERIALIZE +#include "avalonia-native.h" diff --git a/native/Avalonia.Native/inc/avalonia-native.h b/native/Avalonia.Native/inc/avalonia-native.h new file mode 100644 index 0000000000..0c965b7498 --- /dev/null +++ b/native/Avalonia.Native/inc/avalonia-native.h @@ -0,0 +1,363 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +#include "com.h" +#include "key.h" + +#define AVNCOM(name, id) COMINTERFACE(name, 2e2cda0a, 9ae5, 4f1b, 8e, 20, 08, 1a, 04, 27, 9f, id) + +struct IAvnWindowEvents; +struct IAvnWindow; +struct IAvnPopup; +struct IAvnMacOptions; +struct IAvnPlatformThreadingInterface; +struct IAvnSystemDialogEvents; +struct IAvnSystemDialogs; +struct IAvnScreens; +struct IAvnClipboard; +struct IAvnCursor; +struct IAvnCursorFactory; +struct IAvnGlFeature; +struct IAvnGlContext; +struct IAvnGlDisplay; +struct IAvnGlSurfaceRenderTarget; +struct IAvnGlSurfaceRenderingSession; + +struct AvnSize +{ + double Width, Height; +}; + +struct AvnPixelSize +{ + int Width, Height; +}; + +struct AvnRect +{ + double X, Y, Width, Height; +}; + +struct AvnVector +{ + double X, Y; +}; + +struct AvnPoint +{ + double X, Y; +}; + +struct AvnScreen +{ + AvnRect Bounds; + AvnRect WorkingArea; + bool Primary; +}; + +enum AvnPixelFormat +{ + kAvnRgb565, + kAvnRgba8888, + kAvnBgra8888 +}; + +struct AvnFramebuffer +{ + void* Data; + int Width; + int Height; + int Stride; + AvnVector Dpi; + AvnPixelFormat PixelFormat; +}; + +struct AvnColor +{ + unsigned char Alpha; + unsigned char Red; + unsigned char Green; + unsigned char Blue; +}; + +enum AvnRawMouseEventType +{ + LeaveWindow, + LeftButtonDown, + LeftButtonUp, + RightButtonDown, + RightButtonUp, + MiddleButtonDown, + MiddleButtonUp, + Move, + Wheel, + NonClientLeftButtonDown +}; + +enum AvnRawKeyEventType +{ + KeyDown, + KeyUp +}; + +enum AvnInputModifiers +{ + AvnInputModifiersNone = 0, + Alt = 1, + Control = 2, + Shift = 4, + Windows = 8, + LeftMouseButton = 16, + RightMouseButton = 32, + MiddleMouseButton = 64 +}; + +enum AvnWindowState +{ + Normal, + Minimized, + Maximized, +}; + +enum AvnStandardCursorType +{ + CursorArrow, + CursorIbeam, + CursorWait, + CursorCross, + CursorUpArrow, + CursorSizeWestEast, + CursorSizeNorthSouth, + CursorSizeAll, + CursorNo, + CursorHand, + CursorAppStarting, + CursorHelp, + CursorTopSide, + CursorBottomSize, + CursorLeftSide, + CursorRightSide, + CursorTopLeftCorner, + CursorTopRightCorner, + CursorBottomLeftCorner, + CursorBottomRightCorner, + CursorDragMove, + CursorDragCopy, + CursorDragLink, +}; + +enum AvnWindowEdge +{ + WindowEdgeNorthWest, + WindowEdgeNorth, + WindowEdgeNorthEast, + WindowEdgeWest, + WindowEdgeEast, + WindowEdgeSouthWest, + WindowEdgeSouth, + WindowEdgeSouthEast +}; + +AVNCOM(IAvaloniaNativeFactory, 01) : IUnknown +{ +public: + virtual HRESULT Initialize() = 0; + virtual IAvnMacOptions* GetMacOptions() = 0; + virtual HRESULT CreateWindow(IAvnWindowEvents* cb, IAvnWindow** ppv) = 0; + virtual HRESULT CreatePopup (IAvnWindowEvents* cb, IAvnPopup** ppv) = 0; + virtual HRESULT CreatePlatformThreadingInterface(IAvnPlatformThreadingInterface** ppv) = 0; + virtual HRESULT CreateSystemDialogs (IAvnSystemDialogs** ppv) = 0; + virtual HRESULT CreateScreens (IAvnScreens** ppv) = 0; + virtual HRESULT CreateClipboard(IAvnClipboard** ppv) = 0; + virtual HRESULT CreateCursorFactory(IAvnCursorFactory** ppv) = 0; + virtual HRESULT ObtainGlFeature(IAvnGlFeature** ppv) = 0; +}; + +AVNCOM(IAvnWindowBase, 02) : IUnknown +{ + virtual HRESULT Show() = 0; + virtual HRESULT Hide () = 0; + virtual HRESULT Close() = 0; + virtual HRESULT Activate () = 0; + virtual HRESULT GetClientSize(AvnSize*ret) = 0; + virtual HRESULT GetMaxClientSize(AvnSize* ret) = 0; + virtual HRESULT GetScaling(double*ret)=0; + virtual HRESULT SetMinMaxSize(AvnSize minSize, AvnSize maxSize) = 0; + virtual HRESULT Resize(double width, double height) = 0; + virtual HRESULT Invalidate (AvnRect rect) = 0; + virtual HRESULT BeginMoveDrag () = 0; + virtual HRESULT BeginResizeDrag (AvnWindowEdge edge) = 0; + virtual HRESULT GetPosition (AvnPoint*ret) = 0; + virtual HRESULT SetPosition (AvnPoint point) = 0; + virtual HRESULT PointToClient (AvnPoint point, AvnPoint*ret) = 0; + virtual HRESULT PointToScreen (AvnPoint point, AvnPoint*ret) = 0; + virtual HRESULT ThreadSafeSetSwRenderedFrame(AvnFramebuffer* fb, IUnknown* dispose) = 0; + virtual HRESULT SetTopMost (bool value) = 0; + virtual HRESULT SetCursor(IAvnCursor* cursor) = 0; + virtual HRESULT CreateGlRenderTarget(IAvnGlSurfaceRenderTarget** ret) = 0; + virtual HRESULT GetSoftwareFramebuffer(AvnFramebuffer*ret) = 0; + virtual bool TryLock() = 0; + virtual void Unlock() = 0; +}; + +AVNCOM(IAvnPopup, 03) : virtual IAvnWindowBase +{ + +}; + +AVNCOM(IAvnWindow, 04) : virtual IAvnWindowBase +{ + virtual HRESULT ShowDialog (IUnknown**ppv) = 0; + virtual HRESULT SetCanResize(bool value) = 0; + virtual HRESULT SetHasDecorations(bool value) = 0; + virtual HRESULT SetTitle (const char* title) = 0; + virtual HRESULT SetTitleBarColor (AvnColor color) = 0; + virtual HRESULT SetWindowState(AvnWindowState state) = 0; + virtual HRESULT GetWindowState(AvnWindowState*ret) = 0; +}; + +AVNCOM(IAvnWindowBaseEvents, 05) : IUnknown +{ + virtual HRESULT Paint() = 0; + virtual void Closed() = 0; + virtual void Activated() = 0; + virtual void Deactivated() = 0; + virtual void Resized(const AvnSize& size) = 0; + virtual void PositionChanged (AvnPoint position) = 0; + virtual void RawMouseEvent (AvnRawMouseEventType type, + unsigned int timeStamp, + AvnInputModifiers modifiers, + AvnPoint point, + AvnVector delta) = 0; + virtual bool RawKeyEvent (AvnRawKeyEventType type, unsigned int timeStamp, AvnInputModifiers modifiers, unsigned int key) = 0; + virtual bool RawTextInputEvent (unsigned int timeStamp, const char* text) = 0; + virtual void ScalingChanged(double scaling) = 0; + virtual void RunRenderPriorityJobs() = 0; +}; + + +AVNCOM(IAvnWindowEvents, 06) : IAvnWindowBaseEvents +{ + /** + * Closing Event + * Called when the user presses the OS window close button. + * return true to allow the close, return false to prevent close. + */ + virtual bool Closing () = 0; + + virtual void WindowStateChanged (AvnWindowState state) = 0; +}; + +AVNCOM(IAvnMacOptions, 07) : IUnknown +{ + virtual HRESULT SetShowInDock(int show) = 0; +}; + +AVNCOM(IAvnActionCallback, 08) : IUnknown +{ + virtual void Run() = 0; +}; + +AVNCOM(IAvnSignaledCallback, 09) : IUnknown +{ + virtual void Signaled(int priority, bool priorityContainsMeaningfulValue) = 0; +}; + +AVNCOM(IAvnLoopCancellation, 0a) : IUnknown +{ + virtual void Cancel() = 0; +}; + +AVNCOM(IAvnPlatformThreadingInterface, 0b) : IUnknown +{ + virtual bool GetCurrentThreadIsLoopThread() = 0; + virtual void SetSignaledCallback(IAvnSignaledCallback* cb) = 0; + virtual IAvnLoopCancellation* CreateLoopCancellation() = 0; + virtual void RunLoop(IAvnLoopCancellation* cancel) = 0; + // Can't pass int* to sharpgentools for some reason + virtual void Signal(int priority) = 0; + virtual IUnknown* StartTimer(int priority, int ms, IAvnActionCallback* callback) = 0; +}; + +AVNCOM(IAvnSystemDialogEvents, 0c) : IUnknown +{ + virtual void OnCompleted (int numResults, void* ptrFirstResult) = 0; +}; + +AVNCOM(IAvnSystemDialogs, 0d) : IUnknown +{ + virtual void SelectFolderDialog (IAvnWindow* parentWindowHandle, + IAvnSystemDialogEvents* events, + const char* title, + const char* initialPath) = 0; + + virtual void OpenFileDialog (IAvnWindow* parentWindowHandle, + IAvnSystemDialogEvents* events, + bool allowMultiple, + const char* title, + const char* initialDirectory, + const char* initialFile, + const char* filters) = 0; + + virtual void SaveFileDialog (IAvnWindow* parentWindowHandle, + IAvnSystemDialogEvents* events, + const char* title, + const char* initialDirectory, + const char* initialFile, + const char* filters) = 0; +}; + +AVNCOM(IAvnScreens, 0e) : IUnknown +{ + virtual HRESULT GetScreenCount (int* ret) = 0; + virtual HRESULT GetScreen (int index, AvnScreen* ret) = 0; +}; + +AVNCOM(IAvnClipboard, 0f) : IUnknown +{ + virtual HRESULT GetText (void** retOut) = 0; + virtual HRESULT SetText (char* text) = 0; + virtual HRESULT Clear() = 0; +}; + +AVNCOM(IAvnCursor, 10) : IUnknown +{ +}; + +AVNCOM(IAvnCursorFactory, 11) : IUnknown +{ + virtual HRESULT GetCursor (AvnStandardCursorType cursorType, IAvnCursor** retOut) = 0; +}; + + +AVNCOM(IAvnGlFeature, 12) : IUnknown +{ + virtual HRESULT ObtainDisplay(IAvnGlDisplay**retOut) = 0; + virtual HRESULT ObtainImmediateContext(IAvnGlContext**retOut) = 0; +}; + +AVNCOM(IAvnGlDisplay, 13) : IUnknown +{ + virtual HRESULT GetSampleCount(int* ret) = 0; + virtual HRESULT GetStencilSize(int* ret) = 0; + virtual HRESULT ClearContext() = 0; + virtual void* GetProcAddress(char* proc) = 0; +}; + +AVNCOM(IAvnGlContext, 14) : IUnknown +{ + virtual HRESULT MakeCurrent() = 0; +}; + +AVNCOM(IAvnGlSurfaceRenderTarget, 15) : IUnknown +{ + virtual HRESULT BeginDrawing(IAvnGlSurfaceRenderingSession** ret) = 0; +}; + +AVNCOM(IAvnGlSurfaceRenderingSession, 16) : IUnknown +{ + virtual HRESULT GetPixelSize(AvnPixelSize* ret) = 0; + virtual HRESULT GetScaling(double* ret) = 0; +}; + +extern "C" IAvaloniaNativeFactory* CreateAvaloniaNative(); diff --git a/native/Avalonia.Native/inc/com.h b/native/Avalonia.Native/inc/com.h new file mode 100644 index 0000000000..22fb4a11a3 --- /dev/null +++ b/native/Avalonia.Native/inc/com.h @@ -0,0 +1,57 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +#pragma clang diagnostic push +#pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection" +#ifndef COM_H_INCLUDED +#define COM_H_INCLUDED + + +typedef struct _GUID { + unsigned int Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[ 8 ]; +} GUID; +typedef GUID IID; +typedef const IID* REFIID; +typedef unsigned int HRESULT; +typedef unsigned int DWORD; +typedef DWORD ULONG; + +#define STDMETHODCALLTYPE + +#define S_OK 0x0L + +#define E_NOTIMPL 0x80004001L +#define E_NOINTERFACE 0x80004002L +#define E_POINTER 0x80004003L +#define E_ABORT 0x80004004L +#define E_FAIL 0x80004005L +#define E_UNEXPECTED 0x8000FFFFL +#define E_HANDLE 0x80070006L +#define E_INVALIDARG 0x80070057L + +struct IUnknown +{ + virtual HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void **ppvObject) = 0; + + virtual ULONG STDMETHODCALLTYPE AddRef( void) = 0; + + virtual ULONG STDMETHODCALLTYPE Release( void) = 0; + +}; + +#ifdef COM_GUIDS_MATERIALIZE +#define __IID_DEF(name,d1,d2,d3, d41, d42, d43, d44, d45, d46, d47, d48) extern "C" const GUID IID_ ## name = {0x ## d1, 0x ## d2, 0x ## d3, \ +{0x ## d41, 0x ## d42, 0x ## d42, 0x ## d42, 0x ## d42, 0x ## d42, 0x ## d42, 0x ## d42 } }; +#else +#define __IID_DEF(name,d1,d2,d3, d41, d42, d43, d44, d45, d46, d47, d48) extern "C" const GUID IID_ ## name; +#endif +#define COMINTERFACE(name,d1,d2,d3, d41, d42, d43, d44, d45, d46, d47, d48) __IID_DEF(name,d1,d2,d3, d41, d42, d43, d44, d45, d46, d47, d48) \ +struct __attribute__((annotate("uuid(" #d1 "-" #d2 "-" #d3 "-" #d41 #d42 "-" #d43 #d44 #d45 #d46 #d47 #d48 ")" ))) name + +#endif // COM_H_INCLUDED +#pragma clang diagnostic pop diff --git a/native/Avalonia.Native/inc/comimpl.h b/native/Avalonia.Native/inc/comimpl.h new file mode 100644 index 0000000000..cf1aa4c735 --- /dev/null +++ b/native/Avalonia.Native/inc/comimpl.h @@ -0,0 +1,184 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. +#include "com.h" +#pragma clang diagnostic push +#pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection" +#ifndef COMIMPL_H_INCLUDED +#define COMIMPL_H_INCLUDED + +#include + +__IID_DEF(IUnknown, 0, 0, 0, C0, 00, 00, 00, 00, 00, 00, 46); + +class ComObject : public virtual IUnknown +{ +private: + unsigned int _refCount; +public: + + virtual ULONG AddRef() + { + _refCount++; + return _refCount; + } + + + virtual ULONG Release() + { + _refCount--; + ULONG rv = _refCount; + if(_refCount == 0) + delete(this); + return rv; + } + + ComObject() + { + _refCount = 1; + + } + virtual ~ComObject() + { + } + + + virtual ::HRESULT STDMETHODCALLTYPE QueryInterfaceImpl(REFIID riid, void **ppvObject) = 0; + + virtual ::HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, + void **ppvObject) + { + if(0 == memcmp(riid, &IID_IUnknown, sizeof(GUID))) + *ppvObject = (IUnknown*)this; + else + { + auto rv = QueryInterfaceImpl(riid, ppvObject); + if(rv != S_OK) + return rv; + } + _refCount++; + return S_OK; + } + +}; + + +#define FORWARD_IUNKNOWN() \ +virtual ULONG Release() override \ +{ \ +return ComObject::Release(); \ +} \ +virtual ULONG AddRef() override \ +{ \ + return ComObject::AddRef(); \ +} \ +virtual HRESULT QueryInterface(REFIID riid, void **ppvObject) override \ +{ \ + return ComObject::QueryInterface(riid, ppvObject); \ +} + +#define BEGIN_INTERFACE_MAP() public: virtual HRESULT STDMETHODCALLTYPE QueryInterfaceImpl(REFIID riid, void **ppvObject) override { +#define INTERFACE_MAP_ENTRY(TInterface, IID) if(0 == memcmp(riid, &IID, sizeof(GUID))) { TInterface* casted = this; *ppvObject = casted; return S_OK; } +#define END_INTERFACE_MAP() return E_NOINTERFACE; } +#define INHERIT_INTERFACE_MAP(TBase) if(TBase::QueryInterfaceImpl(riid, ppvObject) == S_OK) return S_OK; + + + +class ComUnknownObject : public ComObject +{ +public: + FORWARD_IUNKNOWN() + virtual ::HRESULT STDMETHODCALLTYPE QueryInterfaceImpl(REFIID riid, void **ppvObject) override + { + return E_NOINTERFACE; + }; + virtual ~ComUnknownObject(){} +}; + +template class ComSingleObject : public ComObject, public virtual TInterface +{ + BEGIN_INTERFACE_MAP() + INTERFACE_MAP_ENTRY(TInterface, *TIID) + END_INTERFACE_MAP() + +public: + virtual ~ComSingleObject(){} +}; + +template +class ComPtr +{ +private: + TInterface* _obj; +public: + ComPtr() + { + _obj = 0; + } + + ComPtr(TInterface* pObj) + { + _obj = 0; + + if (pObj) + { + _obj = pObj; + _obj->AddRef(); + } + } + + ComPtr(const ComPtr& ptr) + { + _obj = 0; + + if (ptr._obj) + { + _obj = ptr._obj; + _obj->AddRef(); + } + + } + + ComPtr& operator=(ComPtr other) + { + if(_obj != NULL) + _obj->Release(); + _obj = other._obj; + if(_obj != NULL) + _obj->AddRef(); + return *this; + } + + ~ComPtr() + { + if (_obj) + { + _obj->Release(); + _obj = 0; + } + } + + TInterface* getRaw() + { + return _obj; + } + + operator TInterface*() const + { + return _obj; + } + TInterface& operator*() const + { + return *_obj; + } + TInterface** operator&() + { + return &_obj; + } + TInterface* operator->() const + { + return _obj; + } +}; + +#endif // COMIMPL_H_INCLUDED +#pragma clang diagnostic pop diff --git a/native/Avalonia.Native/inc/key.h b/native/Avalonia.Native/inc/key.h new file mode 100644 index 0000000000..cdc9658e29 --- /dev/null +++ b/native/Avalonia.Native/inc/key.h @@ -0,0 +1,1023 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +#ifndef _KEY_H_ +#define _KEY_H_ + +/// +/// Defines the keys available on a keyboard. +/// +enum AvnKey +{ + /// + /// No key pressed. + /// + AvnKeyNone = 0, + + /// + /// The Cancel key. + /// + AvnKeyCancel = 1, + + /// + /// The Back key. + /// + AvnKeyBack = 2, + + /// + /// The Tab key. + /// + AvnKeyTab = 3, + + /// + /// The Linefeed key. + /// + AvnKeyLineFeed = 4, + + /// + /// The Clear key. + /// + AvnKeyClear = 5, + + /// + /// The Return key. + /// + AvnKeyReturn = 6, + + /// + /// The Enter key. + /// + AvnKeyEnter = 6, + + /// + /// The Pause key. + /// + AvnKeyPause = 7, + + /// + /// The Caps Lock key. + /// + AvnKeyCapsLock = 8, + + /// + /// The Caps Lock key. + /// + AvnKeyCapital = 8, + + /// + /// The IME Hangul mode key. + /// + AvnKeyHangulMode = 9, + + /// + /// The IME Kana mode key. + /// + AvnKeyKanaMode = 9, + + /// + /// The IME Junja mode key. + /// + AvnKeyJunjaMode = 10, + + /// + /// The IME Final mode key. + /// + AvnKeyFinalMode = 11, + + /// + /// The IME Kanji mode key. + /// + AvnKeyKanjiMode = 12, + + /// + /// The IME Hanja mode key. + /// + HanjaMode = 12, + + /// + /// The Escape key. + /// + Escape = 13, + + /// + /// The IME Convert key. + /// + ImeConvert = 14, + + /// + /// The IME NonConvert key. + /// + ImeNonConvert = 15, + + /// + /// The IME Accept key. + /// + ImeAccept = 16, + + /// + /// The IME Mode change key. + /// + ImeModeChange = 17, + + /// + /// The space bar. + /// + Space = 18, + + /// + /// The Page Up key. + /// + PageUp = 19, + + /// + /// The Page Up key. + /// + Prior = 19, + + /// + /// The Page Down key. + /// + PageDown = 20, + + /// + /// The Page Down key. + /// + Next = 20, + + /// + /// The End key. + /// + End = 21, + + /// + /// The Home key. + /// + Home = 22, + + /// + /// The Left arrow key. + /// + Left = 23, + + /// + /// The Up arrow key. + /// + Up = 24, + + /// + /// The Right arrow key. + /// + Right = 25, + + /// + /// The Down arrow key. + /// + Down = 26, + + /// + /// The Select key. + /// + Select = 27, + + /// + /// The Print key. + /// + Print = 28, + + /// + /// The Execute key. + /// + Execute = 29, + + /// + /// The Print Screen key. + /// + Snapshot = 30, + + /// + /// The Print Screen key. + /// + PrintScreen = 30, + + /// + /// The Insert key. + /// + Insert = 31, + + /// + /// The Delete key. + /// + Delete = 32, + + /// + /// The Help key. + /// + Help = 33, + + /// + /// The 0 key. + /// + D0 = 34, + + /// + /// The 1 key. + /// + D1 = 35, + + /// + /// The 2 key. + /// + D2 = 36, + + /// + /// The 3 key. + /// + D3 = 37, + + /// + /// The 4 key. + /// + D4 = 38, + + /// + /// The 5 key. + /// + D5 = 39, + + /// + /// The 6 key. + /// + D6 = 40, + + /// + /// The 7 key. + /// + D7 = 41, + + /// + /// The 8 key. + /// + D8 = 42, + + /// + /// The 9 key. + /// + D9 = 43, + + /// + /// The A key. + /// + A = 44, + + /// + /// The B key. + /// + B = 45, + + /// + /// The C key. + /// + C = 46, + + /// + /// The D key. + /// + D = 47, + + /// + /// The E key. + /// + E = 48, + + /// + /// The F key. + /// + F = 49, + + /// + /// The G key. + /// + G = 50, + + /// + /// The H key. + /// + H = 51, + + /// + /// The I key. + /// + I = 52, + + /// + /// The J key. + /// + J = 53, + + /// + /// The K key. + /// + AvnKeyK = 54, + + /// + /// The L key. + /// + L = 55, + + /// + /// The M key. + /// + M = 56, + + /// + /// The N key. + /// + N = 57, + + /// + /// The O key. + /// + O = 58, + + /// + /// The P key. + /// + P = 59, + + /// + /// The Q key. + /// + Q = 60, + + /// + /// The R key. + /// + R = 61, + + /// + /// The S key. + /// + S = 62, + + /// + /// The T key. + /// + T = 63, + + /// + /// The U key. + /// + U = 64, + + /// + /// The V key. + /// + V = 65, + + /// + /// The W key. + /// + W = 66, + + /// + /// The X key. + /// + X = 67, + + /// + /// The Y key. + /// + Y = 68, + + /// + /// The Z key. + /// + Z = 69, + + /// + /// The left Windows key. + /// + LWin = 70, + + /// + /// The right Windows key. + /// + RWin = 71, + + /// + /// The Application key. + /// + Apps = 72, + + /// + /// The Sleep key. + /// + Sleep = 73, + + /// + /// The 0 key on the numeric keypad. + /// + NumPad0 = 74, + + /// + /// The 1 key on the numeric keypad. + /// + NumPad1 = 75, + + /// + /// The 2 key on the numeric keypad. + /// + NumPad2 = 76, + + /// + /// The 3 key on the numeric keypad. + /// + NumPad3 = 77, + + /// + /// The 4 key on the numeric keypad. + /// + NumPad4 = 78, + + /// + /// The 5 key on the numeric keypad. + /// + NumPad5 = 79, + + /// + /// The 6 key on the numeric keypad. + /// + NumPad6 = 80, + + /// + /// The 7 key on the numeric keypad. + /// + NumPad7 = 81, + + /// + /// The 8 key on the numeric keypad. + /// + NumPad8 = 82, + + /// + /// The 9 key on the numeric keypad. + /// + NumPad9 = 83, + + /// + /// The Multiply key. + /// + Multiply = 84, + + /// + /// The Add key. + /// + Add = 85, + + /// + /// The Separator key. + /// + Separator = 86, + + /// + /// The Subtract key. + /// + Subtract = 87, + + /// + /// The Decimal key. + /// + Decimal = 88, + + /// + /// The Divide key. + /// + Divide = 89, + + /// + /// The F1 key. + /// + F1 = 90, + + /// + /// The F2 key. + /// + F2 = 91, + + /// + /// The F3 key. + /// + F3 = 92, + + /// + /// The F4 key. + /// + F4 = 93, + + /// + /// The F5 key. + /// + F5 = 94, + + /// + /// The F6 key. + /// + F6 = 95, + + /// + /// The F7 key. + /// + F7 = 96, + + /// + /// The F8 key. + /// + F8 = 97, + + /// + /// The F9 key. + /// + F9 = 98, + + /// + /// The F10 key. + /// + F10 = 99, + + /// + /// The F11 key. + /// + F11 = 100, + + /// + /// The F12 key. + /// + F12 = 101, + + /// + /// The F13 key. + /// + F13 = 102, + + /// + /// The F14 key. + /// + F14 = 103, + + /// + /// The F15 key. + /// + F15 = 104, + + /// + /// The F16 key. + /// + F16 = 105, + + /// + /// The F17 key. + /// + F17 = 106, + + /// + /// The F18 key. + /// + F18 = 107, + + /// + /// The F19 key. + /// + F19 = 108, + + /// + /// The F20 key. + /// + F20 = 109, + + /// + /// The F21 key. + /// + F21 = 110, + + /// + /// The F22 key. + /// + F22 = 111, + + /// + /// The F23 key. + /// + F23 = 112, + + /// + /// The F24 key. + /// + F24 = 113, + + /// + /// The Numlock key. + /// + NumLock = 114, + + /// + /// The Scroll key. + /// + Scroll = 115, + + /// + /// The left Shift key. + /// + LeftShift = 116, + + /// + /// The right Shift key. + /// + RightShift = 117, + + /// + /// The left Ctrl key. + /// + LeftCtrl = 118, + + /// + /// The right Ctrl key. + /// + RightCtrl = 119, + + /// + /// The left Alt key. + /// + LeftAlt = 120, + + /// + /// The right Alt key. + /// + RightAlt = 121, + + /// + /// The browser Back key. + /// + BrowserBack = 122, + + /// + /// The browser Forward key. + /// + BrowserForward = 123, + + /// + /// The browser Refresh key. + /// + BrowserRefresh = 124, + + /// + /// The browser Stop key. + /// + BrowserStop = 125, + + /// + /// The browser Search key. + /// + BrowserSearch = 126, + + /// + /// The browser Favorites key. + /// + BrowserFavorites = 127, + + /// + /// The browser Home key. + /// + BrowserHome = 128, + + /// + /// The Volume Mute key. + /// + VolumeMute = 129, + + /// + /// The Volume Down key. + /// + VolumeDown = 130, + + /// + /// The Volume Up key. + /// + VolumeUp = 131, + + /// + /// The media Next Track key. + /// + MediaNextTrack = 132, + + /// + /// The media Previous Track key. + /// + MediaPreviousTrack = 133, + + /// + /// The media Stop key. + /// + MediaStop = 134, + + /// + /// The media Play/Pause key. + /// + MediaPlayPause = 135, + + /// + /// The Launch Mail key. + /// + LaunchMail = 136, + + /// + /// The Select Media key. + /// + SelectMedia = 137, + + /// + /// The Launch Application 1 key. + /// + LaunchApplication1 = 138, + + /// + /// The Launch Application 2 key. + /// + LaunchApplication2 = 139, + + /// + /// The OEM Semicolon key. + /// + OemSemicolon = 140, + + /// + /// The OEM 1 key. + /// + Oem1 = 140, + + /// + /// The OEM Plus key. + /// + OemPlus = 141, + + /// + /// The OEM Comma key. + /// + OemComma = 142, + + /// + /// The OEM Minus key. + /// + OemMinus = 143, + + /// + /// The OEM Period key. + /// + OemPeriod = 144, + + /// + /// The OEM Question Mark key. + /// + OemQuestion = 145, + + /// + /// The OEM 2 key. + /// + Oem2 = 145, + + /// + /// The OEM Tilde key. + /// + OemTilde = 146, + + /// + /// The OEM 3 key. + /// + Oem3 = 146, + + /// + /// The ABNT_C1 (Brazilian) key. + /// + AbntC1 = 147, + + /// + /// The ABNT_C2 (Brazilian) key. + /// + AbntC2 = 148, + + /// + /// The OEM Open Brackets key. + /// + OemOpenBrackets = 149, + + /// + /// The OEM 4 key. + /// + Oem4 = 149, + + /// + /// The OEM Pipe key. + /// + OemPipe = 150, + + /// + /// The OEM 5 key. + /// + Oem5 = 150, + + /// + /// The OEM Close Brackets key. + /// + OemCloseBrackets = 151, + + /// + /// The OEM 6 key. + /// + Oem6 = 151, + + /// + /// The OEM Quotes key. + /// + OemQuotes = 152, + + /// + /// The OEM 7 key. + /// + Oem7 = 152, + + /// + /// The OEM 8 key. + /// + Oem8 = 153, + + /// + /// The OEM Backslash key. + /// + OemBackslash = 154, + + /// + /// The OEM 3 key. + /// + Oem102 = 154, + + /// + /// A special key masking the real key being processed by an IME. + /// + ImeProcessed = 155, + + /// + /// A special key masking the real key being processed as a system key. + /// + System = 156, + + /// + /// The OEM ATTN key. + /// + OemAttn = 157, + + /// + /// The DBE_ALPHANUMERIC key. + /// + DbeAlphanumeric = 157, + + /// + /// The OEM Finish key. + /// + OemFinish = 158, + + /// + /// The DBE_KATAKANA key. + /// + DbeKatakana = 158, + + /// + /// The DBE_HIRAGANA key. + /// + DbeHiragana = 159, + + /// + /// The OEM Copy key. + /// + OemCopy = 159, + + /// + /// The DBE_SBCSCHAR key. + /// + DbeSbcsChar = 160, + + /// + /// The OEM Auto key. + /// + OemAuto = 160, + + /// + /// The DBE_DBCSCHAR key. + /// + DbeDbcsChar = 161, + + /// + /// The OEM ENLW key. + /// + OemEnlw = 161, + + /// + /// The OEM BackTab key. + /// + OemBackTab = 162, + + /// + /// The DBE_ROMAN key. + /// + DbeRoman = 162, + + /// + /// The DBE_NOROMAN key. + /// + DbeNoRoman = 163, + + /// + /// The ATTN key. + /// + Attn = 163, + + /// + /// The CRSEL key. + /// + CrSel = 164, + + /// + /// The DBE_ENTERWORDREGISTERMODE key. + /// + DbeEnterWordRegisterMode = 164, + + /// + /// The EXSEL key. + /// + ExSel = 165, + + /// + /// The DBE_ENTERIMECONFIGMODE key. + /// + DbeEnterImeConfigureMode = 165, + + /// + /// The ERASE EOF Key. + /// + EraseEof = 166, + + /// + /// The DBE_FLUSHSTRING key. + /// + DbeFlushString = 166, + + /// + /// The Play key. + /// + Play = 167, + + /// + /// The DBE_CODEINPUT key. + /// + DbeCodeInput = 167, + + /// + /// The DBE_NOCODEINPUT key. + /// + DbeNoCodeInput = 168, + + /// + /// The Zoom key. + /// + Zoom = 168, + + /// + /// Reserved for future use. + /// + NoName = 169, + + /// + /// The DBE_DETERMINESTRING key. + /// + DbeDetermineString = 169, + + /// + /// The DBE_ENTERDLGCONVERSIONMODE key. + /// + DbeEnterDialogConversionMode = 170, + + /// + /// The PA1 key. + /// + Pa1 = 170, + + /// + /// The OEM Clear key. + /// + OemClear = 171, + + /// + /// The key is used with another key to create a single combined character. + /// + DeadCharProcessed = 172, +}; + +#endif diff --git a/native/Avalonia.Native/src/OSX/.gitignore b/native/Avalonia.Native/src/OSX/.gitignore new file mode 100644 index 0000000000..cbe26bb13c --- /dev/null +++ b/native/Avalonia.Native/src/OSX/.gitignore @@ -0,0 +1,4 @@ +build + +Avalonia.Native.OSX.xcodeproj/xcuserdata +Avalonia.Native.OSX.xcodeproj/project.xcworkspace/xcuserdata diff --git a/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj b/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..bd8ac481a8 --- /dev/null +++ b/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj @@ -0,0 +1,328 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 37A517B32159597E00FBA241 /* Screens.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37A517B22159597E00FBA241 /* Screens.mm */; }; + 37C09D8821580FE4006A6758 /* SystemDialogs.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37C09D8721580FE4006A6758 /* SystemDialogs.mm */; }; + 37E2330F21583241000CB7E2 /* KeyTransform.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37E2330E21583241000CB7E2 /* KeyTransform.mm */; }; + 5B21A982216530F500CEE36E /* cursor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B21A981216530F500CEE36E /* cursor.mm */; }; + 5B8BD94F215BFEA6005ED2A7 /* clipboard.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */; }; + AB00E4F72147CA920032A60A /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB00E4F62147CA920032A60A /* main.mm */; }; + AB1E522C217613570091CD71 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB1E522B217613570091CD71 /* OpenGL.framework */; }; + AB573DC4217605E400D389A2 /* gl.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB573DC3217605E400D389A2 /* gl.mm */; }; + AB661C1E2148230F00291242 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB661C1D2148230F00291242 /* AppKit.framework */; }; + AB661C202148286E00291242 /* window.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB661C1F2148286E00291242 /* window.mm */; }; + AB8F7D6B21482D7F0057DBA5 /* platformthreading.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB8F7D6A21482D7F0057DBA5 /* platformthreading.mm */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 379860FE214DA0C000CD0246 /* KeyTransform.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeyTransform.h; sourceTree = ""; }; + 37A4E71A2178846A00EACBCD /* headers */ = {isa = PBXFileReference; lastKnownFileType = folder; name = headers; path = ../../inc; sourceTree = ""; }; + 37A517B22159597E00FBA241 /* Screens.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = Screens.mm; sourceTree = ""; }; + 37C09D8721580FE4006A6758 /* SystemDialogs.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SystemDialogs.mm; sourceTree = ""; }; + 37C09D8A21581EF2006A6758 /* window.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = window.h; sourceTree = ""; }; + 37E2330E21583241000CB7E2 /* KeyTransform.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KeyTransform.mm; sourceTree = ""; }; + 5B21A981216530F500CEE36E /* cursor.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = cursor.mm; sourceTree = ""; }; + 5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = clipboard.mm; sourceTree = ""; }; + 5BF943652167AD1D009CAE35 /* cursor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cursor.h; sourceTree = ""; }; + AB00E4F62147CA920032A60A /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = ""; }; + AB1E522B217613570091CD71 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; + AB573DC3217605E400D389A2 /* gl.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = gl.mm; sourceTree = ""; }; + AB661C1D2148230F00291242 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; + AB661C1F2148286E00291242 /* window.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = window.mm; sourceTree = ""; }; + AB661C212148288600291242 /* common.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = common.h; sourceTree = ""; }; + AB7A61EF2147C815003C5833 /* libAvalonia.Native.OSX.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libAvalonia.Native.OSX.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; + AB8F7D6A21482D7F0057DBA5 /* platformthreading.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = platformthreading.mm; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + AB7A61EC2147C814003C5833 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + AB1E522C217613570091CD71 /* OpenGL.framework in Frameworks */, + AB661C1E2148230F00291242 /* AppKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + AB661C1C2148230E00291242 /* Frameworks */ = { + isa = PBXGroup; + children = ( + AB1E522B217613570091CD71 /* OpenGL.framework */, + AB661C1D2148230F00291242 /* AppKit.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + AB7A61E62147C814003C5833 = { + isa = PBXGroup; + children = ( + 37A4E71A2178846A00EACBCD /* headers */, + AB573DC3217605E400D389A2 /* gl.mm */, + 5BF943652167AD1D009CAE35 /* cursor.h */, + 5B21A981216530F500CEE36E /* cursor.mm */, + 5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */, + AB8F7D6A21482D7F0057DBA5 /* platformthreading.mm */, + AB661C212148288600291242 /* common.h */, + 379860FE214DA0C000CD0246 /* KeyTransform.h */, + 37E2330E21583241000CB7E2 /* KeyTransform.mm */, + AB661C1F2148286E00291242 /* window.mm */, + 37C09D8A21581EF2006A6758 /* window.h */, + AB00E4F62147CA920032A60A /* main.mm */, + 37A517B22159597E00FBA241 /* Screens.mm */, + 37C09D8721580FE4006A6758 /* SystemDialogs.mm */, + AB7A61F02147C815003C5833 /* Products */, + AB661C1C2148230E00291242 /* Frameworks */, + ); + sourceTree = ""; + }; + AB7A61F02147C815003C5833 /* Products */ = { + isa = PBXGroup; + children = ( + AB7A61EF2147C815003C5833 /* libAvalonia.Native.OSX.dylib */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + AB7A61ED2147C814003C5833 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + AB7A61EE2147C814003C5833 /* Avalonia.Native.OSX */ = { + isa = PBXNativeTarget; + buildConfigurationList = AB7A61F82147C815003C5833 /* Build configuration list for PBXNativeTarget "Avalonia.Native.OSX" */; + buildPhases = ( + AB7A61EB2147C814003C5833 /* Sources */, + AB7A61EC2147C814003C5833 /* Frameworks */, + AB7A61ED2147C814003C5833 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Avalonia.Native.OSX; + productName = Avalonia.Native.OSX; + productReference = AB7A61EF2147C815003C5833 /* libAvalonia.Native.OSX.dylib */; + productType = "com.apple.product-type.library.dynamic"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + AB7A61E72147C814003C5833 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1000; + ORGANIZATIONNAME = Avalonia; + TargetAttributes = { + AB7A61EE2147C814003C5833 = { + CreatedOnToolsVersion = 8.3.2; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = AB7A61EA2147C814003C5833 /* Build configuration list for PBXProject "Avalonia.Native.OSX" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = AB7A61E62147C814003C5833; + productRefGroup = AB7A61F02147C815003C5833 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + AB7A61EE2147C814003C5833 /* Avalonia.Native.OSX */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + AB7A61EB2147C814003C5833 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5B8BD94F215BFEA6005ED2A7 /* clipboard.mm in Sources */, + 5B21A982216530F500CEE36E /* cursor.mm in Sources */, + AB8F7D6B21482D7F0057DBA5 /* platformthreading.mm in Sources */, + 37E2330F21583241000CB7E2 /* KeyTransform.mm in Sources */, + 37A517B32159597E00FBA241 /* Screens.mm in Sources */, + AB00E4F72147CA920032A60A /* main.mm in Sources */, + 37C09D8821580FE4006A6758 /* SystemDialogs.mm in Sources */, + AB573DC4217605E400D389A2 /* gl.mm in Sources */, + AB661C202148286E00291242 /* window.mm in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + AB7A61F62147C815003C5833 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.12; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + AB7A61F72147C815003C5833 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.12; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + }; + name = Release; + }; + AB7A61F92147C815003C5833 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_PREFIX = lib; + HEADER_SEARCH_PATHS = ../../inc; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + AB7A61FA2147C815003C5833 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_PREFIX = lib; + HEADER_SEARCH_PATHS = ../../inc; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + AB7A61EA2147C814003C5833 /* Build configuration list for PBXProject "Avalonia.Native.OSX" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + AB7A61F62147C815003C5833 /* Debug */, + AB7A61F72147C815003C5833 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + AB7A61F82147C815003C5833 /* Build configuration list for PBXNativeTarget "Avalonia.Native.OSX" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + AB7A61F92147C815003C5833 /* Debug */, + AB7A61FA2147C815003C5833 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = AB7A61E72147C814003C5833 /* Project object */; +} diff --git a/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..4ea7ed7566 --- /dev/null +++ b/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/xcshareddata/xcschemes/Avalonia.Native.OSX.xcscheme b/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/xcshareddata/xcschemes/Avalonia.Native.OSX.xcscheme new file mode 100644 index 0000000000..1a665d3ea5 --- /dev/null +++ b/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/xcshareddata/xcschemes/Avalonia.Native.OSX.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/native/Avalonia.Native/src/OSX/KeyTransform.h b/native/Avalonia.Native/src/OSX/KeyTransform.h new file mode 100644 index 0000000000..c4466020c3 --- /dev/null +++ b/native/Avalonia.Native/src/OSX/KeyTransform.h @@ -0,0 +1,12 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +#ifndef keytransform_h +#define keytransform_h +#include "common.h" +#include "key.h" +#include + +extern std::map s_KeyMap; + +#endif diff --git a/native/Avalonia.Native/src/OSX/KeyTransform.mm b/native/Avalonia.Native/src/OSX/KeyTransform.mm new file mode 100644 index 0000000000..7486aaad69 --- /dev/null +++ b/native/Avalonia.Native/src/OSX/KeyTransform.mm @@ -0,0 +1,241 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +#include "KeyTransform.h" + +const int kVK_ANSI_A = 0x00; +const int kVK_ANSI_S = 0x01; +const int kVK_ANSI_D = 0x02; +const int kVK_ANSI_F = 0x03; +const int kVK_ANSI_H = 0x04; +const int kVK_ANSI_G = 0x05; +const int kVK_ANSI_Z = 0x06; +const int kVK_ANSI_X = 0x07; +const int kVK_ANSI_C = 0x08; +const int kVK_ANSI_V = 0x09; +const int kVK_ANSI_B = 0x0B; +const int kVK_ANSI_Q = 0x0C; +const int kVK_ANSI_W = 0x0D; +const int kVK_ANSI_E = 0x0E; +const int kVK_ANSI_R = 0x0F; +const int kVK_ANSI_Y = 0x10; +const int kVK_ANSI_T = 0x11; +const int kVK_ANSI_1 = 0x12; +const int kVK_ANSI_2 = 0x13; +const int kVK_ANSI_3 = 0x14; +const int kVK_ANSI_4 = 0x15; +const int kVK_ANSI_6 = 0x16; +const int kVK_ANSI_5 = 0x17; +//const int kVK_ANSI_Equal = 0x18; +const int kVK_ANSI_9 = 0x19; +const int kVK_ANSI_7 = 0x1A; +const int kVK_ANSI_Minus = 0x1B; +const int kVK_ANSI_8 = 0x1C; +const int kVK_ANSI_0 = 0x1D; +const int kVK_ANSI_RightBracket = 0x1E; +const int kVK_ANSI_O = 0x1F; +const int kVK_ANSI_U = 0x20; +const int kVK_ANSI_LeftBracket = 0x21; +const int kVK_ANSI_I = 0x22; +const int kVK_ANSI_P = 0x23; +const int kVK_ANSI_L = 0x25; +const int kVK_ANSI_J = 0x26; +const int kVK_ANSI_Quote = 0x27; +const int kVK_ANSI_K = 0x28; +const int kVK_ANSI_Semicolon = 0x29; +const int kVK_ANSI_Backslash = 0x2A; +const int kVK_ANSI_Comma = 0x2B; +//const int kVK_ANSI_Slash = 0x2C; +const int kVK_ANSI_N = 0x2D; +const int kVK_ANSI_M = 0x2E; +const int kVK_ANSI_Period = 0x2F; +//const int kVK_ANSI_Grave = 0x32; +const int kVK_ANSI_KeypadDecimal = 0x41; +const int kVK_ANSI_KeypadMultiply = 0x43; +const int kVK_ANSI_KeypadPlus = 0x45; +const int kVK_ANSI_KeypadClear = 0x47; +const int kVK_ANSI_KeypadDivide = 0x4B; +const int kVK_ANSI_KeypadEnter = 0x4C; +const int kVK_ANSI_KeypadMinus = 0x4E; +//const int kVK_ANSI_KeypadEquals = 0x51; +const int kVK_ANSI_Keypad0 = 0x52; +const int kVK_ANSI_Keypad1 = 0x53; +const int kVK_ANSI_Keypad2 = 0x54; +const int kVK_ANSI_Keypad3 = 0x55; +const int kVK_ANSI_Keypad4 = 0x56; +const int kVK_ANSI_Keypad5 = 0x57; +const int kVK_ANSI_Keypad6 = 0x58; +const int kVK_ANSI_Keypad7 = 0x59; +const int kVK_ANSI_Keypad8 = 0x5B; +const int kVK_ANSI_Keypad9 = 0x5C; +const int kVK_Return = 0x24; +const int kVK_Tab = 0x30; +const int kVK_Space = 0x31; +const int kVK_Delete = 0x33; +const int kVK_Escape = 0x35; +const int kVK_Command = 0x37; +const int kVK_Shift = 0x38; +const int kVK_CapsLock = 0x39; +const int kVK_Option = 0x3A; +const int kVK_Control = 0x3B; +const int kVK_RightCommand = 0x36; +const int kVK_RightShift = 0x3C; +const int kVK_RightOption = 0x3D; +const int kVK_RightControl = 0x3E; +//const int kVK_Function = 0x3F; +const int kVK_F17 = 0x40; +const int kVK_VolumeUp = 0x48; +const int kVK_VolumeDown = 0x49; +const int kVK_Mute = 0x4A; +const int kVK_F18 = 0x4F; +const int kVK_F19 = 0x50; +const int kVK_F20 = 0x5A; +const int kVK_F5 = 0x60; +const int kVK_F6 = 0x61; +const int kVK_F7 = 0x62; +const int kVK_F3 = 0x63; +const int kVK_F8 = 0x64; +const int kVK_F9 = 0x65; +const int kVK_F11 = 0x67; +const int kVK_F13 = 0x69; +const int kVK_F16 = 0x6A; +const int kVK_F14 = 0x6B; +const int kVK_F10 = 0x6D; +const int kVK_F12 = 0x6F; +const int kVK_F15 = 0x71; +const int kVK_Help = 0x72; +const int kVK_Home = 0x73; +const int kVK_PageUp = 0x74; +const int kVK_ForwardDelete = 0x75; +const int kVK_F4 = 0x76; +const int kVK_End = 0x77; +const int kVK_F2 = 0x78; +const int kVK_PageDown = 0x79; +const int kVK_F1 = 0x7A; +const int kVK_LeftArrow = 0x7B; +const int kVK_RightArrow = 0x7C; +const int kVK_DownArrow = 0x7D; +const int kVK_UpArrow = 0x7E; +//const int kVK_ISO_Section = 0x0A; +//const int kVK_JIS_Yen = 0x5D; +//const int kVK_JIS_Underscore = 0x5E; +//const int kVK_JIS_KeypadComma = 0x5F; +//const int kVK_JIS_Eisu = 0x66; +//const int kVK_JIS_Kana = 0x68; + + std::map s_KeyMap = + { + {kVK_ANSI_A, A}, + {kVK_ANSI_S, S}, + {kVK_ANSI_D, D}, + {kVK_ANSI_F, F}, + {kVK_ANSI_H, H}, + {kVK_ANSI_G, G}, + {kVK_ANSI_Z, Z}, + {kVK_ANSI_X, X}, + {kVK_ANSI_C, C}, + {kVK_ANSI_V, V}, + {kVK_ANSI_B, B}, + {kVK_ANSI_Q, Q}, + {kVK_ANSI_W, W}, + {kVK_ANSI_E, E}, + {kVK_ANSI_R, R}, + {kVK_ANSI_Y, Y}, + {kVK_ANSI_T, T}, + {kVK_ANSI_1, D1}, + {kVK_ANSI_2, D2}, + {kVK_ANSI_3, D3}, + {kVK_ANSI_4, D4}, + {kVK_ANSI_6, D6}, + {kVK_ANSI_5, D5}, + //{kVK_ANSI_Equal, ?}, + {kVK_ANSI_9, D9}, + {kVK_ANSI_7, D7}, + {kVK_ANSI_Minus, OemMinus}, + {kVK_ANSI_8, D8}, + {kVK_ANSI_0, D0}, + {kVK_ANSI_RightBracket, OemCloseBrackets}, + {kVK_ANSI_O, O}, + {kVK_ANSI_U, U}, + {kVK_ANSI_LeftBracket, OemOpenBrackets}, + {kVK_ANSI_I, I}, + {kVK_ANSI_P, P}, + {kVK_ANSI_L, L}, + {kVK_ANSI_J, J}, + {kVK_ANSI_Quote, OemQuotes}, + {kVK_ANSI_K, AvnKeyK}, + {kVK_ANSI_Semicolon, OemSemicolon}, + {kVK_ANSI_Backslash, OemBackslash}, + {kVK_ANSI_Comma, OemComma}, + //{kVK_ANSI_Slash, ?}, + {kVK_ANSI_N, N}, + {kVK_ANSI_M, M}, + {kVK_ANSI_Period, OemPeriod}, + //{kVK_ANSI_Grave, ?}, + {kVK_ANSI_KeypadDecimal, Decimal}, + {kVK_ANSI_KeypadMultiply, Multiply}, + {kVK_ANSI_KeypadPlus, OemPlus}, + {kVK_ANSI_KeypadClear, AvnKeyClear}, + {kVK_ANSI_KeypadDivide, Divide}, + {kVK_ANSI_KeypadEnter, AvnKeyEnter}, + {kVK_ANSI_KeypadMinus, OemMinus}, + //{kVK_ANSI_KeypadEquals, ?}, + {kVK_ANSI_Keypad0, NumPad0}, + {kVK_ANSI_Keypad1, NumPad1}, + {kVK_ANSI_Keypad2, NumPad2}, + {kVK_ANSI_Keypad3, NumPad3}, + {kVK_ANSI_Keypad4, NumPad4}, + {kVK_ANSI_Keypad5, NumPad5}, + {kVK_ANSI_Keypad6, NumPad6}, + {kVK_ANSI_Keypad7, NumPad7}, + {kVK_ANSI_Keypad8, NumPad8}, + {kVK_ANSI_Keypad9, NumPad9}, + {kVK_Return, AvnKeyReturn}, + {kVK_Tab, AvnKeyTab}, + {kVK_Space, Space}, + {kVK_Delete, AvnKeyBack}, + {kVK_Escape, Escape}, + {kVK_Command, LWin}, + {kVK_Shift, LeftShift}, + {kVK_CapsLock, AvnKeyCapsLock}, + {kVK_Option, LeftAlt}, + {kVK_Control, LeftCtrl}, + {kVK_RightCommand, RWin}, + {kVK_RightShift, RightShift}, + {kVK_RightOption, RightAlt}, + {kVK_RightControl, RightCtrl}, + //{kVK_Function, ?}, + {kVK_F17, F17}, + {kVK_VolumeUp, VolumeUp}, + {kVK_VolumeDown, VolumeDown}, + {kVK_Mute, VolumeMute}, + {kVK_F18, F18}, + {kVK_F19, F19}, + {kVK_F20, F20}, + {kVK_F5, F5}, + {kVK_F6, F6}, + {kVK_F7, F7}, + {kVK_F3, F3}, + {kVK_F8, F8}, + {kVK_F9, F9}, + {kVK_F11, F11}, + {kVK_F13, F13}, + {kVK_F16, F16}, + {kVK_F14, F14}, + {kVK_F10, F10}, + {kVK_F12, F12}, + {kVK_F15, F15}, + {kVK_Help, Help}, + {kVK_Home, Home}, + {kVK_PageUp, PageUp}, + {kVK_ForwardDelete, Delete}, + {kVK_F4, F4}, + {kVK_End, End}, + {kVK_F2, F2}, + {kVK_PageDown, PageDown}, + {kVK_F1, F1}, + {kVK_LeftArrow, Left}, + {kVK_RightArrow, Right}, + {kVK_DownArrow, Down}, + {kVK_UpArrow, Up} +}; diff --git a/native/Avalonia.Native/src/OSX/Screens.mm b/native/Avalonia.Native/src/OSX/Screens.mm new file mode 100644 index 0000000000..9d436b98c5 --- /dev/null +++ b/native/Avalonia.Native/src/OSX/Screens.mm @@ -0,0 +1,51 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +#include "common.h" + +class Screens : public ComSingleObject +{ + public: + FORWARD_IUNKNOWN() + virtual HRESULT GetScreenCount (int* ret) override + { + @autoreleasepool + { + *ret = (int)[NSScreen screens].count; + + return S_OK; + } + } + + virtual HRESULT GetScreen (int index, AvnScreen* ret) override + { + @autoreleasepool + { + if(index < 0 || index >= [NSScreen screens].count) + { + return E_INVALIDARG; + } + + auto screen = [[NSScreen screens] objectAtIndex:index]; + + ret->Bounds.X = [screen frame].origin.x; + ret->Bounds.Y = [screen frame].origin.y; + ret->Bounds.Height = [screen frame].size.height; + ret->Bounds.Width = [screen frame].size.width; + + ret->WorkingArea.X = [screen visibleFrame].origin.x; + ret->WorkingArea.Y = [screen visibleFrame].origin.y; + ret->WorkingArea.Height = [screen visibleFrame].size.height; + ret->WorkingArea.Width = [screen visibleFrame].size.width; + + ret->Primary = index == 0; + + return S_OK; + } + } +}; + +extern IAvnScreens* CreateScreens() +{ + return new Screens(); +} diff --git a/native/Avalonia.Native/src/OSX/SystemDialogs.mm b/native/Avalonia.Native/src/OSX/SystemDialogs.mm new file mode 100644 index 0000000000..7049f77d20 --- /dev/null +++ b/native/Avalonia.Native/src/OSX/SystemDialogs.mm @@ -0,0 +1,262 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +#include "common.h" +#include "window.h" + +class SystemDialogs : public ComSingleObject +{ +public: + FORWARD_IUNKNOWN() + virtual void SelectFolderDialog (IAvnWindow* parentWindowHandle, + IAvnSystemDialogEvents* events, + const char* title, + const char* initialDirectory) override + { + @autoreleasepool + { + auto panel = [NSOpenPanel openPanel]; + + panel.canChooseDirectories = true; + panel.canCreateDirectories = true; + panel.canChooseFiles = false; + + if(title != nullptr) + { + panel.title = [NSString stringWithUTF8String:title]; + } + + if(initialDirectory != nullptr) + { + auto directoryString = [NSString stringWithUTF8String:initialDirectory]; + panel.directoryURL = [NSURL fileURLWithPath:directoryString]; + } + + auto handler = ^(NSModalResponse result) { + if(result == NSFileHandlingPanelOKButton) + { + auto urls = [panel URLs]; + + if(urls.count > 0) + { + void* strings[urls.count]; + + for(int i = 0; i < urls.count; i++) + { + auto url = [urls objectAtIndex:i]; + + auto string = [url absoluteString]; + string = [string substringFromIndex:7]; + + strings[i] = (void*)[string UTF8String]; + } + + events->OnCompleted((int)urls.count, &strings[0]); + + [panel orderOut:panel]; + + if(parentWindowHandle != nullptr) + { + auto windowHolder = dynamic_cast(parentWindowHandle); + [windowHolder->GetNSWindow() makeKeyAndOrderFront:windowHolder->GetNSWindow()]; + } + + return; + } + } + + events->OnCompleted(0, nullptr); + + }; + + if(parentWindowHandle != nullptr) + { + auto windowBase = dynamic_cast(parentWindowHandle); + + [panel beginSheetModalForWindow:windowBase->GetNSWindow() completionHandler:handler]; + } + else + { + [panel beginWithCompletionHandler: handler]; + } + } + } + + virtual void OpenFileDialog (IAvnWindow* parentWindowHandle, + IAvnSystemDialogEvents* events, + bool allowMultiple, + const char* title, + const char* initialDirectory, + const char* initialFile, + const char* filters) override + { + @autoreleasepool + { + auto panel = [NSOpenPanel openPanel]; + + panel.allowsMultipleSelection = allowMultiple; + + if(title != nullptr) + { + panel.title = [NSString stringWithUTF8String:title]; + } + + if(initialDirectory != nullptr) + { + auto directoryString = [NSString stringWithUTF8String:initialDirectory]; + panel.directoryURL = [NSURL fileURLWithPath:directoryString]; + } + + if(initialFile != nullptr) + { + panel.nameFieldStringValue = [NSString stringWithUTF8String:initialFile]; + } + + if(filters != nullptr) + { + auto filtersString = [NSString stringWithUTF8String:filters]; + + if(filtersString.length > 0) + { + auto allowedTypes = [filtersString componentsSeparatedByString:@";"]; + + panel.allowedFileTypes = allowedTypes; + } + } + + auto handler = ^(NSModalResponse result) { + if(result == NSFileHandlingPanelOKButton) + { + auto urls = [panel URLs]; + + if(urls.count > 0) + { + void* strings[urls.count]; + + for(int i = 0; i < urls.count; i++) + { + auto url = [urls objectAtIndex:i]; + + auto string = [url absoluteString]; + string = [string substringFromIndex:7]; + + strings[i] = (void*)[string UTF8String]; + } + + events->OnCompleted((int)urls.count, &strings[0]); + + [panel orderOut:panel]; + + if(parentWindowHandle != nullptr) + { + auto windowHolder = dynamic_cast(parentWindowHandle); + [windowHolder->GetNSWindow() makeKeyAndOrderFront:windowHolder->GetNSWindow()]; + } + + return; + } + } + + events->OnCompleted(0, nullptr); + + }; + + if(parentWindowHandle != nullptr) + { + auto windowHolder = dynamic_cast(parentWindowHandle); + + [panel beginSheetModalForWindow:windowHolder->GetNSWindow() completionHandler:handler]; + } + else + { + [panel beginWithCompletionHandler: handler]; + } + } + } + + virtual void SaveFileDialog (IAvnWindow* parentWindowHandle, + IAvnSystemDialogEvents* events, + const char* title, + const char* initialDirectory, + const char* initialFile, + const char* filters) override + { + @autoreleasepool + { + auto panel = [NSSavePanel savePanel]; + + if(title != nullptr) + { + panel.title = [NSString stringWithUTF8String:title]; + } + + if(initialDirectory != nullptr) + { + auto directoryString = [NSString stringWithUTF8String:initialDirectory]; + panel.directoryURL = [NSURL fileURLWithPath:directoryString]; + } + + if(initialFile != nullptr) + { + panel.nameFieldStringValue = [NSString stringWithUTF8String:initialFile]; + } + + if(filters != nullptr) + { + auto filtersString = [NSString stringWithUTF8String:filters]; + + if(filtersString.length > 0) + { + auto allowedTypes = [filtersString componentsSeparatedByString:@";"]; + + panel.allowedFileTypes = allowedTypes; + } + } + + auto handler = ^(NSModalResponse result) { + if(result == NSFileHandlingPanelOKButton) + { + void* strings[1]; + + auto url = [panel URL]; + + auto string = [url absoluteString]; + string = [string substringFromIndex:7]; + strings[0] = (void*)[string UTF8String]; + + events->OnCompleted(1, &strings[0]); + + [panel orderOut:panel]; + + if(parentWindowHandle != nullptr) + { + auto windowHolder = dynamic_cast(parentWindowHandle); + [windowHolder->GetNSWindow() makeKeyAndOrderFront:windowHolder->GetNSWindow()]; + } + + return; + } + + events->OnCompleted(0, nullptr); + + }; + + if(parentWindowHandle != nullptr) + { + auto windowBase = dynamic_cast(parentWindowHandle); + + [panel beginSheetModalForWindow:windowBase->GetNSWindow() completionHandler:handler]; + } + else + { + [panel beginWithCompletionHandler: handler]; + } + } + } + +}; + +extern IAvnSystemDialogs* CreateSystemDialogs() +{ + return new SystemDialogs(); +} diff --git a/native/Avalonia.Native/src/OSX/clipboard.mm b/native/Avalonia.Native/src/OSX/clipboard.mm new file mode 100644 index 0000000000..19e5c25801 --- /dev/null +++ b/native/Avalonia.Native/src/OSX/clipboard.mm @@ -0,0 +1,47 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +#include "common.h" + +class Clipboard : public ComSingleObject +{ +public: + FORWARD_IUNKNOWN() + virtual HRESULT GetText (void** retOut) override + { + @autoreleasepool + { + NSString *str = [[NSPasteboard generalPasteboard] stringForType:NSPasteboardTypeString]; + *retOut = (void *)str.UTF8String; + } + + return S_OK; + } + + virtual HRESULT SetText (char* text) override + { + @autoreleasepool + { + NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard]; + [pasteBoard clearContents]; + [pasteBoard setString:@(text) forType:NSPasteboardTypeString]; + } + + return S_OK; + } + + virtual HRESULT Clear() override + { + @autoreleasepool + { + [[NSPasteboard generalPasteboard] clearContents]; + } + + return S_OK; + } +}; + +extern IAvnClipboard* CreateClipboard() +{ + return new Clipboard(); +} diff --git a/native/Avalonia.Native/src/OSX/common.h b/native/Avalonia.Native/src/OSX/common.h new file mode 100644 index 0000000000..1647569269 --- /dev/null +++ b/native/Avalonia.Native/src/OSX/common.h @@ -0,0 +1,34 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +#ifndef common_h +#define common_h +#include "comimpl.h" +#include "avalonia-native.h" +#include +#import +#import +#include + +extern IAvnPlatformThreadingInterface* CreatePlatformThreading(); +extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events); +extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events); +extern IAvnSystemDialogs* CreateSystemDialogs(); +extern IAvnScreens* CreateScreens(); +extern IAvnClipboard* CreateClipboard(); +extern IAvnCursorFactory* CreateCursorFactory(); +extern IAvnGlFeature* GetGlFeature(); +extern IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(NSWindow* window, NSView* view); + +extern NSPoint ToNSPoint (AvnPoint p); +extern AvnPoint ToAvnPoint (NSPoint p); +extern AvnPoint ConvertPointY (AvnPoint p); +extern NSSize ToNSSize (AvnSize s); + +#ifdef DEBUG +#define NSDebugLog(...) NSLog(__VA_ARGS__) +#else +#define NSDebugLog(...) (void)0 +#endif + +#endif diff --git a/native/Avalonia.Native/src/OSX/cursor.h b/native/Avalonia.Native/src/OSX/cursor.h new file mode 100644 index 0000000000..a8eb49c0b9 --- /dev/null +++ b/native/Avalonia.Native/src/OSX/cursor.h @@ -0,0 +1,29 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +#ifndef cursor_h +#define cursor_h + +#include "common.h" +#include + +class Cursor : public ComSingleObject +{ +private: + NSCursor * _native; + +public: + FORWARD_IUNKNOWN() + Cursor(NSCursor * cursor) + { + _native = cursor; + } + + NSCursor* GetNative() + { + return _native; + } +}; + +extern std::map s_cursorMap; +#endif /* cursor_h */ diff --git a/native/Avalonia.Native/src/OSX/cursor.mm b/native/Avalonia.Native/src/OSX/cursor.mm new file mode 100644 index 0000000000..bd2c94a4d8 --- /dev/null +++ b/native/Avalonia.Native/src/OSX/cursor.mm @@ -0,0 +1,73 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +#include "common.h" +#include "cursor.h" +#include + +class CursorFactory : public ComSingleObject +{ + Cursor* arrowCursor = new Cursor([NSCursor arrowCursor]); + Cursor* crossCursor = new Cursor([NSCursor crosshairCursor]); + Cursor* resizeUpCursor = new Cursor([NSCursor resizeUpCursor]); + Cursor* resizeDownCursor = new Cursor([NSCursor resizeDownCursor]); + Cursor* resizeUpDownCursor = new Cursor([NSCursor resizeUpDownCursor]); + Cursor* dragCopyCursor = new Cursor([NSCursor dragCopyCursor]); + Cursor* dragLinkCursor = new Cursor([NSCursor dragLinkCursor]); + Cursor* pointingHandCursor = new Cursor([NSCursor pointingHandCursor]); + Cursor* contextualMenuCursor = new Cursor([NSCursor contextualMenuCursor]); + Cursor* IBeamCursor = new Cursor([NSCursor IBeamCursor]); + Cursor* resizeLeftCursor = new Cursor([NSCursor resizeLeftCursor]); + Cursor* resizeRightCursor = new Cursor([NSCursor resizeRightCursor]); + Cursor* resizeWestEastCursor = new Cursor([NSCursor resizeLeftRightCursor]); + Cursor* operationNotAllowedCursor = new Cursor([NSCursor operationNotAllowedCursor]); + + std::map s_cursorMap = + { + { CursorArrow, arrowCursor }, + { CursorAppStarting, arrowCursor }, + { CursorWait, arrowCursor }, + { CursorTopLeftCorner, crossCursor }, + { CursorTopRightCorner, crossCursor }, + { CursorBottomLeftCorner, crossCursor }, + { CursorBottomRightCorner, crossCursor }, + { CursorCross, crossCursor }, + { CursorSizeAll, crossCursor }, + { CursorSizeNorthSouth, resizeUpDownCursor}, + { CursorSizeWestEast, resizeWestEastCursor}, + { CursorTopSide, resizeUpCursor }, + { CursorUpArrow, resizeUpCursor }, + { CursorBottomSize, resizeDownCursor }, + { CursorDragCopy, dragCopyCursor }, + { CursorDragMove, dragCopyCursor }, + { CursorDragLink, dragLinkCursor }, + { CursorHand, pointingHandCursor }, + { CursorHelp, contextualMenuCursor }, + { CursorIbeam, IBeamCursor }, + { CursorLeftSide, resizeLeftCursor }, + { CursorRightSide, resizeRightCursor }, + { CursorNo, operationNotAllowedCursor } + }; + +public: + FORWARD_IUNKNOWN() + virtual HRESULT GetCursor (AvnStandardCursorType cursorType, IAvnCursor** retOut) override + { + *retOut = s_cursorMap[cursorType]; + + if(*retOut != nullptr) + { + (*retOut)->AddRef(); + } + + return S_OK; + } +}; + +extern IAvnCursorFactory* CreateCursorFactory() +{ + @autoreleasepool + { + return new CursorFactory(); + } +} diff --git a/native/Avalonia.Native/src/OSX/gl.mm b/native/Avalonia.Native/src/OSX/gl.mm new file mode 100644 index 0000000000..a62098a074 --- /dev/null +++ b/native/Avalonia.Native/src/OSX/gl.mm @@ -0,0 +1,255 @@ +#include "common.h" +#include +#include + +template char (&ArrayCounter(T (&a)[N]))[N]; +#define ARRAY_COUNT(a) (sizeof(ArrayCounter(a))) + +NSOpenGLPixelFormat* CreateFormat() +{ + NSOpenGLPixelFormatAttribute attribs[] = + { + NSOpenGLPFADoubleBuffer, + NSOpenGLPFAColorSize, 32, + NSOpenGLPFAStencilSize, 8, + NSOpenGLPFADepthSize, 8, + 0 + }; + return [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs]; +} + +class AvnGlContext : public virtual ComSingleObject +{ +public: + FORWARD_IUNKNOWN() + NSOpenGLContext* GlContext; + GLuint Framebuffer, RenderBuffer, StencilBuffer; + AvnGlContext(NSOpenGLContext* gl, bool offscreen) + { + Framebuffer = 0; + RenderBuffer = 0; + StencilBuffer = 0; + GlContext = gl; + if(offscreen) + { + [GlContext makeCurrentContext]; + + glGenFramebuffersEXT(1, &Framebuffer); + glBindFramebufferEXT(GL_FRAMEBUFFER, Framebuffer); + glGenRenderbuffersEXT(1, &RenderBuffer); + glGenRenderbuffersEXT(1, &StencilBuffer); + + glBindRenderbufferEXT(GL_RENDERBUFFER, StencilBuffer); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, StencilBuffer); + glBindRenderbufferEXT(GL_RENDERBUFFER, RenderBuffer); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, RenderBuffer); + } + + } + + + virtual HRESULT MakeCurrent() override + { + [GlContext makeCurrentContext];/* + glBindFramebufferEXT(GL_FRAMEBUFFER, Framebuffer); + glBindRenderbufferEXT(GL_RENDERBUFFER, RenderBuffer); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, RenderBuffer); + glBindRenderbufferEXT(GL_RENDERBUFFER, StencilBuffer); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, StencilBuffer);*/ + return S_OK; + } +}; + +class AvnGlDisplay : public virtual ComSingleObject +{ + int _sampleCount, _stencilSize; + void* _libgl; + +public: + FORWARD_IUNKNOWN() + + AvnGlDisplay(int sampleCount, int stencilSize) + { + _sampleCount = sampleCount; + _stencilSize = stencilSize; + _libgl = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib", RTLD_LAZY); + } + + virtual HRESULT GetSampleCount(int* ret) override + { + *ret = _sampleCount; + return S_OK; + } + virtual HRESULT GetStencilSize(int* ret) override + { + *ret = _stencilSize; + return S_OK; + } + + virtual HRESULT ClearContext() override + { + [NSOpenGLContext clearCurrentContext]; + return S_OK; + } + + virtual void* GetProcAddress(char* proc) override + { + return dlsym(_libgl, proc); + } +}; + + +class GlFeature : public virtual ComSingleObject +{ + IAvnGlDisplay* _display; + AvnGlContext *_immediate; + NSOpenGLContext* _shared; +public: + FORWARD_IUNKNOWN() + NSOpenGLPixelFormat* _format; + GlFeature(IAvnGlDisplay* display, AvnGlContext* immediate, NSOpenGLPixelFormat* format) + { + _display = display; + _immediate = immediate; + _format = format; + _shared = [[NSOpenGLContext alloc] initWithFormat:_format shareContext:_immediate->GlContext]; + } + + NSOpenGLContext* CreateContext() + { + return _shared; + //return [[NSOpenGLContext alloc] initWithFormat:_format shareContext:nil]; + } + + virtual HRESULT ObtainDisplay(IAvnGlDisplay**retOut) override + { + *retOut = _display; + _display->AddRef(); + return S_OK; + } + + virtual HRESULT ObtainImmediateContext(IAvnGlContext**retOut) override + { + *retOut = _immediate; + _immediate->AddRef(); + return S_OK; + } +}; + +static GlFeature* Feature; + +GlFeature* CreateGlFeature() +{ + auto format = CreateFormat(); + if(format == nil) + { + NSLog(@"Unable to choose pixel format"); + return NULL; + } + + auto immediateContext = [[NSOpenGLContext alloc] initWithFormat:format shareContext:nil]; + if(immediateContext == nil) + { + NSLog(@"Unable to create NSOpenGLContext"); + return NULL; + } + + int stencilBits = 0, sampleCount = 0; + + auto fmt = CGLGetPixelFormat([immediateContext CGLContextObj]); + CGLDescribePixelFormat(fmt, 0, kCGLPFASamples, &sampleCount); + CGLDescribePixelFormat(fmt, 0, kCGLPFAStencilSize, &stencilBits); + + auto offscreen = new AvnGlContext(immediateContext, true); + auto display = new AvnGlDisplay(sampleCount, stencilBits); + + return new GlFeature(display, offscreen, format); +} + + +static GlFeature* GetFeature() +{ + if(Feature == nil) + Feature = CreateGlFeature(); + return Feature; +} + +extern IAvnGlFeature* GetGlFeature() +{ + return GetFeature(); +} + +class AvnGlRenderingSession : public ComSingleObject +{ + NSView* _view; + NSWindow* _window; + NSOpenGLContext* _context; +public: + FORWARD_IUNKNOWN() + AvnGlRenderingSession(NSWindow*window, NSView* view, NSOpenGLContext* context) + { + _context = context; + _window = window; + _view = view; + } + + virtual HRESULT GetPixelSize(AvnPixelSize* ret) override + { + auto fsize = [_view convertSizeToBacking: [_view frame].size]; + ret->Width = (int)fsize.width; + ret->Height = (int)fsize.height; + return S_OK; + } + virtual HRESULT GetScaling(double* ret) override + { + *ret = [_window backingScaleFactor]; + return S_OK; + } + + virtual ~AvnGlRenderingSession() + { + glFlush(); + [_context flushBuffer]; + [_context setView:nil]; + CGLUnlockContext([_context CGLContextObj]); + [_view unlockFocus]; + } +}; + +class AvnGlRenderTarget : public ComSingleObject +{ + NSView* _view; + NSWindow* _window; + NSOpenGLContext* _context; +public: + FORWARD_IUNKNOWN() + AvnGlRenderTarget(NSWindow* window, NSView*view) + { + _window = window; + _view = view; + _context = GetFeature()->CreateContext(); + } + + virtual HRESULT BeginDrawing(IAvnGlSurfaceRenderingSession** ret) override + { + auto f = GetFeature(); + if(f == NULL) + return E_FAIL; + if(![_view lockFocusIfCanDraw]) + return E_ABORT; + + auto gl = _context; + CGLLockContext([_context CGLContextObj]); + [gl setView: _view]; + [gl makeCurrentContext]; + auto frame = [_view frame]; + + *ret = new AvnGlRenderingSession(_window, _view, gl); + return S_OK; + } +}; + +extern IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(NSWindow* window, NSView* view) +{ + return new AvnGlRenderTarget(window, view); +} diff --git a/native/Avalonia.Native/src/OSX/main.mm b/native/Avalonia.Native/src/OSX/main.mm new file mode 100644 index 0000000000..4d6dcfed85 --- /dev/null +++ b/native/Avalonia.Native/src/OSX/main.mm @@ -0,0 +1,178 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +//This file will contain actual IID structures +#define COM_GUIDS_MATERIALIZE +#include "common.h" + +static BOOL ShowInDock = 1; + +static void SetActivationPolicy() +{ + [[NSApplication sharedApplication] setActivationPolicy: (ShowInDock ? NSApplicationActivationPolicyRegular : NSApplicationActivationPolicyAccessory)]; +} + +class MacOptions : public ComSingleObject +{ +public: + FORWARD_IUNKNOWN() + virtual HRESULT SetShowInDock(int show) override + { + ShowInDock = show; + SetActivationPolicy(); + return S_OK; + } +}; + + + +/// See "Using POSIX Threads in a Cocoa Application" section here: +/// https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html#//apple_ref/doc/uid/20000738-125024 +@interface ThreadingInitializer : NSObject +- (void) do; +@end +@implementation ThreadingInitializer + +pthread_mutex_t mutex; +pthread_cond_t cond; + +- (void) runOnce +{ + pthread_mutex_lock(&mutex); + pthread_cond_signal(&cond); + pthread_mutex_unlock(&mutex); +} + +- (void) do +{ + pthread_mutex_init(&mutex, NULL); + pthread_cond_init(&cond, NULL); + [[[NSThread alloc] initWithTarget:self selector:@selector(runOnce) object:nil] start]; + pthread_mutex_lock(&mutex); + pthread_cond_wait(&cond, &mutex); + pthread_mutex_unlock(&mutex); + pthread_cond_destroy(&cond); + pthread_mutex_destroy(&mutex); +} + + +@end + + +class AvaloniaNative : public ComSingleObject +{ + +public: + FORWARD_IUNKNOWN() + virtual HRESULT Initialize() override + { + @autoreleasepool{ + [[ThreadingInitializer new] do]; + return S_OK; + } + }; + + virtual IAvnMacOptions* GetMacOptions() override + { + return (IAvnMacOptions*)new MacOptions(); + } + + virtual HRESULT CreateWindow(IAvnWindowEvents* cb, IAvnWindow** ppv) override + { + if(cb == nullptr || ppv == nullptr) + return E_POINTER; + *ppv = CreateAvnWindow(cb); + return S_OK; + }; + + virtual HRESULT CreatePopup(IAvnWindowEvents* cb, IAvnPopup** ppv) override + { + if(cb == nullptr || ppv == nullptr) + return E_POINTER; + + *ppv = CreateAvnPopup(cb); + return S_OK; + } + + virtual HRESULT CreatePlatformThreadingInterface(IAvnPlatformThreadingInterface** ppv) override + { + *ppv = CreatePlatformThreading(); + return S_OK; + } + + virtual HRESULT CreateSystemDialogs(IAvnSystemDialogs** ppv) override + { + *ppv = ::CreateSystemDialogs(); + return S_OK; + } + + virtual HRESULT CreateScreens (IAvnScreens** ppv) override + { + *ppv = ::CreateScreens (); + return S_OK; + } + + virtual HRESULT CreateClipboard(IAvnClipboard** ppv) override + { + *ppv = ::CreateClipboard (); + return S_OK; + } + + virtual HRESULT CreateCursorFactory(IAvnCursorFactory** ppv) override + { + *ppv = ::CreateCursorFactory(); + return S_OK; + } + + virtual HRESULT ObtainGlFeature(IAvnGlFeature** ppv) override + { + auto rv = ::GetGlFeature(); + if(rv == NULL) + return E_FAIL; + rv->AddRef(); + *ppv = rv; + return S_OK; + } +}; + +extern "C" IAvaloniaNativeFactory* CreateAvaloniaNative() +{ + return new AvaloniaNative(); +}; + +NSSize ToNSSize (AvnSize s) +{ + NSSize result; + result.width = s.Width; + result.height = s.Height; + + return result; +} + +NSPoint ToNSPoint (AvnPoint p) +{ + NSPoint result; + result.x = p.X; + result.y = p.Y; + + return result; +} + +AvnPoint ToAvnPoint (NSPoint p) +{ + AvnPoint result; + result.X = p.x; + result.Y = p.y; + + return result; +} + +AvnPoint ConvertPointY (AvnPoint p) +{ + auto sw = [NSScreen.screens objectAtIndex:0].frame; + + auto t = MAX(sw.origin.y, sw.origin.y + sw.size.height); + p.Y = t - p.Y; + + return p; +} diff --git a/native/Avalonia.Native/src/OSX/platformthreading.mm b/native/Avalonia.Native/src/OSX/platformthreading.mm new file mode 100644 index 0000000000..0c814b2088 --- /dev/null +++ b/native/Avalonia.Native/src/OSX/platformthreading.mm @@ -0,0 +1,190 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +#include "common.h" + +class PlatformThreadingInterface; +@interface Signaler : NSObject +-(void) setParent: (PlatformThreadingInterface*)parent; +-(void) signal: (int) priority; +-(Signaler*) init; +@end + + +@interface ActionCallback : NSObject +- (ActionCallback*) initWithCallback: (IAvnActionCallback*) callback; +- (void) action; +@end + +@implementation ActionCallback +{ + ComPtr _callback; + +} +- (ActionCallback*) initWithCallback: (IAvnActionCallback*) callback +{ + _callback = callback; + return self; +} + +- (void) action +{ + _callback->Run(); +} + + +@end + +class TimerWrapper : public ComUnknownObject +{ + NSTimer* _timer; +public: + TimerWrapper(IAvnActionCallback* callback, int ms) + { + auto cb = [[ActionCallback alloc] initWithCallback:callback]; + _timer = [NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)(double)ms/1000 target:cb selector:@selector(action) userInfo:nullptr repeats:true]; + } + + virtual ~TimerWrapper() + { + [_timer invalidate]; + } +}; + + + +class PlatformThreadingInterface : public ComSingleObject +{ +private: + Signaler* _signaler; + + class LoopCancellation : public ComSingleObject + { + public: + FORWARD_IUNKNOWN() + bool Cancelled = 0; + virtual void Cancel() override + { + Cancelled = 1; + } + }; + +public: + FORWARD_IUNKNOWN() + ComPtr SignaledCallback; + + PlatformThreadingInterface() + { + _signaler = [Signaler new]; + [_signaler setParent:this]; + } + + ~PlatformThreadingInterface() + { + if(_signaler) + [_signaler setParent: NULL]; + _signaler = NULL; + } + + virtual bool GetCurrentThreadIsLoopThread() override + { + return [[NSThread currentThread] isMainThread]; + } + virtual void SetSignaledCallback(IAvnSignaledCallback* cb) override + { + SignaledCallback = cb; + } + virtual IAvnLoopCancellation* CreateLoopCancellation() override + { + return new LoopCancellation(); + } + + virtual void RunLoop(IAvnLoopCancellation* cancel) override + { + @autoreleasepool { + auto can = dynamic_cast(cancel); + [[NSApplication sharedApplication] activateIgnoringOtherApps:true]; + while(true) + { + @autoreleasepool + { + if(can != NULL && can->Cancelled) + return; + NSEvent* ev = [[NSApplication sharedApplication] + nextEventMatchingMask:NSEventMaskAny + untilDate: [NSDate dateWithTimeIntervalSinceNow:1] + inMode:NSDefaultRunLoopMode + dequeue:true]; + if(can != NULL && can->Cancelled) + return; + if(ev != NULL) + [[NSApplication sharedApplication] sendEvent:ev]; + } + } + NSDebugLog(@"RunLoop exited"); + } + } + + virtual void Signal(int priority) override + { + [_signaler signal:priority]; + } + + virtual IUnknown* StartTimer(int priority, int ms, IAvnActionCallback* callback) override + { + @autoreleasepool { + + return new TimerWrapper(callback, ms); + } + } +}; + +@implementation Signaler + +PlatformThreadingInterface* _parent = 0; +bool _signaled = 0; +NSArray* _modes; + +-(Signaler*) init +{ + if(self = [super init]) + { + _modes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEventTrackingRunLoopMode, NSModalPanelRunLoopMode, NSRunLoopCommonModes, NSConnectionReplyMode, nil]; + } + return self; +} + +-(void) perform +{ + @synchronized (self) { + _signaled = false; + if(_parent != NULL && _parent->SignaledCallback != NULL) + _parent->SignaledCallback->Signaled(0, false); + } +} + +-(void) setParent:(PlatformThreadingInterface *)parent +{ + @synchronized (self) { + _parent = parent; + } +} + +-(void) signal: (int) priority +{ + + @synchronized (self) { + if(_signaled) + return; + _signaled = true; + [self performSelector:@selector(perform) onThread:[NSThread mainThread] withObject:NULL waitUntilDone:false modes:_modes]; + } + +} +@end + + +extern IAvnPlatformThreadingInterface* CreatePlatformThreading() +{ + return new PlatformThreadingInterface(); +} diff --git a/native/Avalonia.Native/src/OSX/window.h b/native/Avalonia.Native/src/OSX/window.h new file mode 100644 index 0000000000..34592993c3 --- /dev/null +++ b/native/Avalonia.Native/src/OSX/window.h @@ -0,0 +1,33 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +#ifndef window_h +#define window_h + +class WindowBaseImpl; + +@interface AvnView : NSView +-(AvnView* _Nonnull) initWithParent: (WindowBaseImpl* _Nonnull) parent; +-(NSEvent* _Nonnull) lastMouseDownEvent; +-(AvnPoint) translateLocalPoint:(AvnPoint)pt; +-(void) setSwRenderedFrame: (AvnFramebuffer* _Nonnull) fb dispose: (IUnknown* _Nonnull) dispose; +-(void) onClosed; +@end + +@interface AvnWindow : NSWindow +-(AvnWindow* _Nonnull) initWithParent: (WindowBaseImpl* _Nonnull) parent; +-(void) setCanBecomeKeyAndMain; +-(void) pollModalSession: (NSModalSession _Nonnull) session; +@end + +struct INSWindowHolder +{ + virtual AvnWindow* _Nonnull GetNSWindow () = 0; +}; + +struct IWindowStateChanged +{ + virtual void WindowStateChanged () = 0; +}; + +#endif /* window_h */ diff --git a/native/Avalonia.Native/src/OSX/window.mm b/native/Avalonia.Native/src/OSX/window.mm new file mode 100644 index 0000000000..362b765b3d --- /dev/null +++ b/native/Avalonia.Native/src/OSX/window.mm @@ -0,0 +1,1232 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +#include "common.h" +#include "window.h" +#include "KeyTransform.h" +#include "cursor.h" +#include + +class SoftwareDrawingOperation +{ +public: + void* Data = 0; + AvnFramebuffer Desc; + void Alloc(NSView* view) + { + auto logicalSize = [view frame].size; + auto pixelSize = [view convertSizeToBacking:logicalSize]; + int w = pixelSize.width; + int h = pixelSize.height; + int stride = w * 4; + Data = malloc(h * stride); + Desc = { + .Data = Data, + .Stride = stride, + .Width = w, + .Height = h, + .PixelFormat = kAvnRgba8888, + .Dpi = AvnVector { .X = w / logicalSize.width * 96, .Y = h / logicalSize.height * 96} + }; + } + + void Dealloc() + { + if(Data != NULL) + { + free(Data); + Data = NULL; + } + } + + ~SoftwareDrawingOperation() + { + Dealloc(); + } +}; + +class WindowBaseImpl : public virtual ComSingleObject, public INSWindowHolder +{ +private: + NSCursor* cursor; + +public: + FORWARD_IUNKNOWN() + virtual ~WindowBaseImpl() + { + NSDebugLog(@"~WindowBaseImpl()"); + View = NULL; + Window = NULL; + } + AvnView* View; + AvnWindow* Window; + ComPtr BaseEvents; + SoftwareDrawingOperation CurrentSwDrawingOperation; + AvnPoint lastPositionSet; + NSString* _lastTitle; + + WindowBaseImpl(IAvnWindowBaseEvents* events) + { + BaseEvents = events; + View = [[AvnView alloc] initWithParent:this]; + + Window = [[AvnWindow alloc] initWithParent:this]; + + lastPositionSet.X = 100; + lastPositionSet.Y = 100; + _lastTitle = @""; + + [Window setStyleMask:NSWindowStyleMaskBorderless]; + [Window setBackingType:NSBackingStoreBuffered]; + [Window setContentView: View]; + } + + virtual AvnWindow* GetNSWindow() override + { + return Window; + } + + virtual HRESULT Show() override + { + @autoreleasepool + { + SetPosition(lastPositionSet); + UpdateStyle(); + + [Window makeKeyAndOrderFront:Window]; + + [Window setTitle:_lastTitle]; + [Window setTitleVisibility:NSWindowTitleVisible]; + + return S_OK; + } + } + + virtual HRESULT Hide () override + { + @autoreleasepool + { + if(Window != nullptr) + { + [Window orderOut:Window]; + } + + return S_OK; + } + } + + virtual HRESULT Activate () override + { + @autoreleasepool + { + if(Window != nullptr) + { + [Window makeKeyWindow]; + } + } + + return S_OK; + } + + virtual HRESULT SetTopMost (bool value) override + { + @autoreleasepool + { + [Window setLevel: value ? NSFloatingWindowLevel : NSNormalWindowLevel]; + + return S_OK; + } + } + + virtual HRESULT Close() override + { + @autoreleasepool + { + [Window close]; + return S_OK; + } + } + + virtual HRESULT GetClientSize(AvnSize* ret) override + { + @autoreleasepool + { + if(ret == nullptr) + return E_POINTER; + auto frame = [View frame]; + ret->Width = frame.size.width; + ret->Height = frame.size.height; + return S_OK; + } + } + + virtual HRESULT GetMaxClientSize(AvnSize* ret) override + { + @autoreleasepool + { + if(ret == nullptr) + return E_POINTER; + + auto size = [NSScreen.screens objectAtIndex:0].frame.size; + + ret->Height = size.height; + ret->Width = size.width; + + return S_OK; + } + } + + virtual HRESULT GetScaling (double* ret) override + { + @autoreleasepool + { + if(ret == nullptr) + return E_POINTER; + + if(Window == nullptr) + { + *ret = 1; + return S_OK; + } + + *ret = [Window backingScaleFactor]; + return S_OK; + } + } + + virtual HRESULT SetMinMaxSize (AvnSize minSize, AvnSize maxSize) override + { + @autoreleasepool + { + [Window setMinSize: ToNSSize(minSize)]; + [Window setMaxSize: ToNSSize(maxSize)]; + + return S_OK; + } + } + + virtual HRESULT Resize(double x, double y) override + { + @autoreleasepool + { + [Window setContentSize:NSSize{x, y}]; + + return S_OK; + } + } + + virtual HRESULT Invalidate (AvnRect rect) override + { + @autoreleasepool + { + [View setNeedsDisplayInRect:[View frame]]; + + return S_OK; + } + } + + virtual bool TryLock() override + { + @autoreleasepool + { + return [View lockFocusIfCanDraw] == YES; + } + } + + virtual void Unlock() override + { + @autoreleasepool + { + [View unlockFocus]; + } + } + + virtual HRESULT BeginMoveDrag () override + { + @autoreleasepool + { + auto lastEvent = [View lastMouseDownEvent]; + + if(lastEvent == nullptr) + { + return S_OK; + } + + [Window performWindowDragWithEvent:lastEvent]; + + return S_OK; + } + } + + virtual HRESULT BeginResizeDrag (AvnWindowEdge edge) override + { + return S_OK; + } + + virtual HRESULT GetPosition (AvnPoint* ret) override + { + @autoreleasepool + { + if(ret == nullptr) + { + return E_POINTER; + } + + auto frame = [Window frame]; + + ret->X = frame.origin.x; + ret->Y = frame.origin.y + frame.size.height; + + *ret = ConvertPointY(*ret); + + return S_OK; + } + } + + virtual HRESULT SetPosition (AvnPoint point) override + { + @autoreleasepool + { + lastPositionSet = point; + [Window setFrameTopLeftPoint:ToNSPoint(ConvertPointY(point))]; + + return S_OK; + } + } + + virtual HRESULT PointToClient (AvnPoint point, AvnPoint* ret) override + { + @autoreleasepool + { + if(ret == nullptr) + { + return E_POINTER; + } + + point = ConvertPointY(point); + auto viewPoint = [Window convertScreenToBase:ToNSPoint(point)]; + + *ret = [View translateLocalPoint:ToAvnPoint(viewPoint)]; + + return S_OK; + } + } + + virtual HRESULT PointToScreen (AvnPoint point, AvnPoint* ret) override + { + @autoreleasepool + { + if(ret == nullptr) + { + return E_POINTER; + } + + auto cocoaViewPoint = ToNSPoint([View translateLocalPoint:point]); + auto cocoaScreenPoint = [Window convertBaseToScreen:cocoaViewPoint]; + *ret = ConvertPointY(ToAvnPoint(cocoaScreenPoint)); + + return S_OK; + } + } + + virtual HRESULT ThreadSafeSetSwRenderedFrame(AvnFramebuffer* fb, IUnknown* dispose) override + { + [View setSwRenderedFrame: fb dispose: dispose]; + return S_OK; + } + + virtual HRESULT GetSoftwareFramebuffer(AvnFramebuffer*ret) override + { + if(![[NSThread currentThread] isMainThread]) + return E_FAIL; + if(CurrentSwDrawingOperation.Data == NULL) + CurrentSwDrawingOperation.Alloc(View); + *ret = CurrentSwDrawingOperation.Desc; + return S_OK; + } + + virtual HRESULT SetCursor(IAvnCursor* cursor) override + { + @autoreleasepool + { + Cursor* avnCursor = dynamic_cast(cursor); + this->cursor = avnCursor->GetNative(); + UpdateCursor(); + return S_OK; + } + } + + virtual void UpdateCursor() + { + [View resetCursorRects]; + if (cursor != nil) + { + auto rect = [Window frame]; + [View addCursorRect:rect cursor:cursor]; + [cursor set]; + } + } + + virtual HRESULT CreateGlRenderTarget(IAvnGlSurfaceRenderTarget** ppv) override + { + if(View == NULL) + return E_FAIL; + *ppv = ::CreateGlRenderTarget(Window, View); + return S_OK; + } + +protected: + virtual NSWindowStyleMask GetStyle() + { + return NSWindowStyleMaskBorderless; + } + + void UpdateStyle() + { + [Window setStyleMask:GetStyle()]; + } + + virtual void OnResized () + { + + } +}; + +class ModalDisposable : public ComUnknownObject +{ + NSModalSession _session; + AvnWindow* _window; + + void Dispose () + { + [_window orderOut:_window]; + [NSApp endModalSession:_session]; + } + +public: + ModalDisposable(AvnWindow* window, NSModalSession session) + { + _session = session; + _window = window; + } + + virtual ~ModalDisposable() + { + Dispose(); + } +}; + +class WindowImpl : public virtual WindowBaseImpl, public virtual IAvnWindow, public IWindowStateChanged +{ +private: + bool _canResize = true; + bool _hasDecorations = true; + CGRect _lastUndecoratedFrame; + AvnWindowState _lastWindowState; + + FORWARD_IUNKNOWN() + BEGIN_INTERFACE_MAP() + INHERIT_INTERFACE_MAP(WindowBaseImpl) + INTERFACE_MAP_ENTRY(IAvnWindow, IID_IAvnWindow) + END_INTERFACE_MAP() + virtual ~WindowImpl(){ + NSDebugLog(@"~WindowImpl"); + } + + ComPtr WindowEvents; + WindowImpl(IAvnWindowEvents* events) : WindowBaseImpl(events) + { + WindowEvents = events; + [Window setCanBecomeKeyAndMain]; + } + + virtual HRESULT Show () override + { + @autoreleasepool + { + WindowBaseImpl::Show(); + + return SetWindowState(_lastWindowState); + } + } + + virtual HRESULT ShowDialog (IUnknown**ppv) override + { + @autoreleasepool + { + if(ppv == nullptr) + { + return E_POINTER; + } + + auto session = [NSApp beginModalSessionForWindow:Window]; + auto disposable = new ModalDisposable(Window, session); + *ppv = disposable; + + SetPosition(lastPositionSet); + UpdateStyle(); + + [Window setTitle:_lastTitle]; + [Window setTitleVisibility:NSWindowTitleVisible]; + + [Window pollModalSession:session]; + + return S_OK; + } + } + + void WindowStateChanged () override + { + AvnWindowState state; + GetWindowState(&state); + WindowEvents->WindowStateChanged(state); + } + + bool UndecoratedIsMaximized () + { + return CGRectEqualToRect([Window frame], [Window screen].visibleFrame); + } + + bool IsZoomed () + { + return _hasDecorations ? [Window isZoomed] : UndecoratedIsMaximized(); + } + + void DoZoom() + { + if (_hasDecorations) + { + [Window performZoom:Window]; + } + else + { + if (!UndecoratedIsMaximized()) + { + _lastUndecoratedFrame = [Window frame]; + } + + [Window zoom:Window]; + } + } + + virtual HRESULT SetCanResize(bool value) override + { + @autoreleasepool + { + _canResize = value; + UpdateStyle(); + return S_OK; + } + } + + virtual HRESULT SetHasDecorations(bool value) override + { + @autoreleasepool + { + _hasDecorations = value; + UpdateStyle(); + + return S_OK; + } + } + + virtual HRESULT SetTitle (const char* title) override + { + @autoreleasepool + { + _lastTitle = [NSString stringWithUTF8String:title]; + [Window setTitle:_lastTitle]; + [Window setTitleVisibility:NSWindowTitleVisible]; + + return S_OK; + } + } + + virtual HRESULT SetTitleBarColor(AvnColor color) override + { + @autoreleasepool + { + float a = (float)color.Alpha / 255.0f; + float r = (float)color.Red / 255.0f; + float g = (float)color.Green / 255.0f; + float b = (float)color.Blue / 255.0f; + + auto nscolor = [NSColor colorWithSRGBRed:r green:g blue:b alpha:a]; + + // Based on the titlebar color we have to choose either light or dark + // OSX doesnt let you set a foreground color for titlebar. + if ((r*0.299 + g*0.587 + b*0.114) > 186.0f / 255.0f) + { + [Window setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameVibrantLight]]; + } + else + { + [Window setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameVibrantDark]]; + } + + [Window setTitlebarAppearsTransparent:true]; + [Window setBackgroundColor:nscolor]; + } + + return S_OK; + } + + virtual HRESULT GetWindowState (AvnWindowState*ret) override + { + @autoreleasepool + { + if(ret == nullptr) + { + return E_POINTER; + } + + if([Window isMiniaturized]) + { + *ret = Minimized; + return S_OK; + } + + if([Window isZoomed]) + { + *ret = Maximized; + return S_OK; + } + + *ret = Normal; + + return S_OK; + } + } + + virtual HRESULT SetWindowState (AvnWindowState state) override + { + @autoreleasepool + { + _lastWindowState = state; + + switch (state) { + case Maximized: + lastPositionSet.X = 0; + lastPositionSet.Y = 0; + + if([Window isMiniaturized]) + { + [Window deminiaturize:Window]; + } + + if(!IsZoomed()) + { + DoZoom(); + } + break; + + case Minimized: + [Window miniaturize:Window]; + break; + + default: + if([Window isMiniaturized]) + { + [Window deminiaturize:Window]; + } + + if(IsZoomed()) + { + DoZoom(); + } + break; + } + + return S_OK; + } + } + +protected: + virtual void OnResized () override + { + auto windowState = [Window isMiniaturized] ? Minimized + : (IsZoomed() ? Maximized : Normal); + + if (windowState != _lastWindowState) + { + _lastWindowState = windowState; + + WindowEvents->WindowStateChanged(windowState); + } + } + + virtual NSWindowStyleMask GetStyle() override + { + unsigned long s = NSWindowStyleMaskBorderless; + if(_hasDecorations) + s = s | NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable; + if(_canResize) + s = s | NSWindowStyleMaskResizable; + return s; + } +}; + +NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEventTrackingRunLoopMode, NSModalPanelRunLoopMode, NSRunLoopCommonModes, NSConnectionReplyMode, nil]; + +@implementation AvnView +{ + ComPtr _parent; + ComPtr _swRenderedFrame; + AvnFramebuffer _swRenderedFrameBuffer; + bool _queuedDisplayFromThread; + NSTrackingArea* _area; + bool _isLeftPressed, _isMiddlePressed, _isRightPressed, _isMouseOver; + NSEvent* _lastMouseDownEvent; + bool _lastKeyHandled; +} + +- (void)dealloc +{ + NSDebugLog(@"AvnView dealloc"); +} + + +- (void)onClosed +{ + _parent = NULL; +} + +- (NSEvent*) lastMouseDownEvent +{ + return _lastMouseDownEvent; +} + +-(AvnView*) initWithParent: (WindowBaseImpl*) parent +{ + self = [super init]; + [self setWantsBestResolutionOpenGLSurface:true]; + _parent = parent; + _area = nullptr; + return self; +} + +- (BOOL)isOpaque +{ + return YES; +} + +- (BOOL)acceptsFirstResponder +{ + return true; +} + +- (BOOL)acceptsFirstMouse:(NSEvent *)event +{ + return true; +} + +- (BOOL)canBecomeKeyView +{ + return true; +} + +-(void)setFrameSize:(NSSize)newSize +{ + [super setFrameSize:newSize]; + + if(_area != nullptr) + { + [self removeTrackingArea:_area]; + _area = nullptr; + } + + NSRect rect = NSZeroRect; + rect.size = newSize; + + NSTrackingAreaOptions options = NSTrackingActiveAlways | NSTrackingMouseMoved | NSTrackingEnabledDuringMouseDrag; + _area = [[NSTrackingArea alloc] initWithRect:rect options:options owner:self userInfo:nullptr]; + [self addTrackingArea:_area]; + + _parent->UpdateCursor(); + + _parent->BaseEvents->Resized(AvnSize{newSize.width, newSize.height}); +} + +- (void) drawFb: (AvnFramebuffer*) fb +{ + auto colorSpace = CGColorSpaceCreateDeviceRGB(); + auto dataProvider = CGDataProviderCreateWithData(NULL, fb->Data, fb->Height*fb->Stride, NULL); + + + auto image = CGImageCreate(fb->Width, fb->Height, 8, 32, fb->Stride, colorSpace, kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast, + dataProvider, nullptr, false, kCGRenderingIntentDefault); + + auto ctx = [NSGraphicsContext currentContext]; + + [ctx saveGraphicsState]; + auto cgc = [ctx CGContext]; + + CGContextDrawImage(cgc, CGRect{0,0, fb->Width/(fb->Dpi.X/96), fb->Height/(fb->Dpi.Y/96)}, image); + CGImageRelease(image); + CGColorSpaceRelease(colorSpace); + CGDataProviderRelease(dataProvider); + + [ctx restoreGraphicsState]; + +} + +- (void)drawRect:(NSRect)dirtyRect +{ + _parent->BaseEvents->RunRenderPriorityJobs(); + @synchronized (self) { + if(_swRenderedFrame != NULL) + { + [self drawFb: &_swRenderedFrameBuffer]; + return; + } + } + + auto swOp = &_parent->CurrentSwDrawingOperation; + _parent->BaseEvents->Paint(); + if(swOp->Data != NULL) + [self drawFb: &swOp->Desc]; + + swOp->Dealloc(); + return; +} + +-(void) redrawSelf +{ + @autoreleasepool + { + @synchronized(self) + { + if(!_queuedDisplayFromThread) + return; + _queuedDisplayFromThread = false; + } + [self setNeedsDisplayInRect:[self frame]]; + [self display]; + + } +} + +-(void) setSwRenderedFrame: (AvnFramebuffer*) fb dispose: (IUnknown*) dispose +{ + @autoreleasepool { + @synchronized (self) { + _swRenderedFrame = dispose; + _swRenderedFrameBuffer = *fb; + if(!_queuedDisplayFromThread) + { + _queuedDisplayFromThread = true; + [self performSelector:@selector(redrawSelf) onThread:[NSThread mainThread] withObject:NULL waitUntilDone:false modes: AllLoopModes]; + } + } + } +} + +- (AvnPoint) translateLocalPoint:(AvnPoint)pt +{ + pt.Y = [self bounds].size.height - pt.Y; + return pt; +} + +- (AvnPoint)toAvnPoint:(CGPoint)p +{ + AvnPoint result; + + result.X = p.x; + result.Y = p.y; + + return result; +} + +- (void) viewDidChangeBackingProperties +{ + _parent->BaseEvents->ScalingChanged([_parent->Window backingScaleFactor]); + [super viewDidChangeBackingProperties]; +} + +- (void)mouseEvent:(NSEvent *)event withType:(AvnRawMouseEventType) type +{ + [self becomeFirstResponder]; + auto localPoint = [self convertPoint:[event locationInWindow] toView:self]; + auto avnPoint = [self toAvnPoint:localPoint]; + auto point = [self translateLocalPoint:avnPoint]; + AvnVector delta; + + if(type == Wheel) + { + delta.X = [event scrollingDeltaX] / 5; + delta.Y = [event scrollingDeltaY] / 5; + + if(delta.X == 0 && delta.Y == 0) + { + return; + } + } + + auto timestamp = [event timestamp] * 1000; + auto modifiers = [self getModifiers:[event modifierFlags]]; + + [self becomeFirstResponder]; + _parent->BaseEvents->RawMouseEvent(type, timestamp, modifiers, point, delta); + [super mouseMoved:event]; +} + +- (void)mouseMoved:(NSEvent *)event +{ + [self mouseEvent:event withType:Move]; +} + +- (void)mouseDown:(NSEvent *)event +{ + _isLeftPressed = true; + _lastMouseDownEvent = event; + [self mouseEvent:event withType:LeftButtonDown]; +} + +- (void)otherMouseDown:(NSEvent *)event +{ + _isMiddlePressed = true; + _lastMouseDownEvent = event; + [self mouseEvent:event withType:MiddleButtonDown]; +} + +- (void)rightMouseDown:(NSEvent *)event +{ + _isRightPressed = true; + _lastMouseDownEvent = event; + [self mouseEvent:event withType:RightButtonDown]; +} + +- (void)mouseUp:(NSEvent *)event +{ + _isLeftPressed = false; + [self mouseEvent:event withType:LeftButtonUp]; +} + +- (void)otherMouseUp:(NSEvent *)event +{ + _isMiddlePressed = false; + [self mouseEvent:event withType:MiddleButtonUp]; +} + +- (void)rightMouseUp:(NSEvent *)event +{ + _isRightPressed = false; + [self mouseEvent:event withType:RightButtonUp]; +} + +- (void)mouseDragged:(NSEvent *)event +{ + [self mouseEvent:event withType:Move]; + [super mouseDragged:event]; +} + +- (void)otherMouseDragged:(NSEvent *)event +{ + [self mouseEvent:event withType:Move]; + [super otherMouseDragged:event]; +} + +- (void)rightMouseDragged:(NSEvent *)event +{ + [self mouseEvent:event withType:Move]; + [super rightMouseDragged:event]; +} + +- (void)scrollWheel:(NSEvent *)event +{ + [self mouseEvent:event withType:Wheel]; + [super scrollWheel:event]; +} + +- (void)mouseEntered:(NSEvent *)event +{ + _isMouseOver = true; + [super mouseEntered:event]; +} + +- (void)mouseExited:(NSEvent *)event +{ + _isMouseOver = false; + [self mouseEvent:event withType:LeaveWindow]; + [super mouseExited:event]; +} + +- (void) keyboardEvent: (NSEvent *) event withType: (AvnRawKeyEventType)type +{ + auto key = s_KeyMap[[event keyCode]]; + + auto timestamp = [event timestamp] * 1000; + auto modifiers = [self getModifiers:[event modifierFlags]]; + + _lastKeyHandled = _parent->BaseEvents->RawKeyEvent(type, timestamp, modifiers, key); +} + +- (BOOL)performKeyEquivalent:(NSEvent *)event +{ + bool result = _lastKeyHandled; + + _lastKeyHandled = false; + + return result; +} + +- (void)keyDown:(NSEvent *)event +{ + [self keyboardEvent:event withType:KeyDown]; + [[self inputContext] handleEvent:event]; + [super keyDown:event]; +} + +- (void)keyUp:(NSEvent *)event +{ + [self keyboardEvent:event withType:KeyUp]; + [super keyUp:event]; +} + +- (AvnInputModifiers)getModifiers:(NSEventModifierFlags)mod +{ + unsigned int rv = 0; + + if (mod & NSEventModifierFlagControl) + rv |= Control; + if (mod & NSEventModifierFlagShift) + rv |= Shift; + if (mod & NSEventModifierFlagOption) + rv |= Alt; + if (mod & NSEventModifierFlagCommand) + rv |= Windows; + + if (_isLeftPressed) + rv |= LeftMouseButton; + if (_isMiddlePressed) + rv |= MiddleMouseButton; + if (_isRightPressed) + rv |= RightMouseButton; + + return (AvnInputModifiers)rv; +} + +- (BOOL)hasMarkedText +{ + return _lastKeyHandled; +} + +- (NSRange)markedRange +{ + return NSMakeRange(NSNotFound, 0); +} + +- (NSRange)selectedRange +{ + return NSMakeRange(NSNotFound, 0); +} + +- (void)setMarkedText:(id)string selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange +{ + +} + +- (void)unmarkText +{ + +} + +- (NSArray *)validAttributesForMarkedText +{ + return [NSArray new]; +} + +- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)range actualRange:(NSRangePointer)actualRange +{ + return [NSAttributedString new]; +} + +- (void)insertText:(id)string replacementRange:(NSRange)replacementRange +{ + if(!_lastKeyHandled) + { + _lastKeyHandled = _parent->BaseEvents->RawTextInputEvent(0, [string UTF8String]); + } +} + +- (NSUInteger)characterIndexForPoint:(NSPoint)point +{ + return 0; +} + +- (NSRect)firstRectForCharacterRange:(NSRange)range actualRange:(NSRangePointer)actualRange +{ + CGRect result; + + return result; +} +@end + + +@implementation AvnWindow +{ + ComPtr _parent; + bool _canBecomeKeyAndMain; + bool _closed; +} + +- (void)dealloc +{ + NSDebugLog(@"AvnWindow dealloc"); +} + +- (void)pollModalSession:(nonnull NSModalSession)session +{ + auto response = [NSApp runModalSession:session]; + + if(response == NSModalResponseContinue) + { + dispatch_async(dispatch_get_main_queue(), ^{ + [self pollModalSession:session]; + }); + } + else if (!_closed) + { + [self orderOut:self]; + [NSApp endModalSession:session]; + } +} + +-(void) setCanBecomeKeyAndMain +{ + _canBecomeKeyAndMain = true; +} + +-(AvnWindow*) initWithParent: (WindowBaseImpl*) parent +{ + self = [super init]; + [self setReleasedWhenClosed:false]; + _parent = parent; + [self setDelegate:self]; + return self; +} + +- (BOOL)windowShouldClose:(NSWindow *)sender +{ + auto window = dynamic_cast(_parent.getRaw()); + + if(window != nullptr) + { + return !window->WindowEvents->Closing(); + } + + return true; +} + +- (void)windowWillClose:(NSNotification *)notification +{ + _closed = true; + if(_parent) + { + ComPtr parent = _parent; + _parent = NULL; + parent->BaseEvents->Closed(); + [parent->View onClosed]; + [self setContentView: nil]; + } +} + + +-(BOOL)canBecomeKeyWindow +{ + return _canBecomeKeyAndMain; +} + +-(BOOL)canBecomeMainWindow +{ + return _canBecomeKeyAndMain; +} + +-(void)becomeKeyWindow +{ + _parent->BaseEvents->Activated(); + [super becomeKeyWindow]; +} + +- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame +{ + return true; +} + +-(void)resignKeyWindow +{ + if(_parent) + _parent->BaseEvents->Deactivated(); + [super resignKeyWindow]; +} + +- (void)windowDidMove:(NSNotification *)notification +{ + AvnPoint position; + _parent->GetPosition(&position); + _parent->BaseEvents->PositionChanged(position); +} + +// TODO this breaks resizing. +/*- (void)windowDidResize:(NSNotification *)notification +{ + + auto parent = dynamic_cast(_parent.operator->()); + + if(parent != nullptr) + { + parent->WindowStateChanged(); + } +}*/ +@end + +class PopupImpl : public virtual WindowBaseImpl, public IAvnPopup +{ +private: + BEGIN_INTERFACE_MAP() + INHERIT_INTERFACE_MAP(WindowBaseImpl) + INTERFACE_MAP_ENTRY(IAvnPopup, IID_IAvnPopup) + END_INTERFACE_MAP() + virtual ~PopupImpl(){} + ComPtr WindowEvents; + PopupImpl(IAvnWindowEvents* events) : WindowBaseImpl(events) + { + WindowEvents = events; + [Window setLevel:NSPopUpMenuWindowLevel]; + } + +protected: + virtual NSWindowStyleMask GetStyle() override + { + return NSWindowStyleMaskBorderless; + } + + virtual HRESULT Resize(double x, double y) override + { + @autoreleasepool + { + [Window setContentSize:NSSize{x, y}]; + + [Window setFrameTopLeftPoint:ToNSPoint(ConvertPointY(lastPositionSet))]; + return S_OK; + } + } +}; + +extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events) +{ + @autoreleasepool + { + IAvnPopup* ptr = dynamic_cast(new PopupImpl(events)); + return ptr; + } +} + +extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events) +{ + @autoreleasepool + { + IAvnWindow* ptr = (IAvnWindow*)new WindowImpl(events); + return ptr; + } +} diff --git a/packages.cake b/packages.cake deleted file mode 100644 index 9defa3004c..0000000000 --- a/packages.cake +++ /dev/null @@ -1,504 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Xml.Linq; - -public class Packages -{ - public List NuspecNuGetSettings { get; private set; } - public FilePath[] NugetPackages { get; private set; } - public FilePath[] BinFiles { get; private set; } - public string NugetPackagesDir {get; private set;} - public string SkiaSharpVersion {get; private set; } - public string SkiaSharpLinuxVersion {get; private set; } - public Dictionary>> PackageVersions{get; private set;} - - class DependencyBuilder : List - { - Packages _parent; - - public DependencyBuilder(Packages parent) - { - _parent = parent; - } - - string GetVersion(string name) - { - return _parent.PackageVersions[name].First().Item1; - } - - public DependencyBuilder Dep(string name, params string[] fws) - { - if(fws.Length == 0) - Add(new NuSpecDependency() { Id = name, Version = GetVersion(name) }); - foreach(var fw in fws) - Add(new NuSpecDependency() { Id = name, TargetFramework = fw, Version = GetVersion(name) }); - return this; - } - public DependencyBuilder Deps(string[] fws, params string[] deps) - { - foreach(var fw in fws) - foreach(var name in deps) - Add(new NuSpecDependency() { Id = name, TargetFramework = fw, Version = GetVersion(name) }); - return this; - } - } - - public Packages(ICakeContext context, Parameters parameters) - { - // NUGET NUSPECS - context.Information("Getting git modules:"); - - var ignoredSubModulesPaths = System.IO.File.ReadAllLines(".git/config").Where(m=>m.StartsWith("[submodule ")).Select(m => - { - var path = m.Split(' ')[1].Trim("\"[] \t".ToArray()); - context.Information(path); - return ((DirectoryPath)context.Directory(path)).FullPath; - }).ToList(); - - var normalizePath = new Func( - path => path.Replace(System.IO.Path.DirectorySeparatorChar, System.IO.Path.AltDirectorySeparatorChar).ToUpperInvariant()); - - // Key: Package Id - // Value is Tuple where Item1: Package Version, Item2: The *.csproj/*.props file path. - var packageVersions = new Dictionary>>(); - PackageVersions = packageVersions; - System.IO.Directory.EnumerateFiles(((DirectoryPath)context.Directory("./build")).FullPath, - "*.props", SearchOption.AllDirectories).ToList().ForEach(fileName => - { - if (!ignoredSubModulesPaths.Any(i => normalizePath(fileName).Contains(normalizePath(i)))) - { - var xdoc = XDocument.Load(fileName); - foreach (var reference in xdoc.Descendants().Where(x => x.Name.LocalName == "PackageReference")) - { - var name = reference.Attribute("Include").Value; - var versionAttribute = reference.Attribute("Version"); - var version = versionAttribute != null - ? versionAttribute.Value - : reference.Elements().First(x=>x.Name.LocalName == "Version").Value; - IList> versions; - packageVersions.TryGetValue(name, out versions); - if (versions == null) - { - versions = new List>(); - packageVersions[name] = versions; - } - versions.Add(Tuple.Create(version, fileName)); - } - } - }); - - context.Information("Checking installed NuGet package dependencies versions:"); - - packageVersions.ToList().ForEach(package => - { - var packageVersion = package.Value.First().Item1; - bool isValidVersion = package.Value.All(x => x.Item1 == packageVersion); - if (!isValidVersion) - { - context.Information("Error: package {0} has multiple versions installed:", package.Key); - foreach (var v in package.Value) - { - context.Information("{0}, file: {1}", v.Item1, v.Item2); - } - throw new Exception("Detected multiple NuGet package version installed for different projects."); - } - }); - - context.Information("Setting NuGet package dependencies versions:"); - - var SerilogVersion = packageVersions["Serilog"].FirstOrDefault().Item1; - var SerilogSinksDebugVersion = packageVersions["Serilog.Sinks.Debug"].FirstOrDefault().Item1; - var SerilogSinksTraceVersion = packageVersions["Serilog.Sinks.Trace"].FirstOrDefault().Item1; - var SystemReactiveVersion = packageVersions["System.Reactive"].FirstOrDefault().Item1; - var ReactiveUIVersion = packageVersions["reactiveui"].FirstOrDefault().Item1; - var SystemValueTupleVersion = packageVersions["System.ValueTuple"].FirstOrDefault().Item1; - SkiaSharpVersion = packageVersions["SkiaSharp"].FirstOrDefault().Item1; - SkiaSharpLinuxVersion = packageVersions["Avalonia.Skia.Linux.Natives"].FirstOrDefault().Item1; - var SharpDXVersion = packageVersions["SharpDX"].FirstOrDefault().Item1; - var SharpDXDirect2D1Version = packageVersions["SharpDX.Direct2D1"].FirstOrDefault().Item1; - var SharpDXDirect3D11Version = packageVersions["SharpDX.Direct3D11"].FirstOrDefault().Item1; - var SharpDXDirect3D9Version = packageVersions["SharpDX.Direct3D9"].FirstOrDefault().Item1; - var SharpDXDXGIVersion = packageVersions["SharpDX.DXGI"].FirstOrDefault().Item1; - var SystemMemoryVersion = packageVersions["System.Memory"].FirstOrDefault().Item1; - - context.Information("Package: Serilog, version: {0}", SerilogVersion); - context.Information("Package: System.Reactive, version: {0}", SystemReactiveVersion); - context.Information("Package: reactiveui, version: {0}", ReactiveUIVersion); - context.Information("Package: System.ValueTuple, version: {0}", SystemValueTupleVersion); - context.Information("Package: SkiaSharp, version: {0}", SkiaSharpVersion); - context.Information("Package: Avalonia.Skia.Linux.Natives, version: {0}", SkiaSharpLinuxVersion); - context.Information("Package: SharpDX, version: {0}", SharpDXVersion); - context.Information("Package: SharpDX.Direct2D1, version: {0}", SharpDXDirect2D1Version); - context.Information("Package: SharpDX.Direct3D11, version: {0}", SharpDXDirect3D11Version); - context.Information("Package: SharpDX.Direct3D9, version: {0}", SharpDXDirect3D9Version); - context.Information("Package: SharpDX.DXGI, version: {0}", SharpDXDXGIVersion); - context.Information("Package: System.Memory, version: {0}", SystemMemoryVersion); - - var nugetPackagesDir = System.Environment.GetEnvironmentVariable("NUGET_HOME") - ?? System.IO.Path.Combine(System.Environment.GetEnvironmentVariable("USERPROFILE") ?? System.Environment.GetEnvironmentVariable("HOME"), ".nuget"); - - NugetPackagesDir = System.IO.Path.Combine(nugetPackagesDir, "packages"); - - var SetNuGetNuspecCommonProperties = new Action ((nuspec) => { - nuspec.Version = parameters.Version; - nuspec.Authors = new [] { "Avalonia Team" }; - nuspec.Owners = new [] { "stevenk" }; - nuspec.LicenseUrl = new Uri("http://opensource.org/licenses/MIT"); - nuspec.ProjectUrl = new Uri("https://github.com/AvaloniaUI/Avalonia/"); - nuspec.RequireLicenseAcceptance = false; - nuspec.Symbols = false; - nuspec.NoPackageAnalysis = true; - nuspec.Description = "The Avalonia UI framework"; - nuspec.Copyright = "Copyright 2015"; - nuspec.Tags = new [] { "Avalonia" }; - }); - - var coreLibraries = new string[][] - { - new [] { "./src/", "Avalonia.Animation"}, - new [] { "./src/", "Avalonia.Base"}, - new [] { "./src/", "Avalonia.Controls"}, - new [] { "./src/", "Avalonia.DesignerSupport"}, - new [] { "./src/", "Avalonia.Diagnostics"}, - new [] { "./src/", "Avalonia.Input"}, - new [] { "./src/", "Avalonia.Interactivity"}, - new [] { "./src/", "Avalonia.Layout"}, - new [] { "./src/", "Avalonia.Logging.Serilog"}, - new [] { "./src/", "Avalonia.Visuals"}, - new [] { "./src/", "Avalonia.Styling"}, - new [] { "./src/", "Avalonia.Themes.Default"}, - new [] { "./src/Markup/", "Avalonia.Markup"}, - new [] { "./src/Markup/", "Avalonia.Markup.Xaml"}, - }; - - var extensionsToPack = new [] {".dll", ".xml", ".pdb"}; - - var coreLibrariesFiles = coreLibraries - .SelectMany(lib => extensionsToPack.Select(ext => new {lib, ext})) - .Select((lib) => { - return (FilePath)context.File(lib.lib[0] + lib.lib[1] + "/bin/" + parameters.DirSuffix + "/netstandard2.0/" + lib.lib[1] + lib.ext); - }).ToList(); - - var coreLibrariesNuSpecContent = coreLibrariesFiles.Select((file) => { - return new NuSpecContent { - Source = file.FullPath, Target = "lib/netstandard2.0" - }; - }); - - var netFrameworkCoreLibrariesNuSpecContent = coreLibrariesFiles.Select((file) => { - return new NuSpecContent { - Source = file.FullPath, Target = "lib/net461" - }; - }); - - var netcoreappCoreLibrariesNuSpecContent = coreLibrariesFiles.Select((file) => { - return new NuSpecContent { - Source = file.FullPath, Target = "lib/netcoreapp2.0" - }; - }); - - var netFrameworkRuntimePlatform = extensionsToPack.Select(libSuffix => { - return new NuSpecContent { - Source = ((FilePath)context.File("./src/Avalonia.DotNetFrameworkRuntime/bin/" + parameters.DirSuffix + "/net461/Avalonia.DotNetFrameworkRuntime" + libSuffix)).FullPath, - Target = "lib/net461" - }; - }); - - var netCoreRuntimePlatform = extensionsToPack.Select(libSuffix => { - return new NuSpecContent { - Source = ((FilePath)context.File("./src/Avalonia.DotNetCoreRuntime/bin/" + parameters.DirSuffix + "/netcoreapp2.0/Avalonia.DotNetCoreRuntime" + libSuffix)).FullPath, - Target = "lib/netcoreapp2.0" - }; - }); - - var toolHostApp = new NuSpecContent{ - Source = ((FilePath)context.File("./src/tools/Avalonia.Designer.HostApp/bin/" + parameters.DirSuffix + "/netcoreapp2.0/Avalonia.Designer.HostApp.dll")).FullPath, - Target = "tools/netcoreapp2.0/previewer" - }; - - var toolHostAppNetFx = new NuSpecContent{ - Source = ((FilePath)context.File("./src/tools/Avalonia.Designer.HostApp.NetFx/bin/" + parameters.DirSuffix + "/net461/Avalonia.Designer.HostApp.exe")).FullPath, - Target = "tools/net461/previewer" - }; - - var toolsContent = new[] { toolHostApp, toolHostAppNetFx }; - var coreFiles = coreLibrariesNuSpecContent - .Concat(netFrameworkCoreLibrariesNuSpecContent).Concat(netFrameworkRuntimePlatform) - .Concat(netcoreappCoreLibrariesNuSpecContent).Concat(netCoreRuntimePlatform) - .Concat(toolsContent) - .ToList(); - - var nuspecNuGetSettingsCore = new [] - { - /////////////////////////////////////////////////////////////////////////////// - // Avalonia - /////////////////////////////////////////////////////////////////////////////// - new NuGetPackSettings() - { - Id = "Avalonia", - Dependencies = new DependencyBuilder(this) - { - new NuSpecDependency() { Id = "Avalonia.Remote.Protocol", Version = parameters.Version, TargetFramework="netstandard2.0" }, - new NuSpecDependency() { Id = "Avalonia.Remote.Protocol", Version = parameters.Version, TargetFramework="netcoreapp2.0" }, - new NuSpecDependency() { Id = "Avalonia.Remote.Protocol", Version = parameters.Version, TargetFramework="net461" }, - new NuSpecDependency() { Id = "System.ValueTuple", Version = SystemValueTupleVersion, TargetFramework="net461" }, - new NuSpecDependency() { Id = "System.ComponentModel.TypeConverter", Version = "4.3.0", TargetFramework="net461" }, - new NuSpecDependency() { Id = "NETStandard.Library", Version = "2.0.0", TargetFramework="net461"} - } - .Deps(new string[]{"netstandard2.0", "netcoreapp2.0", "net461"}, - "Serilog", "Serilog.Sinks.Debug", "Serilog.Sinks.Trace", - "System.Memory", "System.Reactive", "System.ComponentModel.Annotations") - .ToArray(), - Files = coreFiles, - BasePath = context.Directory("./"), - OutputDirectory = parameters.NugetRoot - }, - /////////////////////////////////////////////////////////////////////////////// - // Avalonia.ReactiveUI - /////////////////////////////////////////////////////////////////////////////// - new NuGetPackSettings() - { - Id = "Avalonia.ReactiveUI", - Dependencies = new DependencyBuilder(this) - { - new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version }, - }.Deps(new string[] {null}, "reactiveui"), - Files = new [] - { - new NuSpecContent { Source = "Avalonia.ReactiveUI.dll", Target = "lib/netstandard2.0" } - }, - BasePath = context.Directory("./src/Avalonia.ReactiveUI/bin/" + parameters.DirSuffix + "/netstandard2.0"), - OutputDirectory = parameters.NugetRoot - }, - /////////////////////////////////////////////////////////////////////////////// - // Avalonia.Remote.Protocol - /////////////////////////////////////////////////////////////////////////////// - new NuGetPackSettings() - { - Id = "Avalonia.Remote.Protocol", - Files = new [] - { - new NuSpecContent { Source = "Avalonia.Remote.Protocol.dll", Target = "lib/netstandard2.0" } - }, - BasePath = context.Directory("./src/Avalonia.Remote.Protocol/bin/" + parameters.DirSuffix + "/netstandard2.0"), - OutputDirectory = parameters.NugetRoot - }, - }; - - var nuspecNuGetSettingsMobile = new [] - { - /////////////////////////////////////////////////////////////////////////////// - // Avalonia.Android - /////////////////////////////////////////////////////////////////////////////// - new NuGetPackSettings() - { - Id = "Avalonia.Android", - Dependencies = new [] - { - new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version }, - new NuSpecDependency() { Id = "Avalonia.Skia", Version = parameters.Version } - }, - Files = new [] - { - new NuSpecContent { Source = "Avalonia.Android.dll", Target = "lib/MonoAndroid10" } - }, - BasePath = context.Directory("./src/Android/Avalonia.Android/bin/" + parameters.DirSuffix + "/monoandroid44/MonoAndroid44/"), - OutputDirectory = parameters.NugetRoot - }, - /////////////////////////////////////////////////////////////////////////////// - // Avalonia.iOS - /////////////////////////////////////////////////////////////////////////////// - new NuGetPackSettings() - { - Id = "Avalonia.iOS", - Dependencies = new [] - { - new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version }, - new NuSpecDependency() { Id = "Avalonia.Skia", Version = parameters.Version } - }, - Files = new [] - { - new NuSpecContent { Source = "Avalonia.iOS.dll", Target = "lib/Xamarin.iOS10" } - }, - BasePath = context.Directory("./src/iOS/Avalonia.iOS/bin/" + parameters.DirSuffix + "/xamarin.ios10/"), - OutputDirectory = parameters.NugetRoot - } - }; - - var nuspecNuGetSettingsDesktop = new [] - { - /////////////////////////////////////////////////////////////////////////////// - // Avalonia.Win32 - /////////////////////////////////////////////////////////////////////////////// - new NuGetPackSettings() - { - Id = "Avalonia.Win32", - Dependencies = new DependencyBuilder(this) - { - new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version } - }.Deps(new string[]{null}, "System.Drawing.Common"), - Files = new [] - { - new NuSpecContent { Source = "Avalonia.Win32/bin/" + parameters.DirSuffix + "/netstandard2.0/Avalonia.Win32.dll", Target = "lib/netstandard2.0" } - }, - BasePath = context.Directory("./src/Windows"), - OutputDirectory = parameters.NugetRoot - }, - /////////////////////////////////////////////////////////////////////////////// - // Avalonia.Direct2D1 - /////////////////////////////////////////////////////////////////////////////// - new NuGetPackSettings() - { - Id = "Avalonia.Direct2D1", - Dependencies = new [] - { - new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version }, - new NuSpecDependency() { Id = "SharpDX", Version = SharpDXVersion }, - new NuSpecDependency() { Id = "SharpDX.Direct2D1", Version = SharpDXDirect2D1Version }, - new NuSpecDependency() { Id = "SharpDX.Direct3D11", Version = SharpDXDirect3D11Version }, - new NuSpecDependency() { Id = "SharpDX.DXGI", Version = SharpDXDXGIVersion } - }, - Files = new [] - { - new NuSpecContent { Source = "Avalonia.Direct2D1.dll", Target = "lib/netstandard2.0" } - }, - BasePath = context.Directory("./src/Windows/Avalonia.Direct2D1/bin/" + parameters.DirSuffix + "/netstandard2.0"), - OutputDirectory = parameters.NugetRoot - }, - /////////////////////////////////////////////////////////////////////////////// - // Avalonia.Gtk3 - /////////////////////////////////////////////////////////////////////////////// - new NuGetPackSettings() - { - Id = "Avalonia.Gtk3", - Dependencies = new [] - { - new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version } - }, - Files = new [] - { - new NuSpecContent { Source = "Avalonia.Gtk3.dll", Target = "lib/netstandard2.0" } - }, - BasePath = context.Directory("./src/Gtk/Avalonia.Gtk3/bin/" + parameters.DirSuffix + "/netstandard2.0"), - OutputDirectory = parameters.NugetRoot - }, - /////////////////////////////////////////////////////////////////////////////// - // Avalonia.Skia - /////////////////////////////////////////////////////////////////////////////// - new NuGetPackSettings() - { - Id = "Avalonia.Skia", - Dependencies = new [] - { - new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version }, - new NuSpecDependency() { Id = "SkiaSharp", Version = SkiaSharpVersion }, - new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version, TargetFramework="netcoreapp2.0" }, - new NuSpecDependency() { Id = "SkiaSharp", Version = SkiaSharpVersion, TargetFramework="netcoreapp2.0" }, - new NuSpecDependency() { Id = "Avalonia.Skia.Linux.Natives", Version = SkiaSharpLinuxVersion, TargetFramework="netcoreapp2.0" }, - new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version, TargetFramework="net461" }, - new NuSpecDependency() { Id = "SkiaSharp", Version = SkiaSharpVersion, TargetFramework="net461" }, - new NuSpecDependency() { Id = "Avalonia.Skia.Linux.Natives", Version = SkiaSharpLinuxVersion, TargetFramework="net461" } - }, - Files = new [] - { - new NuSpecContent { Source = "Avalonia.Skia.dll", Target = "lib/netstandard2.0" } - }, - BasePath = context.Directory("./src/Skia/Avalonia.Skia/bin/" + parameters.DirSuffix + "/netstandard2.0"), - OutputDirectory = parameters.NugetRoot - }, - new NuGetPackSettings() - { - Id = "Avalonia.MonoMac", - Dependencies = new DependencyBuilder(this) - { - new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version } - }.Dep("MonoMac.NetStandard").ToArray(), - Files = new [] - { - new NuSpecContent { Source = "netstandard2.0/Avalonia.MonoMac.dll", Target = "lib/netstandard2.0" }, - }, - BasePath = context.Directory("./src/OSX/Avalonia.MonoMac/bin/" + parameters.DirSuffix), - OutputDirectory = parameters.NugetRoot - }, - /////////////////////////////////////////////////////////////////////////////// - // Avalonia.Desktop - /////////////////////////////////////////////////////////////////////////////// - new NuGetPackSettings() - { - Id = "Avalonia.Desktop", - Dependencies = new [] - { - new NuSpecDependency() { Id = "Avalonia.Direct2D1", Version = parameters.Version }, - new NuSpecDependency() { Id = "Avalonia.Win32", Version = parameters.Version }, - new NuSpecDependency() { Id = "Avalonia.Skia", Version = parameters.Version }, - new NuSpecDependency() { Id = "Avalonia.Gtk3", Version = parameters.Version }, - new NuSpecDependency() { Id = "Avalonia.MonoMac", Version = parameters.Version } - }, - Files = new NuSpecContent[] - { - new NuSpecContent { Source = "licence.md", Target = "" } - }, - BasePath = context.Directory("./"), - OutputDirectory = parameters.NugetRoot - }, - /////////////////////////////////////////////////////////////////////////////// - // Avalonia.LinuxFramebuffer - /////////////////////////////////////////////////////////////////////////////// - new NuGetPackSettings() - { - Id = "Avalonia.LinuxFramebuffer", - Dependencies = new [] - { - new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version }, - new NuSpecDependency() { Id = "Avalonia.Skia", Version = parameters.Version } - }, - Files = new [] - { - new NuSpecContent { Source = "Avalonia.LinuxFramebuffer/bin/" + parameters.DirSuffix + "/netstandard2.0/Avalonia.LinuxFramebuffer.dll", Target = "lib/netstandard2.0" } - }, - BasePath = context.Directory("./src/Linux/"), - OutputDirectory = parameters.NugetRoot - } - }; - - var nuspecNuGetSettingInterop = new NuGetPackSettings() - { - Id = "Avalonia.Win32.Interoperability", - Dependencies = new [] - { - new NuSpecDependency() { Id = "Avalonia.Win32", Version = parameters.Version }, - new NuSpecDependency() { Id = "Avalonia.Direct2D1", Version = parameters.Version }, - new NuSpecDependency() { Id = "SharpDX.Direct3D9", Version = SharpDXDirect3D9Version }, - }, - Files = new [] - { - new NuSpecContent { Source = "Avalonia.Win32.Interop/bin/" + parameters.DirSuffix + "/net461/Avalonia.Win32.Interop.dll", Target = "lib/net461" } - }, - BasePath = context.Directory("./src/Windows"), - OutputDirectory = parameters.NugetRoot - }; - - NuspecNuGetSettings = new List(); - - NuspecNuGetSettings.AddRange(nuspecNuGetSettingsCore); - NuspecNuGetSettings.AddRange(nuspecNuGetSettingsDesktop); - - if (parameters.IsRunningOnWindows) { - NuspecNuGetSettings.Add(nuspecNuGetSettingInterop); - NuspecNuGetSettings.AddRange(nuspecNuGetSettingsMobile); - } - - NuspecNuGetSettings.ForEach((nuspec) => SetNuGetNuspecCommonProperties(nuspec)); - - NugetPackages = NuspecNuGetSettings.Select(nuspec => { - return nuspec.OutputDirectory.CombineWithFilePath(string.Concat(nuspec.Id, ".", nuspec.Version, ".nupkg")); - }).ToArray(); - - BinFiles = NuspecNuGetSettings.SelectMany(nuspec => { - return nuspec.Files.Select(file => { - return ((DirectoryPath)nuspec.BasePath).CombineWithFilePath(file.Source); - }); - }).GroupBy(f => f.FullPath).Select(g => g.First()).ToArray(); - } -} diff --git a/packages/Avalonia/Avalonia.csproj b/packages/Avalonia/Avalonia.csproj new file mode 100644 index 0000000000..dee42fb795 --- /dev/null +++ b/packages/Avalonia/Avalonia.csproj @@ -0,0 +1,41 @@ + + + netstandard2.0;net461;netcoreapp2.0 + + + + + + + + ../../src/tools + + + + + + + <_PackageFiles Include="$(DesignerHostAppPath)/Avalonia.Designer.HostApp/bin/$(Configuration)/netcoreapp2.0/Avalonia.Designer.HostApp.dll"> + tools/netcoreapp2.0/designer + false + None + + <_PackageFiles Include="$(DesignerHostAppPath)/Avalonia.Designer.HostApp/bin/$(Configuration)/net461/Avalonia.Designer.HostApp.exe"> + tools/net461/designer + false + None + + <_PackageFiles Include="Avalonia.props"> + build/Avalonia.props + false + None + + + + + + + + diff --git a/packages/Avalonia/Avalonia.props b/packages/Avalonia/Avalonia.props new file mode 100644 index 0000000000..8234dc4fde --- /dev/null +++ b/packages/Avalonia/Avalonia.props @@ -0,0 +1,6 @@ + + + $(MSBuildThisFileDirectory)\..\tools\netcoreapp2.0\designer\Avalonia.Designer.HostApp.dll + $(MSBuildThisFileDirectory)\..\tools\net461\designer\Avalonia.Designer.HostApp.exe + + diff --git a/parameters.cake b/parameters.cake index 814c96da45..4ef7e8e05a 100644 --- a/parameters.cake +++ b/parameters.cake @@ -9,23 +9,28 @@ public class Parameters public string MasterBranch { get; private set; } public string ReleasePlatform { get; private set; } public string ReleaseConfiguration { get; private set; } + public string ReleaseBranchPrefix { get; private set; } public string MSBuildSolution { get; private set; } public bool IsLocalBuild { get; private set; } public bool IsRunningOnUnix { get; private set; } public bool IsRunningOnWindows { get; private set; } public bool IsRunningOnAppVeyor { get; private set; } + public bool IsRunningOnAzure { get; private set; } public bool IsPullRequest { get; private set; } public bool IsMainRepo { get; private set; } public bool IsMasterBranch { get; private set; } + public bool IsReleaseBranch { get; private set; } public bool IsTagged { get; private set; } public bool IsReleasable { get; private set; } public bool IsMyGetRelease { get; private set; } public bool IsNuGetRelease { get; private set; } + public bool PublishTestResults { get; private set; } public string Version { get; private set; } public DirectoryPath ArtifactsDir { get; private set; } public DirectoryPath NugetRoot { get; private set; } public DirectoryPath ZipRoot { get; private set; } public DirectoryPath BinRoot { get; private set; } + public DirectoryPath TestResultsRoot { get; private set; } public string DirSuffix { get; private set; } public DirectoryPathCollection BuildDirs { get; private set; } public string FileZipSuffix { get; private set; } @@ -43,8 +48,9 @@ public class Parameters SkipTests = context.HasArgument("skip-tests"); // CONFIGURATION - MainRepo = "AvaloniaUI/Avalonia"; + MainRepo = "https://github.com/AvaloniaUI/Avalonia"; MasterBranch = "master"; + ReleaseBranchPrefix = "refs/heads/release/"; ReleaseConfiguration = "Release"; MSBuildSolution = "./dirs.proj"; @@ -53,13 +59,17 @@ public class Parameters IsRunningOnUnix = context.IsRunningOnUnix(); IsRunningOnWindows = context.IsRunningOnWindows(); IsRunningOnAppVeyor = buildSystem.AppVeyor.IsRunningOnAppVeyor; + IsRunningOnAzure = buildSystem.IsRunningOnVSTS || buildSystem.IsRunningOnTFS || context.EnvironmentVariable("LOGNAME") == "vsts"; + IsPullRequest = buildSystem.AppVeyor.Environment.PullRequest.IsPullRequest; - IsMainRepo = StringComparer.OrdinalIgnoreCase.Equals(MainRepo, buildSystem.AppVeyor.Environment.Repository.Name); - IsMasterBranch = StringComparer.OrdinalIgnoreCase.Equals(MasterBranch, buildSystem.AppVeyor.Environment.Repository.Branch); + IsMainRepo = StringComparer.OrdinalIgnoreCase.Equals(MainRepo, context.EnvironmentVariable("BUILD_REPOSITORY_URI")); + IsMasterBranch = StringComparer.OrdinalIgnoreCase.Equals(MasterBranch, context.EnvironmentVariable("BUILD_SOURCEBRANCHNAME")); + IsReleaseBranch = (context.EnvironmentVariable("BUILD_SOURCEBRANCH")??"").StartsWith(ReleaseBranchPrefix, StringComparison.OrdinalIgnoreCase); IsTagged = buildSystem.AppVeyor.Environment.Repository.Tag.IsTag && !string.IsNullOrWhiteSpace(buildSystem.AppVeyor.Environment.Repository.Tag.Name); IsReleasable = StringComparer.OrdinalIgnoreCase.Equals(ReleaseConfiguration, Configuration); IsMyGetRelease = !IsTagged && IsReleasable; + IsNuGetRelease = IsMainRepo && IsReleasable && IsReleaseBranch; // VERSION Version = context.Argument("force-nuget-version", GetVersion()); @@ -85,12 +95,23 @@ public class Parameters Version += "-build" + context.EnvironmentVariable("APPVEYOR_BUILD_NUMBER") + "-beta"; } } + else if (IsRunningOnAzure) + { + if(!IsNuGetRelease) + { + // Use AssemblyVersion with Build as version + Version += "-build" + context.EnvironmentVariable("BUILD_BUILDID") + "-beta"; + } + + PublishTestResults = true; + } // DIRECTORIES ArtifactsDir = (DirectoryPath)context.Directory("./artifacts"); NugetRoot = ArtifactsDir.Combine("nuget"); ZipRoot = ArtifactsDir.Combine("zip"); BinRoot = ArtifactsDir.Combine("bin"); + TestResultsRoot = ArtifactsDir.Combine("test-results"); BuildDirs = context.GetDirectories("**/bin") + context.GetDirectories("**/obj"); DirSuffix = Configuration; FileZipSuffix = Version + ".zip"; diff --git a/readme.md b/readme.md index f345cbd9df..9d113cf2ef 100644 --- a/readme.md +++ b/readme.md @@ -2,9 +2,9 @@ # Avalonia -| Gitter Chat | Windows Build Status | Linux/Mac Build Status | Open Collective | +| Gitter Chat | Build Status (Win, Linux, OSX) | Appveyor Build Status | Open Collective | |---|---|---|---| -| [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/AvaloniaUI/Avalonia?utm_campaign=pr-badge&utm_content=badge&utm_medium=badge&utm_source=badge) | [![Build status](https://ci.appveyor.com/api/projects/status/hubk3k0w9idyibfg/branch/master?svg=true)](https://ci.appveyor.com/project/AvaloniaUI/Avalonia/branch/master) | [![Build Status](https://travis-ci.org/AvaloniaUI/Avalonia.svg?branch=master)](https://travis-ci.org/AvaloniaUI/Avalonia) | [![Backers on Open Collective](https://opencollective.com/Avalonia/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/Avalonia/sponsors/badge.svg)](#sponsors) | +| [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/AvaloniaUI/Avalonia?utm_campaign=pr-badge&utm_content=badge&utm_medium=badge&utm_source=badge) | [![Build Status](https://dev.azure.com/AvaloniaUI/AvaloniaUI/_apis/build/status/AvaloniaUI.Avalonia)](https://dev.azure.com/AvaloniaUI/AvaloniaUI/_build/latest?definitionId=4) | [![Build status](https://ci.appveyor.com/api/projects/status/hubk3k0w9idyibfg/branch/master?svg=true)](https://ci.appveyor.com/project/AvaloniaUI/Avalonia/branch/master) | [![Backers on Open Collective](https://opencollective.com/Avalonia/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/Avalonia/sponsors/badge.svg)](#sponsors) | ## About diff --git a/samples/BindingDemo/App.config b/samples/BindingDemo/App.config deleted file mode 100644 index 538be69997..0000000000 --- a/samples/BindingDemo/App.config +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/samples/BindingDemo/BindingDemo.csproj b/samples/BindingDemo/BindingDemo.csproj index f7568b9c51..b28ab5fd8a 100644 --- a/samples/BindingDemo/BindingDemo.csproj +++ b/samples/BindingDemo/BindingDemo.csproj @@ -4,27 +4,8 @@ netcoreapp2.0;net461 - - - - - - - - - - - - - - - - - - - @@ -32,4 +13,5 @@ + diff --git a/samples/ControlCatalog.Android/ControlCatalog.Android.csproj b/samples/ControlCatalog.Android/ControlCatalog.Android.csproj index 86030bf200..272632e7eb 100644 --- a/samples/ControlCatalog.Android/ControlCatalog.Android.csproj +++ b/samples/ControlCatalog.Android/ControlCatalog.Android.csproj @@ -155,4 +155,5 @@ + diff --git a/samples/ControlCatalog.Desktop/App.config b/samples/ControlCatalog.Desktop/App.config deleted file mode 100644 index cd4593817b..0000000000 --- a/samples/ControlCatalog.Desktop/App.config +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj b/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj index d60d087393..054de2a05f 100644 --- a/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj +++ b/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj @@ -6,16 +6,9 @@ - - - - - - - diff --git a/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj b/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj index ec841db5b2..7e2c707e91 100644 --- a/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj +++ b/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj @@ -6,10 +6,12 @@ - - + - \ No newline at end of file + + + + diff --git a/samples/ControlCatalog.iOS/ControlCatalog.iOS.csproj b/samples/ControlCatalog.iOS/ControlCatalog.iOS.csproj index 6754cdf9a9..7596e4cfe2 100644 --- a/samples/ControlCatalog.iOS/ControlCatalog.iOS.csproj +++ b/samples/ControlCatalog.iOS/ControlCatalog.iOS.csproj @@ -176,4 +176,5 @@ + diff --git a/samples/ControlCatalog/App.config b/samples/ControlCatalog/App.config deleted file mode 100644 index 0c47592f2c..0000000000 --- a/samples/ControlCatalog/App.config +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/samples/ControlCatalog/App.xaml b/samples/ControlCatalog/App.xaml index 43971dec4f..95d515ec60 100644 --- a/samples/ControlCatalog/App.xaml +++ b/samples/ControlCatalog/App.xaml @@ -14,6 +14,11 @@ - + + + - \ No newline at end of file + diff --git a/samples/ControlCatalog/ControlCatalog.csproj b/samples/ControlCatalog/ControlCatalog.csproj index a147eac6ef..13b79d75b5 100644 --- a/samples/ControlCatalog/ControlCatalog.csproj +++ b/samples/ControlCatalog/ControlCatalog.csproj @@ -22,19 +22,8 @@ - - - - - - - - - + - - - diff --git a/samples/ControlCatalog/Pages/ButtonPage.xaml b/samples/ControlCatalog/Pages/ButtonPage.xaml index 38757148ab..a4690e32e1 100644 --- a/samples/ControlCatalog/Pages/ButtonPage.xaml +++ b/samples/ControlCatalog/Pages/ButtonPage.xaml @@ -18,7 +18,7 @@ diff --git a/samples/ControlCatalog/Pages/CanvasPage.xaml b/samples/ControlCatalog/Pages/CanvasPage.xaml index 10a38895a2..d6c138a4f7 100644 --- a/samples/ControlCatalog/Pages/CanvasPage.xaml +++ b/samples/ControlCatalog/Pages/CanvasPage.xaml @@ -11,7 +11,8 @@ - + + diff --git a/samples/ControlCatalog/Pages/LayoutTransformControlPage.xaml b/samples/ControlCatalog/Pages/LayoutTransformControlPage.xaml index b428cd1b9f..f7e1c08cac 100644 --- a/samples/ControlCatalog/Pages/LayoutTransformControlPage.xaml +++ b/samples/ControlCatalog/Pages/LayoutTransformControlPage.xaml @@ -19,7 +19,7 @@ - Layout Transform + diff --git a/samples/ControlCatalog/Pages/MenuPage.xaml b/samples/ControlCatalog/Pages/MenuPage.xaml index 296cfa8704..c5aa35312c 100644 --- a/samples/ControlCatalog/Pages/MenuPage.xaml +++ b/samples/ControlCatalog/Pages/MenuPage.xaml @@ -7,29 +7,46 @@ Margin="0,16,0,0" HorizontalAlignment="Center" Spacing="16"> - - - - - - - + + Defined in XAML + + + + + + + + + + + + + + + + + + - - - - + + - - - - - - - - - - + + + + + Dyanamically generated + + + + + + - \ No newline at end of file + diff --git a/samples/ControlCatalog/Pages/MenuPage.xaml.cs b/samples/ControlCatalog/Pages/MenuPage.xaml.cs index d637c172e1..ec7c000fe6 100644 --- a/samples/ControlCatalog/Pages/MenuPage.xaml.cs +++ b/samples/ControlCatalog/Pages/MenuPage.xaml.cs @@ -1,5 +1,10 @@ +using System.Collections.Generic; +using System.Reactive; +using System.Threading.Tasks; +using System.Windows.Input; using Avalonia.Controls; using Avalonia.Markup.Xaml; +using ReactiveUI; namespace ControlCatalog.Pages { @@ -8,6 +13,51 @@ namespace ControlCatalog.Pages public MenuPage() { this.InitializeComponent(); + var vm = new MenuPageViewModel(); + + vm.MenuItems = new[] + { + new MenuItemViewModel + { + Header = "_File", + Items = new[] + { + new MenuItemViewModel { Header = "_Open...", Command = vm.OpenCommand }, + new MenuItemViewModel { Header = "Save", Command = vm.SaveCommand }, + new MenuItemViewModel { Header = "-" }, + new MenuItemViewModel + { + Header = "Recent", + Items = new[] + { + new MenuItemViewModel + { + Header = "File1.txt", + Command = vm.OpenRecentCommand, + CommandParameter = @"c:\foo\File1.txt" + }, + new MenuItemViewModel + { + Header = "File2.txt", + Command = vm.OpenRecentCommand, + CommandParameter = @"c:\foo\File2.txt" + }, + } + }, + } + }, + new MenuItemViewModel + { + Header = "_Edit", + Items = new[] + { + new MenuItemViewModel { Header = "_Copy" }, + new MenuItemViewModel { Header = "_Paste" }, + } + } + }; + + DataContext = vm; } private void InitializeComponent() @@ -15,4 +65,51 @@ namespace ControlCatalog.Pages AvaloniaXamlLoader.Load(this); } } + + public class MenuPageViewModel + { + public MenuPageViewModel() + { + OpenCommand = ReactiveCommand.CreateFromTask(Open); + SaveCommand = ReactiveCommand.Create(Save); + OpenRecentCommand = ReactiveCommand.Create(OpenRecent); + } + + public IReadOnlyList MenuItems { get; set; } + public ReactiveCommand OpenCommand { get; } + public ReactiveCommand SaveCommand { get; } + public ReactiveCommand OpenRecentCommand { get; } + + public async Task Open() + { + var dialog = new OpenFileDialog(); + var result = await dialog.ShowAsync(); + + if (result != null) + { + foreach (var path in result) + { + System.Diagnostics.Debug.WriteLine($"Opened: {path}"); + } + } + } + + public void Save() + { + System.Diagnostics.Debug.WriteLine("Save"); + } + + public void OpenRecent(string path) + { + System.Diagnostics.Debug.WriteLine($"Open recent: {path}"); + } + } + + public class MenuItemViewModel + { + public string Header { get; set; } + public ICommand Command { get; set; } + public object CommandParameter { get; set; } + public IList Items { get; set; } + } } diff --git a/samples/Directory.Build.props b/samples/Directory.Build.props index 7325bab2a3..b9075b957b 100644 --- a/samples/Directory.Build.props +++ b/samples/Directory.Build.props @@ -1,3 +1,6 @@ + + false + - \ No newline at end of file + diff --git a/samples/Previewer/Previewer.csproj b/samples/Previewer/Previewer.csproj index b4dda473f2..2cdde0c945 100644 --- a/samples/Previewer/Previewer.csproj +++ b/samples/Previewer/Previewer.csproj @@ -8,19 +8,9 @@ %(Filename) - - - - - - - - - - - - - - \ No newline at end of file + + + + diff --git a/samples/RemoteDemo/RemoteDemo.csproj b/samples/RemoteDemo/RemoteDemo.csproj index 2487c66e41..046999e06e 100644 --- a/samples/RemoteDemo/RemoteDemo.csproj +++ b/samples/RemoteDemo/RemoteDemo.csproj @@ -6,20 +6,9 @@ - - - - - - - - - - - - - + + diff --git a/samples/RenderDemo/MainWindow.xaml b/samples/RenderDemo/MainWindow.xaml index df2b221423..fc5b1ce94d 100644 --- a/samples/RenderDemo/MainWindow.xaml +++ b/samples/RenderDemo/MainWindow.xaml @@ -8,12 +8,13 @@ - - + - - - - + + + + + + + + + \ No newline at end of file diff --git a/samples/RenderDemo/Pages/AnimationsPage.xaml b/samples/RenderDemo/Pages/AnimationsPage.xaml index 5287e4e373..1646708797 100644 --- a/samples/RenderDemo/Pages/AnimationsPage.xaml +++ b/samples/RenderDemo/Pages/AnimationsPage.xaml @@ -1,12 +1,12 @@ - +