Browse Source

Merge branch 'master' into feature/immediate-drawing-context

pull/9718/head
Max Katz 4 years ago
committed by GitHub
parent
commit
cb16e911cf
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      .editorconfig
  2. 11
      Avalonia.sln
  3. 2
      samples/ControlCatalog/Pages/ImagePage.xaml.cs
  4. 5
      samples/interop/Direct3DInteropSample/App.paml
  5. 21
      samples/interop/Direct3DInteropSample/App.paml.cs
  6. 32
      samples/interop/Direct3DInteropSample/Direct3DInteropSample.csproj
  7. 283
      samples/interop/Direct3DInteropSample/MainWindow.cs
  8. 14
      samples/interop/Direct3DInteropSample/MainWindow.paml
  9. 45
      samples/interop/Direct3DInteropSample/MainWindowViewModel.cs
  10. 47
      samples/interop/Direct3DInteropSample/MiniCube.fx
  11. 16
      samples/interop/Direct3DInteropSample/Program.cs
  12. 2
      src/Android/Avalonia.Android/Platform/SkiaPlatform/AndroidFramebuffer.cs
  13. 9
      src/Avalonia.Base/CornerRadius.cs
  14. 2
      src/Avalonia.Base/Data/Core/ExpressionNode.cs
  15. 2
      src/Avalonia.Base/Data/Core/ExpressionObserver.cs
  16. 2
      src/Avalonia.Base/Input/KeyEventArgs.cs
  17. 2
      src/Avalonia.Base/Input/TextInputEventArgs.cs
  18. 11
      src/Avalonia.Base/Media/BoxShadow.cs
  19. 4
      src/Avalonia.Base/Media/BoxShadows.cs
  20. 8
      src/Avalonia.Base/Media/DashStyle.cs
  21. 2
      src/Avalonia.Base/Media/FormattedText.cs
  22. 4
      src/Avalonia.Base/Media/Geometry.cs
  23. 2
      src/Avalonia.Base/Media/GeometryDrawing.cs
  24. 2
      src/Avalonia.Base/Media/GlyphRunDrawing.cs
  25. 2
      src/Avalonia.Base/Media/IDashStyle.cs
  26. 2
      src/Avalonia.Base/Media/ImageDrawing.cs
  27. 4
      src/Avalonia.Base/Media/Imaging/CroppedBitmap.cs
  28. 4
      src/Avalonia.Base/Media/Immutable/ImmutableDashStyle.cs
  29. 1
      src/Avalonia.Base/Media/TextFormatting/FormattedTextSource.cs
  30. 4
      src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs
  31. 1
      src/Avalonia.Base/Media/TextFormatting/Unicode/CodepointEnumerator.cs
  32. 2
      src/Avalonia.Base/Media/UnicodeRange.cs
  33. 15
      src/Avalonia.Base/PixelRect.cs
  34. 1
      src/Avalonia.Base/Platform/ITextShaperImpl.cs
  35. 45
      src/Avalonia.Base/PropertyStore/BindingEntryBase.cs
  36. 53
      src/Avalonia.Base/PropertyStore/LocalValueBindingObserver.cs
  37. 53
      src/Avalonia.Base/PropertyStore/LocalValueUntypedBindingObserver.cs
  38. 21
      src/Avalonia.Base/Rect.cs
  39. 2
      src/Avalonia.Base/Rendering/Composition/Server/DrawingContextProxy.cs
  40. 2
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionDrawListVisual.cs
  41. 8
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionTarget.cs
  42. 8
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.cs
  43. 6
      src/Avalonia.Base/Rendering/DeferredRenderer.cs
  44. 5
      src/Avalonia.Base/Rendering/DirtyRects.cs
  45. 6
      src/Avalonia.Base/Rendering/ImmediateRenderer.cs
  46. 2
      src/Avalonia.Base/Rendering/SceneGraph/BitmapBlendModeNode.cs
  47. 2
      src/Avalonia.Base/Rendering/SceneGraph/ClipNode.cs
  48. 2
      src/Avalonia.Base/Rendering/SceneGraph/GeometryClipNode.cs
  49. 4
      src/Avalonia.Base/Rendering/SceneGraph/OpacityMaskNode.cs
  50. 2
      src/Avalonia.Base/Rendering/SceneGraph/OpacityNode.cs
  51. 6
      src/Avalonia.Base/Rendering/SceneGraph/SceneBuilder.cs
  52. 8
      src/Avalonia.Base/Size.cs
  53. 17
      src/Avalonia.Base/Thickness.cs
  54. 24
      src/Avalonia.Build.Tasks/GenerateAvaloniaResourcesTask.cs
  55. 5
      src/Avalonia.Controls.DataGrid/DataGrid.cs
  56. 4
      src/Avalonia.Controls.DataGrid/DataGridCheckBoxColumn.cs
  57. 7
      src/Avalonia.Controls.DataGrid/DataGridColumn.cs
  58. 1
      src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs
  59. 2
      src/Avalonia.Controls.DataGrid/DataGridRowHeader.cs
  60. 10
      src/Avalonia.Controls.DataGrid/DataGridValueConverter.cs
  61. 2
      src/Avalonia.Controls.DataGrid/Primitives/DataGridCellsPresenter.cs
  62. 2
      src/Avalonia.Controls.DataGrid/Primitives/DataGridColumnHeadersPresenter.cs
  63. 2
      src/Avalonia.Controls.DataGrid/Primitives/DataGridDetailsPresenter.cs
  64. 4
      src/Avalonia.Controls/Flyouts/FlyoutBase.cs
  65. 10
      src/Avalonia.Controls/LayoutTransformControl.cs
  66. 2
      src/Avalonia.Controls/NativeControlHost.cs
  67. 9
      src/Avalonia.Controls/NativeMenuBar.cs
  68. 7
      src/Avalonia.Controls/NativeMenuItemSeparator.cs
  69. 6
      src/Avalonia.Controls/Presenters/ItemsPresenter.cs
  70. 3
      src/Avalonia.Controls/Presenters/TextPresenter.cs
  71. 2
      src/Avalonia.Controls/Primitives/PopupPositioning/ManagedPopupPositioner.cs
  72. 2
      src/Avalonia.Controls/Primitives/SelectingItemsControl.cs
  73. 4
      src/Avalonia.Controls/Repeater/ViewportManager.cs
  74. 4
      src/Avalonia.Controls/Selection/SelectedItems.cs
  75. 2
      src/Avalonia.Controls/Shapes/Shape.cs
  76. 6
      src/Avalonia.Controls/Window.cs
  77. 3
      src/Avalonia.Diagnostics/Diagnostics/Controls/Application.cs
  78. 2
      src/Avalonia.Headless/HeadlessPlatformRenderInterface.cs
  79. 3
      src/Avalonia.Native/ClipboardImpl.cs
  80. 1
      src/Avalonia.Native/IAvnMenu.cs
  81. 1
      src/Avalonia.Native/WindowImplBase.cs
  82. 2
      src/Avalonia.Remote.Protocol/MetsysBson.cs
  83. 1
      src/Avalonia.Themes.Fluent/Accents/BaseDark.xaml
  84. 1
      src/Avalonia.Themes.Fluent/Accents/BaseLight.xaml
  85. 7
      src/Avalonia.Themes.Fluent/Controls/ManagedFileChooser.xaml
  86. 17
      src/Avalonia.Themes.Fluent/Controls/NativeMenuBar.xaml
  87. 14
      src/Avalonia.Themes.Simple/Controls/ManagedFileChooser.xaml
  88. 21
      src/Avalonia.Themes.Simple/Controls/NativeMenuBar.xaml
  89. 2
      src/Avalonia.X11/X11Clipboard.cs
  90. 6
      src/Browser/Avalonia.Browser/BrowserNativeControlHost.cs
  91. 2
      src/Browser/Avalonia.Browser/WebEmbeddableControlRoot.cs
  92. 2
      src/Linux/Avalonia.LinuxFramebuffer/Input/EvDev/EvDevBackend.cs
  93. 1
      src/Linux/Avalonia.LinuxFramebuffer/Input/LibInput/LibInputBackend.cs
  94. 13
      src/Skia/Avalonia.Skia/DrawingContextImpl.cs
  95. 2
      src/Skia/Avalonia.Skia/GeometryImpl.cs
  96. 1
      src/Skia/Avalonia.Skia/Helpers/ImageSavingHelper.cs
  97. 2
      src/Skia/Avalonia.Skia/StreamGeometryImpl.cs
  98. 2
      src/Windows/Avalonia.Win32/Interop/Automation/UiaCoreTypesApi.cs
  99. 2
      src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs
  100. 3
      src/Windows/Avalonia.Win32/OpenGl/Angle/AngleWin32PlatformGraphics.cs

4
.editorconfig

@ -140,6 +140,8 @@ dotnet_analyzer_diagnostic.category-Performance.severity = none #error - Uncomme
# CS1591: Missing XML comment for publicly visible type or member # CS1591: Missing XML comment for publicly visible type or member
dotnet_diagnostic.CS1591.severity = suggestion dotnet_diagnostic.CS1591.severity = suggestion
# CS0162: Remove unreachable code
dotnet_diagnostic.CS0162.severity = error
# CA1304: Specify CultureInfo # CA1304: Specify CultureInfo
dotnet_diagnostic.CA1304.severity = warning dotnet_diagnostic.CA1304.severity = warning
# CA1802: Use literals where appropriate # CA1802: Use literals where appropriate
@ -152,6 +154,8 @@ dotnet_diagnostic.CA1820.severity = warning
dotnet_diagnostic.CA1821.severity = warning dotnet_diagnostic.CA1821.severity = warning
# CA1822: Mark members as static # CA1822: Mark members as static
dotnet_diagnostic.CA1822.severity = suggestion dotnet_diagnostic.CA1822.severity = suggestion
# CA1823: Avoid unused private fields
dotnet_diagnostic.CA1823.severity = warning
dotnet_code_quality.CA1822.api_surface = private, internal dotnet_code_quality.CA1822.api_surface = private, internal
# CA1825: Avoid zero-length array allocations # CA1825: Avoid zero-length array allocations
dotnet_diagnostic.CA1825.severity = warning dotnet_diagnostic.CA1825.severity = warning

11
Avalonia.sln

