From 59f4adcdd39ed878d9b8cf38936afd0d0cf2eb04 Mon Sep 17 00:00:00 2001 From: Giuseppe Lippolis Date: Sat, 23 Oct 2021 12:14:38 +0200 Subject: [PATCH 1/9] fix: Warning CS0067 The event is never used --- .../Platform/InternalPlatformThreadingInterface.cs | 2 ++ src/Avalonia.Controls/TextBoxTextInputMethodClient.cs | 2 +- src/Avalonia.DesignerSupport/Remote/FileWatcherTransport.cs | 2 +- src/Avalonia.FreeDesktop/DBusMenuExporter.cs | 6 +++--- src/Avalonia.Native/AvaloniaNativeMenuExporter.cs | 2 +- src/Avalonia.X11/X11Window.Xim.cs | 4 ++-- tests/Avalonia.Controls.UnitTests/ItemsSourceViewTests.cs | 2 +- 7 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Avalonia.Controls/Platform/InternalPlatformThreadingInterface.cs b/src/Avalonia.Controls/Platform/InternalPlatformThreadingInterface.cs index a5495fdfc9..6a95c2e047 100644 --- a/src/Avalonia.Controls/Platform/InternalPlatformThreadingInterface.cs +++ b/src/Avalonia.Controls/Platform/InternalPlatformThreadingInterface.cs @@ -85,7 +85,9 @@ namespace Avalonia.Controls.Platform public bool CurrentThreadIsLoopThread => TlsCurrentThreadIsLoopThread; public event Action Signaled; +#pragma warning disable CS0067 public event Action Tick; +#pragma warning restore CS0067 } } diff --git a/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs b/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs index e8122dd311..c5a729afae 100644 --- a/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs +++ b/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs @@ -18,7 +18,7 @@ namespace Avalonia.Controls public bool SupportsSurroundingText => false; public TextInputMethodSurroundingText SurroundingText => throw new NotSupportedException(); - public event EventHandler SurroundingTextChanged; + public event EventHandler SurroundingTextChanged { add { } remove { } } public string TextBeforeCursor => null; public string TextAfterCursor => null; diff --git a/src/Avalonia.DesignerSupport/Remote/FileWatcherTransport.cs b/src/Avalonia.DesignerSupport/Remote/FileWatcherTransport.cs index 0448a5c05d..45a6c97954 100644 --- a/src/Avalonia.DesignerSupport/Remote/FileWatcherTransport.cs +++ b/src/Avalonia.DesignerSupport/Remote/FileWatcherTransport.cs @@ -59,7 +59,7 @@ namespace Avalonia.DesignerSupport.Remote remove { _onMessage -= value; } } - public event Action OnException; + public event Action OnException { add { } remove { } } public void Start() { UpdaterThread(); diff --git a/src/Avalonia.FreeDesktop/DBusMenuExporter.cs b/src/Avalonia.FreeDesktop/DBusMenuExporter.cs index 9e426688d8..206c24ad5e 100644 --- a/src/Avalonia.FreeDesktop/DBusMenuExporter.cs +++ b/src/Avalonia.FreeDesktop/DBusMenuExporter.cs @@ -413,10 +413,10 @@ namespace Avalonia.FreeDesktop #region Events private event Action<((int, IDictionary)[] updatedProps, (int, string[])[] removedProps)> - ItemsPropertiesUpdated; + ItemsPropertiesUpdated { add { } remove { } } private event Action<(uint revision, int parent)> LayoutUpdated; - private event Action<(int id, uint timestamp)> ItemActivationRequested; - private event Action PropertiesChanged; + private event Action<(int id, uint timestamp)> ItemActivationRequested { add { } remove { } } + private event Action PropertiesChanged { add { } remove { } } async Task IDBusMenu.WatchItemsPropertiesUpdatedAsync(Action<((int, IDictionary)[] updatedProps, (int, string[])[] removedProps)> handler, Action onError) { diff --git a/src/Avalonia.Native/AvaloniaNativeMenuExporter.cs b/src/Avalonia.Native/AvaloniaNativeMenuExporter.cs index 4431e108ed..1582f794ae 100644 --- a/src/Avalonia.Native/AvaloniaNativeMenuExporter.cs +++ b/src/Avalonia.Native/AvaloniaNativeMenuExporter.cs @@ -44,7 +44,7 @@ namespace Avalonia.Native public bool IsNativeMenuExported => _exported; - public event EventHandler OnIsNativeMenuExportedChanged; + public event EventHandler OnIsNativeMenuExportedChanged { add { } remove { } } public void SetNativeMenu(NativeMenu menu) { diff --git a/src/Avalonia.X11/X11Window.Xim.cs b/src/Avalonia.X11/X11Window.Xim.cs index 444c82fd22..ecb23ff097 100644 --- a/src/Avalonia.X11/X11Window.Xim.cs +++ b/src/Avalonia.X11/X11Window.Xim.cs @@ -112,8 +112,8 @@ namespace Avalonia.X11 public ValueTask HandleEventAsync(RawKeyEventArgs args, int keyVal, int keyCode) => new ValueTask(false); - public event Action Commit; - public event Action ForwardKey; + public event Action Commit { add { } remove { } } + public event Action ForwardKey { add { } remove { } } } diff --git a/tests/Avalonia.Controls.UnitTests/ItemsSourceViewTests.cs b/tests/Avalonia.Controls.UnitTests/ItemsSourceViewTests.cs index 529b3b1aa8..22a9b28648 100644 --- a/tests/Avalonia.Controls.UnitTests/ItemsSourceViewTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ItemsSourceViewTests.cs @@ -47,7 +47,7 @@ namespace Avalonia.Controls.UnitTests private class InvalidCollection : INotifyCollectionChanged, IEnumerable { - public event NotifyCollectionChangedEventHandler CollectionChanged; + public event NotifyCollectionChangedEventHandler CollectionChanged { add { } remove { } } public IEnumerator GetEnumerator() { From 055cf64660da4665ecc8724beedb2baf249e5c6d Mon Sep 17 00:00:00 2001 From: Jumar Macato <16554748+jmacato@users.noreply.github.com> Date: Sun, 14 Nov 2021 19:09:36 +0800 Subject: [PATCH 2/9] add the old api back for backporting --- src/Avalonia.Animation/Animation.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Avalonia.Animation/Animation.cs b/src/Avalonia.Animation/Animation.cs index 172782c5a9..90134f3cdf 100644 --- a/src/Avalonia.Animation/Animation.cs +++ b/src/Avalonia.Animation/Animation.cs @@ -353,6 +353,12 @@ namespace Avalonia.Animation return new CompositeDisposable(subscriptions); } + /// + public Task RunAsync(Animatable control, IClock clock = null) + { + return RunAsync(control,clock, default); + } + /// public Task RunAsync(Animatable control, IClock clock = null, CancellationToken cancellationToken = default) { From 3a7298c39ff5ae1328cd6c46194934257f6d4c78 Mon Sep 17 00:00:00 2001 From: Jumar Macato <16554748+jmacato@users.noreply.github.com> Date: Sun, 14 Nov 2021 19:22:53 +0800 Subject: [PATCH 3/9] formatting --- src/Avalonia.Animation/Animation.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Avalonia.Animation/Animation.cs b/src/Avalonia.Animation/Animation.cs index 90134f3cdf..a4515db514 100644 --- a/src/Avalonia.Animation/Animation.cs +++ b/src/Avalonia.Animation/Animation.cs @@ -356,9 +356,9 @@ namespace Avalonia.Animation /// public Task RunAsync(Animatable control, IClock clock = null) { - return RunAsync(control,clock, default); + return RunAsync(control, clock, default); } - + /// public Task RunAsync(Animatable control, IClock clock = null, CancellationToken cancellationToken = default) { From d5420d6b79a66d3534155f2c1bf49c1c7161e284 Mon Sep 17 00:00:00 2001 From: Giuseppe Lippolis Date: Wed, 17 Nov 2021 09:26:49 +0100 Subject: [PATCH 4/9] fixes: Unnecessary re throw --- .../Data/Converters/MethodToCommandConverter.cs | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/Avalonia.Base/Data/Converters/MethodToCommandConverter.cs b/src/Avalonia.Base/Data/Converters/MethodToCommandConverter.cs index 7ff0a8ceca..4a4644317d 100644 --- a/src/Avalonia.Base/Data/Converters/MethodToCommandConverter.cs +++ b/src/Avalonia.Base/Data/Converters/MethodToCommandConverter.cs @@ -140,18 +140,9 @@ namespace Avalonia.Data.Converters ); } - Action action = null; - try - { - action = Expression - .Lambda>(body, parameter) - .Compile(); - } - catch (Exception ex) - { - throw ex; - } - return action; + return Expression + .Lambda>(body, parameter) + .Compile(); } static Func CreateCanExecute(object target From 9e4d562ed6a5e6413d8e0e9c0cd34b760f44ffa2 Mon Sep 17 00:00:00 2001 From: Giuseppe Lippolis Date: Wed, 17 Nov 2021 09:37:19 +0100 Subject: [PATCH 5/9] fixes: CS0188 'RemoteServer.EmbeddableRemoteServerTopLevelImpl.LostFocus' hides inherited member 'OffscreenTopLevelImplBase.LostFocus'. --- src/Avalonia.Controls/Remote/RemoteServer.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Avalonia.Controls/Remote/RemoteServer.cs b/src/Avalonia.Controls/Remote/RemoteServer.cs index 4f5a7cd311..419792f004 100644 --- a/src/Avalonia.Controls/Remote/RemoteServer.cs +++ b/src/Avalonia.Controls/Remote/RemoteServer.cs @@ -15,9 +15,6 @@ namespace Avalonia.Controls.Remote public EmbeddableRemoteServerTopLevelImpl(IAvaloniaRemoteTransportConnection transport) : base(transport) { } -#pragma warning disable 67 - public Action LostFocus { get; set; } - } public RemoteServer(IAvaloniaRemoteTransportConnection transport) From 7703795a4a02142ec5d27a77d74fee59ccfa9db0 Mon Sep 17 00:00:00 2001 From: Jumar Macato <16554748+jmacato@users.noreply.github.com> Date: Fri, 19 Nov 2021 19:05:48 +0800 Subject: [PATCH 6/9] Fix debugging in Rider after we merged .NET 6 Since we merged #6902 our debugging infra for this repo is not working with Rider. This PR fixes it. --- build/SourceLink.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/SourceLink.props b/build/SourceLink.props index 1e007e01eb..0f77c2a613 100644 --- a/build/SourceLink.props +++ b/build/SourceLink.props @@ -3,7 +3,7 @@ true false true - embedded + full $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb From 7a444076669fc55915b848bfb8dc88053fe12842 Mon Sep 17 00:00:00 2001 From: Dariusz Komosinski Date: Sun, 21 Nov 2021 22:59:57 +0100 Subject: [PATCH 7/9] Fix problems caused by missing transform data or invalid order of operations when interpolating matrices. --- src/Avalonia.Visuals/Matrix.cs | 22 ++++++ .../Transformation/InterpolationUtilities.cs | 10 +-- .../Transformation/TransformOperation.cs | 5 +- .../Media/TransformOperationsTests.cs | 72 ++++++++++++++++++- 4 files changed, 101 insertions(+), 8 deletions(-) diff --git a/src/Avalonia.Visuals/Matrix.cs b/src/Avalonia.Visuals/Matrix.cs index 8136f843df..243dafe817 100644 --- a/src/Avalonia.Visuals/Matrix.cs +++ b/src/Avalonia.Visuals/Matrix.cs @@ -215,6 +215,28 @@ namespace Avalonia return angle * 0.0174532925; } + /// + /// Appends another matrix as post-multiplication operation. + /// Equivalent to this * value; + /// + /// A matrix. + /// Post-multiplied matrix. + public Matrix Append(Matrix value) + { + return this * value; + } + + /// + /// Prpends another matrix as pre-multiplication operation. + /// Equivalent to value * this; + /// + /// A matrix. + /// Pre-multiplied matrix. + public Matrix Prepend(Matrix value) + { + return value * this; + } + /// /// Calculates the determinant for this matrix. /// diff --git a/src/Avalonia.Visuals/Media/Transformation/InterpolationUtilities.cs b/src/Avalonia.Visuals/Media/Transformation/InterpolationUtilities.cs index 742bb9c804..76c2deef3b 100644 --- a/src/Avalonia.Visuals/Media/Transformation/InterpolationUtilities.cs +++ b/src/Avalonia.Visuals/Media/Transformation/InterpolationUtilities.cs @@ -18,11 +18,11 @@ namespace Avalonia.Media.Transformation public static Matrix ComposeTransform(Matrix.Decomposed decomposed) { // According to https://www.w3.org/TR/css-transforms-1/#recomposing-to-a-2d-matrix - - return Matrix.CreateTranslation(decomposed.Translate) * - Matrix.CreateRotation(decomposed.Angle) * - Matrix.CreateSkew(decomposed.Skew.X, decomposed.Skew.Y) * - Matrix.CreateScale(decomposed.Scale); + return Matrix.Identity + .Prepend(Matrix.CreateTranslation(decomposed.Translate)) + .Prepend(Matrix.CreateRotation(decomposed.Angle)) + .Prepend(Matrix.CreateSkew(decomposed.Skew.X, decomposed.Skew.Y)) + .Prepend(Matrix.CreateScale(decomposed.Scale)); } public static Matrix.Decomposed InterpolateDecomposedTransforms(ref Matrix.Decomposed from, ref Matrix.Decomposed to, double progress) diff --git a/src/Avalonia.Visuals/Media/Transformation/TransformOperation.cs b/src/Avalonia.Visuals/Media/Transformation/TransformOperation.cs index 36f5dd98f1..13a24cd523 100644 --- a/src/Avalonia.Visuals/Media/Transformation/TransformOperation.cs +++ b/src/Avalonia.Visuals/Media/Transformation/TransformOperation.cs @@ -86,6 +86,8 @@ namespace Avalonia.Media.Transformation if (fromIdentity && toIdentity) { + result.Matrix = Matrix.Identity; + return true; } @@ -179,7 +181,8 @@ namespace Avalonia.Media.Transformation } case OperationType.Identity: { - // Do nothing. + result.Matrix = Matrix.Identity; + break; } } diff --git a/tests/Avalonia.Visuals.UnitTests/Media/TransformOperationsTests.cs b/tests/Avalonia.Visuals.UnitTests/Media/TransformOperationsTests.cs index 856b4615a5..e4f88706d8 100644 --- a/tests/Avalonia.Visuals.UnitTests/Media/TransformOperationsTests.cs +++ b/tests/Avalonia.Visuals.UnitTests/Media/TransformOperationsTests.cs @@ -129,7 +129,7 @@ namespace Avalonia.Visuals.UnitTests.Media Assert.Single(operations); Assert.Equal(TransformOperation.OperationType.Matrix, operations[0].Type); - + var expectedMatrix = new Matrix(1, 2, 3, 4, 5, 6); Assert.Equal(expectedMatrix, operations[0].Matrix); @@ -195,7 +195,7 @@ namespace Avalonia.Visuals.UnitTests.Media [Theory] [InlineData(0d, 10d)] [InlineData(0.5d, 15d)] - [InlineData(1d,20d)] + [InlineData(1d, 20d)] public void Can_Interpolate_Rotation(double progress, double angle) { var from = TransformOperations.Parse("rotate(10deg)"); @@ -225,5 +225,73 @@ namespace Avalonia.Visuals.UnitTests.Media Assert.Single(operations); Assert.Equal(TransformOperation.OperationType.Matrix, operations[0].Type); } + + [Fact] + public void Order_Of_Operations_Is_Preserved_No_Prefix() + { + var from = TransformOperations.Parse("scale(1)"); + var to = TransformOperations.Parse("translate(50px,50px) scale(0.5,0.5)"); + + var interpolated_0 = TransformOperations.Interpolate(from, to, 0); + + Assert.True(interpolated_0.IsIdentity); + + var interpolated_50 = TransformOperations.Interpolate(from, to, 0.5); + + AssertMatrix(interpolated_50.Value, scaleX: 0.75, scaleY: 0.75, translateX: 12.5, translateY: 12.5); + + var interpolated_100 = TransformOperations.Interpolate(from, to, 1); + + AssertMatrix(interpolated_100.Value, scaleX: 0.5, scaleY: 0.5, translateX: 25, translateY: 25); + } + + [Fact] + public void Order_Of_Operations_Is_Preserved_One_Prefix() + { + var from = TransformOperations.Parse("scale(1)"); + var to = TransformOperations.Parse("scale(0.5,0.5) translate(50px,50px)"); + + var interpolated_0 = TransformOperations.Interpolate(from, to, 0); + + Assert.True(interpolated_0.IsIdentity); + + var interpolated_50 = TransformOperations.Interpolate(from, to, 0.5); + + AssertMatrix(interpolated_50.Value, scaleX: 0.75, scaleY: 0.75, translateX: 25.0, translateY: 25); + + var interpolated_100 = TransformOperations.Interpolate(from, to, 1); + + AssertMatrix(interpolated_100.Value, scaleX: 0.5, scaleY: 0.5, translateX: 50, translateY: 50); + } + + private static void AssertMatrix(Matrix matrix, double? angle = null, double? scaleX = null, double? scaleY = null, double? translateX = null, double? translateY = null) + { + Assert.True(Matrix.TryDecomposeTransform(matrix, out var composed)); + + if (angle.HasValue) + { + Assert.Equal(angle.Value, composed.Angle); + } + + if (scaleX.HasValue) + { + Assert.Equal(scaleX.Value, composed.Scale.X); + } + + if (scaleY.HasValue) + { + Assert.Equal(scaleY.Value, composed.Scale.Y); + } + + if (translateX.HasValue) + { + Assert.Equal(translateX.Value, composed.Translate.X); + } + + if (translateY.HasValue) + { + Assert.Equal(translateY.Value, composed.Translate.Y); + } + } } } From f2d4ef25385467561cd1c6562eb2e804a6cb0459 Mon Sep 17 00:00:00 2001 From: Jumar Macato <16554748+jmacato@users.noreply.github.com> Date: Mon, 22 Nov 2021 19:31:07 +0800 Subject: [PATCH 8/9] add ApiCompatBaseline.txt --- src/Avalonia.Animation/ApiCompatBaseline.txt | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 src/Avalonia.Animation/ApiCompatBaseline.txt diff --git a/src/Avalonia.Animation/ApiCompatBaseline.txt b/src/Avalonia.Animation/ApiCompatBaseline.txt deleted file mode 100644 index 58cb7830e7..0000000000 --- a/src/Avalonia.Animation/ApiCompatBaseline.txt +++ /dev/null @@ -1,6 +0,0 @@ -Compat issues with assembly Avalonia.Animation: -MembersMustExist : Member 'public System.Threading.Tasks.Task Avalonia.Animation.Animation.RunAsync(Avalonia.Animation.Animatable, Avalonia.Animation.IClock)' does not exist in the implementation but it does exist in the contract. -InterfacesShouldHaveSameMembers : Interface member 'public System.Threading.Tasks.Task Avalonia.Animation.IAnimation.RunAsync(Avalonia.Animation.Animatable, Avalonia.Animation.IClock)' is present in the contract but not in the implementation. -MembersMustExist : Member 'public System.Threading.Tasks.Task Avalonia.Animation.IAnimation.RunAsync(Avalonia.Animation.Animatable, Avalonia.Animation.IClock)' does not exist in the implementation but it does exist in the contract. -InterfacesShouldHaveSameMembers : Interface member 'public System.Threading.Tasks.Task Avalonia.Animation.IAnimation.RunAsync(Avalonia.Animation.Animatable, Avalonia.Animation.IClock, System.Threading.CancellationToken)' is present in the implementation but not in the contract. -Total Issues: 4 From 8e41e2f889d329b02976cf2ac02fa8b4b6e47f80 Mon Sep 17 00:00:00 2001 From: Jumar Macato <16554748+jmacato@users.noreply.github.com> Date: Mon, 22 Nov 2021 19:32:49 +0800 Subject: [PATCH 9/9] add ApiCompat --- src/Avalonia.Animation/ApiCompatBaseline.txt | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/Avalonia.Animation/ApiCompatBaseline.txt diff --git a/src/Avalonia.Animation/ApiCompatBaseline.txt b/src/Avalonia.Animation/ApiCompatBaseline.txt new file mode 100644 index 0000000000..973698f872 --- /dev/null +++ b/src/Avalonia.Animation/ApiCompatBaseline.txt @@ -0,0 +1,5 @@ +Compat issues with assembly Avalonia.Animation: +InterfacesShouldHaveSameMembers : Interface member 'public System.Threading.Tasks.Task Avalonia.Animation.IAnimation.RunAsync(Avalonia.Animation.Animatable, Avalonia.Animation.IClock)' is present in the contract but not in the implementation. +MembersMustExist : Member 'public System.Threading.Tasks.Task Avalonia.Animation.IAnimation.RunAsync(Avalonia.Animation.Animatable, Avalonia.Animation.IClock)' does not exist in the implementation but it does exist in the contract. +InterfacesShouldHaveSameMembers : Interface member 'public System.Threading.Tasks.Task Avalonia.Animation.IAnimation.RunAsync(Avalonia.Animation.Animatable, Avalonia.Animation.IClock, System.Threading.CancellationToken)' is present in the implementation but not in the contract. +Total Issues: 3