Browse Source

Merge branch 'master' into hsvcolor

pull/7724/head
robloo 4 years ago
committed by GitHub
parent
commit
681abed490
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      .gitignore
  2. 78
      Avalonia.sln
  3. 8
      azure-pipelines.yml
  4. 6
      build/HarfBuzzSharp.props
  5. 6
      build/SkiaSharp.props
  6. 9
      dirs.proj
  7. 3
      global.json
  8. 10
      samples/ControlCatalog.Android/MainActivity.cs
  9. 10
      samples/ControlCatalog.Android/SplashActivity.cs
  10. 1
      samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj
  11. 7
      samples/ControlCatalog.NetCore/Program.cs
  12. 15
      samples/ControlCatalog.iOS.Legacy/AppDelegate.cs
  13. 117
      samples/ControlCatalog.iOS.Legacy/Assets.xcassets/AppIcon.appiconset/Contents.json
  14. 99
      samples/ControlCatalog.iOS.Legacy/ControlCatalog.iOS.Legacy.csproj
  15. 6
      samples/ControlCatalog.iOS.Legacy/Entitlements.plist
  16. 47
      samples/ControlCatalog.iOS.Legacy/Info.plist
  17. 15
      samples/ControlCatalog.iOS.Legacy/Main.cs
  18. 43
      samples/ControlCatalog.iOS.Legacy/Resources/LaunchScreen.xib
  19. 190
      samples/ControlCatalog.iOS/ControlCatalog.iOS.csproj
  20. 7
      samples/ControlCatalog.iOS/Info.plist
  21. 4
      samples/ControlCatalog.iOS/Main.cs
  22. 36
      samples/ControlCatalog.iOS/Properties/AssemblyInfo.cs
  23. 2
      samples/ControlCatalog.iOS/Resources/LaunchScreen.xib
  24. 5
      samples/ControlCatalog/App.xaml.cs
  25. 1
      samples/ControlCatalog/ControlCatalog.csproj
  26. 1
      samples/interop/WindowsInteropTest/WindowsInteropTest.csproj
  27. 5
      src/Android/Avalonia.Android/AndroidPlatform.cs
  28. 3
      src/Android/Avalonia.Android/Avalonia.Android.csproj
  29. 43
      src/Android/Avalonia.Android/AvaloniaActivity.cs
  30. 7
      src/Android/Avalonia.Android/AvaloniaView.cs
  31. 18
      src/Avalonia.Controls/Presenters/TextPresenter.cs
  32. 4
      src/Avalonia.Controls/TextBlock.cs
  33. 135
      src/Avalonia.Controls/TextBox.cs
  34. 46
      src/Avalonia.OpenGL/Egl/EglInterface.cs
  35. 5
      src/Avalonia.OpenGL/GlBasicInfoInterface.cs
  36. 112
      src/Avalonia.OpenGL/GlInterface.cs
  37. 36
      src/Avalonia.Visuals/Media/TextFormatting/ShapeableTextCharacters.cs
  38. 12
      src/Avalonia.Visuals/Media/TextFormatting/TextCharacters.cs
  39. 74
      src/Avalonia.Visuals/Media/TextFormatting/TextFormatterImpl.cs
  40. 2
      src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs
  41. 2
      src/Avalonia.Visuals/Media/TextFormatting/TextLineImpl.cs
  42. 27
      src/Avalonia.Visuals/Utilities/ReadOnlySlice.cs
  43. 15
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlBindingPathHelper.cs
  44. 5
      src/Skia/Avalonia.Skia/FontManagerImpl.cs
  45. 13
      src/Skia/Avalonia.Skia/Gpu/OpenGl/GlRenderTarget.cs
  46. 2
      src/Web/Avalonia.Web.Blazor/AvaloniaView.razor.cs
  47. 14
      src/Windows/Avalonia.Win32/WindowImpl.CustomCaptionProc.cs
  48. 11
      src/Windows/Avalonia.Win32/WindowImpl.cs
  49. 27
      src/iOS/Avalonia.iOS/Avalonia.iOS.csproj
  50. 32
      src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs
  51. 14
      src/iOS/Avalonia.iOS/Boilerplate/AppBuilder.cs
  52. 19
      src/iOS/Avalonia.iOS/EaglDisplay.cs
  53. 5
      src/iOS/Avalonia.iOS/EaglLayerSurface.cs
  54. 4
      src/iOS/Avalonia.iOS/Extensions.cs
  55. 80
      src/iOS/Avalonia.iOS/LayerFbo.cs
  56. 17
      src/iOS/Avalonia.iOS/Platform.cs
  57. 7
      src/iOS/Avalonia.iOS/SingleViewLifetime.cs

1
.gitignore

@ -198,7 +198,6 @@ Index/
Logs/
ModuleCache.noindex/
Build/Intermediates.noindex/
info.plist
build-intermediate
obj-Direct2D1/
obj-Skia/

78
Avalonia.sln