@ -136,8 +136,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Linux", "Linux", "{86C53C40
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.LinuxFramebuffer", "src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj", "{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.LinuxFramebuffer", "src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj", "{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Direct3DInteropSample", "samples\interop\Direct3DInteropSample\Direct3DInteropSample.csproj", "{638580B0-7910-40EF-B674-DCB34DA308CD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Win32.Interop", "src\Windows\Avalonia.Win32.Interop\Avalonia.Win32.Interop.csproj", "{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Win32.Interop", "src\Windows\Avalonia.Win32.Interop\Avalonia.Win32.Interop.csproj", "{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Skia.RenderTests", "tests\Avalonia.Skia.RenderTests\Avalonia.Skia.RenderTests.csproj", "{E1582370-37B3-403C-917F-8209551B1634}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Skia.RenderTests", "tests\Avalonia.Skia.RenderTests\Avalonia.Skia.RenderTests.csproj", "{E1582370-37B3-403C-917F-8209551B1634}"
@ -228,9 +226,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Browser", "src\Bro
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Browser.Blazor", "src\Browser\Avalonia.Browser.Blazor\Avalonia.Browser.Blazor.csproj", "{47F8530C-F19B-4B1A-B4D6-EB231522AE5D}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Browser.Blazor", "src\Browser\Avalonia.Browser.Blazor\Avalonia.Browser.Blazor.csproj", "{47F8530C-F19B-4B1A-B4D6-EB231522AE5D}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog.Browser", "samples\ControlCatalog.Browser\ControlCatalog.Browser.csproj", "{15B93A4C-1B46-43F6-B534-7B25B6E99932}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.Browser", "samples\ControlCatalog.Browser\ControlCatalog.Browser.csproj", "{15B93A4C-1B46-43F6-B534-7B25B6E99932}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog.Browser.Blazor", "samples\ControlCatalog.Browser.Blazor\ControlCatalog.Browser.Blazor.csproj", "{90B08091-9BBD-4362-B712-E9F2CC62B218}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.Browser.Blazor", "samples\ControlCatalog.Browser.Blazor\ControlCatalog.Browser.Blazor.csproj", "{90B08091-9BBD-4362-B712-E9F2CC62B218}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReactiveUIDemo", "samples\ReactiveUIDemo\ReactiveUIDemo.csproj", "{75C47156-C5D8-44BC-A5A7-E8657C2248D6}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReactiveUIDemo", "samples\ReactiveUIDemo\ReactiveUIDemo.csproj", "{75C47156-C5D8-44BC-A5A7-E8657C2248D6}"
EndProject EndProject
@ -366,10 +364,6 @@ Global
{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Debug|Any CPU.Build.0 = Debug|Any CPU {854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Release|Any CPU.ActiveCfg = Release|Any CPU {854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Release|Any CPU.Build.0 = Release|Any CPU {854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Release|Any CPU.Build.0 = Release|Any CPU
{638580B0-7910-40EF-B674-DCB34DA308CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{638580B0-7910-40EF-B674-DCB34DA308CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{638580B0-7910-40EF-B674-DCB34DA308CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{638580B0-7910-40EF-B674-DCB34DA308CD}.Release|Any CPU.Build.0 = Release|Any CPU
{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Debug|Any CPU.Build.0 = Debug|Any CPU {CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Release|Any CPU.ActiveCfg = Release|Any CPU {CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -580,7 +574,6 @@ Global
{7D2D3083-71DD-4CC9-8907-39A0D86FB322} = {3743B0F2-CC41-4F14-A8C8-267F579BF91E} {7D2D3083-71DD-4CC9-8907-39A0D86FB322} = {3743B0F2-CC41-4F14-A8C8-267F579BF91E}
{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3} = {9B9E3891-2366-4253-A952-D08BCEB71098} {39D7B147-1A5B-47C2-9D01-21FB7C47C4B3} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{854568D5-13D1-4B4F-B50D-534DC7EFD3C9} = {86C53C40-57AA-45B8-AD42-FAE0EFDF0F2B} {854568D5-13D1-4B4F-B50D-534DC7EFD3C9} = {86C53C40-57AA-45B8-AD42-FAE0EFDF0F2B}
{638580B0-7910-40EF-B674-DCB34DA308CD} = {A0CC0258-D18C-4AB3-854F-7101680FC3F9}
{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E} = {B39A8919-9F95-48FE-AD7B-76E08B509888} {CBC4FF2F-92D4-420B-BE21-9FE0B930B04E} = {B39A8919-9F95-48FE-AD7B-76E08B509888}
{E1582370-37B3-403C-917F-8209551B1634} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {E1582370-37B3-403C-917F-8209551B1634} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{E2999E4A-9086-401F-898C-AEB0AD38E676} = {9B9E3891-2366-4253-A952-D08BCEB71098} {E2999E4A-9086-401F-898C-AEB0AD38E676} = {9B9E3891-2366-4253-A952-D08BCEB71098}

2
samples/ControlCatalog/Pages/ImagePage.xaml.cs

@ -70,7 +70,7 @@ namespace ControlCatalog.Pages
3 => new PixelRect(new PixelPoint(bitmapWidth - cropSize.Width, 0), cropSize), 3 => new PixelRect(new PixelPoint(bitmapWidth - cropSize.Width, 0), cropSize),
4 => new PixelRect(new PixelPoint(0, bitmapHeight - cropSize.Height), cropSize), 4 => new PixelRect(new PixelPoint(0, bitmapHeight - cropSize.Height), cropSize),
5 => new PixelRect(new PixelPoint(bitmapWidth - cropSize.Width, bitmapHeight - cropSize.Height), cropSize), 5 => new PixelRect(new PixelPoint(bitmapWidth - cropSize.Width, bitmapHeight - cropSize.Height), cropSize),
_ => PixelRect.Empty _ => default
}; };
} }

5
samples/interop/Direct3DInteropSample/App.paml

@ -1,5 +0,0 @@
<Application xmlns="https://github.com/avaloniaui">
<Application.Styles>
<SimpleTheme Mode="Light" />
</Application.Styles>
</Application>

21
samples/interop/Direct3DInteropSample/App.paml.cs

@ -1,21 +0,0 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
namespace Direct3DInteropSample
{
public class App : Application
{
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}
public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
desktop.MainWindow = new MainWindow();
base.OnFrameworkInitializationCompleted();
}
}
}

32
samples/interop/Direct3DInteropSample/Direct3DInteropSample.csproj

@ -1,32 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net461</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SharpDX.Mathematics" Version="4.0.1" />
<PackageReference Include="SharpDX.D3DCompiler" Version="4.0.1" />
<Compile Update="**\*.paml.cs">
<DependentUpon>%(Filename)</DependentUpon>
</Compile>
<EmbeddedResource Include="**\*.paml">
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Remove="MiniCube.fx" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="MiniCube.fx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Avalonia.Themes.Simple\Avalonia.Themes.Simple.csproj" />
<ProjectReference Include="..\..\..\src\Windows\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj" />
<ProjectReference Include="..\..\..\src\Windows\Avalonia.Win32\Avalonia.Win32.csproj" />
<ProjectReference Include="..\..\MiniMvvm\MiniMvvm.csproj" />
</ItemGroup>
<Import Project="..\..\..\build\Rx.props" />
<Import Project="..\..\..\build\ReferenceCoreLibraries.props" />
</Project>

283
samples/interop/Direct3DInteropSample/MainWindow.cs

@ -1,283 +0,0 @@
using System;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Direct2D1;
using Avalonia.Direct2D1.Media;
using Avalonia.Markup.Xaml;
using Avalonia.Platform;
using Avalonia.Rendering;
using SharpDX;
using SharpDX.D3DCompiler;
using SharpDX.Direct2D1;
using SharpDX.Direct3D;
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using AlphaMode = SharpDX.Direct2D1.AlphaMode;
using Buffer = SharpDX.Direct3D11.Buffer;
using DeviceContext = SharpDX.Direct2D1.DeviceContext;
using Factory2 = SharpDX.DXGI.Factory2;
using InputElement = SharpDX.Direct3D11.InputElement;
using Matrix = SharpDX.Matrix;
using PixelFormat = SharpDX.Direct2D1.PixelFormat;
using Resource = SharpDX.Direct3D11.Resource;
namespace Direct3DInteropSample
{
public class MainWindow : Window
{
Texture2D _backBuffer;
RenderTargetView _renderView;
Texture2D _depthBuffer;
DepthStencilView _depthView;
private readonly SwapChain _swapChain;
private SwapChainDescription1 _desc;
private Matrix _proj = Matrix.Identity;
private readonly Matrix _view;
private Buffer _contantBuffer;
private DeviceContext _deviceContext;
private readonly MainWindowViewModel _model;
public MainWindow()
{
DataContext = _model = new MainWindowViewModel();
_desc = new SwapChainDescription1()
{
BufferCount = 1,
Width = (int)ClientSize.Width,
Height = (int)ClientSize.Height,
Format = Format.R8G8B8A8_UNorm,
SampleDescription = new SampleDescription(1, 0),
SwapEffect = SwapEffect.Discard,
Usage = Usage.RenderTargetOutput
};
using (var factory = Direct2D1Platform.DxgiDevice.Adapter.GetParent<Factory2>())
{
_swapChain = new SwapChain1(factory, Direct2D1Platform.DxgiDevice, PlatformImpl?.Handle.Handle ?? IntPtr.Zero, ref _desc);
}
_deviceContext = new DeviceContext(Direct2D1Platform.Direct2D1Device, DeviceContextOptions.None)
{
DotsPerInch = new Size2F(96, 96)
};
CreateMesh();
_view = Matrix.LookAtLH(new Vector3(0, 0, -5), new Vector3(0, 0, 0), Vector3.UnitY);
this.GetObservable(ClientSizeProperty).Subscribe(Resize);
Resize(ClientSize);
AvaloniaXamlLoader.Load(this);
Background = Avalonia.Media.Brushes.Transparent;
}
protected override void HandlePaint(Rect rect)
{
var viewProj = Matrix.Multiply(_view, _proj);
var context = Direct2D1Platform.Direct3D11Device.ImmediateContext;
// Clear views
context.ClearDepthStencilView(_depthView, DepthStencilClearFlags.Depth, 1.0f, 0);
context.ClearRenderTargetView(_renderView, Color.White);
// Update WorldViewProj Matrix
var worldViewProj = Matrix.RotationX((float)_model.RotationX) * Matrix.RotationY((float)_model.RotationY)
* Matrix.RotationZ((float)_model.RotationZ)
* Matrix.Scaling((float)_model.Zoom)
* viewProj;
worldViewProj.Transpose();
context.UpdateSubresource(ref worldViewProj, _contantBuffer);
// Draw the cube
context.Draw(36, 0);
base.HandlePaint(rect);
// Present!
_swapChain.Present(0, PresentFlags.None);
}
private void CreateMesh()
{
var device = Direct2D1Platform.Direct3D11Device;
// Compile Vertex and Pixel shaders
var vertexShaderByteCode = ShaderBytecode.CompileFromFile("MiniCube.fx", "VS", "vs_4_0");
var vertexShader = new VertexShader(device, vertexShaderByteCode);
var pixelShaderByteCode = ShaderBytecode.CompileFromFile("MiniCube.fx", "PS", "ps_4_0");
var pixelShader = new PixelShader(device, pixelShaderByteCode);
var signature = ShaderSignature.GetInputSignature(vertexShaderByteCode);
var inputElements = new[]
{
new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 16, 0)
};
// Layout from VertexShader input signature
var layout = new InputLayout(
device,
signature,
inputElements);
// Instantiate Vertex buffer from vertex data
var vertices = Buffer.Create(
device,
BindFlags.VertexBuffer,
new[]
{
new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), // Front
new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), // BACK
new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), // Top
new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f), // Bottom
new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f), // Left
new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f), // Right
new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
});
// Create Constant Buffer
_contantBuffer = new Buffer(device, Utilities.SizeOf<Matrix>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
var context = Direct2D1Platform.Direct3D11Device.ImmediateContext;
// Prepare All the stages
context.InputAssembler.InputLayout = layout;
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertices, Utilities.SizeOf<Vector4>() * 2, 0));
context.VertexShader.SetConstantBuffer(0, _contantBuffer);
context.VertexShader.Set(vertexShader);
context.PixelShader.Set(pixelShader);
}
private void Resize(Size size)
{
Utilities.Dispose(ref _deviceContext);
Utilities.Dispose(ref _backBuffer);
Utilities.Dispose(ref _renderView);
Utilities.Dispose(ref _depthBuffer);
Utilities.Dispose(ref _depthView);
var context = Direct2D1Platform.Direct3D11Device.ImmediateContext;
// Resize the backbuffer
_swapChain.ResizeBuffers(0, 0, 0, Format.Unknown, SwapChainFlags.None);
// Get the backbuffer from the swapchain
_backBuffer = Resource.FromSwapChain<Texture2D>(_swapChain, 0);
// Renderview on the backbuffer
_renderView = new RenderTargetView(Direct2D1Platform.Direct3D11Device, _backBuffer);
// Create the depth buffer
_depthBuffer = new Texture2D(
Direct2D1Platform.Direct3D11Device,
new Texture2DDescription()
{
Format = Format.D32_Float_S8X24_UInt,
ArraySize = 1,
MipLevels = 1,
Width = (int)size.Width,
Height = (int)size.Height,
SampleDescription = new SampleDescription(1, 0),
Usage = ResourceUsage.Default,
BindFlags = BindFlags.DepthStencil,
CpuAccessFlags = CpuAccessFlags.None,
OptionFlags = ResourceOptionFlags.None
});
// Create the depth buffer view
_depthView = new DepthStencilView(Direct2D1Platform.Direct3D11Device, _depthBuffer);
// Setup targets and viewport for rendering
context.Rasterizer.SetViewport(new Viewport(0, 0, (int)size.Width, (int)size.Height, 0.0f, 1.0f));
context.OutputMerger.SetTargets(_depthView, _renderView);
// Setup new projection matrix with correct aspect ratio
_proj = Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, (float)(size.Width / size.Height), 0.1f, 100.0f);
using (var dxgiBackBuffer = _swapChain.GetBackBuffer<Surface>(0))
{
var renderTarget = new SharpDX.Direct2D1.RenderTarget(
Direct2D1Platform.Direct2D1Factory,
dxgiBackBuffer,
new RenderTargetProperties
{
DpiX = 96,
DpiY = 96,
Type = RenderTargetType.Default,
PixelFormat = new PixelFormat(
Format.Unknown,
AlphaMode.Premultiplied)
});
_deviceContext = renderTarget.QueryInterface<DeviceContext>();
renderTarget.Dispose();
}
}
private class D3DRenderTarget : IRenderTarget
{
private readonly MainWindow _window;
public D3DRenderTarget(MainWindow window)
{
_window = window;
}
public void Dispose()
{
}
public IDrawingContextImpl CreateDrawingContext(IVisualBrushRenderer visualBrushRenderer)
{
return new DrawingContextImpl(visualBrushRenderer, null, _window._deviceContext);
}
}
protected override IRenderTarget CreateRenderTarget() => new D3DRenderTarget(this);
}
}

14
samples/interop/Direct3DInteropSample/MainWindow.paml

@ -1,14 +0,0 @@
<Window xmlns="https://github.com/avaloniaui" Background="White" Title="Avalonia Direct3D Demo">
<Grid ColumnDefinitions="*,Auto" Margin="20">
<StackPanel Grid.Column="1" MinWidth="200">
<TextBlock>Rotation X</TextBlock>
<Slider Value="{Binding RotationX, Mode=TwoWay}" Maximum="10"/>
<TextBlock>Rotation Y</TextBlock>
<Slider Value="{Binding RotationY, Mode=TwoWay}" Maximum="10"/>
<TextBlock>Rotation Z</TextBlock>
<Slider Value="{Binding RotationZ, Mode=TwoWay}" Maximum="10"/>
<TextBlock>Zoom</TextBlock>
<Slider Value="{Binding Zoom, Mode=TwoWay}" Maximum="3" Minimum="0.5"/>
</StackPanel>
</Grid>
</Window>

45
samples/interop/Direct3DInteropSample/MainWindowViewModel.cs

@ -1,45 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MiniMvvm;
namespace Direct3DInteropSample
{
public class MainWindowViewModel : ViewModelBase
{
private double _rotationX;
public double RotationX
{
get { return _rotationX; }
set { this.RaiseAndSetIfChanged(ref _rotationX, value); }
}
private double _rotationY = 1;
public double RotationY
{
get { return _rotationY; }
set { this.RaiseAndSetIfChanged(ref _rotationY, value); }
}
private double _rotationZ = 2;
public double RotationZ
{
get { return _rotationZ; }
set { this.RaiseAndSetIfChanged(ref _rotationZ, value); }
}
private double _zoom = 1;
public double Zoom
{
get { return _zoom; }
set { this.RaiseAndSetIfChanged(ref _zoom, value); }
}
}
}

47
samples/interop/Direct3DInteropSample/MiniCube.fx

@ -1,47 +0,0 @@
// Copyright (c) 2010-2013 SharpDX - Alexandre Mutel
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
struct VS_IN
{
float4 pos : POSITION;
float4 col : COLOR;
};
struct PS_IN
{
float4 pos : SV_POSITION;
float4 col : COLOR;
};
float4x4 worldViewProj;
PS_IN VS( VS_IN input )
{
PS_IN output = (PS_IN)0;
output.pos = mul(input.pos, worldViewProj);
output.col = input.col;
return output;
}
float4 PS( PS_IN input ) : SV_Target
{
return input.col;
}

16
samples/interop/Direct3DInteropSample/Program.cs

@ -1,16 +0,0 @@
using Avalonia;
namespace Direct3DInteropSample
{
class Program
{
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.With(new Win32PlatformOptions { UseDeferredRendering = false })
.UseWin32()
.UseDirect2D1();
public static int Main(string[] args)
=> BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
}
}

2
src/Android/Avalonia.Android/Platform/SkiaPlatform/AndroidFramebuffer.cs

@ -96,12 +96,14 @@ namespace Avalonia.Android.Platform.SkiaPlatform
public IntPtr bits; public IntPtr bits;
// Do not touch. // Do not touch.
#pragma warning disable CA1823 // Avoid unused private fields
uint reserved1; uint reserved1;
uint reserved2; uint reserved2;
uint reserved3; uint reserved3;
uint reserved4; uint reserved4;
uint reserved5; uint reserved5;
uint reserved6; uint reserved6;
#pragma warning restore CA1823 // Avoid unused private fields
} }
} }
} }

9
src/Avalonia.Base/CornerRadius.cs

