From 8132bdc162705394e7a9dad115ad3727f690f30b Mon Sep 17 00:00:00 2001 From: ahopper Date: Wed, 31 Oct 2018 09:49:43 +0000 Subject: [PATCH 1/9] end animation cleanly with correct value --- src/Avalonia.Animation/AnimationInstance`1.cs | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/Avalonia.Animation/AnimationInstance`1.cs b/src/Avalonia.Animation/AnimationInstance`1.cs index 1ad609bce8..04c91ced99 100644 --- a/src/Avalonia.Animation/AnimationInstance`1.cs +++ b/src/Avalonia.Animation/AnimationInstance`1.cs @@ -141,9 +141,6 @@ namespace Avalonia.Animation } else if (time > iterationEndpoint) { - //Subtract first iteration to properly get the subsequent iteration time - time -= iterationEndpoint; - if (!_iterationDelay & delayEndpoint > TimeSpan.Zero) { delayEndpoint = TimeSpan.Zero; @@ -151,27 +148,32 @@ namespace Avalonia.Animation } //Calculate the current iteration number - _currentIteration = (int)Math.Floor((double)((double)time.Ticks / iterationEndpoint.Ticks)) + 2; + _currentIteration = (int)Math.Floor((double)((double)time.Ticks / iterationEndpoint.Ticks))+1; } else { return; } - time = TimeSpan.FromTicks((long)(time.Ticks % iterationEndpoint.Ticks)); - - if (!_isLooping) - { - if ((_currentIteration > _repeatCount) || (time > iterationEndpoint)) - DoComplete(); - } - - // Determine if the current iteration should have its normalized time inverted. + // Determine if the current iteration should have its normalized time inverted. bool isCurIterReverse = _animationDirection == PlaybackDirection.Normal ? false : _animationDirection == PlaybackDirection.Alternate ? (_currentIteration % 2 == 0) ? false : true : _animationDirection == PlaybackDirection.AlternateReverse ? (_currentIteration % 2 == 0) ? true : false : _animationDirection == PlaybackDirection.Reverse ? true : false; - + + if (!_isLooping) + { + if ((_currentIteration > _repeatCount) || (time >= iterationEndpoint)) + { + var easedTime = _easeFunc.Ease(isCurIterReverse?0.0:1.0); + _lastInterpValue = _interpolator(easedTime, _neutralValue); + + DoComplete(); + return; + } + } + time = TimeSpan.FromTicks((long)(time.Ticks % iterationEndpoint.Ticks)); + if (delayEndpoint > TimeSpan.Zero & time < delayEndpoint) { DoDelay(); From 8864dc8e10e4ac36e6222451176ab93980c005ac Mon Sep 17 00:00:00 2001 From: ahopper Date: Wed, 31 Oct 2018 11:36:01 +0000 Subject: [PATCH 2/9] Fix repeating animations --- src/Avalonia.Animation/AnimationInstance`1.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Avalonia.Animation/AnimationInstance`1.cs b/src/Avalonia.Animation/AnimationInstance`1.cs index 04c91ced99..273c59df0a 100644 --- a/src/Avalonia.Animation/AnimationInstance`1.cs +++ b/src/Avalonia.Animation/AnimationInstance`1.cs @@ -163,7 +163,8 @@ namespace Avalonia.Animation if (!_isLooping) { - if ((_currentIteration > _repeatCount) || (time >= iterationEndpoint)) + var totalTime = _repeatCount * _duration.Ticks + _delay.Ticks; + if (time.Ticks >= totalTime) { var easedTime = _easeFunc.Ease(isCurIterReverse?0.0:1.0); _lastInterpValue = _interpolator(easedTime, _neutralValue); From 29aad6bc9a35839fc2718ab1b6ec61844b554b1b Mon Sep 17 00:00:00 2001 From: ahopper Date: Wed, 31 Oct 2018 12:09:06 +0000 Subject: [PATCH 3/9] allow for Delay --- src/Avalonia.Animation/AnimationInstance`1.cs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Avalonia.Animation/AnimationInstance`1.cs b/src/Avalonia.Animation/AnimationInstance`1.cs index 273c59df0a..5f8e33b09a 100644 --- a/src/Avalonia.Animation/AnimationInstance`1.cs +++ b/src/Avalonia.Animation/AnimationInstance`1.cs @@ -133,6 +133,7 @@ namespace Avalonia.Animation DoPlayStates(); var delayEndpoint = _delay; var iterationEndpoint = delayEndpoint + _duration; + var iterationTime = time; //determine if time is currently in the first iteration. if (time >= TimeSpan.Zero & time <= iterationEndpoint) @@ -141,6 +142,9 @@ namespace Avalonia.Animation } else if (time > iterationEndpoint) { + //Subtract first iteration to properly get the subsequent iteration time + iterationTime -= iterationEndpoint; + if (!_iterationDelay & delayEndpoint > TimeSpan.Zero) { delayEndpoint = TimeSpan.Zero; @@ -148,7 +152,7 @@ namespace Avalonia.Animation } //Calculate the current iteration number - _currentIteration = (int)Math.Floor((double)((double)time.Ticks / iterationEndpoint.Ticks))+1; + _currentIteration = Math.Max(_repeatCount,(int)Math.Floor((double)((double)iterationTime.Ticks / iterationEndpoint.Ticks)) + 2); } else { @@ -173,20 +177,20 @@ namespace Avalonia.Animation return; } } - time = TimeSpan.FromTicks((long)(time.Ticks % iterationEndpoint.Ticks)); + iterationTime = TimeSpan.FromTicks((long)(iterationTime.Ticks % iterationEndpoint.Ticks)); - if (delayEndpoint > TimeSpan.Zero & time < delayEndpoint) + if (delayEndpoint > TimeSpan.Zero & iterationTime < delayEndpoint) { DoDelay(); } else { // Offset the delay time - time -= delayEndpoint; + iterationTime -= delayEndpoint; iterationEndpoint -= delayEndpoint; // Normalize time - var interpVal = (double)time.Ticks / iterationEndpoint.Ticks; + var interpVal = (double)iterationTime.Ticks / iterationEndpoint.Ticks; if (isCurIterReverse) interpVal = 1 - interpVal; From d82a25ea5f72fd51b344c7accff9360e76abddf1 Mon Sep 17 00:00:00 2001 From: ahopper Date: Wed, 31 Oct 2018 12:25:17 +0000 Subject: [PATCH 4/9] fix reversing --- src/Avalonia.Animation/AnimationInstance`1.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Avalonia.Animation/AnimationInstance`1.cs b/src/Avalonia.Animation/AnimationInstance`1.cs index 5f8e33b09a..ea033d8cc9 100644 --- a/src/Avalonia.Animation/AnimationInstance`1.cs +++ b/src/Avalonia.Animation/AnimationInstance`1.cs @@ -152,7 +152,7 @@ namespace Avalonia.Animation } //Calculate the current iteration number - _currentIteration = Math.Max(_repeatCount,(int)Math.Floor((double)((double)iterationTime.Ticks / iterationEndpoint.Ticks)) + 2); + _currentIteration = Math.Min(_repeatCount,(int)Math.Floor((double)((double)iterationTime.Ticks / iterationEndpoint.Ticks)) + 2); } else { From bb0bb392821eefde12ef9fc985c93c2665038e2a Mon Sep 17 00:00:00 2001 From: ahopper Date: Wed, 31 Oct 2018 15:25:42 +0000 Subject: [PATCH 5/9] respect FillMode=Forward if animation stopped part way through --- src/Avalonia.Animation/AnimationInstance`1.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Avalonia.Animation/AnimationInstance`1.cs b/src/Avalonia.Animation/AnimationInstance`1.cs index ea033d8cc9..8184e68d42 100644 --- a/src/Avalonia.Animation/AnimationInstance`1.cs +++ b/src/Avalonia.Animation/AnimationInstance`1.cs @@ -72,10 +72,13 @@ namespace Avalonia.Animation _onCompleteAction = OnComplete; _interpolator = Interpolator; _baseClock = baseClock; - } + } protected override void Unsubscribed() { + //Animation may have been stopped before it has finished + ApplyFinalFill(); + _timerSubscription?.Dispose(); _clock.PlayState = PlayState.Stop; } @@ -98,11 +101,15 @@ namespace Avalonia.Animation } } - private void DoComplete() + private void ApplyFinalFill() { if (_fillMode == FillMode.Forward || _fillMode == FillMode.Both) _targetControl.SetValue(_parent.Property, _lastInterpValue, BindingPriority.LocalValue); + } + private void DoComplete() + { + ApplyFinalFill(); _onCompleteAction?.Invoke(); PublishCompleted(); } @@ -167,10 +174,10 @@ namespace Avalonia.Animation if (!_isLooping) { - var totalTime = _repeatCount * _duration.Ticks + _delay.Ticks; + var totalTime = _iterationDelay ? _repeatCount * ( _duration.Ticks + _delay.Ticks) : _repeatCount * _duration.Ticks + _delay.Ticks; if (time.Ticks >= totalTime) { - var easedTime = _easeFunc.Ease(isCurIterReverse?0.0:1.0); + var easedTime = _easeFunc.Ease(isCurIterReverse ? 0.0 : 1.0); _lastInterpValue = _interpolator(easedTime, _neutralValue); DoComplete(); From b4dcc14b8d04738760f08724f09c003d4990e81e Mon Sep 17 00:00:00 2001 From: Stano Turza Date: Sat, 3 Nov 2018 14:47:25 +0100 Subject: [PATCH 6/9] make sure pointer is always inside presenter --- src/Avalonia.Controls/TextBox.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs index d6c3a1041e..fc1b64a631 100644 --- a/src/Avalonia.Controls/TextBox.cs +++ b/src/Avalonia.Controls/TextBox.cs @@ -655,6 +655,8 @@ namespace Avalonia.Controls if (_presenter != null && e.Device.Captured == _presenter) { var point = e.GetPosition(_presenter); + + point = new Point(Math.Max(Math.Min(point.X, _presenter.Bounds.Width - 1), 0), Math.Max(Math.Min(point.Y, _presenter.Bounds.Height - 1), 0)); CaretIndex = SelectionEnd = _presenter.GetCaretIndex(point); } } From 12a49d4336e86ac8f2e6fa144e53a216c049e3a7 Mon Sep 17 00:00:00 2001 From: Stano Turza Date: Sat, 3 Nov 2018 18:15:43 +0100 Subject: [PATCH 7/9] [skia] fixes right aligned textbox selection --- src/Skia/Avalonia.Skia/FormattedTextImpl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Skia/Avalonia.Skia/FormattedTextImpl.cs b/src/Skia/Avalonia.Skia/FormattedTextImpl.cs index 2a8f517995..56c5c57f7b 100644 --- a/src/Skia/Avalonia.Skia/FormattedTextImpl.cs +++ b/src/Skia/Avalonia.Skia/FormattedTextImpl.cs @@ -121,7 +121,7 @@ namespace Avalonia.Skia int offset = 0; - if (point.X >= (rects[line.Start].X + line.Width) / 2 && line.Length > 0) + if (point.X >= (rects[line.Start].X + line.Width) && line.Length > 0) { offset = line.TextLength > line.Length ? line.Length : (line.Length - 1); From 3dd51660df8f6fb594375de5302fd440abf97952 Mon Sep 17 00:00:00 2001 From: Stano Turza Date: Sun, 4 Nov 2018 15:09:24 +0100 Subject: [PATCH 8/9] use MathUtilities.Clamp --- src/Avalonia.Controls/TextBox.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs index fc1b64a631..dc2884b36b 100644 --- a/src/Avalonia.Controls/TextBox.cs +++ b/src/Avalonia.Controls/TextBox.cs @@ -14,6 +14,7 @@ using Avalonia.Interactivity; using Avalonia.Media; using Avalonia.Metadata; using Avalonia.Data; +using Avalonia.Utilities; namespace Avalonia.Controls { @@ -656,7 +657,7 @@ namespace Avalonia.Controls { var point = e.GetPosition(_presenter); - point = new Point(Math.Max(Math.Min(point.X, _presenter.Bounds.Width - 1), 0), Math.Max(Math.Min(point.Y, _presenter.Bounds.Height - 1), 0)); + point = new Point(MathUtilities.Clamp(point.X, 0, _presenter.Bounds.Width - 1), MathUtilities.Clamp(point.Y, 0, _presenter.Bounds.Height - 1)); CaretIndex = SelectionEnd = _presenter.GetCaretIndex(point); } } From fd192cf3c21617f767d389df3f6f65bda9bea6aa Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Mon, 5 Nov 2018 20:33:11 +0300 Subject: [PATCH 9/9] Fixed Rider support for Avalonia.Native project --- src/Avalonia.Native/.gitignore | 1 + src/Avalonia.Native/Avalonia.Native.csproj | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 src/Avalonia.Native/.gitignore diff --git a/src/Avalonia.Native/.gitignore b/src/Avalonia.Native/.gitignore new file mode 100644 index 0000000000..b1153e777c --- /dev/null +++ b/src/Avalonia.Native/.gitignore @@ -0,0 +1 @@ +Generated/*.cs diff --git a/src/Avalonia.Native/Avalonia.Native.csproj b/src/Avalonia.Native/Avalonia.Native.csproj index 9d6a82a2fb..c8ee73ad5d 100644 --- a/src/Avalonia.Native/Avalonia.Native.csproj +++ b/src/Avalonia.Native/Avalonia.Native.csproj @@ -7,6 +7,8 @@ /usr/bin/castxml /usr/local/bin/castxml true + + $(MSBuildThisFileDirectory)/Generated