@ -95,8 +95,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog", "samples\C
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.Desktop", "samples\ControlCatalog.Desktop\ControlCatalog.Desktop.csproj", "{2B888490-D14A-4BCA-AB4B-48676FA93C9B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.iOS", "samples\ControlCatalog.iOS\ControlCatalog.iOS.csproj", "{57E0455D-D565-44BB-B069-EE1AA20F8337}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.DesignerSupport.Tests", "tests\Avalonia.DesignerSupport.Tests\Avalonia.DesignerSupport.Tests.csproj", "{52F55355-D120-42AC-8116-8410A7D602FA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.DesignerSupport.TestApp", "tests\Avalonia.DesignerSupport.TestApp\Avalonia.DesignerSupport.TestApp.csproj", "{F1381F98-4D24-409A-A6C5-1C5B1E08BB08}"
@ -121,7 +119,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1
build\CoreLibraries.props = build\CoreLibraries.props
build\EmbedXaml.props = build\EmbedXaml.props
build\HarfBuzzSharp.props = build\HarfBuzzSharp.props
build\iOSWorkarounds.props = build\iOSWorkarounds.props
build\JetBrains.Annotations.props = build\JetBrains.Annotations.props
build\JetBrains.dotMemoryUnit.props = build\JetBrains.dotMemoryUnit.props
build\Magick.NET-Q16-AnyCPU.props = build\Magick.NET-Q16-AnyCPU.props
@ -235,6 +232,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlSamples", "samples\S
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.PlatformSupport", "src\Avalonia.PlatformSupport\Avalonia.PlatformSupport.csproj", "{E8A597F0-2AB5-4BDA-A235-41162DAF53CF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog.iOS", "samples\ControlCatalog.iOS\ControlCatalog.iOS.csproj", "{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog.iOS.Legacy", "samples\ControlCatalog.iOS.Legacy\ControlCatalog.iOS.Legacy.csproj", "{3AF75F00-B497-4517-9491-922173DE216E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
@ -1097,26 +1098,6 @@ Global
{2B888490-D14A-4BCA-AB4B-48676FA93C9B}.Release|iPhone.Build.0 = Release|Any CPU
{2B888490-D14A-4BCA-AB4B-48676FA93C9B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{2B888490-D14A-4BCA-AB4B-48676FA93C9B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{57E0455D-D565-44BB-B069-EE1AA20F8337}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone
{57E0455D-D565-44BB-B069-EE1AA20F8337}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
{57E0455D-D565-44BB-B069-EE1AA20F8337}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
{57E0455D-D565-44BB-B069-EE1AA20F8337}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
{57E0455D-D565-44BB-B069-EE1AA20F8337}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
{57E0455D-D565-44BB-B069-EE1AA20F8337}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone
{57E0455D-D565-44BB-B069-EE1AA20F8337}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
{57E0455D-D565-44BB-B069-EE1AA20F8337}.AppStore|iPhone.Build.0 = AppStore|iPhone
{57E0455D-D565-44BB-B069-EE1AA20F8337}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
{57E0455D-D565-44BB-B069-EE1AA20F8337}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
{57E0455D-D565-44BB-B069-EE1AA20F8337}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{57E0455D-D565-44BB-B069-EE1AA20F8337}.Debug|iPhone.ActiveCfg = Debug|iPhone
{57E0455D-D565-44BB-B069-EE1AA20F8337}.Debug|iPhone.Build.0 = Debug|iPhone
{57E0455D-D565-44BB-B069-EE1AA20F8337}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{57E0455D-D565-44BB-B069-EE1AA20F8337}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{57E0455D-D565-44BB-B069-EE1AA20F8337}.Release|Any CPU.ActiveCfg = Release|iPhone
{57E0455D-D565-44BB-B069-EE1AA20F8337}.Release|iPhone.ActiveCfg = Release|iPhone
{57E0455D-D565-44BB-B069-EE1AA20F8337}.Release|iPhone.Build.0 = Release|iPhone
{57E0455D-D565-44BB-B069-EE1AA20F8337}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{57E0455D-D565-44BB-B069-EE1AA20F8337}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{52F55355-D120-42AC-8116-8410A7D602FA}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{52F55355-D120-42AC-8116-8410A7D602FA}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{52F55355-D120-42AC-8116-8410A7D602FA}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
@ -2209,6 +2190,54 @@ Global
{E8A597F0-2AB5-4BDA-A235-41162DAF53CF}.Release|iPhone.Build.0 = Release|Any CPU
{E8A597F0-2AB5-4BDA-A235-41162DAF53CF}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{E8A597F0-2AB5-4BDA-A235-41162DAF53CF}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.AppStore|iPhone.Build.0 = Debug|Any CPU
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Debug|iPhone.Build.0 = Debug|Any CPU
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Release|Any CPU.Build.0 = Release|Any CPU
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Release|iPhone.ActiveCfg = Release|Any CPU
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Release|iPhone.Build.0 = Release|Any CPU
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{3AF75F00-B497-4517-9491-922173DE216E}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{3AF75F00-B497-4517-9491-922173DE216E}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{3AF75F00-B497-4517-9491-922173DE216E}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{3AF75F00-B497-4517-9491-922173DE216E}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{3AF75F00-B497-4517-9491-922173DE216E}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{3AF75F00-B497-4517-9491-922173DE216E}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{3AF75F00-B497-4517-9491-922173DE216E}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{3AF75F00-B497-4517-9491-922173DE216E}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{3AF75F00-B497-4517-9491-922173DE216E}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{3AF75F00-B497-4517-9491-922173DE216E}.AppStore|iPhone.Build.0 = Debug|Any CPU
{3AF75F00-B497-4517-9491-922173DE216E}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{3AF75F00-B497-4517-9491-922173DE216E}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{3AF75F00-B497-4517-9491-922173DE216E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3AF75F00-B497-4517-9491-922173DE216E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3AF75F00-B497-4517-9491-922173DE216E}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{3AF75F00-B497-4517-9491-922173DE216E}.Debug|iPhone.Build.0 = Debug|Any CPU
{3AF75F00-B497-4517-9491-922173DE216E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{3AF75F00-B497-4517-9491-922173DE216E}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{3AF75F00-B497-4517-9491-922173DE216E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3AF75F00-B497-4517-9491-922173DE216E}.Release|Any CPU.Build.0 = Release|Any CPU
{3AF75F00-B497-4517-9491-922173DE216E}.Release|iPhone.ActiveCfg = Release|Any CPU
{3AF75F00-B497-4517-9491-922173DE216E}.Release|iPhone.Build.0 = Release|Any CPU
{3AF75F00-B497-4517-9491-922173DE216E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{3AF75F00-B497-4517-9491-922173DE216E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -2238,7 +2267,6 @@ Global
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{D0A739B9-3C68-4BA6-A328-41606954B6BD} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{2B888490-D14A-4BCA-AB4B-48676FA93C9B} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{57E0455D-D565-44BB-B069-EE1AA20F8337} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{52F55355-D120-42AC-8116-8410A7D602FA} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{F1381F98-4D24-409A-A6C5-1C5B1E08BB08} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{FBCAF3D0-2808-4934-8E96-3F607594517B} = {9B9E3891-2366-4253-A952-D08BCEB71098}
@ -2273,6 +2301,8 @@ Global
{C08E9894-AA92-426E-BF56-033E262CAD3E} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{26A98DA1-D89D-4A95-8152-349F404DA2E2} = {A0CC0258-D18C-4AB3-854F-7101680FC3F9}
{A0D0A6A4-5C72-4ADA-9B27-621C7D94F270} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{3AF75F00-B497-4517-9491-922173DE216E} = {9B9E3891-2366-4253-A952-D08BCEB71098}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {87366D66-1391-4D90-8999-95A620AD786A}

8
azure-pipelines.yml

@ -38,7 +38,7 @@ jobs:
- task: UseDotNet@2
displayName: 'Use .NET Core SDK 6.0.100'
inputs:
version: 6.0.100
version: 6.0.200
- task: CmdLine@2
displayName: 'Run Build'
@ -69,7 +69,7 @@ jobs:
- task: UseDotNet@2
displayName: 'Use .NET Core SDK 6.0.100'
inputs:
version: 6.0.100
version: 6.0.200
- task: CmdLine@2
displayName: 'Install Mono 5.18'
@ -141,13 +141,13 @@ jobs:
- task: UseDotNet@2
displayName: 'Use .NET Core SDK 6.0.100'
inputs:
version: 6.0.100
version: 6.0.200
- task: CmdLine@2
displayName: 'Install Workloads'
inputs:
script: |
dotnet workload install android
dotnet workload install --no-cache --disable-parallel android ios --skip-manifest-update --source "https://api.nuget.org/v3/index.json"
- task: CmdLine@2
displayName: 'Install Nuke'

6
build/HarfBuzzSharp.props

@ -1,7 +1,7 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<PackageReference Include="HarfBuzzSharp" Version="2.8.2-preview.178" />
<PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="HarfBuzzSharp.NativeAssets.Linux" Version="2.8.2-preview.178" />
<PackageReference Condition="'$(IncludeWasmSkia)' == 'true'" Include="HarfBuzzSharp.NativeAssets.WebAssembly" Version="2.8.2-preview.178"/>
<PackageReference Include="HarfBuzzSharp" Version="2.8.2-preview.209" />
<PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="HarfBuzzSharp.NativeAssets.Linux" Version="2.8.2-preview.209" />
<PackageReference Condition="'$(IncludeWasmSkia)' == 'true'" Include="HarfBuzzSharp.NativeAssets.WebAssembly" Version="2.8.2-preview.209"/>
</ItemGroup>
</Project>

6
build/SkiaSharp.props

@ -1,7 +1,7 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<PackageReference Include="SkiaSharp" Version="2.88.0-preview.178" />
<PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="SkiaSharp.NativeAssets.Linux" Version="2.88.0-preview.178" />
<PackageReference Condition="'$(IncludeWasmSkia)' == 'true'" Include="SkiaSharp.NativeAssets.WebAssembly" Version="2.88.0-preview.178"/>
<PackageReference Include="SkiaSharp" Version="2.88.0-preview.209" />
<PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="SkiaSharp.NativeAssets.Linux" Version="2.88.0-preview.209" />
<PackageReference Condition="'$(IncludeWasmSkia)' == 'true'" Include="SkiaSharp.NativeAssets.WebAssembly" Version="2.88.0-preview.209"/>
</ItemGroup>
</Project>

9
dirs.proj

@ -10,21 +10,20 @@
<ProjectReference Remove="src/Markup/Avalonia.Markup.Xaml/PortableXaml/**/*.*proj" />
<ProjectReference Remove="src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github/**/*.*proj" />
<ProjectReference Remove="tests/Avalonia.ReactiveUI.Events.UnitTests/Avalonia.ReactiveUI.Events.UnitTests.csproj" />
<ProjectReference Remove="samples/ControlCatalog.iOS/ControlCatalog.iOS.csproj" />
<ProjectReference Remove="samples/ControlCatalog.iOS.Legacy/ControlCatalog.iOS.Legacy.csproj" />
<ProjectReference Remove="samples/ControlCatalog.Android/ControlCatalog.Android.csproj" />
<ProjectReference Remove="src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj" />
</ItemGroup>
<ItemGroup Condition="!Exists('$(MSBuildExtensionsPath)\Xamarin\iOS')">
<ProjectReference Remove="src/iOS/**/*.*proj" />
<ProjectReference Remove="samples/ControlCatalog.iOS/ControlCatalog.iOS.csproj" />
</ItemGroup>
<ItemGroup Condition="!$([MSBuild]::IsOsPlatform('Windows')) OR '$(MSBuildRuntimeType)' != 'Full'">
<ProjectReference Remove="src/Windows/Avalonia.Win32.Interop/Avalonia.Win32.Interop.csproj" />
<ProjectReference Remove="samples/interop/**/*.*proj" />
<ProjectReference Remove="samples/ControlCatalog.Desktop/*.*proj" />
</ItemGroup>
<!-- Build android projects only on Windows, where we have installed android workload -->
<!-- Build android and iOS projects only on Windows, where we have installed android workload -->
<ItemGroup Condition="!$([MSBuild]::IsOsPlatform('Windows'))">
<ProjectReference Remove="src/Android/**/*.*proj" />
<ProjectReference Remove="src/iOS/**/*.*proj" />
</ItemGroup>
<ItemGroup>

3
global.json

@ -1,6 +1,7 @@
{
"sdk": {
"version": "6.0.100"
"version": "6.0.200",
"rollForward": "latestFeature"
},
"msbuild-sdks": {
"Microsoft.Build.Traversal": "1.0.43",

10
samples/ControlCatalog.Android/MainActivity.cs

@ -1,18 +1,16 @@
using Android.App;
using Android.OS;
using Android.Content.PM;
using Avalonia;
using Avalonia.Android;
namespace ControlCatalog.Android
{
[Activity(Label = "ControlCatalog.Android", Theme = "@style/MyTheme.NoActionBar", Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleInstance, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)]
public class MainActivity : AvaloniaActivity
public class MainActivity : AvaloniaActivity<App>
{
protected override void OnCreate(Bundle? savedInstanceState)
protected override AppBuilder CustomizeAppBuilder(AppBuilder builder)
{
base.OnCreate(savedInstanceState);
Content = new MainView();
return base.CustomizeAppBuilder(builder);
}
}
}

10
samples/ControlCatalog.Android/SplashActivity.cs

@ -1,9 +1,6 @@
using Android.App;
using Android.Content;
using Android.OS;
using Application = Android.App.Application;
using Avalonia;
namespace ControlCatalog.Android
{
@ -19,13 +16,6 @@ namespace ControlCatalog.Android
{
base.OnResume();
if (Avalonia.Application.Current == null)
{
AppBuilder.Configure<App>()
.UseAndroid()
.SetupWithoutStarting();
}
StartActivity(new Intent(Application.Context, typeof(MainActivity)));
}
}

1
samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj

@ -13,6 +13,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Headless.Vnc\Avalonia.Headless.Vnc.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Dialogs\Avalonia.Dialogs.csproj" />
<ProjectReference Include="..\..\src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj" />

7
samples/ControlCatalog.NetCore/Program.cs

@ -118,6 +118,13 @@ namespace ControlCatalog.NetCore
})
.UseSkia()
.UseManagedSystemDialogs()
.AfterSetup(builder =>
{
builder.Instance!.AttachDevTools(new Avalonia.Diagnostics.DevToolsOptions()
{
StartupScreenIndex = 1,
});
})
.LogToTrace();
static void SilenceConsole()

15
samples/ControlCatalog.iOS.Legacy/AppDelegate.cs

@ -0,0 +1,15 @@
using Avalonia.iOS;
using Foundation;
using UIKit;
namespace ControlCatalog.iOS.Legacy
{
// The UIApplicationDelegate for the application. This class is responsible for launching the
// User Interface of the application, as well as listening (and optionally responding) to
// application events from iOS.
[Register("AppDelegate")]
public partial class AppDelegate : AvaloniaAppDelegate<App>
{
}
}

117
samples/ControlCatalog.iOS.Legacy/Assets.xcassets/AppIcon.appiconset/Contents.json

@ -0,0 +1,117 @@
{
"images": [
{
"scale": "2x",
"size": "20x20",
"idiom": "iphone",
"filename": "Icon40.png"
},
{
"scale": "3x",
"size": "20x20",
"idiom": "iphone",
"filename": "Icon60.png"
},
{
"scale": "2x",
"size": "29x29",
"idiom": "iphone",
"filename": "Icon58.png"
},
{
"scale": "3x",
"size": "29x29",
"idiom": "iphone",
"filename": "Icon87.png"
},
{
"scale": "2x",
"size": "40x40",
"idiom": "iphone",
"filename": "Icon80.png"
},
{
"scale": "3x",
"size": "40x40",
"idiom": "iphone",
"filename": "Icon120.png"
},
{
"scale": "2x",
"size": "60x60",
"idiom": "iphone",
"filename": "Icon120.png"
},
{
"scale": "3x",
"size": "60x60",
"idiom": "iphone",
"filename": "Icon180.png"
},
{
"scale": "1x",
"size": "20x20",
"idiom": "ipad",
"filename": "Icon20.png"
},
{
"scale": "2x",
"size": "20x20",
"idiom": "ipad",
"filename": "Icon40.png"
},
{
"scale": "1x",
"size": "29x29",
"idiom": "ipad",
"filename": "Icon29.png"
},
{
"scale": "2x",
"size": "29x29",
"idiom": "ipad",
"filename": "Icon58.png"
},
{
"scale": "1x",
"size": "40x40",
"idiom": "ipad",
"filename": "Icon40.png"
},
{
"scale": "2x",
"size": "40x40",
"idiom": "ipad",
"filename": "Icon80.png"
},
{
"scale": "1x",
"size": "76x76",
"idiom": "ipad",
"filename": "Icon76.png"
},
{
"scale": "2x",
"size": "76x76",
"idiom": "ipad",
"filename": "Icon152.png"
},
{
"scale": "2x",
"size": "83.5x83.5",
"idiom": "ipad",
"filename": "Icon167.png"
},
{
"scale": "1x",
"size": "1024x1024",
"idiom": "ios-marketing",
"filename": "Icon1024.png"
}
],
"properties": {},
"info": {
"version": 1,
"author": "xcode"
}
}

99
samples/ControlCatalog.iOS.Legacy/ControlCatalog.iOS.Legacy.csproj

@ -0,0 +1,99 @@
<Project Sdk="Xamarin.Legacy.Sdk">
<PropertyGroup>
<TargetFramework>xamarin.ios10</TargetFramework>
<SupportedOSPlatformVersion>15.0</SupportedOSPlatformVersion>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform>
<ProjectGuid>{3AF75F00-B497-4517-9491-922173DE216E}</ProjectGuid>
<ProjectTypeGuids>{FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<OutputType>Exe</OutputType>
<RootNamespace>ControlCatalog.iOS.Legacy</RootNamespace>
<IPhoneResourcePrefix>Resources</IPhoneResourcePrefix>
<AssemblyName>ControlCatalog.iOS.Legacy</AssemblyName>
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
<ProvisioningType>manual</ProvisioningType>
<MtouchInterpreter>-all</MtouchInterpreter>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\iPhoneSimulator\Debug</OutputPath>
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<MtouchArch>x86_64</MtouchArch>
<MtouchLink>None</MtouchLink>
<MtouchDebug>true</MtouchDebug>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\iPhoneSimulator\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<MtouchLink>None</MtouchLink>
<MtouchArch>x86_64</MtouchArch>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\iPhone\Debug</OutputPath>
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<MtouchArch>ARM64</MtouchArch>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<MtouchDebug>true</MtouchDebug>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\iPhone\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<MtouchArch>ARM64</MtouchArch>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<ItemGroup>
<None Include="Info.plist" />
<Content Include="Entitlements.plist" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
<Reference Include="System.Core" />
<Reference Include="Xamarin.iOS" />
</ItemGroup>
<ItemGroup>
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Contents.json">
<Visible>false</Visible>
</ImageAsset>
</ItemGroup>
<ItemGroup>
<Folder Include="Resources\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Avalonia.Controls\Avalonia.Controls.csproj">
<Project>{d2221c82-4a25-4583-9b43-d791e3f6820c}</Project>
<Name>Avalonia.Controls</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\iOS\Avalonia.iOS\Avalonia.iOS.csproj">
<Project>{4488ad85-1495-4809-9aa4-ddfe0a48527e}</Project>
<Name>Avalonia.iOS</Name>
</ProjectReference>
<ProjectReference Include="..\ControlCatalog\ControlCatalog.csproj">
<Project>{d0a739b9-3c68-4ba6-a328-41606954b6bd}</Project>
<Name>ControlCatalog</Name>
</ProjectReference>
</ItemGroup>
<!-- <Import Project="..\..\build\LegacyProject.targets" />-->
<!-- <Import Project="..\..\build\SkiaSharp.props" />-->
<!-- <Import Project="..\..\build\HarfBuzzSharp.props" />-->
</Project>

6
samples/ControlCatalog.iOS.Legacy/Entitlements.plist

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
</dict>
</plist>

47
samples/ControlCatalog.iOS.Legacy/Info.plist

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDisplayName</key>
<string>ControlCatalog</string>
<key>CFBundleIdentifier</key>
<string>com.companyname.ControlCatalog.iOS</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>MinimumOSVersion</key>
<string>15.0</string>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer><integer>2</integer>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>XSAppIconAssets</key>
<string>Assets.xcassets/AppIcon.appiconset</string>
<key>UIStatusBarHidden</key>
<true/>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
</dict>
</plist>

15
samples/ControlCatalog.iOS.Legacy/Main.cs

@ -0,0 +1,15 @@
using UIKit;
namespace ControlCatalog.iOS.Legacy
{
public class Application
{
// This is the main entry point of the application.
static void Main(string[] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main(args, null, "AppDelegate");
}
}
}

43
samples/ControlCatalog.iOS.Legacy/Resources/LaunchScreen.xib

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6214" systemVersion="14A314h" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6207" />
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1" />
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" />
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder" />
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="480" height="480" />
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" />
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright (c) 2022 " textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines"
minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
<rect key="frame" x="20" y="439" width="441" height="21" />
<fontDescription key="fontDescription" type="system" pointSize="17" />
<color key="textColor" cocoaTouchSystemColor="darkTextColor" />
<nil key="highlightedColor" />
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="ControlCatalog.iOS.Legacy" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines"
minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
<rect key="frame" x="20" y="140" width="441" height="43" />
<fontDescription key="fontDescription" type="boldSystem" pointSize="36" />
<color key="textColor" cocoaTouchSystemColor="darkTextColor" />
<nil key="highlightedColor" />
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite" />
<constraints>
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC" />
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk" />
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l" />
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0" />
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9" />
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g" />
</constraints>
<nil key="simulatedStatusBarMetrics" />
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics" />
<point key="canvasLocation" x="548" y="455" />
</view>
</objects>
</document>

190
samples/ControlCatalog.iOS/ControlCatalog.iOS.csproj

@ -1,186 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform>
<ProjectGuid>{57E0455D-D565-44BB-B069-EE1AA20F8337}</ProjectGuid>
<ProjectTypeGuids>{FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<OutputType>Exe</OutputType>
<RootNamespace>ControlCatalog.iOS</RootNamespace>
<IPhoneResourcePrefix>Resources</IPhoneResourcePrefix>
<AssemblyName>ControlCatalogiOS</AssemblyName>
<MtouchEnableSGenConc>true</MtouchEnableSGenConc>
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
<ProvisioningType>automatic</ProvisioningType>
<ProvisioningType>manual</ProvisioningType>
<TargetFramework>net6.0-ios</TargetFramework>
<SupportedOSPlatformVersion>10.0</SupportedOSPlatformVersion>
<!-- temporal workaround for our GL interface backend -->
<UseInterpreter>True</UseInterpreter>
<RuntimeIdentifier>iossimulator-x64</RuntimeIdentifier>
<!-- <RuntimeIdentifier>ios-arm64</RuntimeIdentifier>-->
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\iPhoneSimulator\Debug</OutputPath>
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<MtouchArch>x86_64</MtouchArch>
<MtouchLink>None</MtouchLink>
<MtouchDebug>True</MtouchDebug>
<MtouchSdkVersion>9.1</MtouchSdkVersion>
<MtouchProfiling>False</MtouchProfiling>
<MtouchFastDev>False</MtouchFastDev>
<MtouchNoSymbolStrip>False</MtouchNoSymbolStrip>
<MtouchUseLlvm>False</MtouchUseLlvm>
<MtouchUseThumb>False</MtouchUseThumb>
<MtouchEnableBitcode>False</MtouchEnableBitcode>
<MtouchUseSGen>False</MtouchUseSGen>
<MtouchUseRefCounting>False</MtouchUseRefCounting>
<OptimizePNGs>True</OptimizePNGs>
<MtouchTlsProvider>Default</MtouchTlsProvider>
<MtouchHttpClientHandler>HttpClientHandler</MtouchHttpClientHandler>
<MtouchFloat32>False</MtouchFloat32>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\iPhoneSimulator\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<MtouchLink>None</MtouchLink>
<MtouchArch>x86_64</MtouchArch>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\iPhone\Debug</OutputPath>
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<MtouchArch>ARMv7, ARM64</MtouchArch>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchDebug>true</MtouchDebug>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\iPhone\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<MtouchArch>ARMv7, ARM64</MtouchArch>
<ConsolePause>false</ConsolePause>
<CodesignKey>iPhone Developer</CodesignKey>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Ad-Hoc|iPhone' ">
<DebugType>none</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\iPhone\Ad-Hoc</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>False</ConsolePause>
<MtouchArch>ARMv7, ARM64</MtouchArch>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<BuildIpa>True</BuildIpa>
<CodesignProvision>Automatic:AdHoc</CodesignProvision>
<CodesignKey>iPhone Distribution</CodesignKey>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'AppStore|iPhone' ">
<DebugType>none</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\iPhone\AppStore</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>False</ConsolePause>
<MtouchArch>ARMv7, ARM64</MtouchArch>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<CodesignProvision>Automatic:AppStore</CodesignProvision>
<CodesignKey>iPhone Distribution</CodesignKey>
</PropertyGroup>
<ItemGroup>
<Compile Include="Main.cs" />
<Compile Include="AppDelegate.cs" />
<None Include="Info.plist" />
<Compile Include="Properties\AssemblyInfo.cs" />
<InterfaceDefinition Include="Resources\LaunchScreen.xib" />
<Content Include="Entitlements.plist" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
<Reference Include="System.Core" />
<Reference Include="Xamarin.iOS" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\iOS\Avalonia.iOS\Avalonia.iOS.csproj">
<Project>{4488AD85-1495-4809-9AA4-DDFE0A48527E}</Project>
<Name>Avalonia.iOS</Name>
<IsAppExtension>false</IsAppExtension>
<IsWatchApp>false</IsWatchApp>
</ProjectReference>
<ProjectReference Include="..\..\src\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj">
<Project>{3E53A01A-B331-47F3-B828-4A5717E77A24}</Project>
<Name>Avalonia.Markup.Xaml</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Markup\Avalonia.Markup\Avalonia.Markup.csproj">
<Project>{6417E941-21BC-467B-A771-0DE389353CE6}</Project>
<Name>Avalonia.Markup</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Animation\Avalonia.Animation.csproj">
<Project>{D211E587-D8BC-45B9-95A4-F297C8FA5200}</Project>
<Name>Avalonia.Animation</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Base\Avalonia.Base.csproj">
<Project>{B09B78D8-9B26-48B0-9149-D64A2F120F3F}</Project>
<Name>Avalonia.Base</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Controls\Avalonia.Controls.csproj">
<Project>{D2221C82-4A25-4583-9B43-D791E3F6820C}</Project>
<Name>Avalonia.Controls</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj">
<Project>{7062AE20-5DCC-4442-9645-8195BDECE63E}</Project>
<Name>Avalonia.Diagnostics</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Input\Avalonia.Input.csproj">
<Project>{62024B2D-53EB-4638-B26B-85EEAA54866E}</Project>
<Name>Avalonia.Input</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Interactivity\Avalonia.Interactivity.csproj">
<Project>{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}</Project>
<Name>Avalonia.Interactivity</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Layout\Avalonia.Layout.csproj">
<Project>{42472427-4774-4C81-8AFF-9F27B8E31721}</Project>
<Name>Avalonia.Layout</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Visuals\Avalonia.Visuals.csproj">
<Project>{EB582467-6ABB-43A1-B052-E981BA910E3A}</Project>
<Name>Avalonia.Visuals</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Styling\Avalonia.Styling.csproj">
<Project>{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}</Project>
<Name>Avalonia.Styling</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj">
<Project>{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}</Project>
<Name>Avalonia.Themes.Default</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Skia\Avalonia.Skia\Avalonia.Skia.csproj">
<Project>{7d2d3083-71dd-4cc9-8907-39a0d86fb322}</Project>
<Name>Avalonia.Skia</Name>
</ProjectReference>
<ProjectReference Include="..\ControlCatalog\ControlCatalog.csproj">
<Project>{d0a739b9-3c68-4ba6-a328-41606954b6bd}</Project>
<Name>ControlCatalog</Name>
</ProjectReference>
<PackageReference Include="SkiaSharp.HarfBuzz" Version="2.80.2-preview.33" />
<ProjectReference Include="..\..\src\iOS\Avalonia.iOS\Avalonia.iOS.csproj" />
<ProjectReference Include="..\ControlCatalog\ControlCatalog.csproj" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
<Import Project="..\..\build\LegacyProject.targets" />
<Import Project="..\..\build\SkiaSharp.props" />
<Import Project="..\..\build\HarfBuzzSharp.props" />
</Project>

7
samples/ControlCatalog.iOS/Info.plist

@ -13,7 +13,7 @@
<key>LSRequiresIPhoneOS</key>
<true/>
<key>MinimumOSVersion</key>
<string>8.0</string>
<string>10.0</string>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>
@ -28,6 +28,7 @@
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
@ -38,5 +39,9 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIStatusBarHidden</key>
<true/>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
</dict>
</plist>

4
samples/ControlCatalog.iOS/Main.cs

@ -9,7 +9,7 @@ namespace ControlCatalog.iOS
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main(args, null, "AppDelegate");
UIApplication.Main(args, null, typeof(AppDelegate));
}
}
}
}

36
samples/ControlCatalog.iOS/Properties/AssemblyInfo.cs

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

2
samples/ControlCatalog.iOS/Resources/LaunchScreen.xib

@ -11,7 +11,7 @@
<rect key="frame" x="0.0" y="0.0" width="480" height="480" />
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" />
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright (c) 2016 " textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines"
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright (c) 2022 " textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines"
minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
<rect key="frame" x="20" y="439" width="441" height="21" />
<fontDescription key="fontDescription" type="system" pointSize="17" />

5
samples/ControlCatalog/App.xaml.cs

@ -78,11 +78,6 @@ namespace ControlCatalog
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktopLifetime)
{
desktopLifetime.MainWindow = new MainWindow();
this.AttachDevTools(new Avalonia.Diagnostics.DevToolsOptions()
{
StartupScreenIndex = 1,
});
}
else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewLifetime)
{

1
samples/ControlCatalog/ControlCatalog.csproj

@ -23,7 +23,6 @@
<ItemGroup>
<ProjectReference Include="..\..\packages\Avalonia\Avalonia.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Controls.DataGrid\Avalonia.Controls.DataGrid.csproj" />
<ProjectReference Include="..\MiniMvvm\MiniMvvm.csproj" />
<ProjectReference Include="..\SampleControls\ControlSamples.csproj" />

1
samples/interop/WindowsInteropTest/WindowsInteropTest.csproj

@ -8,6 +8,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" />
<ProjectReference Include="..\..\..\src\Windows\Avalonia.Win32.Interop\Avalonia.Win32.Interop.csproj" />
<ProjectReference Include="..\..\ControlCatalog\ControlCatalog.csproj">
<Project>{d0a739b9-3c68-4ba6-a328-41606954b6bd}</Project>

5
src/Android/Avalonia.Android/AndroidPlatform.cs

@ -1,9 +1,9 @@
using System;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Android;
using Avalonia.Android.Platform;
using Avalonia.Android.Platform.Input;
using Avalonia.Controls;
using Avalonia.Controls.Platform;
using Avalonia.Input;
using Avalonia.Input.Platform;
@ -19,6 +19,7 @@ namespace Avalonia
public static T UseAndroid<T>(this T builder) where T : AppBuilderBase<T>, new()
{
var options = AvaloniaLocator.Current.GetService<AndroidPlatformOptions>() ?? new AndroidPlatformOptions();
return builder
.UseWindowingSubsystem(() => AndroidPlatform.Initialize(options), "Android")
.UseSkia();

3
src/Android/Avalonia.Android/Avalonia.Android.csproj

@ -1,6 +1,7 @@
<Project Sdk="Xamarin.Legacy.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0-android;monoandroid11.0</TargetFrameworks>
<TargetFrameworks>net6.0-android</TargetFrameworks>
<TargetFrameworks Condition="'$(MSBuildRuntimeType)' != 'Core'">$(TargetFrameworks);monoandroid11.0</TargetFrameworks>
<SupportedOSPlatformVersion>21</SupportedOSPlatformVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<MSBuildEnableWorkloadResolver>true</MSBuildEnableWorkloadResolver>

43
src/Android/Avalonia.Android/AvaloniaActivity.cs

@ -1,28 +1,55 @@
using Android.App;
using Android.OS;
using Android.Views;
using Android.Content.PM;
using AndroidX.AppCompat.App;
using Android.Content.Res;
using AndroidX.Lifecycle;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Controls;
namespace Avalonia.Android
{
public abstract class AvaloniaActivity : AppCompatActivity
public abstract class AvaloniaActivity<TApp> : AppCompatActivity where TApp : Application, new()
{
internal class SingleViewLifetime : ISingleViewApplicationLifetime
{
public AvaloniaView View { get; internal set; }
public Control MainView
{
get => (Control)View.Content;
set => View.Content = value;
}
}
internal AvaloniaView View;
internal AvaloniaViewModel _viewModel;
protected virtual AppBuilder CustomizeAppBuilder(AppBuilder builder) => builder.UseAndroid();
protected override void OnCreate(Bundle savedInstanceState)
{
var builder = AppBuilder.Configure<TApp>();
CustomizeAppBuilder(builder);
View = new AvaloniaView(this);
SetContentView(View);
_viewModel = new ViewModelProvider(this).Get(Java.Lang.Class.FromType(typeof(AvaloniaViewModel))) as AvaloniaViewModel;
var lifetime = new SingleViewLifetime();
lifetime.View = View;
if (_viewModel.Content != null)
builder.AfterSetup(x =>
{
View.Content = _viewModel.Content;
}
_viewModel = new ViewModelProvider(this).Get(Java.Lang.Class.FromType(typeof(AvaloniaViewModel))) as AvaloniaViewModel;
if (_viewModel.Content != null)
{
View.Content = _viewModel.Content;
}
View.Prepare();
});
builder.SetupWithLifetime(lifetime);
base.OnCreate(savedInstanceState);
}

7
src/Android/Avalonia.Android/AvaloniaView.cs

@ -12,7 +12,7 @@ namespace Avalonia.Android
{
public class AvaloniaView : FrameLayout
{
private readonly EmbeddableControlRoot _root;
private EmbeddableControlRoot _root;
private readonly ViewImpl _view;
private IDisposable? _timerSubscription;
@ -21,6 +21,11 @@ namespace Avalonia.Android
{
_view = new ViewImpl(context);
AddView(_view.View);
}
internal void Prepare ()
{
_root = new EmbeddableControlRoot(_view);
_root.Prepare();
}

18
src/Avalonia.Controls/Presenters/TextPresenter.cs

@ -394,10 +394,14 @@ namespace Avalonia.Controls.Presenters
var x = Math.Floor(_caretBounds.X) + 0.5;
var y = Math.Floor(_caretBounds.Y) + 0.5;
var b = Math.Ceiling(_caretBounds.Bottom) - 0.5;
var caretIndex = _lastCharacterHit.FirstCharacterIndex + _lastCharacterHit.TrailingLength;
var lineIndex = TextLayout.GetLineIndexFromCharacterIndex(caretIndex, _lastCharacterHit.TrailingLength > 0);
var textLine = TextLayout.TextLines[lineIndex];
if (x >= Bounds.Width)
if (_caretBounds.X > 0 && _caretBounds.X >= textLine.WidthIncludingTrailingWhitespace)
{
x = Math.Floor(_caretBounds.X - 1) + 0.5;
x -= 1;
}
return (new Point(x, y), new Point(x, b));
@ -468,8 +472,8 @@ namespace Avalonia.Controls.Presenters
var typeface = new Typeface(FontFamily, FontStyle, FontWeight);
var selectionStart = SelectionStart;
var selectionEnd = SelectionEnd;
var selectionStart = CoerceCaretIndex(SelectionStart);
var selectionEnd = CoerceCaretIndex(SelectionEnd);
var start = Math.Min(selectionStart, selectionEnd);
var length = Math.Max(selectionStart, selectionEnd) - start;
@ -512,11 +516,9 @@ namespace Avalonia.Controls.Presenters
_textLayout = null;
InvalidateArrange();
var scale = LayoutHelper.GetLayoutScale(this);
var measuredSize = PixelSize.FromSize(TextLayout.Bounds.Size, scale);
var measuredSize = PixelSize.FromSize(TextLayout.Bounds.Size, 1);
return new Size(measuredSize.Width, measuredSize.Height);
}

4
src/Avalonia.Controls/TextBlock.cs

@ -549,10 +549,8 @@ namespace Avalonia.Controls
_textLayout = null;
InvalidateArrange();
var scale = LayoutHelper.GetLayoutScale(this);
var measuredSize = PixelSize.FromSize(TextLayout.Bounds.Size, scale);
var measuredSize = PixelSize.FromSize(TextLayout.Bounds.Size, 1);
return new Size(measuredSize.Width, measuredSize.Height).Inflate(padding);
}

135
src/Avalonia.Controls/TextBox.cs

@ -257,6 +257,8 @@ namespace Avalonia.Controls
UndoRedoState state;
if (IsUndoEnabled && _undoRedoHelper.TryGetLastState(out state) && state.Text == Text)
_undoRedoHelper.UpdateLastState();
SelectionStart = SelectionEnd = value;
}
}
@ -301,14 +303,15 @@ namespace Avalonia.Controls
{
value = CoerceCaretIndex(value);
var changed = SetAndRaise(SelectionStartProperty, ref _selectionStart, value);
if (changed)
{
UpdateCommandStates();
}
if (value == SelectionEnd)
if (SelectionEnd == value && CaretIndex != value)
{
CaretIndex = SelectionStart;
CaretIndex = value;
}
}
}
@ -329,8 +332,8 @@ namespace Avalonia.Controls
{
UpdateCommandStates();
}
if (value == SelectionStart)
if (SelectionStart == value && CaretIndex != value)
{
CaretIndex = value;
}
@ -352,10 +355,12 @@ namespace Avalonia.Controls
if (!_ignoreTextChanges)
{
var caretIndex = CaretIndex;
var selectionStart = SelectionStart;
var selectionEnd = SelectionEnd;
SelectionStart = CoerceCaretIndex(SelectionStart, value);
SelectionEnd = CoerceCaretIndex(SelectionEnd, value);
CaretIndex = CoerceCaretIndex(caretIndex, value);
SelectionStart = CoerceCaretIndex(selectionStart, value);
SelectionEnd = CoerceCaretIndex(selectionEnd, value);
if (SetAndRaise(TextProperty, ref _text, value) && IsUndoEnabled && !_isUndoingRedoing)
{
@ -458,7 +463,7 @@ namespace Avalonia.Controls
/// </summary>
public void ClearSelection()
{
SelectionStart = SelectionEnd = CaretIndex;
CaretIndex = SelectionStart;
}
/// <summary>
@ -856,6 +861,7 @@ namespace Avalonia.Controls
movement = true;
selection = false;
handled = true;
CaretIndex = _presenter.CaretIndex;
}
else if (Match(keymap.MoveCursorToTheEndOfDocument))
{
@ -863,6 +869,7 @@ namespace Avalonia.Controls
movement = true;
selection = false;
handled = true;
CaretIndex = _presenter.CaretIndex;
}
else if (Match(keymap.MoveCursorToTheStartOfLine))
{
@ -870,7 +877,7 @@ namespace Avalonia.Controls
movement = true;
selection = false;
handled = true;
CaretIndex = _presenter.CaretIndex;
}
else if (Match(keymap.MoveCursorToTheEndOfLine))
{
@ -878,6 +885,7 @@ namespace Avalonia.Controls
movement = true;
selection = false;
handled = true;
CaretIndex = _presenter.CaretIndex;
}
else if (Match(keymap.MoveCursorToTheStartOfDocumentWithSelection))
{
@ -950,7 +958,7 @@ namespace Avalonia.Controls
}
else
{
SelectionStart = SelectionEnd = _presenter.CaretIndex;
CaretIndex = _presenter.CaretIndex;
}
break;
@ -972,7 +980,7 @@ namespace Avalonia.Controls
}
else
{
SelectionStart = SelectionEnd = _presenter.CaretIndex;
CaretIndex = _presenter.CaretIndex;
}
break;
@ -996,6 +1004,8 @@ namespace Avalonia.Controls
SetTextInternal(text.Substring(0, length) +
text.Substring(caretIndex));
CaretIndex = _presenter.CaretIndex;
}
SnapshotUndoRedo();
@ -1070,8 +1080,6 @@ namespace Avalonia.Controls
{
e.Handled = true;
}
CaretIndex = _presenter.CaretIndex;
}
protected override void OnPointerPressed(PointerPressedEventArgs e)
@ -1240,6 +1248,7 @@ namespace Avalonia.Controls
{
var text = Text ?? string.Empty;
var selectionStart = SelectionStart;
var selectionEnd = SelectionEnd;
if (!wholeWord)
{
@ -1248,15 +1257,32 @@ namespace Avalonia.Controls
return;
}
_presenter.MoveCaretHorizontal(direction > 0 ? LogicalDirection.Forward : LogicalDirection.Backward);
if (isSelecting)
{
_presenter.MoveCaretToTextPosition(selectionEnd);
_presenter.MoveCaretHorizontal(direction > 0 ?
LogicalDirection.Forward :
LogicalDirection.Backward);
SelectionEnd = _presenter.CaretIndex;
}
else
{
SelectionStart = SelectionEnd = _presenter.CaretIndex;
if (selectionStart != selectionEnd)
{
_presenter.MoveCaretToTextPosition(direction > 0 ?
Math.Max(selectionStart, selectionEnd) :
Math.Min(selectionStart, selectionEnd));
}
else
{
_presenter.MoveCaretHorizontal(direction > 0 ?
LogicalDirection.Forward :
LogicalDirection.Backward);
}
CaretIndex = _presenter.CaretIndex;
}
}
else
@ -1265,14 +1291,19 @@ namespace Avalonia.Controls
if (direction > 0)
{
offset = StringUtils.NextWord(text, selectionStart) - selectionStart;
offset = StringUtils.NextWord(text, selectionEnd) - selectionEnd;
}
else
{
offset = StringUtils.PreviousWord(text, selectionStart) - selectionStart;
offset = StringUtils.PreviousWord(text, selectionEnd) - selectionEnd;
}
SelectionEnd = CaretIndex + offset;
SelectionEnd += offset;
if (!isSelecting)
{
CaretIndex = SelectionEnd;
}
}
}
@ -1316,10 +1347,18 @@ namespace Avalonia.Controls
else
{
var textLines = _presenter.TextLayout.TextLines;
var lineIndex = _presenter.TextLayout.GetLineIndexFromCharacterIndex(caretIndex, false);
var lineIndex = _presenter.TextLayout.GetLineIndexFromCharacterIndex(caretIndex, true);
var textLine = textLines[lineIndex];
if (caretIndex == textLine.TextRange.Start + textLine.TextRange.Length - textLine.NewLineLength &&
lineIndex + 1 < textLines.Count)
{
textLine = textLines[++lineIndex];
}
var textPosition = textLine.TextRange.Start + textLine.TextRange.Length - textLine.NewLineLength;
_presenter.MoveCaretToTextPosition(textLine.TextRange.Start + textLine.TextRange.Length, true);
_presenter.MoveCaretToTextPosition(textPosition, true);
}
}
@ -1330,50 +1369,56 @@ namespace Avalonia.Controls
{
SelectionStart = 0;
SelectionEnd = Text?.Length ?? 0;
CaretIndex = SelectionEnd;
}
private bool DeleteSelection(bool raiseTextChanged = true)
{
if (!IsReadOnly)
{
var selectionStart = SelectionStart;
var selectionEnd = SelectionEnd;
if (IsReadOnly) return true;
var selectionStart = SelectionStart;
var selectionEnd = SelectionEnd;
if (selectionStart != selectionEnd)
{
var start = Math.Min(selectionStart, selectionEnd);
var end = Math.Max(selectionStart, selectionEnd);
var text = Text!;
SetTextInternal(text.Substring(0, start) + text.Substring(end), raiseTextChanged);
CaretIndex = start;
ClearSelection();
return true;
}
else
{
return false;
}
}
else
if (selectionStart != selectionEnd)
{
var start = Math.Min(selectionStart, selectionEnd);
var end = Math.Max(selectionStart, selectionEnd);
var text = Text!;
SetTextInternal(text.Substring(0, start) + text.Substring(end), raiseTextChanged);
_presenter?.MoveCaretToTextPosition(start);
CaretIndex= start;
ClearSelection();
return true;
}
CaretIndex = SelectionStart;
return false;
}
private string GetSelection()
{
var text = Text;
if (string.IsNullOrEmpty(text))
{
return "";
}
var selectionStart = SelectionStart;
var selectionEnd = SelectionEnd;
var start = Math.Min(selectionStart, selectionEnd);
var end = Math.Max(selectionStart, selectionEnd);
if (start == end || (Text?.Length ?? 0) < end)
{
return "";
}
return text.Substring(start, end - start);
}
@ -1399,9 +1444,11 @@ namespace Avalonia.Controls
private void SetSelectionForControlBackspace()
{
SelectionStart = CaretIndex;
var selectionStart = CaretIndex;
MoveHorizontal(-1, true, false);
SelectionStart = selectionStart;
}
private void SetSelectionForControlDelete()
@ -1413,7 +1460,7 @@ namespace Avalonia.Controls
SelectionStart = CaretIndex;
MoveHorizontal(1, true, false);
MoveHorizontal(1, true, true);
if (SelectionEnd < _text.Length && _text[SelectionEnd] == ' ')
{

46
src/Avalonia.OpenGL/Egl/EglInterface.cs

@ -46,93 +46,114 @@ namespace Avalonia.OpenGL.Egl
}
// ReSharper disable UnassignedGetOnlyAutoProperty
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate int EglGetError();
[GlEntryPoint("eglGetError")]
public EglGetError GetError { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate IntPtr EglGetDisplay(IntPtr nativeDisplay);
[GlEntryPoint("eglGetDisplay")]
public EglGetDisplay GetDisplay { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate IntPtr EglGetPlatformDisplayEXT(int platform, IntPtr nativeDisplay, int[] attrs);
[GlEntryPoint("eglGetPlatformDisplayEXT")]
[GlOptionalEntryPoint]
public EglGetPlatformDisplayEXT GetPlatformDisplayEXT { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate bool EglInitialize(IntPtr display, out int major, out int minor);
[GlEntryPoint("eglInitialize")]
public EglInitialize Initialize { get; }
public EglInitialize Initialize { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate IntPtr EglGetProcAddress(Utf8Buffer proc);
[GlEntryPoint("eglGetProcAddress")]
public EglGetProcAddress GetProcAddress { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate bool EglBindApi(int api);
[GlEntryPoint("eglBindAPI")]
public EglBindApi BindApi { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate bool EglChooseConfig(IntPtr display, int[] attribs,
out IntPtr surfaceConfig, int numConfigs, out int choosenConfig);
[GlEntryPoint("eglChooseConfig")]
public EglChooseConfig ChooseConfig { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate IntPtr EglCreateContext(IntPtr display, IntPtr config,
IntPtr share, int[] attrs);
[GlEntryPoint("eglCreateContext")]
public EglCreateContext CreateContext { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate bool EglDestroyContext(IntPtr display, IntPtr context);
[GlEntryPoint("eglDestroyContext")]
public EglDestroyContext DestroyContext { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate IntPtr EglCreatePBufferSurface(IntPtr display, IntPtr config, int[] attrs);
[GlEntryPoint("eglCreatePbufferSurface")]
public EglCreatePBufferSurface CreatePBufferSurface { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate bool EglMakeCurrent(IntPtr display, IntPtr draw, IntPtr read, IntPtr context);
[GlEntryPoint("eglMakeCurrent")]
public EglMakeCurrent MakeCurrent { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate IntPtr EglGetCurrentContext();
[GlEntryPoint("eglGetCurrentContext")]
public EglGetCurrentContext GetCurrentContext { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate IntPtr EglGetCurrentDisplay();
[GlEntryPoint("eglGetCurrentDisplay")]
public EglGetCurrentContext GetCurrentDisplay { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate IntPtr EglGetCurrentSurface(int readDraw);
[GlEntryPoint("eglGetCurrentSurface")]
public EglGetCurrentSurface GetCurrentSurface { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void EglDisplaySurfaceVoidDelegate(IntPtr display, IntPtr surface);
[GlEntryPoint("eglDestroySurface")]
public EglDisplaySurfaceVoidDelegate DestroySurface { get; }
[GlEntryPoint("eglSwapBuffers")]
public EglDisplaySurfaceVoidDelegate SwapBuffers { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate IntPtr
EglCreateWindowSurface(IntPtr display, IntPtr config, IntPtr window, int[] attrs);
[GlEntryPoint("eglCreateWindowSurface")]
public EglCreateWindowSurface CreateWindowSurface { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate bool EglGetConfigAttrib(IntPtr display, IntPtr config, int attr, out int rv);
[GlEntryPoint("eglGetConfigAttrib")]
public EglGetConfigAttrib GetConfigAttrib { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate bool EglWaitGL();
[GlEntryPoint("eglWaitGL")]
public EglWaitGL WaitGL { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate bool EglWaitClient();
[GlEntryPoint("eglWaitClient")]
public EglWaitGL WaitClient { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate bool EglWaitNative(int engine);
[GlEntryPoint("eglWaitNative")]
public EglWaitNative WaitNative { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate IntPtr EglQueryString(IntPtr display, int i);
[GlEntryPoint("eglQueryString")]
@ -145,17 +166,20 @@ namespace Avalonia.OpenGL.Egl
return null;
return Marshal.PtrToStringAnsi(rv);
}
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate IntPtr EglCreatePbufferFromClientBuffer(IntPtr display, int buftype, IntPtr buffer, IntPtr config, int[] attrib_list);
[GlEntryPoint("eglCreatePbufferFromClientBuffer")]
public EglCreatePbufferFromClientBuffer CreatePbufferFromClientBuffer { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate bool EglQueryDisplayAttribEXT(IntPtr display, int attr, out IntPtr res);
[GlEntryPoint("eglQueryDisplayAttribEXT"), GlOptionalEntryPoint]
public EglQueryDisplayAttribEXT QueryDisplayAttribExt { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate bool EglQueryDeviceAttribEXT(IntPtr display, int attr, out IntPtr res);
[GlEntryPoint("eglQueryDeviceAttribEXT"), GlOptionalEntryPoint]

5
src/Avalonia.OpenGL/GlBasicInfoInterface.cs

@ -15,9 +15,12 @@ namespace Avalonia.OpenGL
public GlBasicInfoInterface(Func<Utf8Buffer, IntPtr> nativeGetProcAddress) : base(nativeGetProcAddress, null)
{
}
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlGetIntegerv(int name, out int rv);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate IntPtr GlGetString(int v);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate IntPtr GlGetStringi(int v, int v1);
}

112
src/Avalonia.OpenGL/GlInterface.cs

@ -60,32 +60,41 @@ namespace Avalonia.OpenGL
public T GetProcAddress<T>(string proc) => Marshal.GetDelegateForFunctionPointer<T>(GetProcAddress(proc));
// ReSharper disable UnassignedGetOnlyAutoProperty
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate int GlGetError();
[GlEntryPoint("glGetError")]
public GlGetError GetError { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlClearStencil(int s);
[GlEntryPoint("glClearStencil")]
public GlClearStencil ClearStencil { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlClearColor(float r, float g, float b, float a);
[GlEntryPoint("glClearColor")]
public GlClearColor ClearColor { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlClear(int bits);
[GlEntryPoint("glClear")]
public GlClear Clear { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlViewport(int x, int y, int width, int height);
[GlEntryPoint("glViewport")]
public GlViewport Viewport { get; }
[GlEntryPoint("glFlush")]
public Action Flush { get; }
public UnmanagedAction Flush { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void UnmanagedAction();
[GlEntryPoint("glFinish")]
public Action Finish { get; }
public UnmanagedAction Finish { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate IntPtr GlGetString(int v);
[GlEntryPoint("glGetString")]
public GlGetString GetStringNative { get; }
@ -98,26 +107,32 @@ namespace Avalonia.OpenGL
return null;
}
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlGetIntegerv(int name, out int rv);
[GlEntryPoint("glGetIntegerv")]
public GlGetIntegerv GetIntegerv { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlGenFramebuffers(int count, int[] res);
[GlEntryPoint("glGenFramebuffers")]
public GlGenFramebuffers GenFramebuffers { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlDeleteFramebuffers(int count, int[] framebuffers);
[GlEntryPoint("glDeleteFramebuffers")]
public GlDeleteFramebuffers DeleteFramebuffers { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlBindFramebuffer(int target, int fb);
[GlEntryPoint("glBindFramebuffer")]
public GlBindFramebuffer BindFramebuffer { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate int GlCheckFramebufferStatus(int target);
[GlEntryPoint("glCheckFramebufferStatus")]
public GlCheckFramebufferStatus CheckFramebufferStatus { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlBlitFramebuffer(int srcX0,
int srcY0,
int srcX1,
@ -130,69 +145,84 @@ namespace Avalonia.OpenGL
int filter);
[GlMinVersionEntryPoint("glBlitFramebuffer", 3, 0), GlOptionalEntryPoint]
public GlBlitFramebuffer BlitFramebuffer { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlGenRenderbuffers(int count, int[] res);
[GlEntryPoint("glGenRenderbuffers")]
public GlGenRenderbuffers GenRenderbuffers { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlDeleteRenderbuffers(int count, int[] renderbuffers);
[GlEntryPoint("glDeleteRenderbuffers")]
public GlDeleteTextures DeleteRenderbuffers { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlBindRenderbuffer(int target, int fb);
[GlEntryPoint("glBindRenderbuffer")]
public GlBindRenderbuffer BindRenderbuffer { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlRenderbufferStorage(int target, int internalFormat, int width, int height);
[GlEntryPoint("glRenderbufferStorage")]
public GlRenderbufferStorage RenderbufferStorage { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlFramebufferRenderbuffer(int target, int attachment,
int renderbufferTarget, int renderbuffer);
[GlEntryPoint("glFramebufferRenderbuffer")]
public GlFramebufferRenderbuffer FramebufferRenderbuffer { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlGenTextures(int count, int[] res);
[GlEntryPoint("glGenTextures")]
public GlGenTextures GenTextures { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlBindTexture(int target, int fb);
[GlEntryPoint("glBindTexture")]
public GlBindTexture BindTexture { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlActiveTexture(int texture);
[GlEntryPoint("glActiveTexture")]
public GlActiveTexture ActiveTexture { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlDeleteTextures(int count, int[] textures);
[GlEntryPoint("glDeleteTextures")]
public GlDeleteTextures DeleteTextures { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlTexImage2D(int target, int level, int internalFormat, int width, int height, int border,
int format, int type, IntPtr data);
[GlEntryPoint("glTexImage2D")]
public GlTexImage2D TexImage2D { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlCopyTexSubImage2D(int target, int level, int xoffset, int yoffset, int x, int y,
int width, int height);
[GlEntryPoint("glCopyTexSubImage2D")]
public GlCopyTexSubImage2D CopyTexSubImage2D { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlTexParameteri(int target, int name, int value);
[GlEntryPoint("glTexParameteri")]
public GlTexParameteri TexParameteri { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlFramebufferTexture2D(int target, int attachment,
int texTarget, int texture, int level);
[GlEntryPoint("glFramebufferTexture2D")]
public GlFramebufferTexture2D FramebufferTexture2D { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate int GlCreateShader(int shaderType);
[GlEntryPoint("glCreateShader")]
public GlCreateShader CreateShader { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlShaderSource(int shader, int count, IntPtr strings, IntPtr lengths);
[GlEntryPoint("glShaderSource")]
public GlShaderSource ShaderSource { get; }
@ -207,14 +237,17 @@ namespace Avalonia.OpenGL
}
}
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlCompileShader(int shader);
[GlEntryPoint("glCompileShader")]
public GlCompileShader CompileShader { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlGetShaderiv(int shader, int name, int* parameters);
[GlEntryPoint("glGetShaderiv")]
public GlGetShaderiv GetShaderiv { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlGetShaderInfoLog(int shader, int maxLength, out int length, void*infoLog);
[GlEntryPoint("glGetShaderInfoLog")]
public GlGetShaderInfoLog GetShaderInfoLog { get; }
@ -237,23 +270,28 @@ namespace Avalonia.OpenGL
GetShaderInfoLog(shader, logLength, out len, ptr);
return Encoding.UTF8.GetString(logData,0, len);
}
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate int GlCreateProgram();
[GlEntryPoint("glCreateProgram")]
public GlCreateProgram CreateProgram { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlAttachShader(int program, int shader);
[GlEntryPoint("glAttachShader")]
public GlAttachShader AttachShader { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlLinkProgram(int program);
[GlEntryPoint("glLinkProgram")]
public GlLinkProgram LinkProgram { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlGetProgramiv(int program, int name, int* parameters);
[GlEntryPoint("glGetProgramiv")]
public GlGetProgramiv GetProgramiv { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlGetProgramInfoLog(int program, int maxLength, out int len, void* infoLog);
[GlEntryPoint("glGetProgramInfoLog")]
public GlGetProgramInfoLog GetProgramInfoLog { get; }
@ -274,6 +312,7 @@ namespace Avalonia.OpenGL
return Encoding.UTF8.GetString(logData,0, len);
}
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlBindAttribLocation(int program, int index, IntPtr name);
[GlEntryPoint("glBindAttribLocation")]
public GlBindAttribLocation BindAttribLocation { get; }
@ -283,7 +322,8 @@ namespace Avalonia.OpenGL
using (var b = new Utf8Buffer(name))
BindAttribLocation(program, index, b.DangerousGetHandle());
}
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlGenBuffers(int len, int[] rv);
[GlEntryPoint("glGenBuffers")]
public GlGenBuffers GenBuffers { get; }
@ -294,15 +334,18 @@ namespace Avalonia.OpenGL
GenBuffers(1, rv);
return rv[0];
}
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlBindBuffer(int target, int buffer);
[GlEntryPoint("glBindBuffer")]
public GlBindBuffer BindBuffer { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlBufferData(int target, IntPtr size, IntPtr data, int usage);
[GlEntryPoint("glBufferData")]
public GlBufferData BufferData { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate int GlGetAttribLocation(int program, IntPtr name);
[GlEntryPoint("glGetAttribLocation")]
public GlGetAttribLocation GetAttribLocation { get; }
@ -313,27 +356,33 @@ namespace Avalonia.OpenGL
return GetAttribLocation(program, b.DangerousGetHandle());
}
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlVertexAttribPointer(int index, int size, int type,
int normalized, int stride, IntPtr pointer);
[GlEntryPoint("glVertexAttribPointer")]
public GlVertexAttribPointer VertexAttribPointer { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlEnableVertexAttribArray(int index);
[GlEntryPoint("glEnableVertexAttribArray")]
public GlEnableVertexAttribArray EnableVertexAttribArray { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlUseProgram(int program);
[GlEntryPoint("glUseProgram")]
public GlUseProgram UseProgram { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlDrawArrays(int mode, int first, IntPtr count);
[GlEntryPoint("glDrawArrays")]
public GlDrawArrays DrawArrays { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlDrawElements(int mode, int count, int type, IntPtr indices);
[GlEntryPoint("glDrawElements")]
public GlDrawElements DrawElements { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate int GlGetUniformLocation(int program, IntPtr name);
[GlEntryPoint("glGetUniformLocation")]
public GlGetUniformLocation GetUniformLocation { get; }
@ -343,31 +392,42 @@ namespace Avalonia.OpenGL
using (var b = new Utf8Buffer(name))
return GetUniformLocation(program, b.DangerousGetHandle());
}
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlUniform1f(int location, float falue);
[GlEntryPoint("glUniform1f")]
public GlUniform1f Uniform1f { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlUniformMatrix4fv(int location, int count, bool transpose, void* value);
[GlEntryPoint("glUniformMatrix4fv")]
public GlUniformMatrix4fv UniformMatrix4fv { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlEnable(int what);
[GlEntryPoint("glEnable")]
public GlEnable Enable { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlDeleteBuffers(int count, int[] buffers);
[GlEntryPoint("glDeleteBuffers")]
public GlDeleteBuffers DeleteBuffers { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlDeleteProgram(int program);
[GlEntryPoint("glDeleteProgram")]
public GlDeleteProgram DeleteProgram { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GlDeleteShader(int shader);
[GlEntryPoint("glDeleteShader")]
public GlDeleteShader DeleteShader { get; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void GLGetRenderbufferParameteriv(int target, int name, int[] value);
[GlEntryPoint("glGetRenderbufferParameteriv")]
public GLGetRenderbufferParameteriv GetRenderbufferParameteriv { get; }
// ReSharper restore UnassignedGetOnlyAutoProperty
}
}

36
src/Avalonia.Visuals/Media/TextFormatting/ShapeableTextCharacters.cs

@ -22,5 +22,41 @@ namespace Avalonia.Media.TextFormatting
public override TextRunProperties Properties { get; }
public sbyte BidiLevel { get; }
public bool CanShapeTogether(ShapeableTextCharacters shapeableTextCharacters)
{
if (!Text.Buffer.Equals(shapeableTextCharacters.Text.Buffer))
{
return false;
}
if (Text.Start + Text.Length != shapeableTextCharacters.Text.Start)
{
return false;
}
if (BidiLevel != shapeableTextCharacters.BidiLevel)
{
return false;
}
if (!MathUtilities.AreClose(Properties.FontRenderingEmSize,
shapeableTextCharacters.Properties.FontRenderingEmSize))
{
return false;
}
if (Properties.Typeface != shapeableTextCharacters.Properties.Typeface)
{
return false;
}
if (Properties.BaselineAlignment != shapeableTextCharacters.Properties.BaselineAlignment)
{
return false;
}
return true;
}
}
}

12
src/Avalonia.Visuals/Media/TextFormatting/TextCharacters.cs

@ -176,6 +176,12 @@ namespace Avalonia.Media.TextFormatting
var currentScript = currentGrapheme.FirstCodepoint.Script;
//Stop at the first missing glyph
if (!currentGrapheme.FirstCodepoint.IsBreakChar && !font.TryGetGlyph(currentGrapheme.FirstCodepoint, out _))
{
break;
}
if (currentScript != script)
{
if (script is Script.Unknown || currentScript != Script.Common &&
@ -192,12 +198,6 @@ namespace Avalonia.Media.TextFormatting
}
}
//Stop at the first missing glyph
if (!currentGrapheme.FirstCodepoint.IsBreakChar && !font.TryGetGlyph(currentGrapheme.FirstCodepoint, out _))
{
break;
}
length += currentGrapheme.Text.Length;
}

74
src/Avalonia.Visuals/Media/TextFormatting/TextFormatterImpl.cs

@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using Avalonia.Media.TextFormatting.Unicode;
using Avalonia.Utilities;
@ -171,25 +173,83 @@ namespace Avalonia.Media.TextFormatting
resolvedFlowDirection =
(resolvedEmbeddingLevel & 1) == 0 ? FlowDirection.LeftToRight : FlowDirection.RightToLeft;
foreach (var shapeableRuns in CoalesceLevels(textRuns, biDi.ResolvedLevels))
var shapeableRuns = new List<ShapeableTextCharacters>(textRuns.Count);
foreach (var coalescedRuns in CoalesceLevels(textRuns, biDi.ResolvedLevels))
{
shapeableRuns.AddRange(coalescedRuns);
}
for (var index = 0; index < shapeableRuns.Count; index++)
{
for (var index = 0; index < shapeableRuns.Count; index++)
var currentRun = shapeableRuns[index];
var groupedRuns = new List<ShapeableTextCharacters>(2) { currentRun };
var text = currentRun.Text;
var start = currentRun.Text.Start;
var length = currentRun.Text.Length;
var bufferOffset = currentRun.Text.BufferOffset;
while (index + 1 < shapeableRuns.Count)
{
var currentRun = shapeableRuns[index];
var nextRun = shapeableRuns[index + 1];
var shapedBuffer = TextShaper.Current.ShapeText(currentRun.Text, currentRun.Properties.Typeface.GlyphTypeface,
currentRun.Properties.FontRenderingEmSize, currentRun.Properties.CultureInfo, currentRun.BidiLevel);
if (currentRun.CanShapeTogether(nextRun))
{
groupedRuns.Add(nextRun);
var shapedCharacters = new ShapedTextCharacters(shapedBuffer, currentRun.Properties);
length += nextRun.Text.Length;
if (start > nextRun.Text.Start)
{
start = nextRun.Text.Start;
}
if (bufferOffset > nextRun.Text.BufferOffset)
{
bufferOffset = nextRun.Text.BufferOffset;
}
text = new ReadOnlySlice<char>(text.Buffer, start, length, bufferOffset);
index++;
shapedTextCharacters.Add(shapedCharacters);
currentRun = nextRun;
continue;
}
break;
}
shapedTextCharacters.AddRange(ShapeTogether(groupedRuns, text));
}
return shapedTextCharacters;
}
private static IReadOnlyList<ShapedTextCharacters> ShapeTogether(
IReadOnlyList<ShapeableTextCharacters> textRuns, ReadOnlySlice<char> text)
{
var shapedRuns = new List<ShapedTextCharacters>(textRuns.Count);
var firstRun = textRuns[0];
var shapedBuffer = TextShaper.Current.ShapeText(text, firstRun.Properties.Typeface.GlyphTypeface,
firstRun.Properties.FontRenderingEmSize, firstRun.Properties.CultureInfo, firstRun.BidiLevel);
for (var i = 0; i < textRuns.Count; i++)
{
var currentRun = textRuns[i];
var splitResult = shapedBuffer.Split(currentRun.Text.Length);
shapedRuns.Add(new ShapedTextCharacters(splitResult.First, currentRun.Properties));
shapedBuffer = splitResult.Second!;
}
return shapedRuns;
}
/// <summary>
/// Coalesces ranges of the same bidi level to form <see cref="ShapeableTextCharacters"/>
/// </summary>

2
src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs

@ -607,7 +607,7 @@ namespace Avalonia.Media.TextFormatting
textLines.Add(textLine);
UpdateBounds(textLine,ref left, ref width, ref height);
UpdateBounds(textLine, ref left, ref width, ref height);
previousLine = textLine;

2
src/Avalonia.Visuals/Media/TextFormatting/TextLineImpl.cs

@ -553,7 +553,7 @@ namespace Avalonia.Media.TextFormatting
out _);
var isAtEnd = foundCharacterHit.FirstCharacterIndex + foundCharacterHit.TrailingLength ==
TextRange.Length;
TextRange.Start + TextRange.Length;
if (isAtEnd && !run.GlyphRun.IsLeftToRight)
{

27
src/Avalonia.Visuals/Utilities/ReadOnlySlice.cs

@ -13,7 +13,7 @@ namespace Avalonia.Utilities
[DebuggerTypeProxy(typeof(ReadOnlySlice<>.ReadOnlySliceDebugView))]
public readonly struct ReadOnlySlice<T> : IReadOnlyList<T> where T : struct
{
private readonly int _offset;
private readonly int _bufferOffset;
/// <summary>
/// Gets an empty <see cref="ReadOnlySlice{T}"/>
@ -24,7 +24,7 @@ namespace Avalonia.Utilities
public ReadOnlySlice(ReadOnlyMemory<T> buffer) : this(buffer, 0, buffer.Length) { }
public ReadOnlySlice(ReadOnlyMemory<T> buffer, int start, int length, int offset = 0)
public ReadOnlySlice(ReadOnlyMemory<T> buffer, int start, int length, int bufferOffset = 0)
{
#if DEBUG
if (start.CompareTo(0) < 0)
@ -41,7 +41,7 @@ namespace Avalonia.Utilities
_buffer = buffer;
Start = start;
Length = length;
_offset = offset;
_bufferOffset = bufferOffset;
}
/// <summary>
@ -74,12 +74,17 @@ namespace Avalonia.Utilities
public bool IsEmpty => Length == 0;
/// <summary>
/// The underlying span.
/// Get the underlying span.
/// </summary>
public ReadOnlySpan<T> Span => _buffer.Span.Slice(_offset, Length);
public ReadOnlySpan<T> Span => _buffer.Span.Slice(_bufferOffset, Length);
/// <summary>
/// The underlying buffer.
/// Get the buffer offset.
/// </summary>
public int BufferOffset => _bufferOffset;
/// <summary>
/// Get the underlying buffer.
/// </summary>
public ReadOnlyMemory<T> Buffer => _buffer;
@ -124,17 +129,17 @@ namespace Avalonia.Utilities
return Empty;
}
if (start < 0 || _offset + start > _buffer.Length - 1)
if (start < 0 || _bufferOffset + start > _buffer.Length - 1)
{
throw new ArgumentOutOfRangeException(nameof(start));
}
if (_offset + start + length > _buffer.Length)
if (_bufferOffset + start + length > _buffer.Length)
{
throw new ArgumentOutOfRangeException(nameof(length));
}
return new ReadOnlySlice<T>(_buffer, start, length, _offset);
return new ReadOnlySlice<T>(_buffer, start, length, _bufferOffset);
}
/// <summary>
@ -154,7 +159,7 @@ namespace Avalonia.Utilities
throw new ArgumentOutOfRangeException(nameof(length));
}
return new ReadOnlySlice<T>(_buffer, Start, length, _offset);
return new ReadOnlySlice<T>(_buffer, Start, length, _bufferOffset);
}
/// <summary>
@ -174,7 +179,7 @@ namespace Avalonia.Utilities
throw new ArgumentOutOfRangeException(nameof(length));
}
return new ReadOnlySlice<T>(_buffer, Start + length, Length - length, _offset + length);
return new ReadOnlySlice<T>(_buffer, Start + length, Length - length, _bufferOffset + length);
}
/// <summary>

15
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlBindingPathHelper.cs

@ -72,10 +72,19 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
private static XamlIlBindingPathNode TransformForTargetTyping(XamlIlBindingPathNode transformed, AstTransformationContext context)
{
if (context.ParentNodes().OfType<XamlPropertyAssignmentNode>().FirstOrDefault().Property.Getter.ReturnType == context.GetAvaloniaTypes().ICommand
&& transformed.Elements[transformed.Elements.Count - 1] is XamlIlClrMethodPathElementNode method)
var parentNode = context.ParentNodes().OfType<XamlPropertyAssignmentNode>().FirstOrDefault();
if (parentNode == null)
{
return transformed;
}
var lastElement =
transformed.Elements[transformed.Elements.Count - 1];
if (parentNode.Property?.Getter?.ReturnType == context.GetAvaloniaTypes().ICommand && lastElement is XamlIlClrMethodPathElementNode methodPathElement)
{
IXamlMethod executeMethod = method.Method;
IXamlMethod executeMethod = methodPathElement.Method;
IXamlMethod canExecuteMethod = executeMethod.DeclaringType.FindMethod(new FindMethodMethodSignature($"Can{executeMethod.Name}", context.Configuration.WellKnownTypes.Boolean, context.Configuration.WellKnownTypes.Object));
List<string> dependsOnProperties = new();
if (canExecuteMethod is not null)

5
src/Skia/Avalonia.Skia/FontManagerImpl.cs

@ -132,7 +132,10 @@ namespace Avalonia.Skia
break;
}
skTypeface ??= _skFontManager.MatchTypeface(SKTypeface.Default, fontStyle);
// MatchTypeface can return "null" if matched typeface wasn't found for the style
// Fallback to the default typeface and styles instead.
skTypeface ??= _skFontManager.MatchTypeface(SKTypeface.Default, fontStyle)
?? SKTypeface.Default;
}
else
{

13
src/Skia/Avalonia.Skia/Gpu/OpenGl/GlRenderTarget.cs

@ -69,6 +69,7 @@ namespace Avalonia.Skia
gl.GetIntegerv(GL_FRAMEBUFFER_BINDING, out var fb);
var size = glSession.Size;
var colorType = SKColorType.Rgba8888;
var scaling = glSession.Scaling;
if (size.Width <= 0 || size.Height <= 0 || scaling < 0)
{
@ -81,12 +82,16 @@ namespace Avalonia.Skia
{
_grContext.ResetContext();
var renderTarget =
new GRBackendRenderTarget(size.Width, size.Height, disp.SampleCount, disp.StencilSize,
new GRGlFramebufferInfo((uint)fb, SKColorType.Rgba8888.ToGlSizedFormat()));
var samples = disp.SampleCount;
var maxSamples = _grContext.GetMaxSurfaceSampleCount(colorType);
if (samples > maxSamples)
samples = maxSamples;
var glInfo = new GRGlFramebufferInfo((uint)fb, colorType.ToGlSizedFormat());
var renderTarget = new GRBackendRenderTarget(size.Width, size.Height, samples, disp.StencilSize, glInfo);
var surface = SKSurface.Create(_grContext, renderTarget,
glSession.IsYFlipped ? GRSurfaceOrigin.TopLeft : GRSurfaceOrigin.BottomLeft,
SKColorType.Rgba8888);
colorType);
success = true;

2
src/Web/Avalonia.Web.Blazor/AvaloniaView.razor.cs

@ -224,7 +224,7 @@ namespace Avalonia.Web.Blazor
private void OnKeyDown(KeyboardEventArgs e)
{
_topLevelImpl.RawKeyboardEvent(RawKeyEventType.KeyDown, e.Key, GetModifiers(e));
_topLevelImpl.RawKeyboardEvent(RawKeyEventType.KeyDown, e.Code, GetModifiers(e));
}
private void OnKeyUp(KeyboardEventArgs e)

14
src/Windows/Avalonia.Win32/WindowImpl.CustomCaptionProc.cs

@ -23,16 +23,10 @@ namespace Avalonia.Win32
AdjustWindowRectEx(ref rcFrame, (uint)(WindowStyles.WS_OVERLAPPEDWINDOW & ~WindowStyles.WS_CAPTION), false, 0);
var borderThickness = new RECT();
if (GetStyle().HasAllFlags(WindowStyles.WS_THICKFRAME))
{
AdjustWindowRectEx(ref borderThickness, (uint)(GetStyle()), false, 0);
borderThickness.left *= -1;
borderThickness.top *= -1;
}
else if (GetStyle().HasAllFlags(WindowStyles.WS_BORDER))
{
borderThickness = new RECT { bottom = 1, left = 1, right = 1, top = 1 };
}
AdjustWindowRectEx(ref borderThickness, (uint)GetStyle(), false, 0);
borderThickness.left *= -1;
borderThickness.top *= -1;
if (_extendTitleBarHint >= 0)
{

11
src/Windows/Avalonia.Win32/WindowImpl.cs

@ -633,13 +633,16 @@ namespace Avalonia.Win32
public void BeginResizeDrag(WindowEdge edge, PointerPressedEventArgs e)
{
if (_windowProperties.IsResizable)
{
#if USE_MANAGED_DRAG
_managedDrag.BeginResizeDrag(edge, ScreenToClient(MouseDevice.Position.ToPoint(_scaling)));
_managedDrag.BeginResizeDrag(edge, ScreenToClient(MouseDevice.Position.ToPoint(_scaling)));
#else
_mouseDevice.Capture(null);
DefWindowProc(_hwnd, (int)WindowsMessage.WM_NCLBUTTONDOWN,
new IntPtr((int)s_edgeLookup[edge]), IntPtr.Zero);
_mouseDevice.Capture(null);
DefWindowProc(_hwnd, (int)WindowsMessage.WM_NCLBUTTONDOWN,
new IntPtr((int)s_edgeLookup[edge]), IntPtr.Zero);
#endif
}
}
public void SetTitle(string title)

27
src/iOS/Avalonia.iOS/Avalonia.iOS.csproj

@ -1,17 +1,22 @@
<Project Sdk="MSBuild.Sdk.Extras">
<Project>
<Import Project="Sdk.props" Sdk="Xamarin.Legacy.Sdk" />
<PropertyGroup>
<TargetFramework>xamarin.ios10</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>latest</LangVersion>
<TargetFrameworks>net6.0-ios</TargetFrameworks>
<TargetFrameworks Condition="'$(MSBuildRuntimeType)' != 'Core'">$(TargetFrameworks);xamarin.ios10</TargetFrameworks>
<SupportedOSPlatformVersion>10.0</SupportedOSPlatformVersion>
<MSBuildEnableWorkloadResolver>true</MSBuildEnableWorkloadResolver>
</PropertyGroup>
<ItemGroup>
<Reference Include="OpenTK-1.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\packages\Avalonia\Avalonia.csproj" />
<ProjectReference Include="..\..\Avalonia.PlatformSupport\Avalonia.PlatformSupport.csproj">
<SetTargetFramework>TargetFramework=netstandard2.0</SetTargetFramework>
</ProjectReference>
<ProjectReference Include="..\..\Avalonia.Base\Avalonia.Base.csproj" />
<ProjectReference Include="..\..\Skia\Avalonia.Skia\Avalonia.Skia.csproj" />
</ItemGroup>
<Import Project="Sdk.targets" Sdk="Xamarin.Legacy.Sdk" />
<!-- Workaround for https://github.com/dotnet/msbuild/issues/4584 -->
<Target Name="_RemoveNativeReferencesManifest" AfterTargets="BuiltProjectOutputGroup">
<ItemGroup>
<_BuiltProjectOutputGroupOutputIntermediate Remove="$(OutDir)$(_DeploymentTargetApplicationManifestFileName)" />
<BuiltProjectOutputGroupOutput Remove="$(ProjectDir)$(OutDir)$(_DeploymentTargetApplicationManifestFileName)" />
</ItemGroup>
</Target>
</Project>

32
src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs

@ -1,6 +1,7 @@
using Foundation;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Foundation;
using UIKit;
namespace Avalonia.iOS
@ -8,7 +9,18 @@ namespace Avalonia.iOS
public class AvaloniaAppDelegate<TApp> : UIResponder, IUIApplicationDelegate
where TApp : Application, new()
{
protected virtual AppBuilder CustomizeAppBuilder(AppBuilder builder) => builder;
class SingleViewLifetime : ISingleViewApplicationLifetime
{
public AvaloniaView View;
public Control MainView
{
get => View.Content;
set => View.Content = value;
}
}
protected virtual AppBuilder CustomizeAppBuilder(AppBuilder builder) => builder.UseiOS();
[Export("window")]
public UIWindow Window { get; set; }
@ -18,7 +30,9 @@ namespace Avalonia.iOS
{
var builder = AppBuilder.Configure<TApp>();
CustomizeAppBuilder(builder);
var lifetime = new Lifetime();
var lifetime = new SingleViewLifetime();
builder.AfterSetup(_ =>
{
Window = new UIWindow();
@ -35,15 +49,5 @@ namespace Avalonia.iOS
Window.Hidden = false;
return true;
}
class Lifetime : ISingleViewApplicationLifetime
{
public AvaloniaView View;
public Control MainView
{
get => View.Content;
set => View.Content = value;
}
}
}
}
}

14
src/iOS/Avalonia.iOS/Boilerplate/AppBuilder.cs

@ -1,14 +0,0 @@
using Avalonia.Controls;
using Avalonia.PlatformSupport;
namespace Avalonia
{
public class AppBuilder : AppBuilderBase<AppBuilder>
{
public AppBuilder() : base(new StandardRuntimePlatform(),
b => StandardRuntimePlatformServices.Register(b.ApplicationType.Assembly))
{
this.UseSkia().UseWindowingSubsystem(iOS.Platform.Register);
}
}
}

19
src/iOS/Avalonia.iOS/EaglDisplay.cs

@ -2,7 +2,6 @@ using System;
using System.Reactive.Disposables;
using Avalonia.OpenGL;
using OpenGLES;
using OpenTK.Graphics.ES30;
namespace Avalonia.iOS
{
@ -75,7 +74,21 @@ namespace Avalonia.iOS
public GlVersion Version { get; } = new GlVersion(GlProfileType.OpenGLES, 3, 0);
public GlInterface GlInterface { get; }
public int SampleCount { get; } = 0;
public int StencilSize { get; } = 9;
public int SampleCount
{
get
{
GlInterface.GetIntegerv(GlConsts.GL_SAMPLES, out var samples);
return samples;
}
}
public int StencilSize
{
get
{
GlInterface.GetIntegerv(GlConsts.GL_STENCIL_BITS, out var stencil);
return stencil;
}
}
}
}

5
src/iOS/Avalonia.iOS/EaglLayerSurface.cs

@ -4,7 +4,6 @@ using System.Threading;
using Avalonia.OpenGL;
using Avalonia.OpenGL.Surfaces;
using CoreAnimation;
using OpenTK.Graphics.ES30;
namespace Avalonia.iOS
{
@ -35,7 +34,7 @@ namespace Avalonia.iOS
public void Dispose()
{
GL.Finish();
_ctx.GlInterface.Finish();
_fbo.Present();
_restoreContext.Dispose();
}
@ -85,7 +84,7 @@ namespace Avalonia.iOS
var ctx = Platform.GlFeature.Context;
using (ctx.MakeCurrent())
{
var fbo = new SizeSynchronizedLayerFbo(ctx.Context, _layer);
var fbo = new SizeSynchronizedLayerFbo(ctx.Context, ctx.GlInterface, _layer);
if (!fbo.Sync())
throw new InvalidOperationException("Unable to create render target");
return new RenderTarget(ctx, fbo);

4
src/iOS/Avalonia.iOS/Extensions.cs

@ -12,7 +12,7 @@ namespace Avalonia.iOS
public static Point ToAvalonia(this CGPoint point) => new Point(point.X, point.Y);
static nfloat ColorComponent(byte c) => ((float) c) / 255;
static float ColorComponent(byte c) => (float) c / 255;
public static UIColor ToUiColor(this Color color) => new UIColor(
ColorComponent(color.R),
@ -20,4 +20,4 @@ namespace Avalonia.iOS
ColorComponent(color.B),
ColorComponent(color.A));
}
}
}

80
src/iOS/Avalonia.iOS/LayerFbo.cs

@ -1,64 +1,71 @@
using System;
using Avalonia.OpenGL;
using CoreAnimation;
using OpenGLES;
using OpenTK.Graphics.ES20;
namespace Avalonia.iOS
{
public class LayerFbo
{
private readonly EAGLContext _context;
private readonly GlInterface _gl;
private readonly CAEAGLLayer _layer;
private int _framebuffer;
private int _renderbuffer;
private int _depthBuffer;
private int[] _framebuffer;
private int[] _renderbuffer;
private int[] _depthBuffer;
private bool _disposed;
private LayerFbo(EAGLContext context, CAEAGLLayer layer, in int framebuffer, in int renderbuffer, in int depthBuffer)
private LayerFbo(EAGLContext context, GlInterface gl, CAEAGLLayer layer, int[] framebuffer, int[] renderbuffer, int[] depthBuffer)
{
_context = context;
_gl = gl;
_layer = layer;
_framebuffer = framebuffer;
_renderbuffer = renderbuffer;
_depthBuffer = depthBuffer;
}
public static LayerFbo TryCreate(EAGLContext context, CAEAGLLayer layer)
public static LayerFbo TryCreate(EAGLContext context, GlInterface gl, CAEAGLLayer layer)
{
if (context != EAGLContext.CurrentContext)
return null;
GL.GenFramebuffers(1, out int fb);
GL.GenRenderbuffers(1, out int rb);
GL.BindFramebuffer(FramebufferTarget.Framebuffer, fb);
GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, rb);
context.RenderBufferStorage((uint) All.Renderbuffer, layer);
var fb = new int[2];
var rb = new int[2];
var db = new int[2];
GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferSlot.ColorAttachment0, RenderbufferTarget.Renderbuffer, rb);
gl.GenRenderbuffers(1, rb);
gl.BindRenderbuffer(GlConsts.GL_RENDERBUFFER, rb[0]);
context.RenderBufferStorage(GlConsts.GL_RENDERBUFFER, layer);
gl.GenFramebuffers(1, fb);
gl.BindFramebuffer(GlConsts.GL_FRAMEBUFFER, fb[0]);
gl.FramebufferRenderbuffer(GlConsts.GL_FRAMEBUFFER, GlConsts.GL_COLOR_ATTACHMENT0, GlConsts.GL_RENDERBUFFER, rb[0]);
int w;
int h;
GL.GetRenderbufferParameter(RenderbufferTarget.Renderbuffer, RenderbufferParameterName.RenderbufferWidth, out w);
GL.GetRenderbufferParameter(RenderbufferTarget.Renderbuffer, RenderbufferParameterName.RenderbufferHeight, out h);
int[] w = new int[1];
int[] h = new int[1];
gl.GetRenderbufferParameteriv(GlConsts.GL_RENDERBUFFER, GlConsts.GL_RENDERBUFFER_WIDTH, w);
gl.GetRenderbufferParameteriv(GlConsts.GL_RENDERBUFFER, GlConsts.GL_RENDERBUFFER_HEIGHT, h);
GL.GenRenderbuffers(1, out int depthBuffer);
gl.GenRenderbuffers(1, db);
//GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, depthBuffer);
//GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferInternalFormat.DepthComponent16, w, h);
GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferSlot.DepthAttachment, RenderbufferTarget.Renderbuffer, depthBuffer);
gl.FramebufferRenderbuffer(GlConsts.GL_FRAMEBUFFER, GlConsts.GL_DEPTH_ATTACHMENT, GlConsts.GL_RENDERBUFFER, db[0]);
var frameBufferError = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer);
if(frameBufferError != FramebufferErrorCode.FramebufferComplete)
var frameBufferError = gl.CheckFramebufferStatus(GlConsts.GL_FRAMEBUFFER);
if(frameBufferError != GlConsts.GL_FRAMEBUFFER_COMPLETE)
{
GL.DeleteFramebuffers(1, ref fb);
GL.DeleteRenderbuffers(1, ref depthBuffer);
GL.DeleteRenderbuffers(1, ref rb);
gl.DeleteFramebuffers(1, fb);
gl.DeleteRenderbuffers(1, db);
gl.DeleteRenderbuffers(1, rb);
return null;
}
return new LayerFbo(context, layer, fb, rb, depthBuffer)
return new LayerFbo(context, gl, layer, fb, rb, db)
{
Width = w,
Height = h
Width = w[0],
Height = h[0]
};
}
@ -67,13 +74,13 @@ namespace Avalonia.iOS
public void Bind()
{
GL.BindFramebuffer(FramebufferTarget.Framebuffer, _framebuffer);
_gl.BindFramebuffer(GlConsts.GL_FRAMEBUFFER, _framebuffer[0]);
}
public void Present()
{
Bind();
var success = _context.PresentRenderBuffer((uint) All.Renderbuffer);
var success = _context.PresentRenderBuffer(GlConsts.GL_RENDERBUFFER);
}
public void Dispose()
@ -81,9 +88,9 @@ namespace Avalonia.iOS
if(_disposed)
return;
_disposed = true;
GL.DeleteFramebuffers(1, ref _framebuffer);
GL.DeleteRenderbuffers(1, ref _depthBuffer);
GL.DeleteRenderbuffers(1, ref _renderbuffer);
_gl.DeleteFramebuffers(1, _framebuffer);
_gl.DeleteRenderbuffers(1, _depthBuffer);
_gl.DeleteRenderbuffers(1, _renderbuffer);
if (_context != EAGLContext.CurrentContext)
throw new InvalidOperationException("Associated EAGLContext is not current");
}
@ -92,15 +99,16 @@ namespace Avalonia.iOS
class SizeSynchronizedLayerFbo : IDisposable
{
private readonly EAGLContext _context;
private readonly GlInterface _gl;
private readonly CAEAGLLayer _layer;
private LayerFbo _fbo;
private nfloat _oldLayerWidth, _oldLayerHeight, _oldLayerScale;
private double _oldLayerWidth, _oldLayerHeight, _oldLayerScale;
public SizeSynchronizedLayerFbo(EAGLContext context, CAEAGLLayer layer)
public SizeSynchronizedLayerFbo(EAGLContext context, GlInterface gl, CAEAGLLayer layer)
{
_context = context;
_gl = gl;
_layer = layer;
}
public bool Sync()
@ -112,7 +120,7 @@ namespace Avalonia.iOS
return true;
_fbo?.Dispose();
_fbo = null;
_fbo = LayerFbo.TryCreate(_context, _layer);
_fbo = LayerFbo.TryCreate(_context, _gl, _layer);
_oldLayerWidth = _layer.Bounds.Width;
_oldLayerHeight = _layer.Bounds.Height;
_oldLayerScale = _layer.ContentsScale;
@ -140,4 +148,4 @@ namespace Avalonia.iOS
public int Height => _fbo?.Height ?? 0;
public double Scaling => _oldLayerScale;
}
}
}

17
src/iOS/Avalonia.iOS/Platform.cs

@ -1,10 +1,25 @@
using System;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Input.Platform;
using Avalonia.OpenGL;
using Avalonia.Platform;
using Avalonia.Rendering;
namespace Avalonia
{
public static class IOSApplicationExtensions
{
public static T UseiOS<T>(this T builder) where T : AppBuilderBase<T>, new()
{
return builder
.UseWindowingSubsystem(iOS.Platform.Register, "iOS")
.UseSkia();
}
}
}
namespace Avalonia.iOS
{
static class Platform
@ -30,6 +45,7 @@ namespace Avalonia.iOS
Timer ??= new DisplayLinkTimer();
var keyboard = new KeyboardDevice();
var softKeyboard = new SoftKeyboardHelper();
AvaloniaLocator.CurrentMutable
.Bind<IPlatformOpenGlInterface>().ToConstant(GlFeature)
.Bind<ICursorFactory>().ToConstant(new CursorFactoryStub())
@ -42,6 +58,7 @@ namespace Avalonia.iOS
.Bind<IRenderTimer>().ToConstant(Timer)
.Bind<IPlatformThreadingInterface>().ToConstant(new PlatformThreadingInterface())
.Bind<IKeyboardDevice>().ToConstant(keyboard);
keyboard.PropertyChanged += (_, changed) =>
{
if (changed.PropertyName == nameof(KeyboardDevice.FocusedElement))

7
src/iOS/Avalonia.iOS/SingleViewLifetime.cs

@ -1,7 +0,0 @@
namespace Avalonia.iOS
{
public class SingleViewLifetime
{
}
}
Loading…
Cancel
Save