@ -61,9 +61,13 @@ namespace Avalonia
public double BottomLeft { get; } public double BottomLeft { get; }
/// <summary> /// <summary>
/// Gets a value indicating whether all corner radii are set to 0. /// Gets a value indicating whether the instance has default values (all corner radii are set to 0).
/// </summary> /// </summary>
public bool IsEmpty => TopLeft.Equals(0) && IsUniform; public bool IsDefault => TopLeft == 0 && TopRight == 0 && BottomLeft == 0 && BottomRight == 0;
/// <inheritdoc cref="IsDefault"/>
[Obsolete("Use IsDefault instead.")]
public bool IsEmpty => IsDefault;
/// <summary> /// <summary>
/// Gets a value indicating whether all corner radii are equal. /// Gets a value indicating whether all corner radii are equal.
@ -79,7 +83,6 @@ namespace Avalonia
{ {
// ReSharper disable CompareOfFloatsByEqualityOperator // ReSharper disable CompareOfFloatsByEqualityOperator
return TopLeft == other.TopLeft && return TopLeft == other.TopLeft &&
TopRight == other.TopRight && TopRight == other.TopRight &&
BottomRight == other.BottomRight && BottomRight == other.BottomRight &&
BottomLeft == other.BottomLeft; BottomLeft == other.BottomLeft;

2
src/Avalonia.Base/Data/Core/ExpressionNode.cs

@ -4,8 +4,6 @@ namespace Avalonia.Data.Core
{ {
public abstract class ExpressionNode public abstract class ExpressionNode
{ {
private static readonly object CacheInvalid = new object();
protected static readonly WeakReference<object?> UnsetReference = protected static readonly WeakReference<object?> UnsetReference =
new WeakReference<object?>(AvaloniaProperty.UnsetValue); new WeakReference<object?>(AvaloniaProperty.UnsetValue);

2
src/Avalonia.Base/Data/Core/ExpressionObserver.cs

@ -49,8 +49,6 @@ namespace Avalonia.Data.Core
new TaskStreamPlugin(), new TaskStreamPlugin(),
new ObservableStreamPlugin(), new ObservableStreamPlugin(),
}; };
private static readonly object UninitializedValue = new object();
private readonly ExpressionNode _node; private readonly ExpressionNode _node;
private object? _root; private object? _root;
private Func<object?>? _rootGetter; private Func<object?>? _rootGetter;

2
src/Avalonia.Base/Input/KeyEventArgs.cs

@ -5,7 +5,7 @@ namespace Avalonia.Input
{ {
public class KeyEventArgs : RoutedEventArgs public class KeyEventArgs : RoutedEventArgs
{ {
internal KeyEventArgs() public KeyEventArgs()
{ {
} }

2
src/Avalonia.Base/Input/TextInputEventArgs.cs

@ -4,7 +4,7 @@ namespace Avalonia.Input
{ {
public class TextInputEventArgs : RoutedEventArgs public class TextInputEventArgs : RoutedEventArgs
{ {
internal TextInputEventArgs() public TextInputEventArgs()
{ {
} }

11
src/Avalonia.Base/Media/BoxShadow.cs

@ -45,7 +45,14 @@ namespace Avalonia.Media
} }
} }
public bool IsEmpty => OffsetX == 0 && OffsetY == 0 && Blur == 0 && Spread == 0; /// <summary>
/// Gets a value indicating whether the instance has default values.
/// </summary>
public bool IsDefault => OffsetX == 0 && OffsetY == 0 && Blur == 0 && Spread == 0;
/// <inheritdoc cref="IsDefault"/>
[Obsolete("Use IsDefault instead.")]
public bool IsEmpty => IsDefault;
private readonly static char[] s_Separator = new char[] { ' ', '\t' }; private readonly static char[] s_Separator = new char[] { ' ', '\t' };
@ -82,7 +89,7 @@ namespace Avalonia.Media
{ {
var sb = StringBuilderCache.Acquire(); var sb = StringBuilderCache.Acquire();
if (IsEmpty) if (IsDefault)
{ {
return "none"; return "none";
} }

4
src/Avalonia.Base/Media/BoxShadows.cs

@ -21,7 +21,7 @@ namespace Avalonia.Media
{ {
_first = shadow; _first = shadow;
_list = null; _list = null;
Count = _first.IsEmpty ? 0 : 1; Count = _first.IsDefault ? 0 : 1;
} }
public BoxShadows(BoxShadow first, BoxShadow[] rest) public BoxShadows(BoxShadow first, BoxShadow[] rest)
@ -120,7 +120,7 @@ namespace Avalonia.Media
get get
{ {
foreach(var boxShadow in this) foreach(var boxShadow in this)
if (!boxShadow.IsEmpty && boxShadow.IsInset) if (!boxShadow.IsDefault && boxShadow.IsInset)
return true; return true;
return false; return false;
} }

8
src/Avalonia.Base/Media/DashStyle.cs

@ -17,8 +17,8 @@ namespace Avalonia.Media
/// <summary> /// <summary>
/// Defines the <see cref="Dashes"/> property. /// Defines the <see cref="Dashes"/> property.
/// </summary> /// </summary>
public static readonly StyledProperty<AvaloniaList<double>> DashesProperty = public static readonly StyledProperty<AvaloniaList<double>?> DashesProperty =
AvaloniaProperty.Register<DashStyle, AvaloniaList<double>>(nameof(Dashes)); AvaloniaProperty.Register<DashStyle, AvaloniaList<double>?>(nameof(Dashes));
/// <summary> /// <summary>
/// Defines the <see cref="Offset"/> property. /// Defines the <see cref="Offset"/> property.
@ -83,7 +83,7 @@ namespace Avalonia.Media
/// <summary> /// <summary>
/// Gets or sets the length of alternating dashes and gaps. /// Gets or sets the length of alternating dashes and gaps.
/// </summary> /// </summary>
public AvaloniaList<double> Dashes public AvaloniaList<double>? Dashes
{ {
get => GetValue(DashesProperty); get => GetValue(DashesProperty);
set => SetValue(DashesProperty, value); set => SetValue(DashesProperty, value);
@ -98,7 +98,7 @@ namespace Avalonia.Media
set => SetValue(OffsetProperty, value); set => SetValue(OffsetProperty, value);
} }
IReadOnlyList<double> IDashStyle.Dashes => Dashes; IReadOnlyList<double>? IDashStyle.Dashes => Dashes;
/// <summary> /// <summary>
/// Raised when the dash style changes. /// Raised when the dash style changes.

2
src/Avalonia.Base/Media/FormattedText.cs

@ -1379,7 +1379,7 @@ namespace Avalonia.Media
} }
} }
if (accumulatedBounds?.PlatformImpl == null || accumulatedBounds.PlatformImpl.Bounds.IsEmpty) if (accumulatedBounds?.PlatformImpl == null || accumulatedBounds.PlatformImpl.Bounds.IsDefault)
{ {
return null; return null;
} }

4
src/Avalonia.Base/Media/Geometry.cs

@ -30,7 +30,7 @@ namespace Avalonia.Media
/// <summary> /// <summary>
/// Gets the geometry's bounding rectangle. /// Gets the geometry's bounding rectangle.
/// </summary> /// </summary>
public Rect Bounds => PlatformImpl?.Bounds ?? Rect.Empty; public Rect Bounds => PlatformImpl?.Bounds ?? default;
/// <summary> /// <summary>
/// Gets the platform-specific implementation of the geometry. /// Gets the platform-specific implementation of the geometry.
@ -84,7 +84,7 @@ namespace Avalonia.Media
/// </summary> /// </summary>
/// <param name="pen">The stroke thickness.</param> /// <param name="pen">The stroke thickness.</param>
/// <returns>The bounding rectangle.</returns> /// <returns>The bounding rectangle.</returns>
public Rect GetRenderBounds(IPen pen) => PlatformImpl?.GetRenderBounds(pen) ?? Rect.Empty; public Rect GetRenderBounds(IPen pen) => PlatformImpl?.GetRenderBounds(pen) ?? default;
/// <summary> /// <summary>
/// Indicates whether the geometry's fill contains the specified point. /// Indicates whether the geometry's fill contains the specified point.

2
src/Avalonia.Base/Media/GeometryDrawing.cs

@ -69,7 +69,7 @@ namespace Avalonia.Media
public override Rect GetBounds() public override Rect GetBounds()
{ {
IPen pen = Pen ?? s_boundsPen; IPen pen = Pen ?? s_boundsPen;
return Geometry?.GetRenderBounds(pen) ?? Rect.Empty; return Geometry?.GetRenderBounds(pen) ?? default;
} }
} }
} }

2
src/Avalonia.Base/Media/GlyphRunDrawing.cs

@ -32,7 +32,7 @@
public override Rect GetBounds() public override Rect GetBounds()
{ {
return GlyphRun != null ? new Rect(GlyphRun.Size) : Rect.Empty; return GlyphRun != null ? new Rect(GlyphRun.Size) : default;
} }
} }
} }

2
src/Avalonia.Base/Media/IDashStyle.cs

@ -12,7 +12,7 @@ namespace Avalonia.Media
/// <summary> /// <summary>
/// Gets or sets the length of alternating dashes and gaps. /// Gets or sets the length of alternating dashes and gaps.
/// </summary> /// </summary>
IReadOnlyList<double> Dashes { get; } IReadOnlyList<double>? Dashes { get; }
/// <summary> /// <summary>
/// Gets or sets how far in the dash sequence the stroke will start. /// Gets or sets how far in the dash sequence the stroke will start.

2
src/Avalonia.Base/Media/ImageDrawing.cs

@ -42,7 +42,7 @@ namespace Avalonia.Media
var imageSource = ImageSource; var imageSource = ImageSource;
var rect = Rect; var rect = Rect;
if (imageSource is object && !rect.IsEmpty) if (imageSource is object && !rect.IsDefault)
{ {
context.DrawImage(imageSource, rect); context.DrawImage(imageSource, rect);
} }

4
src/Avalonia.Base/Media/Imaging/CroppedBitmap.cs

@ -78,8 +78,8 @@ namespace Avalonia.Media.Imaging
get get
{ {
if (Source is not IBitmap bmp) if (Source is not IBitmap bmp)
return Size.Empty; return default;
if (SourceRect.IsEmpty) if (SourceRect.IsDefault)
return Source.Size; return Source.Size;
return SourceRect.Size.ToSizeWithDpi(bmp.Dpi); return SourceRect.Size.ToSizeWithDpi(bmp.Dpi);
} }

4
src/Avalonia.Base/Media/Immutable/ImmutableDashStyle.cs

@ -17,7 +17,7 @@ namespace Avalonia.Media.Immutable
/// </summary> /// </summary>
/// <param name="dashes">The dashes collection.</param> /// <param name="dashes">The dashes collection.</param>
/// <param name="offset">The dash sequence offset.</param> /// <param name="offset">The dash sequence offset.</param>
public ImmutableDashStyle(IEnumerable<double> dashes, double offset) public ImmutableDashStyle(IEnumerable<double>? dashes, double offset)
{ {
_dashes = dashes?.ToArray() ?? Array.Empty<double>(); _dashes = dashes?.ToArray() ?? Array.Empty<double>();
Offset = offset; Offset = offset;
@ -69,7 +69,7 @@ namespace Avalonia.Media.Immutable
return hashCode; return hashCode;
} }
private static bool SequenceEqual(IReadOnlyList<double> left, IReadOnlyList<double> right) private static bool SequenceEqual(IReadOnlyList<double> left, IReadOnlyList<double>? right)
{ {
if (ReferenceEquals(left, right)) if (ReferenceEquals(left, right))
{ {

1
src/Avalonia.Base/Media/TextFormatting/FormattedTextSource.cs

@ -8,7 +8,6 @@ namespace Avalonia.Media.TextFormatting
internal readonly struct FormattedTextSource : ITextSource internal readonly struct FormattedTextSource : ITextSource
{ {
private readonly CharacterBufferRange _text; private readonly CharacterBufferRange _text;
private readonly int length;
private readonly TextRunProperties _defaultProperties; private readonly TextRunProperties _defaultProperties;
private readonly IReadOnlyList<ValueSpan<TextRunProperties>>? _textModifier; private readonly IReadOnlyList<ValueSpan<TextRunProperties>>? _textModifier;

4
src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs

@ -532,7 +532,7 @@ namespace Avalonia.Media.TextFormatting
var startX = Start; var startX = Start;
double currentWidth = 0; double currentWidth = 0;
var currentRect = Rect.Empty; var currentRect = default(Rect);
TextRunBounds lastRunBounds = default; TextRunBounds lastRunBounds = default;
@ -748,7 +748,7 @@ namespace Avalonia.Media.TextFormatting
var startX = WidthIncludingTrailingWhitespace; var startX = WidthIncludingTrailingWhitespace;
double currentWidth = 0; double currentWidth = 0;
var currentRect = Rect.Empty; var currentRect = default(Rect);
for (var index = TextRuns.Count - 1; index >= 0; index--) for (var index = TextRuns.Count - 1; index >= 0; index--)
{ {

1
src/Avalonia.Base/Media/TextFormatting/Unicode/CodepointEnumerator.cs

@ -5,7 +5,6 @@ namespace Avalonia.Media.TextFormatting.Unicode
public ref struct CodepointEnumerator public ref struct CodepointEnumerator
{ {
private CharacterBufferRange _text; private CharacterBufferRange _text;
private int _pos;
public CodepointEnumerator(CharacterBufferRange text) public CodepointEnumerator(CharacterBufferRange text)
{ {

2
src/Avalonia.Base/Media/UnicodeRange.cs

@ -104,7 +104,7 @@ namespace Avalonia.Media
public readonly record struct UnicodeRangeSegment public readonly record struct UnicodeRangeSegment
{ {
private static Regex s_regex = new Regex(@"^(?:[uU]\+)?(?:([0-9a-fA-F](?:[0-9a-fA-F?]{1,5})?))$"); private static Regex s_regex = new Regex(@"^(?:[uU]\+)?(?:([0-9a-fA-F](?:[0-9a-fA-F?]{1,5})?))$", RegexOptions.Compiled);
public UnicodeRangeSegment(int start, int end) public UnicodeRangeSegment(int start, int end)
{ {

15
src/Avalonia.Base/PixelRect.cs

@ -12,6 +12,7 @@ namespace Avalonia
/// <summary> /// <summary>
/// An empty rectangle. /// An empty rectangle.
/// </summary> /// </summary>
[Obsolete("Use the default keyword instead.")]
public static readonly PixelRect Empty = default; public static readonly PixelRect Empty = default;
/// <summary> /// <summary>
@ -133,9 +134,13 @@ namespace Avalonia
public PixelPoint Center => new PixelPoint(X + (Width / 2), Y + (Height / 2)); public PixelPoint Center => new PixelPoint(X + (Width / 2), Y + (Height / 2));
/// <summary> /// <summary>
/// Gets a value that indicates whether the rectangle is empty. /// Gets a value indicating whether the instance has default values (the rectangle is empty).
/// </summary> /// </summary>
public bool IsEmpty => Width == 0 && Height == 0; public bool IsDefault => Width == 0 && Height == 0;
/// <inheritdoc cref="IsDefault"/>
[Obsolete("Use IsDefault instead.")]
public bool IsEmpty => IsDefault;
/// <summary> /// <summary>
/// Checks for equality between two <see cref="PixelRect"/>s. /// Checks for equality between two <see cref="PixelRect"/>s.
@ -257,7 +262,7 @@ namespace Avalonia
} }
else else
{ {
return Empty; return default;
} }
} }
@ -290,11 +295,11 @@ namespace Avalonia
/// <returns>The union.</returns> /// <returns>The union.</returns>
public PixelRect Union(PixelRect rect) public PixelRect Union(PixelRect rect)
{ {
if (IsEmpty) if (IsDefault)
{ {
return rect; return rect;
} }
else if (rect.IsEmpty) else if (rect.IsDefault)
{ {
return this; return this;
} }

1
src/Avalonia.Base/Platform/ITextShaperImpl.cs

@ -13,6 +13,7 @@ namespace Avalonia.Platform
/// Shapes the specified region within the text and returns a shaped buffer. /// Shapes the specified region within the text and returns a shaped buffer.
/// </summary> /// </summary>
/// <param name="text">The text buffer.</param> /// <param name="text">The text buffer.</param>
/// <param name="length">The length of text.</param>
/// <param name="options">Text shaper options to customize the shaping process.</param> /// <param name="options">Text shaper options to customize the shaping process.</param>
/// <returns>A shaped glyph run.</returns> /// <returns>A shaped glyph run.</returns>
ShapedBuffer ShapeText(CharacterBufferReference text, int length, TextShaperOptions options); ShapedBuffer ShapeText(CharacterBufferReference text, int length, TextShaperOptions options);

45
src/Avalonia.Base/PropertyStore/BindingEntryBase.cs

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using Avalonia.Data; using Avalonia.Data;
using Avalonia.Threading;
namespace Avalonia.PropertyStore namespace Avalonia.PropertyStore
{ {
@ -116,26 +117,42 @@ namespace Avalonia.PropertyStore
private void SetValue(BindingValue<TValue> value) private void SetValue(BindingValue<TValue> value)
{ {
if (Frame.Owner is null) static void Execute(BindingEntryBase<TValue, TSource> instance, BindingValue<TValue> value)
return; {
if (instance.Frame.Owner is null)
return;
LoggingUtils.LogIfNecessary(Frame.Owner.Owner, Property, value); LoggingUtils.LogIfNecessary(instance.Frame.Owner.Owner, instance.Property, value);
if (value.HasValue) if (value.HasValue)
{ {
if (!_hasValue || !EqualityComparer<TValue>.Default.Equals(_value, value.Value)) if (!instance._hasValue || !EqualityComparer<TValue>.Default.Equals(instance._value, value.Value))
{
instance._value = value.Value;
instance._hasValue = true;
if (instance._subscription is not null && instance._subscription != s_creatingQuiet)
instance.Frame.Owner?.OnBindingValueChanged(instance, instance.Frame.Priority);
}
}
else if (value.Type != BindingValueType.DoNothing)
{ {
_value = value.Value; instance.ClearValue();
_hasValue = true; if (instance._subscription is not null && instance._subscription != s_creatingQuiet)
if (_subscription is not null && _subscription != s_creatingQuiet) instance.Frame.Owner?.OnBindingValueCleared(instance.Property, instance.Frame.Priority);
Frame.Owner?.OnBindingValueChanged(this, Frame.Priority);
} }
} }
else if (value.Type != BindingValueType.DoNothing)
if (Dispatcher.UIThread.CheckAccess())
{ {
ClearValue(); Execute(this, value);
if (_subscription is not null && _subscription != s_creatingQuiet) }
Frame.Owner?.OnBindingValueCleared(Property, Frame.Priority); else
{
// To avoid allocating closure in the outer scope we need to capture variables
// locally. This allows us to skip most of the allocations when on UI thread.
var instance = this;
var newValue = value;
Dispatcher.UIThread.Post(() => Execute(instance, newValue));
} }
} }

53
src/Avalonia.Base/PropertyStore/LocalValueBindingObserver.cs

@ -1,5 +1,6 @@
using System; using System;
using Avalonia.Data; using Avalonia.Data;
using Avalonia.Threading;
namespace Avalonia.PropertyStore namespace Avalonia.PropertyStore
{ {
@ -40,20 +41,56 @@ namespace Avalonia.PropertyStore
public void OnNext(T value) public void OnNext(T value)
{ {
if (Property.ValidateValue?.Invoke(value) != false) static void Execute(ValueStore owner, StyledPropertyBase<T> property, T value)
_owner.SetValue(Property, value, BindingPriority.LocalValue); {
if (property.ValidateValue?.Invoke(value) != false)
owner.SetValue(property, value, BindingPriority.LocalValue);
else
owner.ClearLocalValue(property);
}
if (Dispatcher.UIThread.CheckAccess())
{
Execute(_owner, Property, value);
}
else else
_owner.ClearLocalValue(Property); {
// To avoid allocating closure in the outer scope we need to capture variables
// locally. This allows us to skip most of the allocations when on UI thread.
var instance = _owner;
var property = Property;
var newValue = value;
Dispatcher.UIThread.Post(() => Execute(instance, property, newValue));
}
} }
public void OnNext(BindingValue<T> value) public void OnNext(BindingValue<T> value)
{ {
LoggingUtils.LogIfNecessary(_owner.Owner, Property, value); static void Execute(LocalValueBindingObserver<T> instance, BindingValue<T> value)
{
var owner = instance._owner;
var property = instance.Property;
LoggingUtils.LogIfNecessary(owner.Owner, property, value);
if (value.HasValue) if (value.HasValue)
_owner.SetValue(Property, value.Value, BindingPriority.LocalValue); owner.SetValue(property, value.Value, BindingPriority.LocalValue);
else if (value.Type != BindingValueType.DataValidationError) else if (value.Type != BindingValueType.DataValidationError)
_owner.ClearLocalValue(Property); owner.ClearLocalValue(property);
}
if (Dispatcher.UIThread.CheckAccess())
{
Execute(this, value);
}
else
{
// To avoid allocating closure in the outer scope we need to capture variables
// locally. This allows us to skip most of the allocations when on UI thread.
var instance = this;
var newValue = value;
Dispatcher.UIThread.Post(() => Execute(instance, newValue));
}
} }
} }
} }

53
src/Avalonia.Base/PropertyStore/LocalValueUntypedBindingObserver.cs

@ -1,5 +1,7 @@
using System; using System;
using System.Security.Cryptography;
using Avalonia.Data; using Avalonia.Data;
using Avalonia.Threading;
namespace Avalonia.PropertyStore namespace Avalonia.PropertyStore
{ {
@ -34,28 +36,47 @@ namespace Avalonia.PropertyStore
public void OnNext(object? value) public void OnNext(object? value)
{ {
if (value is BindingNotification n) static void Execute(LocalValueUntypedBindingObserver<T> instance, object? value)
{ {
value = n.Value; var owner = instance._owner;
LoggingUtils.LogIfNecessary(_owner.Owner, Property, n); var property = instance.Property;
}
if (value == AvaloniaProperty.UnsetValue) if (value is BindingNotification n)
{ {
_owner.ClearLocalValue(Property); value = n.Value;
} LoggingUtils.LogIfNecessary(owner.Owner, property, n);
else if (value == BindingOperations.DoNothing) }
{
// Do nothing! if (value == AvaloniaProperty.UnsetValue)
{
owner.ClearLocalValue(property);
}
else if (value == BindingOperations.DoNothing)
{
// Do nothing!
}
else if (UntypedValueUtils.TryConvertAndValidate(property, value, out var typedValue))
{
owner.SetValue(property, typedValue, BindingPriority.LocalValue);
}
else
{
owner.ClearLocalValue(property);
LoggingUtils.LogInvalidValue(owner.Owner, property, typeof(T), value);
}
} }
else if (UntypedValueUtils.TryConvertAndValidate(Property, value, out var typedValue))
if (Dispatcher.UIThread.CheckAccess())
{ {
_owner.SetValue(Property, typedValue, BindingPriority.LocalValue); Execute(this, value);
} }
else else if (value != BindingOperations.DoNothing)
{ {
_owner.ClearLocalValue(Property); // To avoid allocating closure in the outer scope we need to capture variables
LoggingUtils.LogInvalidValue(_owner.Owner, Property, typeof(T), value); // locally. This allows us to skip most of the allocations when on UI thread.
var instance = this;
var newValue = value;
Dispatcher.UIThread.Post(() => Execute(instance, newValue));
} }
} }
} }

21
src/Avalonia.Base/Rect.cs

@ -18,7 +18,8 @@ namespace Avalonia
/// <summary> /// <summary>
/// An empty rectangle. /// An empty rectangle.
/// </summary> /// </summary>
public static readonly Rect Empty = default(Rect); [Obsolete("Use the default keyword instead.")]
public static readonly Rect Empty = default;
/// <summary> /// <summary>
/// The X position. /// The X position.
@ -169,12 +170,16 @@ namespace Avalonia
public Point Center => new Point(_x + (_width / 2), _y + (_height / 2)); public Point Center => new Point(_x + (_width / 2), _y + (_height / 2));
/// <summary> /// <summary>
/// Gets a value that indicates whether the rectangle is empty. /// Gets a value indicating whether the instance has default values (the rectangle is empty).
/// </summary> /// </summary>
// ReSharper disable CompareOfFloatsByEqualityOperator // ReSharper disable CompareOfFloatsByEqualityOperator
public bool IsEmpty => _width == 0 && _height == 0; public bool IsDefault => _width == 0 && _height == 0;
// ReSharper restore CompareOfFloatsByEqualityOperator // ReSharper restore CompareOfFloatsByEqualityOperator
/// <inheritdoc cref="IsDefault"/>
[Obsolete("Use IsDefault instead.")]
public bool IsEmpty => IsDefault;
/// <summary> /// <summary>
/// Checks for equality between two <see cref="Rect"/>s. /// Checks for equality between two <see cref="Rect"/>s.
/// </summary> /// </summary>
@ -390,7 +395,7 @@ namespace Avalonia
} }
else else
{ {
return Empty; return default;
} }
} }
@ -457,13 +462,13 @@ namespace Avalonia
/// </remarks> /// </remarks>
public Rect Normalize() public Rect Normalize()
{ {
Rect rect = this; Rect rect = this;
if(double.IsNaN(rect.Right) || double.IsNaN(rect.Bottom) || if(double.IsNaN(rect.Right) || double.IsNaN(rect.Bottom) ||
double.IsNaN(rect.X) || double.IsNaN(rect.Y) || double.IsNaN(rect.X) || double.IsNaN(rect.Y) ||
double.IsNaN(Height) || double.IsNaN(Width)) double.IsNaN(Height) || double.IsNaN(Width))
{ {
return Rect.Empty; return default;
} }
if (rect.Width < 0) if (rect.Width < 0)
@ -493,11 +498,11 @@ namespace Avalonia
/// <returns>The union.</returns> /// <returns>The union.</returns>
public Rect Union(Rect rect) public Rect Union(Rect rect)
{ {
if (IsEmpty) if (IsDefault)
{ {
return rect; return rect;
} }
else if (rect.IsEmpty) else if (rect.IsDefault)
{ {
return this; return this;
} }

2
src/Avalonia.Base/Rendering/Composition/Server/DrawingContextProxy.cs

@ -163,7 +163,7 @@ internal class CompositorDrawingContextProxy : IDrawingContextImpl, IDrawingCont
public CompositionDrawList? VisualBrushDrawList { get; set; } public CompositionDrawList? VisualBrushDrawList { get; set; }
public Size GetRenderTargetSize(IVisualBrush brush) public Size GetRenderTargetSize(IVisualBrush brush)
{ {
return VisualBrushDrawList?.Size ?? Size.Empty; return VisualBrushDrawList?.Size ?? default;
} }
public void RenderVisualBrush(IDrawingContextImpl context, IVisualBrush brush) public void RenderVisualBrush(IDrawingContextImpl context, IVisualBrush brush)

2
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionDrawListVisual.cs

@ -37,7 +37,7 @@ internal class ServerCompositionDrawListVisual : ServerCompositionContainerVisua
{ {
if (_contentBounds == null) if (_contentBounds == null)
{ {
var rect = Rect.Empty; var rect = default(Rect);
if(_renderCommands!=null) if(_renderCommands!=null)
foreach (var cmd in _renderCommands) foreach (var cmd in _renderCommands)
rect = rect.Union(cmd.Item.Bounds); rect = rect.Union(cmd.Item.Bounds);

8
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionTarget.cs

@ -88,7 +88,7 @@ namespace Avalonia.Rendering.Composition.Server
_renderTarget ??= _compositor.CreateRenderTarget(_surfaces()); _renderTarget ??= _compositor.CreateRenderTarget(_surfaces());
if(_dirtyRect.IsEmpty && !_redrawRequested) if(_dirtyRect.IsDefault && !_redrawRequested)
return; return;
Revision++; Revision++;
@ -117,7 +117,7 @@ namespace Avalonia.Rendering.Composition.Server
_dirtyRect = new Rect(0, 0, layerSize.Width, layerSize.Height); _dirtyRect = new Rect(0, 0, layerSize.Width, layerSize.Height);
} }
if (!_dirtyRect.IsEmpty) if (!_dirtyRect.IsDefault)
{ {
var visualBrushHelper = new CompositorDrawingContextProxy.VisualBrushRenderer(); var visualBrushHelper = new CompositorDrawingContextProxy.VisualBrushRenderer();
using (var context = _layer.CreateDrawingContext(visualBrushHelper)) using (var context = _layer.CreateDrawingContext(visualBrushHelper))
@ -160,7 +160,7 @@ namespace Avalonia.Rendering.Composition.Server
} }
RenderedVisuals = 0; RenderedVisuals = 0;
_dirtyRect = Rect.Empty; _dirtyRect = default;
} }
} }
@ -179,7 +179,7 @@ namespace Avalonia.Rendering.Composition.Server
public void AddDirtyRect(Rect rect) public void AddDirtyRect(Rect rect)
{ {
if(rect.IsEmpty) if(rect.IsDefault)
return; return;
var snapped = SnapToDevicePixels(rect, Scaling); var snapped = SnapToDevicePixels(rect, Scaling);
DebugEvents?.RectInvalidated(rect); DebugEvents?.RectInvalidated(rect);

8
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.cs

@ -37,7 +37,7 @@ namespace Avalonia.Rendering.Composition.Server
return; return;
currentTransformedClip = currentTransformedClip.Intersect(_combinedTransformedClipBounds); currentTransformedClip = currentTransformedClip.Intersect(_combinedTransformedClipBounds);
if(currentTransformedClip.IsEmpty) if(currentTransformedClip.IsDefault)
return; return;
Root!.RenderedVisuals++; Root!.RenderedVisuals++;
@ -139,7 +139,7 @@ namespace Avalonia.Rendering.Composition.Server
if (ownBounds != _oldOwnContentBounds || positionChanged) if (ownBounds != _oldOwnContentBounds || positionChanged)
{ {
_oldOwnContentBounds = ownBounds; _oldOwnContentBounds = ownBounds;
if (ownBounds.IsEmpty) if (ownBounds.IsDefault)
TransformedOwnContentBounds = default; TransformedOwnContentBounds = default;
else else
TransformedOwnContentBounds = TransformedOwnContentBounds =
@ -163,7 +163,7 @@ namespace Avalonia.Rendering.Composition.Server
EffectiveOpacity = Opacity * (Parent?.EffectiveOpacity ?? 1); EffectiveOpacity = Opacity * (Parent?.EffectiveOpacity ?? 1);
IsVisibleInFrame = _parent?.IsVisibleInFrame != false && Visible && EffectiveOpacity > 0.04 && !_isBackface && IsVisibleInFrame = _parent?.IsVisibleInFrame != false && Visible && EffectiveOpacity > 0.04 && !_isBackface &&
!_combinedTransformedClipBounds.IsEmpty; !_combinedTransformedClipBounds.IsDefault;
if (wasVisible != IsVisibleInFrame || positionChanged) if (wasVisible != IsVisibleInFrame || positionChanged)
{ {
@ -192,7 +192,7 @@ namespace Avalonia.Rendering.Composition.Server
void AddDirtyRect(Rect rc) void AddDirtyRect(Rect rc)
{ {
if(rc == Rect.Empty) if(rc == default)
return; return;
Root?.AddDirtyRect(rc); Root?.AddDirtyRect(rc);
} }

6
src/Avalonia.Base/Rendering/DeferredRenderer.cs

@ -49,6 +49,8 @@ namespace Avalonia.Rendering
/// </summary> /// </summary>
/// <param name="root">The control to render.</param> /// <param name="root">The control to render.</param>
/// <param name="renderLoop">The render loop.</param> /// <param name="renderLoop">The render loop.</param>
/// <param name="renderTargetFactory">The target render factory.</param>
/// <param name="renderInterface">The Platform Render Context.</param>
/// <param name="sceneBuilder">The scene builder to use. Optional.</param> /// <param name="sceneBuilder">The scene builder to use. Optional.</param>
/// <param name="dispatcher">The dispatcher to use. Optional.</param> /// <param name="dispatcher">The dispatcher to use. Optional.</param>
/// <param name="rendererLock">Lock object used before trying to access render target</param> /// <param name="rendererLock">Lock object used before trying to access render target</param>
@ -309,7 +311,7 @@ namespace Avalonia.Rendering
/// <inheritdoc/> /// <inheritdoc/>
Size IVisualBrushRenderer.GetRenderTargetSize(IVisualBrush brush) Size IVisualBrushRenderer.GetRenderTargetSize(IVisualBrush brush)
{ {
return TryGetChildScene(_currentDraw)?.Size ?? Size.Empty; return TryGetChildScene(_currentDraw)?.Size ?? default;
} }
/// <inheritdoc/> /// <inheritdoc/>
@ -461,7 +463,7 @@ namespace Avalonia.Rendering
{ {
clipBounds = node.ClipBounds.Intersect(clipBounds); clipBounds = node.ClipBounds.Intersect(clipBounds);
if (!clipBounds.IsEmpty && node.Opacity > 0) if (!clipBounds.IsDefault && node.Opacity > 0)
{ {
var isLayerRoot = node.Visual == layer; var isLayerRoot = node.Visual == layer;

5
src/Avalonia.Base/Rendering/DirtyRects.cs

@ -10,6 +10,9 @@ namespace Avalonia.Rendering
{ {
private List<Rect> _rects = new List<Rect>(); private List<Rect> _rects = new List<Rect>();
/// <summary>
/// Gets a value indicating whether the collection of dirty rectangles is empty.
/// </summary>
public bool IsEmpty => _rects.Count == 0; public bool IsEmpty => _rects.Count == 0;
/// <summary> /// <summary>
@ -27,7 +30,7 @@ namespace Avalonia.Rendering
/// </remarks> /// </remarks>
public void Add(Rect rect) public void Add(Rect rect)
{ {
if (!rect.IsEmpty) if (!rect.IsDefault)
{ {
for (var i = 0; i < _rects.Count; ++i) for (var i = 0; i < _rects.Count; ++i)
{ {

6
src/Avalonia.Base/Rendering/ImmediateRenderer.cs

@ -30,6 +30,8 @@ namespace Avalonia.Rendering
/// Initializes a new instance of the <see cref="ImmediateRenderer"/> class. /// Initializes a new instance of the <see cref="ImmediateRenderer"/> class.
/// </summary> /// </summary>
/// <param name="root">The control to render.</param> /// <param name="root">The control to render.</param>
/// <param name="renderTargetFactory">The target render factory.</param>
/// <param name="renderContext">The render contex.</param>
public ImmediateRenderer(Visual root, Func<IRenderTarget> renderTargetFactory, public ImmediateRenderer(Visual root, Func<IRenderTarget> renderTargetFactory,
PlatformRenderInterfaceContextManager? renderContext = null) PlatformRenderInterfaceContextManager? renderContext = null)
{ {
@ -136,7 +138,7 @@ namespace Avalonia.Rendering
/// <inheritdoc/> /// <inheritdoc/>
public void AddDirty(Visual visual) public void AddDirty(Visual visual)
{ {
if (visual.Bounds != Rect.Empty) if (!visual.Bounds.IsDefault)
{ {
var m = visual.TransformToVisual(_root); var m = visual.TransformToVisual(_root);
@ -201,7 +203,7 @@ namespace Avalonia.Rendering
Size IVisualBrushRenderer.GetRenderTargetSize(IVisualBrush brush) Size IVisualBrushRenderer.GetRenderTargetSize(IVisualBrush brush)
{ {
(brush.Visual as IVisualBrushInitialize)?.EnsureInitialized(); (brush.Visual as IVisualBrushInitialize)?.EnsureInitialized();
return brush.Visual?.Bounds.Size ?? Size.Empty; return brush.Visual?.Bounds.Size ?? default;
} }
/// <inheritdoc/> /// <inheritdoc/>

2
src/Avalonia.Base/Rendering/SceneGraph/BitmapBlendModeNode.cs

@ -27,7 +27,7 @@ namespace Avalonia.Rendering.SceneGraph
} }
/// <inheritdoc/> /// <inheritdoc/>
public Rect Bounds => Rect.Empty; public Rect Bounds => default;
/// <summary> /// <summary>
/// Gets the BitmapBlend to be pushed or null if the operation represents a pop. /// Gets the BitmapBlend to be pushed or null if the operation represents a pop.

2
src/Avalonia.Base/Rendering/SceneGraph/ClipNode.cs

@ -40,7 +40,7 @@ namespace Avalonia.Rendering.SceneGraph
} }
/// <inheritdoc/> /// <inheritdoc/>
public Rect Bounds => Rect.Empty; public Rect Bounds => default;
/// <summary> /// <summary>
/// Gets the clip to be pushed or null if the operation represents a pop. /// Gets the clip to be pushed or null if the operation represents a pop.

2
src/Avalonia.Base/Rendering/SceneGraph/GeometryClipNode.cs

@ -28,7 +28,7 @@ namespace Avalonia.Rendering.SceneGraph
} }
/// <inheritdoc/> /// <inheritdoc/>
public Rect Bounds => Rect.Empty; public Rect Bounds => default;
/// <summary> /// <summary>
/// Gets the clip to be pushed or null if the operation represents a pop. /// Gets the clip to be pushed or null if the operation represents a pop.

4
src/Avalonia.Base/Rendering/SceneGraph/OpacityMaskNode.cs

@ -19,7 +19,7 @@ namespace Avalonia.Rendering.SceneGraph
/// <param name="bounds">The bounds of the mask.</param> /// <param name="bounds">The bounds of the mask.</param>
/// <param name="aux">Auxiliary data required to draw the brush.</param> /// <param name="aux">Auxiliary data required to draw the brush.</param>
public OpacityMaskNode(IBrush mask, Rect bounds, IDisposable? aux = null) public OpacityMaskNode(IBrush mask, Rect bounds, IDisposable? aux = null)
: base(Rect.Empty, Matrix.Identity, aux) : base(default, Matrix.Identity, aux)
{ {
Mask = mask.ToImmutable(); Mask = mask.ToImmutable();
MaskBounds = bounds; MaskBounds = bounds;
@ -30,7 +30,7 @@ namespace Avalonia.Rendering.SceneGraph
/// opacity mask pop. /// opacity mask pop.
/// </summary> /// </summary>
public OpacityMaskNode() public OpacityMaskNode()
: base(Rect.Empty, Matrix.Identity, null) : base(default, Matrix.Identity, null)
{ {
} }

2
src/Avalonia.Base/Rendering/SceneGraph/OpacityNode.cs

@ -26,7 +26,7 @@ namespace Avalonia.Rendering.SceneGraph
} }
/// <inheritdoc/> /// <inheritdoc/>
public Rect Bounds => Rect.Empty; public Rect Bounds => default;
/// <summary> /// <summary>
/// Gets the opacity to be pushed or null if the operation represents a pop. /// Gets the opacity to be pushed or null if the operation represents a pop.

6
src/Avalonia.Base/Rendering/SceneGraph/SceneBuilder.cs

@ -331,8 +331,8 @@ namespace Avalonia.Rendering.SceneGraph
scene.Size = newSize; scene.Size = newSize;
Rect horizontalDirtyRect = Rect.Empty; Rect horizontalDirtyRect = default;
Rect verticalDirtyRect = Rect.Empty; Rect verticalDirtyRect = default;
if (newSize.Width > oldSize.Width) if (newSize.Width > oldSize.Width)
{ {
@ -429,7 +429,7 @@ namespace Avalonia.Rendering.SceneGraph
else else
{ {
layer.OpacityMask = null; layer.OpacityMask = null;
layer.OpacityMaskRect = Rect.Empty; layer.OpacityMaskRect = default;
} }
layer.GeometryClip = node.HasAncestorGeometryClip ? layer.GeometryClip = node.HasAncestorGeometryClip ?

8
src/Avalonia.Base/Size.cs

@ -28,8 +28,9 @@ namespace Avalonia
public static readonly Size Infinity = new Size(double.PositiveInfinity, double.PositiveInfinity); public static readonly Size Infinity = new Size(double.PositiveInfinity, double.PositiveInfinity);
/// <summary> /// <summary>
/// A size representing zero /// A size representing zero.
/// </summary> /// </summary>
[Obsolete("Use the default keyword instead.")]
public static readonly Size Empty = new Size(0, 0); public static readonly Size Empty = new Size(0, 0);
/// <summary> /// <summary>
@ -309,9 +310,6 @@ namespace Avalonia
/// <summary> /// <summary>
/// Gets a value indicating whether the Width and Height values are zero. /// Gets a value indicating whether the Width and Height values are zero.
/// </summary> /// </summary>
public bool IsDefault public bool IsDefault => (_width == 0) && (_height == 0);
{
get { return (_width == 0) && (_height == 0); }
}
} }
} }

17
src/Avalonia.Base/Thickness.cs

@ -97,10 +97,9 @@ namespace Avalonia
/// </summary> /// </summary>
public double Bottom => _bottom; public double Bottom => _bottom;
/// <summary> /// <inheritdoc cref="IsDefault"/>
/// Gets a value indicating whether all sides are set to 0. [Obsolete("Use IsDefault instead.")]
/// </summary> public bool IsEmpty => IsDefault;
public bool IsEmpty => Left.Equals(0) && IsUniform;
/// <summary> /// <summary>
/// Gets a value indicating whether all sides are equal. /// Gets a value indicating whether all sides are equal.
@ -292,15 +291,13 @@ namespace Avalonia
left = this._left; left = this._left;
top = this._top; top = this._top;
right = this._right; right = this._right;
bottom = this._bottom; bottom = this._bottom;
} }
/// <summary> /// <summary>
/// Gets a value indicating whether the left, top, right and bottom thickness values are zero. /// Gets a value indicating whether the instance has default values
/// (the left, top, right and bottom values are zero).
/// </summary> /// </summary>
public bool IsDefault public bool IsDefault => (_left == 0) && (_top == 0) && (_right == 0) && (_bottom == 0);
{
get { return (_left == 0) && (_top == 0) && (_right == 0) && (_bottom == 0); }
}
} }
} }

24
src/Avalonia.Build.Tasks/GenerateAvaloniaResourcesTask.cs

@ -7,7 +7,7 @@ using System.Text;
using Avalonia.Markup.Xaml.PortableXaml; using Avalonia.Markup.Xaml.PortableXaml;
using Avalonia.Utilities; using Avalonia.Utilities;
using Microsoft.Build.Framework; using Microsoft.Build.Framework;
using SPath=System.IO.Path; using SPath = System.IO.Path;
namespace Avalonia.Build.Tasks namespace Avalonia.Build.Tasks
{ {
public class GenerateAvaloniaResourcesTask : ITask public class GenerateAvaloniaResourcesTask : ITask
@ -30,12 +30,17 @@ namespace Avalonia.Build.Tasks
private byte[] _data; private byte[] _data;
private string _sourcePath; private string _sourcePath;
public Source(string relativePath, string root) public Source(ITaskItem avaloniaResourceItem, string root)
{ {
root = SPath.GetFullPath(root); root = SPath.GetFullPath(root);
Path = "/" + relativePath.Replace('\\', '/'); var relativePath = avaloniaResourceItem.ItemSpec;
_sourcePath = SPath.Combine(root, relativePath); _sourcePath = SPath.Combine(root, relativePath);
Size = (int)new FileInfo(_sourcePath).Length; Size = (int)new FileInfo(_sourcePath).Length;
var link = avaloniaResourceItem.GetMetadata("Link");
var path = !string.IsNullOrEmpty(link)
? link
: relativePath;
Path = "/" + path.Replace('\\', '/');
} }
public string SystemPath => _sourcePath ?? Path; public string SystemPath => _sourcePath ?? Path;
@ -65,8 +70,7 @@ namespace Avalonia.Build.Tasks
List<Source> BuildResourceSources() List<Source> BuildResourceSources()
=> Resources.Select(r => => Resources.Select(r =>
{ {
var src = new Source(r, Root);
var src = new Source(r.ItemSpec, Root);
BuildEngine.LogMessage(FormattableString.Invariant($"avares -> name:{src.Path}, path: {src.SystemPath}, size:{src.Size}, ItemSpec:{r.ItemSpec}"), _reportImportance); BuildEngine.LogMessage(FormattableString.Invariant($"avares -> name:{src.Path}, path: {src.SystemPath}, size:{src.Size}, ItemSpec:{r.ItemSpec}"), _reportImportance);
return src; return src;
}).ToList(); }).ToList();
@ -93,15 +97,15 @@ namespace Avalonia.Build.Tasks
ms.CopyTo(output); ms.CopyTo(output);
foreach (var s in sources) foreach (var s in sources)
{ {
using(var input = s.Open()) using (var input = s.Open())
input.CopyTo(output); input.CopyTo(output);
} }
} }
private bool PreProcessXamlFiles(List<Source> sources) private bool PreProcessXamlFiles(List<Source> sources)
{ {
var typeToXamlIndex = new Dictionary<string, string>(); var typeToXamlIndex = new Dictionary<string, string>();
foreach (var s in sources.ToArray()) foreach (var s in sources.ToArray())
{ {
if (s.Path.ToLowerInvariant().EndsWith(".xaml") || s.Path.ToLowerInvariant().EndsWith(".paml") || s.Path.ToLowerInvariant().EndsWith(".axaml")) if (s.Path.ToLowerInvariant().EndsWith(".xaml") || s.Path.ToLowerInvariant().EndsWith(".paml") || s.Path.ToLowerInvariant().EndsWith(".axaml"))
@ -111,7 +115,7 @@ namespace Avalonia.Build.Tasks
{ {
info = XamlFileInfo.Parse(s.ReadAsString()); info = XamlFileInfo.Parse(s.ReadAsString());
} }
catch(Exception e) catch (Exception e)
{ {
BuildEngine.LogError(BuildEngineErrorCode.InvalidXAML, s.SystemPath, "File doesn't contain valid XAML: " + e); BuildEngine.LogError(BuildEngineErrorCode.InvalidXAML, s.SystemPath, "File doesn't contain valid XAML: " + e);
return false; return false;
@ -121,7 +125,7 @@ namespace Avalonia.Build.Tasks
{ {
if (typeToXamlIndex.ContainsKey(info.XClass)) if (typeToXamlIndex.ContainsKey(info.XClass))
{ {
BuildEngine.LogError(BuildEngineErrorCode.DuplicateXClass, s.SystemPath, BuildEngine.LogError(BuildEngineErrorCode.DuplicateXClass, s.SystemPath,
$"Duplicate x:Class directive, {info.XClass} is already used in {typeToXamlIndex[info.XClass]}"); $"Duplicate x:Class directive, {info.XClass} is already used in {typeToXamlIndex[info.XClass]}");
return false; return false;

5
src/Avalonia.Controls.DataGrid/DataGrid.cs

@ -48,7 +48,6 @@ namespace Avalonia.Controls
private const string DATAGRID_elementColumnHeadersPresenterName = "PART_ColumnHeadersPresenter"; private const string DATAGRID_elementColumnHeadersPresenterName = "PART_ColumnHeadersPresenter";
private const string DATAGRID_elementFrozenColumnScrollBarSpacerName = "PART_FrozenColumnScrollBarSpacer"; private const string DATAGRID_elementFrozenColumnScrollBarSpacerName = "PART_FrozenColumnScrollBarSpacer";
private const string DATAGRID_elementHorizontalScrollbarName = "PART_HorizontalScrollbar"; private const string DATAGRID_elementHorizontalScrollbarName = "PART_HorizontalScrollbar";
private const string DATAGRID_elementRowHeadersPresenterName = "PART_RowHeadersPresenter";
private const string DATAGRID_elementTopLeftCornerHeaderName = "PART_TopLeftCornerHeader"; private const string DATAGRID_elementTopLeftCornerHeaderName = "PART_TopLeftCornerHeader";
private const string DATAGRID_elementTopRightCornerHeaderName = "PART_TopRightCornerHeader"; private const string DATAGRID_elementTopRightCornerHeaderName = "PART_TopRightCornerHeader";
private const string DATAGRID_elementBottomRightCornerHeaderName = "PART_BottomRightCorner"; private const string DATAGRID_elementBottomRightCornerHeaderName = "PART_BottomRightCorner";
@ -1124,7 +1123,7 @@ namespace Avalonia.Controls
EnsureColumnHeadersVisibility(); EnsureColumnHeadersVisibility();
if (!newValueCols) if (!newValueCols)
{ {
_columnHeadersPresenter.Measure(Size.Empty); _columnHeadersPresenter.Measure(default(Size));
} }
else else
{ {
@ -1165,7 +1164,7 @@ namespace Avalonia.Controls
_topLeftCornerHeader.IsVisible = newValueRows && newValueCols; _topLeftCornerHeader.IsVisible = newValueRows && newValueCols;
if (_topLeftCornerHeader.IsVisible) if (_topLeftCornerHeader.IsVisible)
{ {
_topLeftCornerHeader.Measure(Size.Empty); _topLeftCornerHeader.Measure(default(Size));
} }
} }

4
src/Avalonia.Controls.DataGrid/DataGridCheckBoxColumn.cs

@ -192,14 +192,14 @@ namespace Avalonia.Controls
void OnLayoutUpdated(object sender, EventArgs e) void OnLayoutUpdated(object sender, EventArgs e)
{ {
if(!editingCheckBox.Bounds.IsEmpty) if(!editingCheckBox.Bounds.IsDefault)
{ {
editingCheckBox.LayoutUpdated -= OnLayoutUpdated; editingCheckBox.LayoutUpdated -= OnLayoutUpdated;
ProcessPointerArgs(); ProcessPointerArgs();
} }
} }
if(editingCheckBox.Bounds.IsEmpty) if(editingCheckBox.Bounds.IsDefault)
{ {
editingCheckBox.LayoutUpdated += OnLayoutUpdated; editingCheckBox.LayoutUpdated += OnLayoutUpdated;
} }

7
src/Avalonia.Controls.DataGrid/DataGridColumn.cs

@ -50,10 +50,13 @@ namespace Avalonia.Controls
InheritsWidth = true; InheritsWidth = true;
} }
internal DataGrid OwningGrid /// <summary>
/// Gets the <see cref="T:Avalonia.Controls.DataGrid"/> control that contains this column.
/// </summary>
protected internal DataGrid OwningGrid
{ {
get; get;
set; internal set;
} }
internal int Index internal int Index

1
src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs

@ -34,7 +34,6 @@ namespace Avalonia.Controls
} }
private const int DATAGRIDCOLUMNHEADER_resizeRegionWidth = 5; private const int DATAGRIDCOLUMNHEADER_resizeRegionWidth = 5;
private const double DATAGRIDCOLUMNHEADER_separatorThickness = 1;
private const int DATAGRIDCOLUMNHEADER_columnsDragTreshold = 5; private const int DATAGRIDCOLUMNHEADER_columnsDragTreshold = 5;
private bool _areHandlersSuspended; private bool _areHandlersSuspended;

2
src/Avalonia.Controls.DataGrid/DataGridRowHeader.cs

@ -18,8 +18,6 @@ namespace Avalonia.Controls.Primitives
public class DataGridRowHeader : ContentControl public class DataGridRowHeader : ContentControl
{ {
private const string DATAGRIDROWHEADER_elementRootName = "PART_Root"; private const string DATAGRIDROWHEADER_elementRootName = "PART_Root";
private const double DATAGRIDROWHEADER_separatorThickness = 1;
private Control _rootElement; private Control _rootElement;
public static readonly StyledProperty<IBrush> SeparatorBrushProperty = public static readonly StyledProperty<IBrush> SeparatorBrushProperty =

10
src/Avalonia.Controls.DataGrid/DataGridValueConverter.cs

@ -22,14 +22,18 @@ namespace Avalonia.Controls
return DefaultValueConverter.Instance.Convert(value, targetType, parameter, culture); return DefaultValueConverter.Instance.Convert(value, targetType, parameter, culture);
} }
// This suppresses a warning saying that we should use String.IsNullOrEmpty instead of a string
// comparison, but in this case we want to explicitly check for Empty and not Null.
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{ {
if (targetType != null && targetType.IsNullableType()) if (targetType != null && targetType.IsNullableType())
{ {
var strValue = value as string; var strValue = value as string;
if (string.IsNullOrEmpty(strValue))
// This suppresses a warning saying that we should use String.IsNullOrEmpty instead of a string
// comparison, but in this case we want to explicitly check for Empty and not Null.
#pragma warning disable CA1820
if (strValue == string.Empty)
#pragma warning restore CA1820
{ {
return null; return null;
} }

2
src/Avalonia.Controls.DataGrid/Primitives/DataGridCellsPresenter.cs

@ -161,7 +161,7 @@ namespace Avalonia.Controls.Primitives
{ {
// Clip // Clip
RectangleGeometry rg = new RectangleGeometry(); RectangleGeometry rg = new RectangleGeometry();
rg.Rect = Rect.Empty; rg.Rect = default;
cell.Clip = rg; cell.Clip = rg;
} }
} }

2
src/Avalonia.Controls.DataGrid/Primitives/DataGridColumnHeadersPresenter.cs

@ -305,7 +305,7 @@ namespace Avalonia.Controls.Primitives
} }
if (!OwningGrid.AreColumnHeadersVisible) if (!OwningGrid.AreColumnHeadersVisible)
{ {
return Size.Empty; return default;
} }
double height = OwningGrid.ColumnHeaderHeight; double height = OwningGrid.ColumnHeaderHeight;
bool autoSizeHeight; bool autoSizeHeight;

2
src/Avalonia.Controls.DataGrid/Primitives/DataGridDetailsPresenter.cs

@ -112,7 +112,7 @@ namespace Avalonia.Controls.Primitives
{ {
if (OwningGrid == null || Children.Count == 0) if (OwningGrid == null || Children.Count == 0)
{ {
return Size.Empty; return default;
} }
double desiredWidth = OwningGrid.AreRowDetailsFrozen ? double desiredWidth = OwningGrid.AreRowDetailsFrozen ?

4
src/Avalonia.Controls/Flyouts/FlyoutBase.cs

@ -435,7 +435,7 @@ namespace Avalonia.Controls.Primitives
{ {
Size sz; Size sz;
// Popup.Child can't be null here, it was set in ShowAtCore. // Popup.Child can't be null here, it was set in ShowAtCore.
if (Popup.Child!.DesiredSize == Size.Empty) if (Popup.Child!.DesiredSize.IsDefault)
{ {
// Popup may not have been shown yet. Measure content // Popup may not have been shown yet. Measure content
sz = LayoutHelper.MeasureChild(Popup.Child, Size.Infinity, new Thickness()); sz = LayoutHelper.MeasureChild(Popup.Child, Size.Infinity, new Thickness());
@ -457,7 +457,7 @@ namespace Avalonia.Controls.Primitives
PopupPositioning.PopupPositionerConstraintAdjustment.SlideY; PopupPositioning.PopupPositionerConstraintAdjustment.SlideY;
} }
var trgtBnds = Target?.Bounds ?? Rect.Empty; var trgtBnds = Target?.Bounds ?? default;
switch (Placement) switch (Placement)
{ {

10
src/Avalonia.Controls/LayoutTransformControl.cs

@ -91,7 +91,7 @@ namespace Avalonia.Controls
arrangedsize = TransformRoot.Bounds.Size; arrangedsize = TransformRoot.Bounds.Size;
// This is the first opportunity under Silverlight to find out the Child's true DesiredSize // This is the first opportunity under Silverlight to find out the Child's true DesiredSize
if (IsSizeSmaller(finalSizeTransformed, arrangedsize) && (Size.Empty == _childActualSize)) if (IsSizeSmaller(finalSizeTransformed, arrangedsize) && _childActualSize.IsDefault)
{ {
//// Unfortunately, all the work so far is invalid because the wrong DesiredSize was used //// Unfortunately, all the work so far is invalid because the wrong DesiredSize was used
//// Make a note of the actual DesiredSize //// Make a note of the actual DesiredSize
@ -102,7 +102,7 @@ namespace Avalonia.Controls
else else
{ {
// Clear the "need to measure/arrange again" flag // Clear the "need to measure/arrange again" flag
_childActualSize = Size.Empty; _childActualSize = default;
} }
// Return result to perform the transformation // Return result to perform the transformation
@ -122,7 +122,7 @@ namespace Avalonia.Controls
} }
Size measureSize; Size measureSize;
if (_childActualSize == Size.Empty) if (_childActualSize.IsDefault)
{ {
// Determine the largest size after the transformation // Determine the largest size after the transformation
measureSize = ComputeLargestTransformedSize(availableSize); measureSize = ComputeLargestTransformedSize(availableSize);
@ -206,7 +206,7 @@ namespace Avalonia.Controls
/// <summary> /// <summary>
/// Actual DesiredSize of Child element (the value it returned from its MeasureOverride method). /// Actual DesiredSize of Child element (the value it returned from its MeasureOverride method).
/// </summary> /// </summary>
private Size _childActualSize = Size.Empty; private Size _childActualSize = default;
/// <summary> /// <summary>
/// RenderTransform/MatrixTransform applied to TransformRoot. /// RenderTransform/MatrixTransform applied to TransformRoot.
@ -281,7 +281,7 @@ namespace Avalonia.Controls
private Size ComputeLargestTransformedSize(Size arrangeBounds) private Size ComputeLargestTransformedSize(Size arrangeBounds)
{ {
// Computed largest transformed size // Computed largest transformed size
Size computedSize = Size.Empty; Size computedSize = default;
// Detect infinite bounds and constrain the scenario // Detect infinite bounds and constrain the scenario
bool infiniteWidth = double.IsInfinity(arrangeBounds.Width); bool infiniteWidth = double.IsInfinity(arrangeBounds.Width);

2
src/Avalonia.Controls/NativeControlHost.cs

@ -145,7 +145,7 @@ namespace Avalonia.Controls
if (IsEffectivelyVisible && bounds.HasValue) if (IsEffectivelyVisible && bounds.HasValue)
{ {
if (bounds.Value.IsEmpty) if (bounds.Value.IsDefault)
return false; return false;
_attachment?.ShowInBounds(bounds.Value); _attachment?.ShowInBounds(bounds.Value);
} }

9
src/Avalonia.Controls/NativeMenuBar.cs

@ -23,15 +23,6 @@ namespace Avalonia.Controls
}); });
} }
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(NativeMenu))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(NativeMenuItem))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(NativeMenuItemBase))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(NativeMenuItemSeparator))]
public NativeMenuBar()
{
}
public static void SetEnableMenuItemClickForwarding(MenuItem menuItem, bool enable) public static void SetEnableMenuItemClickForwarding(MenuItem menuItem, bool enable)
{ {
menuItem.SetValue(EnableMenuItemClickForwardingProperty, enable); menuItem.SetValue(EnableMenuItemClickForwardingProperty, enable);

7
src/Avalonia.Controls/NativeMenuItemSeparator.cs

@ -1,7 +1,10 @@
namespace Avalonia.Controls namespace Avalonia.Controls
{ {
public class NativeMenuItemSeparator : NativeMenuItemBase public class NativeMenuItemSeparator : NativeMenuItem
{ {
public NativeMenuItemSeparator()
{
Header = "-";
}
} }
} }

6
src/Avalonia.Controls/Presenters/ItemsPresenter.cs

@ -77,7 +77,7 @@ namespace Avalonia.Controls.Presenters
} }
/// <inheritdoc/> /// <inheritdoc/>
Size IScrollable.Extent => Virtualizer?.Extent ?? Size.Empty; Size IScrollable.Extent => Virtualizer?.Extent ?? default;
/// <inheritdoc/> /// <inheritdoc/>
Vector IScrollable.Offset Vector IScrollable.Offset
@ -136,12 +136,12 @@ namespace Avalonia.Controls.Presenters
/// <inheritdoc/> /// <inheritdoc/>
protected override Size MeasureOverride(Size availableSize) protected override Size MeasureOverride(Size availableSize)
{ {
return Virtualizer?.MeasureOverride(availableSize) ?? Size.Empty; return Virtualizer?.MeasureOverride(availableSize) ?? default;
} }
protected override Size ArrangeOverride(Size finalSize) protected override Size ArrangeOverride(Size finalSize)
{ {
return Virtualizer?.ArrangeOverride(finalSize) ?? Size.Empty; return Virtualizer?.ArrangeOverride(finalSize) ?? default;
} }
/// <inheritdoc/> /// <inheritdoc/>

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

@ -106,11 +106,10 @@ namespace Avalonia.Controls.Presenters
private Rect _caretBounds; private Rect _caretBounds;
private Point _navigationPosition; private Point _navigationPosition;
private string? _preeditText; private string? _preeditText;
private CharacterHit _compositionStartHit = new CharacterHit(-1);
static TextPresenter() static TextPresenter()
{ {
AffectsRender<TextPresenter>(CaretBrushProperty, SelectionBrushProperty); AffectsRender<TextPresenter>(CaretBrushProperty, SelectionBrushProperty, TextElement.ForegroundProperty);
} }
public TextPresenter() public TextPresenter()

2
src/Avalonia.Controls/Primitives/PopupPositioning/ManagedPopupPositioner.cs

@ -112,7 +112,7 @@ namespace Avalonia.Controls.Primitives.PopupPositioning
?? screens.FirstOrDefault(s => s.Bounds.Intersects(parentGeometry)) ?? screens.FirstOrDefault(s => s.Bounds.Intersects(parentGeometry))
?? screens.FirstOrDefault(); ?? screens.FirstOrDefault();
if (targetScreen != null && targetScreen.WorkingArea.IsEmpty) if (targetScreen != null && targetScreen.WorkingArea.IsDefault)
{ {
return targetScreen.Bounds; return targetScreen.Bounds;
} }

2
src/Avalonia.Controls/Primitives/SelectingItemsControl.cs

@ -119,8 +119,6 @@ namespace Avalonia.Controls.Primitives
/// </summary> /// </summary>
public static readonly StyledProperty<bool> WrapSelectionProperty = public static readonly StyledProperty<bool> WrapSelectionProperty =
AvaloniaProperty.Register<SelectingItemsControl, bool>(nameof(WrapSelection), defaultValue: false); AvaloniaProperty.Register<SelectingItemsControl, bool>(nameof(WrapSelection), defaultValue: false);
private static readonly IList Empty = Array.Empty<object>();
private string _textSearchTerm = string.Empty; private string _textSearchTerm = string.Empty;
private DispatcherTimer? _textSearchTimer; private DispatcherTimer? _textSearchTimer;
private ISelectionModel? _selection; private ISelectionModel? _selection;

4
src/Avalonia.Controls/Repeater/ViewportManager.cs

@ -465,7 +465,7 @@ namespace Avalonia.Controls
_pendingViewportShift = default; _pendingViewportShift = default;
_unshiftableShift = default; _unshiftableShift = default;
if (_visibleWindow.IsEmpty) if (_visibleWindow.IsDefault)
{ {
// We got cleared. // We got cleared.
_layoutExtent = default; _layoutExtent = default;
@ -551,7 +551,7 @@ namespace Avalonia.Controls
private void TryInvalidateMeasure() private void TryInvalidateMeasure()
{ {
// Don't invalidate measure if we have an invalid window. // Don't invalidate measure if we have an invalid window.
if (!_visibleWindow.IsEmpty) if (!_visibleWindow.IsDefault)
{ {
// We invalidate measure instead of just invalidating arrange because // We invalidate measure instead of just invalidating arrange because
// we don't invalidate measure in UpdateViewport if the view is changing to // we don't invalidate measure in UpdateViewport if the view is changing to

4
src/Avalonia.Controls/Selection/SelectedItems.cs

@ -35,9 +35,9 @@ namespace Avalonia.Controls.Selection
{ {
return _owner.SelectedItem; return _owner.SelectedItem;
} }
else if (Items is object) else if (Items is not null && Ranges is not null)
{ {
return Items[index]; return Items[IndexRange.GetAt(Ranges, index)];
} }
else else
{ {

2
src/Avalonia.Controls/Shapes/Shape.cs

@ -292,7 +292,7 @@ namespace Avalonia.Controls.Shapes
return finalSize; return finalSize;
} }
return Size.Empty; return default;
} }
internal static (Size size, Matrix transform) CalculateSizeAndTransform(Size availableSize, Rect shapeBounds, Stretch Stretch) internal static (Size size, Matrix transform) CalculateSizeAndTransform(Size availableSize, Rect shapeBounds, Stretch Stretch)

6
src/Avalonia.Controls/Window.cs

@ -169,10 +169,6 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
public static readonly RoutedEvent<RoutedEventArgs> WindowOpenedEvent = public static readonly RoutedEvent<RoutedEventArgs> WindowOpenedEvent =
RoutedEvent.Register<Window, RoutedEventArgs>("WindowOpened", RoutingStrategies.Direct); RoutedEvent.Register<Window, RoutedEventArgs>("WindowOpened", RoutingStrategies.Direct);
private readonly NameScope _nameScope = new NameScope();
private object? _dialogResult; private object? _dialogResult;
private readonly Size _maxPlatformClientSize; private readonly Size _maxPlatformClientSize;
private WindowStartupLocation _windowStartupLocation; private WindowStartupLocation _windowStartupLocation;
@ -235,7 +231,7 @@ namespace Avalonia.Controls
impl.GotInputWhenDisabled = OnGotInputWhenDisabled; impl.GotInputWhenDisabled = OnGotInputWhenDisabled;
impl.WindowStateChanged = HandleWindowStateChanged; impl.WindowStateChanged = HandleWindowStateChanged;
_maxPlatformClientSize = PlatformImpl?.MaxAutoSizeHint ?? default(Size); _maxPlatformClientSize = PlatformImpl?.MaxAutoSizeHint ?? default(Size);
impl.ExtendClientAreaToDecorationsChanged = ExtendClientAreaToDecorationsChanged; impl.ExtendClientAreaToDecorationsChanged = ExtendClientAreaToDecorationsChanged;
this.GetObservable(ClientSizeProperty).Skip(1).Subscribe(x => PlatformImpl?.Resize(x, PlatformResizeReason.Application)); this.GetObservable(ClientSizeProperty).Skip(1).Subscribe(x => PlatformImpl?.Resize(x, PlatformResizeReason.Application));
PlatformImpl?.ShowTaskbarIcon(ShowInTaskbar); PlatformImpl?.ShowTaskbarIcon(ShowInTaskbar);

3
src/Avalonia.Diagnostics/Diagnostics/Controls/Application.cs

@ -10,8 +10,7 @@ namespace Avalonia.Diagnostics.Controls
{ {
private readonly App _application; private readonly App _application;
private static readonly Version s_version = typeof(AvaloniaObject).Assembly?.GetName()?.Version
?? Version.Parse("0.0.00");
public event EventHandler? Closed; public event EventHandler? Closed;
public Application(App application) public Application(App application)

2
src/Avalonia.Headless/HeadlessPlatformRenderInterface.cs

@ -215,7 +215,7 @@ namespace Avalonia.Headless
class HeadlessStreamingGeometryStub : HeadlessGeometryStub, IStreamGeometryImpl class HeadlessStreamingGeometryStub : HeadlessGeometryStub, IStreamGeometryImpl
{ {
public HeadlessStreamingGeometryStub() : base(Rect.Empty) public HeadlessStreamingGeometryStub() : base(default)
{ {
} }

3
src/Avalonia.Native/ClipboardImpl.cs

@ -15,8 +15,7 @@ namespace Avalonia.Native
private IAvnClipboard _native; private IAvnClipboard _native;
private const string NSPasteboardTypeString = "public.utf8-plain-text"; private const string NSPasteboardTypeString = "public.utf8-plain-text";
private const string NSFilenamesPboardType = "NSFilenamesPboardType"; private const string NSFilenamesPboardType = "NSFilenamesPboardType";
private const string NSPasteboardTypeFileUrl = "public.file-url";
public ClipboardImpl(IAvnClipboard native) public ClipboardImpl(IAvnClipboard native)
{ {
_native = native; _native = native;

1
src/Avalonia.Native/IAvnMenu.cs

@ -46,7 +46,6 @@ namespace Avalonia.Native.Interop.Impl
private AvaloniaNativeMenuExporter _exporter; private AvaloniaNativeMenuExporter _exporter;
private List<__MicroComIAvnMenuItemProxy> _menuItems = new List<__MicroComIAvnMenuItemProxy>(); private List<__MicroComIAvnMenuItemProxy> _menuItems = new List<__MicroComIAvnMenuItemProxy>();
private Dictionary<NativeMenuItemBase, __MicroComIAvnMenuItemProxy> _menuItemLookup = new Dictionary<NativeMenuItemBase, __MicroComIAvnMenuItemProxy>(); private Dictionary<NativeMenuItemBase, __MicroComIAvnMenuItemProxy> _menuItemLookup = new Dictionary<NativeMenuItemBase, __MicroComIAvnMenuItemProxy>();
private CompositeDisposable _propertyDisposables = new CompositeDisposable();
public void RaiseNeedsUpdate() public void RaiseNeedsUpdate()
{ {

1
src/Avalonia.Native/WindowImplBase.cs

@ -63,7 +63,6 @@ namespace Avalonia.Native
private double _savedScaling; private double _savedScaling;
private GlPlatformSurface _glSurface; private GlPlatformSurface _glSurface;
private NativeControlHostImpl _nativeControlHost; private NativeControlHostImpl _nativeControlHost;
private IGlContext _glContext;
internal WindowBaseImpl(IAvaloniaNativeFactory factory, AvaloniaNativePlatformOptions opts, internal WindowBaseImpl(IAvaloniaNativeFactory factory, AvaloniaNativePlatformOptions opts,
AvaloniaNativeGlPlatformGraphics glFeature) AvaloniaNativeGlPlatformGraphics glFeature)

2
src/Avalonia.Remote.Protocol/MetsysBson.cs

@ -1370,7 +1370,7 @@ namespace Metsys.Bson
var pattern = ReadName(); var pattern = ReadName();
var optionsString = ReadName(); var optionsString = ReadName();
var options = RegexOptions.None; var options = RegexOptions.Compiled;
if (optionsString.Contains('e')) options = options | RegexOptions.ECMAScript; if (optionsString.Contains('e')) options = options | RegexOptions.ECMAScript;
if (optionsString.Contains('i')) options = options | RegexOptions.IgnoreCase; if (optionsString.Contains('i')) options = options | RegexOptions.IgnoreCase;
if (optionsString.Contains('l')) options = options | RegexOptions.CultureInvariant; if (optionsString.Contains('l')) options = options | RegexOptions.CultureInvariant;

1
src/Avalonia.Themes.Fluent/Accents/BaseDark.xaml

@ -36,6 +36,7 @@
<SolidColorBrush x:Key="SystemControlBackgroundAltMediumHighBrush" Color="{StaticResource SystemAltMediumHighColor}" /> <SolidColorBrush x:Key="SystemControlBackgroundAltMediumHighBrush" Color="{StaticResource SystemAltMediumHighColor}" />
<SolidColorBrush x:Key="SystemControlBackgroundAltMediumBrush" Color="{StaticResource SystemAltMediumColor}" /> <SolidColorBrush x:Key="SystemControlBackgroundAltMediumBrush" Color="{StaticResource SystemAltMediumColor}" />
<SolidColorBrush x:Key="SystemControlBackgroundAltMediumLowBrush" Color="{StaticResource SystemAltMediumLowColor}" /> <SolidColorBrush x:Key="SystemControlBackgroundAltMediumLowBrush" Color="{StaticResource SystemAltMediumLowColor}" />
<SolidColorBrush x:Key="SystemControlBackgroundAltLowBrush" Color="{StaticResource SystemAltLowColor}" />
<SolidColorBrush x:Key="SystemControlBackgroundBaseHighBrush" Color="{StaticResource SystemBaseHighColor}" /> <SolidColorBrush x:Key="SystemControlBackgroundBaseHighBrush" Color="{StaticResource SystemBaseHighColor}" />
<SolidColorBrush x:Key="SystemControlBackgroundBaseLowBrush" Color="{StaticResource SystemBaseLowColor}" /> <SolidColorBrush x:Key="SystemControlBackgroundBaseLowBrush" Color="{StaticResource SystemBaseLowColor}" />
<SolidColorBrush x:Key="SystemControlBackgroundBaseMediumBrush" Color="{StaticResource SystemBaseMediumColor}" /> <SolidColorBrush x:Key="SystemControlBackgroundBaseMediumBrush" Color="{StaticResource SystemBaseMediumColor}" />

1
src/Avalonia.Themes.Fluent/Accents/BaseLight.xaml

@ -36,6 +36,7 @@
<SolidColorBrush x:Key="SystemControlBackgroundAltMediumHighBrush" Color="{StaticResource SystemAltMediumHighColor}" /> <SolidColorBrush x:Key="SystemControlBackgroundAltMediumHighBrush" Color="{StaticResource SystemAltMediumHighColor}" />
<SolidColorBrush x:Key="SystemControlBackgroundAltMediumBrush" Color="{StaticResource SystemAltMediumColor}" /> <SolidColorBrush x:Key="SystemControlBackgroundAltMediumBrush" Color="{StaticResource SystemAltMediumColor}" />
<SolidColorBrush x:Key="SystemControlBackgroundAltMediumLowBrush" Color="{StaticResource SystemAltMediumLowColor}" /> <SolidColorBrush x:Key="SystemControlBackgroundAltMediumLowBrush" Color="{StaticResource SystemAltMediumLowColor}" />
<SolidColorBrush x:Key="SystemControlBackgroundAltLowBrush" Color="{StaticResource SystemAltLowColor}" />
<SolidColorBrush x:Key="SystemControlBackgroundBaseHighBrush" Color="{StaticResource SystemBaseHighColor}" /> <SolidColorBrush x:Key="SystemControlBackgroundBaseHighBrush" Color="{StaticResource SystemBaseHighColor}" />
<SolidColorBrush x:Key="SystemControlBackgroundBaseLowBrush" Color="{StaticResource SystemBaseLowColor}" /> <SolidColorBrush x:Key="SystemControlBackgroundBaseLowBrush" Color="{StaticResource SystemBaseLowColor}" />
<SolidColorBrush x:Key="SystemControlBackgroundBaseMediumBrush" Color="{StaticResource SystemBaseMediumColor}" /> <SolidColorBrush x:Key="SystemControlBackgroundBaseMediumBrush" Color="{StaticResource SystemBaseMediumColor}" />

7
src/Avalonia.Themes.Fluent/Controls/ManagedFileChooser.xaml

@ -153,9 +153,13 @@
<DockPanel x:Name="NavBar" DockPanel.Dock="Top" Margin="8,5,8,0" VerticalAlignment="Center"> <DockPanel x:Name="NavBar" DockPanel.Dock="Top" Margin="8,5,8,0" VerticalAlignment="Center">
<Rectangle Fill="{DynamicResource SystemControlHighlightAltBaseMediumLowBrush}" Height="1" Margin="0,5,0,0" DockPanel.Dock="Bottom"/> <Rectangle Fill="{DynamicResource SystemControlHighlightAltBaseMediumLowBrush}" Height="1" Margin="0,5,0,0" DockPanel.Dock="Bottom"/>
<DockPanel Margin="4,0"> <DockPanel Margin="4,0">
<Button Command="{Binding GoUp}" DockPanel.Dock="Left"> <Button Command="{Binding GoUp}" DockPanel.Dock="Left" Margin="0,0,8,0">
<Path Data="M 0 7 L 7 0 L 14 7 M 7 0 L 7 16" Stroke="{CompiledBinding $parent[Button].Foreground}" StrokeThickness="1" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,1,0,-1"/> <Path Data="M 0 7 L 7 0 L 14 7 M 7 0 L 7 16" Stroke="{CompiledBinding $parent[Button].Foreground}" StrokeThickness="1" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,1,0,-1"/>
</Button> </Button>
<Button Command="{Binding Refresh}" DockPanel.Dock="Right" Margin="8,0,0,0">
<Path Data="M18.62 3.32c.39 0 .7.29.76.66v3c0 .39-.28.7-.66.76h-3a.77.77 0 0 1-.1-1.52h1.08a7.42 7.42 0 1 0 2.65 4.37.77.77 0 1 1 1.5-.3 8.94 8.94 0 1 1-3-5.12V4.09c0-.43.35-.77.77-.77Z"
Fill="{CompiledBinding $parent[Button].Foreground}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="-2,-4,0,0"/>
</Button>
<TextBox x:Name="Location" Text="{Binding Location}"> <TextBox x:Name="Location" Text="{Binding Location}">
<TextBox.KeyBindings> <TextBox.KeyBindings>
<KeyBinding Command="{Binding EnterPressed}" Gesture="Enter"/> <KeyBinding Command="{Binding EnterPressed}" Gesture="Enter"/>
@ -322,7 +326,6 @@
<Style Selector="^ /template/ DockPanel#NavBar Button"> <Style Selector="^ /template/ DockPanel#NavBar Button">
<Setter Property="VerticalAlignment" Value="Stretch"/> <Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="Width" Value="40"/> <Setter Property="Width" Value="40"/>
<Setter Property="Margin" Value="0,0,8,0"/>
<Setter Property="BorderThickness" Value="0"/> <Setter Property="BorderThickness" Value="0"/>
</Style> </Style>
<Style Selector="^ /template/ DockPanel#NavBar Button:not(:pointerover):not(:pressed)"> <Style Selector="^ /template/ DockPanel#NavBar Button:not(:pointerover):not(:pressed)">

17
src/Avalonia.Themes.Fluent/Controls/NativeMenuBar.xaml

@ -9,17 +9,16 @@
IsVisible="{Binding !$parent[TopLevel].(NativeMenu.IsNativeMenuExported)}" IsVisible="{Binding !$parent[TopLevel].(NativeMenu.IsNativeMenuExported)}"
Items="{Binding $parent[TopLevel].(NativeMenu.Menu).Items}"> Items="{Binding $parent[TopLevel].(NativeMenu.Menu).Items}">
<Menu.Styles> <Menu.Styles>
<!-- Don't use x:DataType and compiled bindings here, as it might crash https://github.com/AvaloniaUI/Avalonia/pull/7954 --> <Style Selector="MenuItem" x:DataType="NativeMenuItem">
<Style Selector="MenuItem"> <Setter Property="Header" Value="{Binding Header}"/>
<Setter Property="Header" Value="{ReflectionBinding Header}"/> <Setter Property="IsEnabled" Value="{Binding IsEnabled}"/>
<Setter Property="IsEnabled" Value="{ReflectionBinding IsEnabled}"/> <Setter Property="InputGesture" Value="{Binding Gesture}"/>
<Setter Property="InputGesture" Value="{ReflectionBinding Gesture}"/> <Setter Property="Items" Value="{Binding Menu.Items}"/>
<Setter Property="Items" Value="{ReflectionBinding Menu.Items}"/> <Setter Property="Command" Value="{Binding Command}"/>
<Setter Property="Command" Value="{ReflectionBinding Command}"/> <Setter Property="CommandParameter" Value="{Binding CommandParameter}"/>
<Setter Property="CommandParameter" Value="{ReflectionBinding CommandParameter}"/>
<Setter Property="(NativeMenuBar.EnableMenuItemClickForwarding)" Value="True"/> <Setter Property="(NativeMenuBar.EnableMenuItemClickForwarding)" Value="True"/>
<!--NativeMenuItem is IBitmap and MenuItem is Image--> <!--NativeMenuItem is IBitmap and MenuItem is Image-->
<Setter Property="Icon" Value="{ReflectionBinding Icon , Converter={StaticResource AvaloniaThemesFluentNativeMenuBarIBitmapToImageConverter}}"/> <Setter Property="Icon" Value="{Binding Icon , Converter={StaticResource AvaloniaThemesFluentNativeMenuBarIBitmapToImageConverter}}"/>
</Style> </Style>
</Menu.Styles> </Menu.Styles>
</Menu> </Menu>

14
src/Avalonia.Themes.Simple/Controls/ManagedFileChooser.xaml

@ -11,6 +11,12 @@
<GeometryDrawing Brush="#FF00529C" Geometry="F1M8,11L5,8 2,11 2,13 4,11 4,15 6,15 6,11 8,13z" /> <GeometryDrawing Brush="#FF00529C" Geometry="F1M8,11L5,8 2,11 2,13 4,11 4,15 6,15 6,11 8,13z" />
<GeometryDrawing Brush="#FFF0EFF1" Geometry="F1M8.0001,1.9996L7.5001,3.0006 14.0001,3.0006 14.0001,1.9996z" /> <GeometryDrawing Brush="#FFF0EFF1" Geometry="F1M8.0001,1.9996L7.5001,3.0006 14.0001,3.0006 14.0001,1.9996z" />
</DrawingGroup> </DrawingGroup>
<DrawingGroup x:Key="Refresh">
<GeometryDrawing Brush="#FFF6F6F6"
Geometry="F1M13.5049,7.3896L13.2339,6.2646 9.9299,7.5886 10.0729,8.3896C10.0909,8.4906 10.1079,8.5926 10.1079,8.6976 10.1079,9.8596 9.1619,10.8046 7.9999,10.8046 6.8369,10.8046 5.8909,9.8596 5.8909,8.6976 5.8909,7.8966 6.3399,7.1996 6.9999,6.8426L6.9999,9.4986 12.6789,4.8156 8.0569,0.9996 6.9999,0.9996 6.9999,3.1266C4.3539,3.6006 2.3389,5.9176 2.3389,8.6976 2.3389,11.8186 4.8789,14.3586 7.9999,14.3586 11.1209,14.3586 13.6609,11.8186 13.6609,8.6976 13.6609,8.2626 13.6089,7.8226 13.5049,7.3896" />
<GeometryDrawing Brush="#FF414141"
Geometry="F1M12.5322,7.623L11.0572,8.214C11.0862,8.372 11.1072,8.533 11.1072,8.697 11.1072,10.415 9.7172,11.805 8.0002,11.805 6.2852,11.805 4.8912,10.415 4.8912,8.697 4.8912,6.983 6.2852,5.59 8.0002,5.59L8.0002,7.378 11.1072,4.815 8.0002,2.25 8.0002,4.039C5.4262,4.039 3.3392,6.123 3.3392,8.697 3.3392,11.27 5.4262,13.358 8.0002,13.358 10.5762,13.358 12.6612,11.27 12.6612,8.697 12.6612,8.327 12.6152,7.969 12.5322,7.623" />
</DrawingGroup>
<internal:ResourceSelectorConverter x:Key="Icons"> <internal:ResourceSelectorConverter x:Key="Icons">
<DrawingGroup x:Key="Icon_Folder"> <DrawingGroup x:Key="Icon_Folder">
<GeometryDrawing Brush="#00FFFFFF" Geometry="F1M0,0L16,0 16,16 0,16z" /> <GeometryDrawing Brush="#00FFFFFF" Geometry="F1M0,0L16,0 16,16 0,16z" />
@ -54,6 +60,14 @@
</Image> </Image>
</Button> </Button>
</internal:ChildFitter> </internal:ChildFitter>
<internal:ChildFitter Width="{Binding ElementName=Location, Path=Bounds.Height}"
DockPanel.Dock="Right">
<Button Command="{Binding Refresh}">
<Image Stretch="Fill">
<DrawingImage Drawing="{StaticResource Refresh}" />
</Image>
</Button>
</internal:ChildFitter>
<TextBox x:Name="Location" <TextBox x:Name="Location"
Margin="0,0,5,0" Margin="0,0,5,0"
Text="{Binding Location}"> Text="{Binding Location}">

21
src/Avalonia.Themes.Simple/Controls/NativeMenuBar.xaml

@ -9,17 +9,16 @@
<Menu IsVisible="{Binding !$parent[TopLevel].(NativeMenu.IsNativeMenuExported)}" <Menu IsVisible="{Binding !$parent[TopLevel].(NativeMenu.IsNativeMenuExported)}"
Items="{Binding $parent[TopLevel].(NativeMenu.Menu).Items}"> Items="{Binding $parent[TopLevel].(NativeMenu.Menu).Items}">
<Menu.Styles> <Menu.Styles>
<!-- Don't use x:DataType and compiled bindings here, as it might crash https://github.com/AvaloniaUI/Avalonia/pull/7954 --> <Style Selector="MenuItem" x:DataType="NativeMenuItem">
<Style Selector="MenuItem"> <Setter Property="Header" Value="{Binding Header}"/>
<Setter Property="Header" Value="{ReflectionBinding Header}" /> <Setter Property="IsEnabled" Value="{Binding IsEnabled}"/>
<Setter Property="IsEnabled" Value="{ReflectionBinding IsEnabled}" /> <Setter Property="InputGesture" Value="{Binding Gesture}"/>
<Setter Property="InputGesture" Value="{ReflectionBinding Gesture}" /> <Setter Property="Items" Value="{Binding Menu.Items}"/>
<Setter Property="Items" Value="{ReflectionBinding Menu.Items}" /> <Setter Property="Command" Value="{Binding Command}"/>
<Setter Property="Command" Value="{ReflectionBinding Command}" /> <Setter Property="CommandParameter" Value="{Binding CommandParameter}"/>
<Setter Property="CommandParameter" Value="{ReflectionBinding CommandParameter}" /> <Setter Property="(NativeMenuBar.EnableMenuItemClickForwarding)" Value="True"/>
<Setter Property="(NativeMenuBar.EnableMenuItemClickForwarding)" Value="True" /> <!--NativeMenuItem is IBitmap and MenuItem is Image-->
<!-- NativeMenuItem is IBitmap and MenuItem is Image --> <Setter Property="Icon" Value="{Binding Icon , Converter={StaticResource AvaloniaThemesSimpleNativeMenuBarIBitmapToImageConverter}}"/>
<Setter Property="Icon" Value="{ReflectionBinding Icon, Converter={StaticResource AvaloniaThemesSimpleNativeMenuBarIBitmapToImageConverter}}" />
</Style> </Style>
</Menu.Styles> </Menu.Styles>
</Menu> </Menu>

2
src/Avalonia.X11/X11Clipboard.cs

@ -18,8 +18,6 @@ namespace Avalonia.X11
private TaskCompletionSource<object> _requestedDataTcs; private TaskCompletionSource<object> _requestedDataTcs;
private readonly IntPtr[] _textAtoms; private readonly IntPtr[] _textAtoms;
private readonly IntPtr _avaloniaSaveTargetsAtom; private readonly IntPtr _avaloniaSaveTargetsAtom;
private readonly Dictionary<string, IntPtr> _formatAtoms = new Dictionary<string, IntPtr>();
private readonly Dictionary<IntPtr, string> _atomFormats = new Dictionary<IntPtr, string>();
public X11Clipboard(AvaloniaX11Platform platform) public X11Clipboard(AvaloniaX11Platform platform)
{ {

6
src/Browser/Avalonia.Browser/BrowserNativeControlHost.cs

@ -55,12 +55,6 @@ namespace Avalonia.Browser
private class Attachment : INativeControlHostControlTopLevelAttachment private class Attachment : INativeControlHostControlTopLevelAttachment
{ {
private const string InitializeWithChildHandleSymbol = "InitializeWithChildHandle";
private const string AttachToSymbol = "AttachTo";
private const string ShowInBoundsSymbol = "ShowInBounds";
private const string HideWithSizeSymbol = "HideWithSize";
private const string ReleaseChildSymbol = "ReleaseChild";
private JSObject? _native; private JSObject? _native;
private BrowserNativeControlHost? _attachedTo; private BrowserNativeControlHost? _attachedTo;

2
src/Browser/Avalonia.Browser/WebEmbeddableControlRoot.cs

@ -18,7 +18,7 @@ namespace Avalonia.Browser
_onFirstRender = onFirstRender; _onFirstRender = onFirstRender;
} }
public Rect Bounds => Rect.Empty; public Rect Bounds => default;
public bool HasRendered => _hasRendered; public bool HasRendered => _hasRendered;

2
src/Linux/Avalonia.LinuxFramebuffer/Input/EvDev/EvDevBackend.cs

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Threading; using System.Threading;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Input.Raw; using Avalonia.Input.Raw;
using Avalonia.Threading;
using static Avalonia.LinuxFramebuffer.NativeUnsafeMethods; using static Avalonia.LinuxFramebuffer.NativeUnsafeMethods;
namespace Avalonia.LinuxFramebuffer.Input.EvDev namespace Avalonia.LinuxFramebuffer.Input.EvDev
@ -13,7 +12,6 @@ namespace Avalonia.LinuxFramebuffer.Input.EvDev
private readonly EvDevDeviceDescription[] _deviceDescriptions; private readonly EvDevDeviceDescription[] _deviceDescriptions;
private readonly List<EvDevDeviceHandler> _handlers = new List<EvDevDeviceHandler>(); private readonly List<EvDevDeviceHandler> _handlers = new List<EvDevDeviceHandler>();
private int _epoll; private int _epoll;
private object _lock = new object();
private Action<RawInputEventArgs> _onInput; private Action<RawInputEventArgs> _onInput;
private IInputRoot _inputRoot; private IInputRoot _inputRoot;
private RawEventGroupingThreadingHelper _inputQueue; private RawEventGroupingThreadingHelper _inputQueue;

1
src/Linux/Avalonia.LinuxFramebuffer/Input/LibInput/LibInputBackend.cs

@ -11,7 +11,6 @@ namespace Avalonia.LinuxFramebuffer.Input.LibInput
{ {
private IScreenInfoProvider _screen; private IScreenInfoProvider _screen;
private IInputRoot _inputRoot; private IInputRoot _inputRoot;
private readonly Queue<Action> _inputThreadActions = new Queue<Action>();
private TouchDevice _touch = new TouchDevice(); private TouchDevice _touch = new TouchDevice();
private const string LibInput = nameof(Avalonia.LinuxFramebuffer) + "/" + nameof(Avalonia.LinuxFramebuffer.Input) + "/" + nameof(LibInput); private const string LibInput = nameof(Avalonia.LinuxFramebuffer) + "/" + nameof(Avalonia.LinuxFramebuffer.Input) + "/" + nameof(LibInput);
private readonly RawEventGroupingThreadingHelper _inputQueue; private readonly RawEventGroupingThreadingHelper _inputQueue;

13
src/Skia/Avalonia.Skia/DrawingContextImpl.cs

@ -362,7 +362,7 @@ namespace Avalonia.Skia
foreach (var boxShadow in boxShadows) foreach (var boxShadow in boxShadows)
{ {
if (!boxShadow.IsEmpty && !boxShadow.IsInset) if (!boxShadow.IsDefault && !boxShadow.IsInset)
{ {
using (var shadow = BoxShadowFilter.Create(_boxShadowPaint, boxShadow, _currentOpacity)) using (var shadow = BoxShadowFilter.Create(_boxShadowPaint, boxShadow, _currentOpacity))
{ {
@ -418,7 +418,7 @@ namespace Avalonia.Skia
foreach (var boxShadow in boxShadows) foreach (var boxShadow in boxShadows)
{ {
if (!boxShadow.IsEmpty && boxShadow.IsInset) if (!boxShadow.IsDefault && boxShadow.IsInset)
{ {
using (var shadow = BoxShadowFilter.Create(_boxShadowPaint, boxShadow, _currentOpacity)) using (var shadow = BoxShadowFilter.Create(_boxShadowPaint, boxShadow, _currentOpacity))
{ {
@ -1137,11 +1137,14 @@ namespace Avalonia.Skia
if (pen.DashStyle?.Dashes != null && pen.DashStyle.Dashes.Count > 0) if (pen.DashStyle?.Dashes != null && pen.DashStyle.Dashes.Count > 0)
{ {
var srcDashes = pen.DashStyle.Dashes; var srcDashes = pen.DashStyle.Dashes;
var dashesArray = new float[srcDashes.Count];
for (var i = 0; i < srcDashes.Count; ++i) var count = srcDashes.Count % 2 == 0 ? srcDashes.Count : srcDashes.Count * 2;
var dashesArray = new float[count];
for (var i = 0; i < count; ++i)
{ {
dashesArray[i] = (float) srcDashes[i] * paint.StrokeWidth; dashesArray[i] = (float) srcDashes[i % srcDashes.Count] * paint.StrokeWidth;
} }
var offset = (float)(pen.DashStyle.Offset * pen.Thickness); var offset = (float)(pen.DashStyle.Offset * pen.Thickness);

2
src/Skia/Avalonia.Skia/GeometryImpl.cs

@ -244,7 +244,7 @@ namespace Avalonia.Skia
public void Invalidate() public void Invalidate()
{ {
CachedStrokePath?.Dispose(); CachedStrokePath?.Dispose();
CachedGeometryRenderBounds = Rect.Empty; CachedGeometryRenderBounds = default;
_cachedStrokeWidth = default(float); _cachedStrokeWidth = default(float);
} }
} }

1
src/Skia/Avalonia.Skia/Helpers/ImageSavingHelper.cs

@ -34,6 +34,7 @@ namespace Avalonia.Skia.Helpers
/// Save Skia image to a stream. /// Save Skia image to a stream.
/// </summary> /// </summary>
/// <param name="image">Image to save</param> /// <param name="image">Image to save</param>
/// <param name="stream">The output stream to save the image.</param>
/// <param name="quality"> /// <param name="quality">
/// The optional quality for PNG compression. /// The optional quality for PNG compression.
/// The quality value is interpreted from 0 - 100. If quality is null /// The quality value is interpreted from 0 - 100. If quality is null

2
src/Skia/Avalonia.Skia/StreamGeometryImpl.cs

@ -34,7 +34,7 @@ namespace Avalonia.Skia
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="StreamGeometryImpl"/> class. /// Initializes a new instance of the <see cref="StreamGeometryImpl"/> class.
/// </summary> /// </summary>
public StreamGeometryImpl() : this(CreateEmptyPath(), Rect.Empty) public StreamGeometryImpl() : this(CreateEmptyPath(), default)
{ {
} }

2
src/Windows/Avalonia.Win32/Interop/Automation/UiaCoreTypesApi.cs

@ -6,8 +6,6 @@ namespace Avalonia.Win32.Interop.Automation
{ {
internal static class UiaCoreTypesApi internal static class UiaCoreTypesApi
{ {
private const string StartListeningExportName = "SynchronizedInputPattern_StartListening";
internal enum AutomationIdType internal enum AutomationIdType
{ {
Property, Property,

2
src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs

@ -1409,7 +1409,7 @@ namespace Avalonia.Win32.Interop
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern bool TranslateMessage(ref MSG lpMsg); public static extern bool TranslateMessage(ref MSG lpMsg);
[DllImport("user32.dll")] [DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern bool UnregisterClass(string lpClassName, IntPtr hInstance); public static extern bool UnregisterClass(string lpClassName, IntPtr hInstance);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "SetWindowTextW")] [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "SetWindowTextW")]

3
src/Windows/Avalonia.Win32/OpenGl/Angle/AngleWin32PlatformGraphics.cs

@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Runtime.ExceptionServices;
using Avalonia.Logging; using Avalonia.Logging;
using Avalonia.OpenGL; using Avalonia.OpenGL;
using Avalonia.OpenGL.Angle; using Avalonia.OpenGL.Angle;
@ -88,8 +87,6 @@ internal class AngleWin32PlatformGraphics : IPlatformGraphics
return null; return null;
} }
return new AngleWin32PlatformGraphics(egl, AngleWin32EglDisplay.CreateSharedD3D11Display(egl));
foreach (var api in (options?.AllowedPlatformApis ?? new [] foreach (var api in (options?.AllowedPlatformApis ?? new []
{ {
AngleOptions.PlatformApi.DirectX11 AngleOptions.PlatformApi.DirectX11

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save