committed by
GitHub
168 changed files with 2695 additions and 1008 deletions
@ -0,0 +1,5 @@ |
|||
<ProjectConfiguration> |
|||
<Settings> |
|||
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely> |
|||
</Settings> |
|||
</ProjectConfiguration> |
|||
@ -0,0 +1,5 @@ |
|||
<ProjectConfiguration> |
|||
<Settings> |
|||
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely> |
|||
</Settings> |
|||
</ProjectConfiguration> |
|||
@ -1,5 +1,5 @@ |
|||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<ItemGroup> |
|||
<PackageReference Include="Magick.NET-Q16-AnyCPU" Version="7.0.6.102" /> |
|||
<PackageReference Include="Magick.NET-Q16-AnyCPU" Version="7.9.0.2" /> |
|||
</ItemGroup> |
|||
</Project> |
|||
|
|||
@ -1,6 +1,6 @@ |
|||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<ItemGroup> |
|||
<PackageReference Include="SkiaSharp" Version="1.60.0" /> |
|||
<PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="Avalonia.Skia.Linux.Natives" Version="1.60.0.1" /> |
|||
<PackageReference Include="SkiaSharp" Version="1.68.0" /> |
|||
<PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="SkiaSharp.NativeAssets.Linux" Version="1.68.0" /> |
|||
</ItemGroup> |
|||
</Project> |
|||
|
|||
@ -0,0 +1,8 @@ |
|||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<Import Project="$(MSBuildThisFileDirectory)/NetFX.props" /> |
|||
<ItemGroup Condition="$(TargetFramework.StartsWith('net4'))"> |
|||
<Content Include="$(MSBuildThisFileDirectory)/xunit.runner.mono.json" Link="xunit.runner.json" > |
|||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> |
|||
</Content> |
|||
</ItemGroup> |
|||
</Project> |
|||
@ -0,0 +1 @@ |
|||
{ "appDomain": "denied" } |
|||
@ -1,7 +1,7 @@ |
|||
{ |
|||
"msbuild-sdks": { |
|||
"Microsoft.Build.Traversal": "1.0.43", |
|||
"MSBuild.Sdk.Extras": "1.6.46", |
|||
"MSBuild.Sdk.Extras": "1.6.65", |
|||
"AggregatePackage.NuGet.Sdk" : "0.1.12" |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,8 @@ |
|||
# editorconfig.org |
|||
|
|||
# top-most EditorConfig file |
|||
root = false |
|||
|
|||
# C# files |
|||
[*.cs] |
|||
dotnet_style_require_accessibility_modifiers = never |
|||
@ -1,129 +0,0 @@ |
|||
using System.Xml.Linq; |
|||
using System.Linq; |
|||
|
|||
public class Parameters |
|||
{ |
|||
public string Configuration { get; private set; } |
|||
public bool SkipTests { get; private set; } |
|||
public string MainRepo { get; private set; } |
|||
public string MasterBranch { get; private set; } |
|||
public string ReleasePlatform { get; private set; } |
|||
public string ReleaseConfiguration { get; private set; } |
|||
public string ReleaseBranchPrefix { get; private set; } |
|||
public string MSBuildSolution { get; private set; } |
|||
public bool IsLocalBuild { get; private set; } |
|||
public bool IsRunningOnUnix { get; private set; } |
|||
public bool IsRunningOnWindows { get; private set; } |
|||
public bool IsRunningOnAppVeyor { get; private set; } |
|||
public bool IsRunningOnAzure { get; private set; } |
|||
public bool IsPullRequest { get; private set; } |
|||
public bool IsMainRepo { get; private set; } |
|||
public bool IsMasterBranch { get; private set; } |
|||
public bool IsReleaseBranch { get; private set; } |
|||
public bool IsTagged { get; private set; } |
|||
public bool IsReleasable { get; private set; } |
|||
public bool IsMyGetRelease { get; private set; } |
|||
public bool IsNuGetRelease { get; private set; } |
|||
public bool PublishTestResults { get; private set; } |
|||
public string Version { get; private set; } |
|||
public DirectoryPath ArtifactsDir { get; private set; } |
|||
public DirectoryPath NugetRoot { get; private set; } |
|||
public DirectoryPath ZipRoot { get; private set; } |
|||
public DirectoryPath BinRoot { get; private set; } |
|||
public DirectoryPath TestResultsRoot { get; private set; } |
|||
public string DirSuffix { get; private set; } |
|||
public DirectoryPathCollection BuildDirs { get; private set; } |
|||
public string FileZipSuffix { get; private set; } |
|||
public FilePath ZipCoreArtifacts { get; private set; } |
|||
public FilePath ZipNuGetArtifacts { get; private set; } |
|||
public DirectoryPath ZipSourceControlCatalogDesktopDirs { get; private set; } |
|||
public FilePath ZipTargetControlCatalogDesktopDirs { get; private set; } |
|||
|
|||
public Parameters(ICakeContext context) |
|||
{ |
|||
var buildSystem = context.BuildSystem(); |
|||
|
|||
// ARGUMENTS |
|||
Configuration = context.Argument("configuration", "Release"); |
|||
SkipTests = context.HasArgument("skip-tests"); |
|||
|
|||
// CONFIGURATION |
|||
MainRepo = "https://github.com/AvaloniaUI/Avalonia"; |
|||
MasterBranch = "master"; |
|||
ReleaseBranchPrefix = "refs/heads/release/"; |
|||
ReleaseConfiguration = "Release"; |
|||
MSBuildSolution = "./dirs.proj"; |
|||
|
|||
// PARAMETERS |
|||
IsLocalBuild = buildSystem.IsLocalBuild; |
|||
IsRunningOnUnix = context.IsRunningOnUnix(); |
|||
IsRunningOnWindows = context.IsRunningOnWindows(); |
|||
IsRunningOnAppVeyor = buildSystem.AppVeyor.IsRunningOnAppVeyor; |
|||
IsRunningOnAzure = buildSystem.IsRunningOnVSTS || buildSystem.IsRunningOnTFS || context.EnvironmentVariable("LOGNAME") == "vsts"; |
|||
|
|||
IsPullRequest = buildSystem.AppVeyor.Environment.PullRequest.IsPullRequest; |
|||
IsMainRepo = StringComparer.OrdinalIgnoreCase.Equals(MainRepo, context.EnvironmentVariable("BUILD_REPOSITORY_URI")); |
|||
IsMasterBranch = StringComparer.OrdinalIgnoreCase.Equals(MasterBranch, context.EnvironmentVariable("BUILD_SOURCEBRANCHNAME")); |
|||
IsReleaseBranch = (context.EnvironmentVariable("BUILD_SOURCEBRANCH")??"").StartsWith(ReleaseBranchPrefix, StringComparison.OrdinalIgnoreCase); |
|||
IsTagged = buildSystem.AppVeyor.Environment.Repository.Tag.IsTag |
|||
&& !string.IsNullOrWhiteSpace(buildSystem.AppVeyor.Environment.Repository.Tag.Name); |
|||
IsReleasable = StringComparer.OrdinalIgnoreCase.Equals(ReleaseConfiguration, Configuration); |
|||
IsMyGetRelease = !IsTagged && IsReleasable; |
|||
IsNuGetRelease = IsMainRepo && IsReleasable && IsReleaseBranch; |
|||
|
|||
// VERSION |
|||
Version = context.Argument("force-nuget-version", GetVersion()); |
|||
|
|||
if (IsRunningOnAppVeyor) |
|||
{ |
|||
string tagVersion = null; |
|||
if (IsTagged) |
|||
{ |
|||
var tag = buildSystem.AppVeyor.Environment.Repository.Tag.Name; |
|||
var nugetReleasePrefix = "nuget-release-"; |
|||
IsNuGetRelease = IsTagged && IsReleasable && tag.StartsWith(nugetReleasePrefix); |
|||
if(IsNuGetRelease) |
|||
tagVersion = tag.Substring(nugetReleasePrefix.Length); |
|||
} |
|||
if(tagVersion != null) |
|||
{ |
|||
Version = tagVersion; |
|||
} |
|||
else |
|||
{ |
|||
// Use AssemblyVersion with Build as version |
|||
Version += "-build" + context.EnvironmentVariable("APPVEYOR_BUILD_NUMBER") + "-beta"; |
|||
} |
|||
} |
|||
else if (IsRunningOnAzure) |
|||
{ |
|||
if(!IsNuGetRelease) |
|||
{ |
|||
// Use AssemblyVersion with Build as version |
|||
Version += "-build" + context.EnvironmentVariable("BUILD_BUILDID") + "-beta"; |
|||
} |
|||
|
|||
PublishTestResults = true; |
|||
} |
|||
|
|||
// DIRECTORIES |
|||
ArtifactsDir = (DirectoryPath)context.Directory("./artifacts"); |
|||
NugetRoot = ArtifactsDir.Combine("nuget"); |
|||
ZipRoot = ArtifactsDir.Combine("zip"); |
|||
BinRoot = ArtifactsDir.Combine("bin"); |
|||
TestResultsRoot = ArtifactsDir.Combine("test-results"); |
|||
BuildDirs = context.GetDirectories("**/bin") + context.GetDirectories("**/obj"); |
|||
DirSuffix = Configuration; |
|||
FileZipSuffix = Version + ".zip"; |
|||
ZipCoreArtifacts = ZipRoot.CombineWithFilePath("Avalonia-" + FileZipSuffix); |
|||
ZipNuGetArtifacts = ZipRoot.CombineWithFilePath("Avalonia-NuGet-" + FileZipSuffix); |
|||
ZipSourceControlCatalogDesktopDirs = (DirectoryPath)context.Directory("./samples/ControlCatalog.Desktop/bin/" + DirSuffix + "/net461"); |
|||
ZipTargetControlCatalogDesktopDirs = ZipRoot.CombineWithFilePath("ControlCatalog.Desktop-" + FileZipSuffix); |
|||
} |
|||
|
|||
private static string GetVersion() |
|||
{ |
|||
var xdoc = XDocument.Load("./build/SharedVersion.props"); |
|||
return xdoc.Descendants().First(x => x.Name.LocalName == "Version").Value; |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="bool"/> properties.
|
|||
/// </summary>
|
|||
public class BoolAnimator : Animator<bool> |
|||
{ |
|||
/// <inheritdocs/>
|
|||
public override bool Interpolate(double progress, bool oldValue, bool newValue) |
|||
{ |
|||
if(progress >= 1d) |
|||
return newValue; |
|||
if(progress >= 0) |
|||
return oldValue; |
|||
return oldValue; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="byte"/> properties.
|
|||
/// </summary>
|
|||
public class ByteAnimator : Animator<byte> |
|||
{ |
|||
const double maxVal = (double)byte.MaxValue; |
|||
|
|||
/// <inheritdocs/>
|
|||
public override byte Interpolate(double progress, byte oldValue, byte newValue) |
|||
{ |
|||
var normOV = oldValue / maxVal; |
|||
var normNV = newValue / maxVal; |
|||
var deltaV = normNV - normOV; |
|||
return (byte)Math.Round(maxVal * ((deltaV * progress) + normOV)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="decimal"/> properties.
|
|||
/// </summary>
|
|||
public class DecimalAnimator : Animator<decimal> |
|||
{ |
|||
/// <inheritdocs/>
|
|||
public override decimal Interpolate(double progress, decimal oldValue, decimal newValue) |
|||
{ |
|||
return ((newValue - oldValue) * (decimal)progress) + oldValue; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="double"/> properties.
|
|||
/// </summary>
|
|||
public class DoubleAnimator : Animator<double> |
|||
{ |
|||
/// <inheritdocs/>
|
|||
public override double Interpolate(double progress, double oldValue, double newValue) |
|||
{ |
|||
return ((newValue - oldValue) * progress) + oldValue; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="float"/> properties.
|
|||
/// </summary>
|
|||
public class FloatAnimator : Animator<float> |
|||
{ |
|||
/// <inheritdocs/>
|
|||
public override float Interpolate(double progress, float oldValue, float newValue) |
|||
{ |
|||
return (float)(((newValue - oldValue) * progress) + oldValue); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="Int16"/> properties.
|
|||
/// </summary>
|
|||
public class Int16Animator : Animator<Int16> |
|||
{ |
|||
const double maxVal = (double)Int16.MaxValue; |
|||
|
|||
/// <inheritdocs/>
|
|||
public override Int16 Interpolate(double progress, Int16 oldValue, Int16 newValue) |
|||
{ |
|||
var normOV = oldValue / maxVal; |
|||
var normNV = newValue / maxVal; |
|||
var deltaV = normNV - normOV; |
|||
return (Int16)Math.Round(maxVal * ((deltaV * progress) + normOV)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="Int32"/> properties.
|
|||
/// </summary>
|
|||
public class Int32Animator : Animator<Int32> |
|||
{ |
|||
const double maxVal = (double)Int32.MaxValue; |
|||
|
|||
/// <inheritdocs/>
|
|||
public override Int32 Interpolate(double progress, Int32 oldValue, Int32 newValue) |
|||
{ |
|||
var normOV = oldValue / maxVal; |
|||
var normNV = newValue / maxVal; |
|||
var deltaV = normNV - normOV; |
|||
return (Int32)Math.Round(maxVal * ((deltaV * progress) + normOV)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="Int64"/> properties.
|
|||
/// </summary>
|
|||
public class Int64Animator : Animator<Int64> |
|||
{ |
|||
const double maxVal = (double)Int64.MaxValue; |
|||
|
|||
/// <inheritdocs/>
|
|||
public override Int64 Interpolate(double progress, Int64 oldValue, Int64 newValue) |
|||
{ |
|||
var normOV = oldValue / maxVal; |
|||
var normNV = newValue / maxVal; |
|||
var deltaV = normNV - normOV; |
|||
return (Int64)Math.Round(maxVal * ((deltaV * progress) + normOV)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="UInt16"/> properties.
|
|||
/// </summary>
|
|||
public class UInt16Animator : Animator<UInt16> |
|||
{ |
|||
const double maxVal = (double)UInt16.MaxValue; |
|||
|
|||
/// <inheritdocs/>
|
|||
public override UInt16 Interpolate(double progress, UInt16 oldValue, UInt16 newValue) |
|||
{ |
|||
var normOV = oldValue / maxVal; |
|||
var normNV = newValue / maxVal; |
|||
var deltaV = normNV - normOV; |
|||
return (UInt16)Math.Round(maxVal * ((deltaV * progress) + normOV)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="UInt32"/> properties.
|
|||
/// </summary>
|
|||
public class UInt32Animator : Animator<UInt32> |
|||
{ |
|||
const double maxVal = (double)UInt32.MaxValue; |
|||
|
|||
/// <inheritdocs/>
|
|||
public override UInt32 Interpolate(double progress, UInt32 oldValue, UInt32 newValue) |
|||
{ |
|||
var normOV = oldValue / maxVal; |
|||
var normNV = newValue / maxVal; |
|||
var deltaV = normNV - normOV; |
|||
return (UInt32)Math.Round(maxVal * ((deltaV * progress) + normOV)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="UInt64"/> properties.
|
|||
/// </summary>
|
|||
public class UInt64Animator : Animator<UInt64> |
|||
{ |
|||
const double maxVal = (double)UInt64.MaxValue; |
|||
|
|||
/// <inheritdocs/>
|
|||
public override UInt64 Interpolate(double progress, UInt64 oldValue, UInt64 newValue) |
|||
{ |
|||
var normOV = oldValue / maxVal; |
|||
var normNV = newValue / maxVal; |
|||
var deltaV = normNV - normOV; |
|||
return (UInt64)Math.Round(maxVal * ((deltaV * progress) + normOV)); |
|||
} |
|||
} |
|||
} |
|||
@ -1,35 +0,0 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
namespace Avalonia.Animation |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="double"/> properties.
|
|||
/// </summary>
|
|||
public class DoubleAnimator : Animator<double> |
|||
{ |
|||
|
|||
/// <inheritdocs/>
|
|||
protected override double DoInterpolation(double t, double neutralValue) |
|||
{ |
|||
var pair = GetKFPairAndIntraKFTime(t); |
|||
double y0, y1; |
|||
|
|||
var firstKF = pair.KFPair.FirstKeyFrame; |
|||
var secondKF = pair.KFPair.SecondKeyFrame; |
|||
|
|||
if (firstKF.isNeutral) |
|||
y0 = neutralValue; |
|||
else |
|||
y0 = firstKF.TargetValue; |
|||
|
|||
if (secondKF.isNeutral) |
|||
y1 = neutralValue; |
|||
else |
|||
y1 = secondKF.TargetValue; |
|||
|
|||
// Do linear parametric interpolation
|
|||
return y0 + (pair.IntraKFTime) * (y1 - y0); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,176 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.ComponentModel; |
|||
using System.Globalization; |
|||
|
|||
namespace Avalonia.Animation |
|||
{ |
|||
/// <summary>
|
|||
/// Defines the valid modes for a <see cref="IterationCount"/>.
|
|||
/// </summary>
|
|||
public enum IterationType |
|||
{ |
|||
Many, |
|||
Infinite |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Determines the number of iterations of an animation.
|
|||
/// Also defines its repeat behavior.
|
|||
/// </summary>
|
|||
[TypeConverter(typeof(IterationCountTypeConverter))] |
|||
public struct IterationCount : IEquatable<IterationCount> |
|||
{ |
|||
private readonly IterationType _type; |
|||
private readonly ulong _value; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IterationCount"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="value">The number of iterations of an animation.</param>
|
|||
public IterationCount(ulong value) |
|||
: this(value, IterationType.Many) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IterationCount"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="value">The size of the IterationCount.</param>
|
|||
/// <param name="type">The unit of the IterationCount.</param>
|
|||
public IterationCount(ulong value, IterationType type) |
|||
{ |
|||
if (type > IterationType.Infinite) |
|||
{ |
|||
throw new ArgumentException("Invalid value", nameof(type)); |
|||
} |
|||
|
|||
_type = type; |
|||
_value = value; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets an instance of <see cref="IterationCount"/> that indicates that an animation
|
|||
/// should repeat forever.
|
|||
/// </summary>
|
|||
public static IterationCount Infinite => new IterationCount(0, IterationType.Infinite); |
|||
|
|||
/// <summary>
|
|||
/// Gets the unit of the <see cref="IterationCount"/>.
|
|||
/// </summary>
|
|||
public IterationType RepeatType => _type; |
|||
|
|||
/// <summary>
|
|||
/// Gets a value that indicates whether the <see cref="IterationCount"/> is set to loop.
|
|||
/// </summary>
|
|||
public bool IsInfinite => _type == IterationType.Infinite; |
|||
|
|||
/// <summary>
|
|||
/// Gets the number of repeat iterations.
|
|||
/// </summary>
|
|||
public ulong Value => _value; |
|||
|
|||
/// <summary>
|
|||
/// Compares two IterationCount structures for equality.
|
|||
/// </summary>
|
|||
/// <param name="a">The first IterationCount.</param>
|
|||
/// <param name="b">The second IterationCount.</param>
|
|||
/// <returns>True if the structures are equal, otherwise false.</returns>
|
|||
public static bool operator ==(IterationCount a, IterationCount b) |
|||
{ |
|||
return (a.IsInfinite && b.IsInfinite) |
|||
|| (a._value == b._value && a._type == b._type); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Compares two IterationCount structures for inequality.
|
|||
/// </summary>
|
|||
/// <param name="rc1">The first IterationCount.</param>
|
|||
/// <param name="rc2">The first IterationCount.</param>
|
|||
/// <returns>True if the structures are unequal, otherwise false.</returns>
|
|||
public static bool operator !=(IterationCount rc1, IterationCount rc2) |
|||
{ |
|||
return !(rc1 == rc2); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Determines whether the <see cref="IterationCount"/> is equal to the specified object.
|
|||
/// </summary>
|
|||
/// <param name="o">The object with which to test equality.</param>
|
|||
/// <returns>True if the objects are equal, otherwise false.</returns>
|
|||
public override bool Equals(object o) |
|||
{ |
|||
if (o == null) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (!(o is IterationCount)) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
return this == (IterationCount)o; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Compares two IterationCount structures for equality.
|
|||
/// </summary>
|
|||
/// <param name="IterationCount">The structure with which to test equality.</param>
|
|||
/// <returns>True if the structures are equal, otherwise false.</returns>
|
|||
public bool Equals(IterationCount IterationCount) |
|||
{ |
|||
return this == IterationCount; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets a hash code for the IterationCount.
|
|||
/// </summary>
|
|||
/// <returns>The hash code.</returns>
|
|||
public override int GetHashCode() |
|||
{ |
|||
return _value.GetHashCode() ^ _type.GetHashCode(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets a string representation of the <see cref="IterationCount"/>.
|
|||
/// </summary>
|
|||
/// <returns>The string representation.</returns>
|
|||
public override string ToString() |
|||
{ |
|||
if (IsInfinite) |
|||
{ |
|||
return "Infinite"; |
|||
} |
|||
|
|||
string s = _value.ToString(); |
|||
return s; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Parses a string to return a <see cref="IterationCount"/>.
|
|||
/// </summary>
|
|||
/// <param name="s">The string.</param>
|
|||
/// <returns>The <see cref="IterationCount"/>.</returns>
|
|||
public static IterationCount Parse(string s) |
|||
{ |
|||
s = s.ToUpperInvariant().Trim(); |
|||
|
|||
if (s.EndsWith("INFINITE")) |
|||
{ |
|||
return Infinite; |
|||
} |
|||
else |
|||
{ |
|||
if (s.StartsWith("-")) |
|||
throw new InvalidCastException("IterationCount can't be a negative number."); |
|||
|
|||
var value = ulong.Parse(s, CultureInfo.InvariantCulture); |
|||
|
|||
return new IterationCount(value); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,33 +0,0 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
namespace Avalonia.Animation |
|||
{ |
|||
/// <summary>
|
|||
/// Represents a pair of keyframe, usually the
|
|||
/// Start and End keyframes of a <see cref="Animator{T}"/> object.
|
|||
/// </summary>
|
|||
public struct KeyFramePair<T> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes this <see cref="KeyFramePair{T}"/>
|
|||
/// </summary>
|
|||
/// <param name="FirstKeyFrame"></param>
|
|||
/// <param name="LastKeyFrame"></param>
|
|||
public KeyFramePair((T TargetValue, bool isNeutral) FirstKeyFrame, (T TargetValue, bool isNeutral) LastKeyFrame) : this() |
|||
{ |
|||
this.FirstKeyFrame = FirstKeyFrame; |
|||
this.SecondKeyFrame = LastKeyFrame; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// First <see cref="KeyFrame"/> object.
|
|||
/// </summary>
|
|||
public (T TargetValue, bool isNeutral) FirstKeyFrame { get; } |
|||
|
|||
/// <summary>
|
|||
/// Second <see cref="KeyFrame"/> object.
|
|||
/// </summary>
|
|||
public (T TargetValue, bool isNeutral) SecondKeyFrame { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Avalonia.Collections; |
|||
|
|||
namespace Avalonia.Animation |
|||
{ |
|||
/// <summary>
|
|||
/// A collection of <see cref="KeyFrame"/>s.
|
|||
/// </summary>
|
|||
public class KeyFrames : AvaloniaList<KeyFrame> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="KeyFrames"/> class.
|
|||
/// </summary>
|
|||
public KeyFrames() |
|||
{ |
|||
ResetBehavior = ResetBehavior.Remove; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="KeyFrames"/> class.
|
|||
/// </summary>
|
|||
/// <param name="items">The initial items in the collection.</param>
|
|||
public KeyFrames(IEnumerable<KeyFrame> items) |
|||
: base(items) |
|||
{ |
|||
ResetBehavior = ResetBehavior.Remove; |
|||
} |
|||
} |
|||
} |
|||
@ -1,199 +0,0 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.ComponentModel; |
|||
using System.Globalization; |
|||
|
|||
namespace Avalonia.Animation |
|||
{ |
|||
/// <summary>
|
|||
/// Defines the valid modes for a <see cref="RepeatCount"/>.
|
|||
/// </summary>
|
|||
public enum RepeatType |
|||
{ |
|||
None, |
|||
Repeat, |
|||
Loop |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Determines the number of iterations of an animation.
|
|||
/// Also defines its repeat behavior.
|
|||
/// </summary>
|
|||
[TypeConverter(typeof(RepeatCountTypeConverter))] |
|||
public struct RepeatCount : IEquatable<RepeatCount> |
|||
{ |
|||
private readonly RepeatType _type; |
|||
private readonly ulong _value; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="RepeatCount"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="value">The number of iterations of an animation.</param>
|
|||
public RepeatCount(ulong value) |
|||
: this(value, RepeatType.Repeat) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="RepeatCount"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="value">The size of the RepeatCount.</param>
|
|||
/// <param name="type">The unit of the RepeatCount.</param>
|
|||
public RepeatCount(ulong value, RepeatType type) |
|||
{ |
|||
if (type < RepeatType.None || type > RepeatType.Loop) |
|||
{ |
|||
throw new ArgumentException("Invalid value", "type"); |
|||
} |
|||
|
|||
_type = type; |
|||
_value = value; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets an instance of <see cref="RepeatCount"/> that indicates that an animation
|
|||
/// should repeat forever.
|
|||
/// </summary>
|
|||
public static RepeatCount Loop => new RepeatCount(0, RepeatType.Loop); |
|||
|
|||
/// <summary>
|
|||
/// Gets an instance of <see cref="RepeatCount"/> that indicates that an animation
|
|||
/// should not repeat.
|
|||
/// </summary>
|
|||
public static RepeatCount None => new RepeatCount(0, RepeatType.None); |
|||
|
|||
/// <summary>
|
|||
/// Gets the unit of the <see cref="RepeatCount"/>.
|
|||
/// </summary>
|
|||
public RepeatType RepeatType => _type; |
|||
|
|||
/// <summary>
|
|||
/// Gets a value that indicates whether the <see cref="RepeatCount"/> is set to loop.
|
|||
/// </summary>
|
|||
public bool IsLoop => _type == RepeatType.Loop; |
|||
|
|||
/// <summary>
|
|||
/// Gets a value that indicates whether the <see cref="RepeatCount"/> is set to not repeat.
|
|||
/// </summary>
|
|||
public bool IsNone => _type == RepeatType.None; |
|||
|
|||
/// <summary>
|
|||
/// Gets the number of repeat iterations.
|
|||
/// </summary>
|
|||
public ulong Value => _value; |
|||
|
|||
/// <summary>
|
|||
/// Compares two RepeatCount structures for equality.
|
|||
/// </summary>
|
|||
/// <param name="a">The first RepeatCount.</param>
|
|||
/// <param name="b">The second RepeatCount.</param>
|
|||
/// <returns>True if the structures are equal, otherwise false.</returns>
|
|||
public static bool operator ==(RepeatCount a, RepeatCount b) |
|||
{ |
|||
return (a.IsNone && b.IsNone) && (a.IsLoop && b.IsLoop) |
|||
|| (a._value == b._value && a._type == b._type); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Compares two RepeatCount structures for inequality.
|
|||
/// </summary>
|
|||
/// <param name="rc1">The first RepeatCount.</param>
|
|||
/// <param name="rc2">The first RepeatCount.</param>
|
|||
/// <returns>True if the structures are unequal, otherwise false.</returns>
|
|||
public static bool operator !=(RepeatCount rc1, RepeatCount rc2) |
|||
{ |
|||
return !(rc1 == rc2); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Determines whether the <see cref="RepeatCount"/> is equal to the specified object.
|
|||
/// </summary>
|
|||
/// <param name="o">The object with which to test equality.</param>
|
|||
/// <returns>True if the objects are equal, otherwise false.</returns>
|
|||
public override bool Equals(object o) |
|||
{ |
|||
if (o == null) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (!(o is RepeatCount)) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
return this == (RepeatCount)o; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Compares two RepeatCount structures for equality.
|
|||
/// </summary>
|
|||
/// <param name="RepeatCount">The structure with which to test equality.</param>
|
|||
/// <returns>True if the structures are equal, otherwise false.</returns>
|
|||
public bool Equals(RepeatCount RepeatCount) |
|||
{ |
|||
return this == RepeatCount; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets a hash code for the RepeatCount.
|
|||
/// </summary>
|
|||
/// <returns>The hash code.</returns>
|
|||
public override int GetHashCode() |
|||
{ |
|||
return _value.GetHashCode() ^ _type.GetHashCode(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets a string representation of the <see cref="RepeatCount"/>.
|
|||
/// </summary>
|
|||
/// <returns>The string representation.</returns>
|
|||
public override string ToString() |
|||
{ |
|||
if (IsLoop) |
|||
{ |
|||
return "Auto"; |
|||
} |
|||
else if (IsNone) |
|||
{ |
|||
return "None"; |
|||
} |
|||
|
|||
string s = _value.ToString(); |
|||
return s; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Parses a string to return a <see cref="RepeatCount"/>.
|
|||
/// </summary>
|
|||
/// <param name="s">The string.</param>
|
|||
/// <returns>The <see cref="RepeatCount"/>.</returns>
|
|||
public static RepeatCount Parse(string s) |
|||
{ |
|||
s = s.ToUpperInvariant().Trim(); |
|||
|
|||
if (s == "NONE") |
|||
{ |
|||
return None; |
|||
} |
|||
else if (s.EndsWith("LOOP")) |
|||
{ |
|||
return Loop; |
|||
} |
|||
else |
|||
{ |
|||
if(s.StartsWith("-")) |
|||
throw new InvalidCastException("RepeatCount can't be a negative number."); |
|||
|
|||
var value = ulong.Parse(s, CultureInfo.InvariantCulture); |
|||
|
|||
if (value == 1) |
|||
return None; |
|||
|
|||
return new RepeatCount(value); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace Avalonia.Threading |
|||
{ |
|||
public class ThreadSafeObjectPool<T> where T : class, new() |
|||
{ |
|||
private Stack<T> _stack = new Stack<T>(); |
|||
private object _lock = new object(); |
|||
public static ThreadSafeObjectPool<T> Default { get; } = new ThreadSafeObjectPool<T>(); |
|||
|
|||
public T Get() |
|||
{ |
|||
lock (_lock) |
|||
{ |
|||
if(_stack.Count == 0) |
|||
return new T(); |
|||
return _stack.Pop(); |
|||
} |
|||
} |
|||
|
|||
public void Return(T obj) |
|||
{ |
|||
lock (_stack) |
|||
{ |
|||
_stack.Push(obj); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
namespace Avalonia.OpenGL |
|||
{ |
|||
public enum EglErrors |
|||
{ |
|||
EGL_SUCCESS = EglConsts.EGL_SUCCESS, |
|||
EGL_NOT_INITIALIZED = EglConsts.EGL_NOT_INITIALIZED, |
|||
EGL_BAD_ACCESS = EglConsts.EGL_BAD_ACCESS, |
|||
EGL_BAD_ALLOC = EglConsts.EGL_BAD_ALLOC, |
|||
EGL_BAD_ATTRIBUTE = EglConsts.EGL_BAD_ATTRIBUTE, |
|||
EGL_BAD_CONTEXT = EglConsts.EGL_BAD_CONTEXT, |
|||
EGL_BAD_CONFIG = EglConsts.EGL_BAD_CONFIG, |
|||
EGL_BAD_CURRENT_SURFACE = EglConsts.EGL_BAD_CURRENT_SURFACE, |
|||
EGL_BAD_DISPLAY = EglConsts.EGL_BAD_DISPLAY, |
|||
EGL_BAD_SURFACE = EglConsts.EGL_BAD_SURFACE, |
|||
EGL_BAD_MATCH = EglConsts.EGL_BAD_MATCH, |
|||
EGL_BAD_PARAMETER = EglConsts.EGL_BAD_PARAMETER, |
|||
EGL_BAD_NATIVE_PIXMAP = EglConsts.EGL_BAD_NATIVE_PIXMAP, |
|||
EGL_BAD_NATIVE_WINDOW = EglConsts.EGL_BAD_NATIVE_WINDOW, |
|||
EGL_CONTEXT_LOST = EglConsts.EGL_CONTEXT_LOST |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
namespace Avalonia.OpenGL |
|||
{ |
|||
public enum GlErrors |
|||
{ |
|||
GL_NO_ERROR = GlConsts.GL_NO_ERROR, |
|||
GL_INVALID_ENUM = GlConsts.GL_INVALID_ENUM, |
|||
GL_INVALID_VALUE = GlConsts.GL_INVALID_VALUE, |
|||
GL_INVALID_OPERATION = GlConsts.GL_INVALID_OPERATION, |
|||
GL_INVALID_FRAMEBUFFER_OPERATION = GlConsts.GL_INVALID_FRAMEBUFFER_OPERATION, |
|||
GL_STACK_OVERFLOW = GlConsts.GL_STACK_OVERFLOW, |
|||
GL_STACK_UNDERFLOW = GlConsts.GL_STACK_UNDERFLOW, |
|||
GL_OUT_OF_MEMORY = GlConsts.GL_OUT_OF_MEMORY, |
|||
GL_CONTEXT_LOST = GlConsts.GL_CONTEXT_LOST |
|||
} |
|||
} |
|||
@ -0,0 +1,70 @@ |
|||
// Original color interpolation code was written by Romain Guy and Francois Blavoet
|
|||
// and adopted from LottieSharp Project (https://github.com/ascora/LottieSharp).
|
|||
|
|||
using System; |
|||
using System.Reactive.Disposables; |
|||
using Avalonia.Logging; |
|||
using Avalonia.Media; |
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that interpolates <see cref="Color"/> through
|
|||
/// gamma sRGB color space for better visual result.
|
|||
/// </summary>
|
|||
public class ColorAnimator : Animator<Color> |
|||
{ |
|||
// Opto-electronic conversion function for the sRGB color space
|
|||
// Takes a gamma-encoded sRGB value and converts it to a linear sRGB value
|
|||
private static double OECF_sRGB(double linear) |
|||
{ |
|||
// IEC 61966-2-1:1999
|
|||
return linear <= 0.0031308d ? linear * 12.92d : (double)(Math.Pow(linear, 1.0d / 2.4d) * 1.055d - 0.055d); |
|||
} |
|||
|
|||
// Electro-optical conversion function for the sRGB color space
|
|||
// Takes a linear sRGB value and converts it to a gamma-encoded sRGB value
|
|||
private static double EOCF_sRGB(double srgb) |
|||
{ |
|||
// IEC 61966-2-1:1999
|
|||
return srgb <= 0.04045d ? srgb / 12.92d : (double)Math.Pow((srgb + 0.055d) / 1.055d, 2.4d); |
|||
} |
|||
|
|||
public override Color Interpolate(double progress, Color oldValue, Color newValue) |
|||
{ |
|||
// normalize sRGB values.
|
|||
var oldA = oldValue.A / 255d; |
|||
var oldR = oldValue.R / 255d; |
|||
var oldG = oldValue.G / 255d; |
|||
var oldB = oldValue.B / 255d; |
|||
|
|||
var newA = newValue.A / 255d; |
|||
var newR = newValue.R / 255d; |
|||
var newG = newValue.G / 255d; |
|||
var newB = newValue.B / 255d; |
|||
|
|||
// convert from sRGB to linear
|
|||
oldR = EOCF_sRGB(oldR); |
|||
oldG = EOCF_sRGB(oldG); |
|||
oldB = EOCF_sRGB(oldB); |
|||
|
|||
newR = EOCF_sRGB(newR); |
|||
newG = EOCF_sRGB(newG); |
|||
newB = EOCF_sRGB(newB); |
|||
|
|||
// compute the interpolated color in linear space
|
|||
var a = oldA + progress * (newA - oldA); |
|||
var r = oldR + progress * (newR - oldR); |
|||
var g = oldG + progress * (newG - oldG); |
|||
var b = oldB + progress * (newB - oldB); |
|||
|
|||
// convert back to sRGB in the [0..255] range
|
|||
a = a * 255d; |
|||
r = OECF_sRGB(r) * 255d; |
|||
g = OECF_sRGB(g) * 255d; |
|||
b = OECF_sRGB(b) * 255d; |
|||
|
|||
return new Color((byte)Math.Round(a), (byte)Math.Round(r), (byte)Math.Round(g), (byte)Math.Round(b)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
using System; |
|||
using Avalonia.Logging; |
|||
using Avalonia.Media; |
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="CornerRadius"/> properties.
|
|||
/// </summary>
|
|||
public class CornerRadiusAnimator : Animator<CornerRadius> |
|||
{ |
|||
public override CornerRadius Interpolate(double progress, CornerRadius oldValue, CornerRadius newValue) |
|||
{ |
|||
var deltaTL = newValue.TopLeft - oldValue.TopLeft; |
|||
var deltaTR = newValue.TopRight - oldValue.TopRight; |
|||
var deltaBR = newValue.BottomRight - oldValue.BottomRight; |
|||
var deltaBL = newValue.BottomLeft - oldValue.BottomLeft; |
|||
|
|||
var nTL = progress * deltaTL + oldValue.TopLeft; |
|||
var nTR = progress * deltaTR + oldValue.TopRight; |
|||
var nBR = progress * deltaBR + oldValue.BottomRight; |
|||
var nBL = progress * deltaBL + oldValue.BottomLeft; |
|||
|
|||
return new CornerRadius(nTL, nTR, nBR, nBL); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using System; |
|||
using Avalonia.Logging; |
|||
using Avalonia.Media; |
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="Point"/> properties.
|
|||
/// </summary>
|
|||
public class PointAnimator : Animator<Point> |
|||
{ |
|||
public override Point Interpolate(double progress, Point oldValue, Point newValue) |
|||
{ |
|||
return ((newValue - oldValue) * progress) + oldValue; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
using System; |
|||
using Avalonia.Logging; |
|||
using Avalonia.Media; |
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="Rect"/> properties.
|
|||
/// </summary>
|
|||
public class RectAnimator : Animator<Rect> |
|||
{ |
|||
public override Rect Interpolate(double progress, Rect oldValue, Rect newValue) |
|||
{ |
|||
var deltaPos = newValue.Position - oldValue.Position; |
|||
var deltaSize = newValue.Size - oldValue.Size; |
|||
|
|||
var newPos = (deltaPos * progress) + oldValue.Position; |
|||
var newSize = (deltaSize * progress) + oldValue.Size; |
|||
|
|||
return new Rect(newPos, newSize); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using System; |
|||
using Avalonia.Logging; |
|||
using Avalonia.Media; |
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="Size"/> properties.
|
|||
/// </summary>
|
|||
public class SizeAnimator : Animator<Size> |
|||
{ |
|||
public override Size Interpolate(double progress, Size oldValue, Size newValue) |
|||
{ |
|||
return ((newValue - oldValue) * progress) + oldValue; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,74 @@ |
|||
using System; |
|||
using System.Reactive.Disposables; |
|||
using Avalonia.Logging; |
|||
using Avalonia.Media; |
|||
using Avalonia.Media.Immutable; |
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="SolidColorBrush"/>.
|
|||
/// </summary>
|
|||
public class SolidColorBrushAnimator : Animator<SolidColorBrush> |
|||
{ |
|||
ColorAnimator _colorAnimator; |
|||
|
|||
void InitializeColorAnimator() |
|||
{ |
|||
_colorAnimator = new ColorAnimator(); |
|||
|
|||
foreach (AnimatorKeyFrame keyframe in this) |
|||
{ |
|||
_colorAnimator.Add(keyframe); |
|||
} |
|||
|
|||
_colorAnimator.Property = SolidColorBrush.ColorProperty; |
|||
} |
|||
|
|||
public override IDisposable Apply(Animation animation, Animatable control, IClock clock, IObservable<bool> match, Action onComplete) |
|||
{ |
|||
foreach (var keyframe in this) |
|||
{ |
|||
if (keyframe.Value as ISolidColorBrush == null) |
|||
return Disposable.Empty; |
|||
|
|||
// Preprocess keyframe values to Color if the xaml parser converts them to ISCB.
|
|||
if (keyframe.Value.GetType() == typeof(ImmutableSolidColorBrush)) |
|||
{ |
|||
keyframe.Value = ((ImmutableSolidColorBrush)keyframe.Value).Color; |
|||
} |
|||
} |
|||
|
|||
// Add SCB if the target prop is empty.
|
|||
if (control.GetValue(Property) == null) |
|||
control.SetValue(Property, new SolidColorBrush(Colors.Transparent)); |
|||
|
|||
var targetVal = control.GetValue(Property); |
|||
|
|||
// Continue if target prop is not empty & is a SolidColorBrush derivative.
|
|||
if (typeof(ISolidColorBrush).IsAssignableFrom(targetVal.GetType())) |
|||
{ |
|||
if (_colorAnimator == null) |
|||
InitializeColorAnimator(); |
|||
|
|||
SolidColorBrush finalTarget; |
|||
|
|||
// If it's ISCB, change it back to SCB.
|
|||
if (targetVal.GetType() == typeof(ImmutableSolidColorBrush)) |
|||
{ |
|||
var col = (ImmutableSolidColorBrush)targetVal; |
|||
targetVal = new SolidColorBrush(col.Color); |
|||
control.SetValue(Property, targetVal); |
|||
} |
|||
|
|||
finalTarget = targetVal as SolidColorBrush; |
|||
|
|||
return _colorAnimator.Apply(animation, finalTarget, clock ?? control.Clock, match, onComplete); |
|||
} |
|||
|
|||
return Disposable.Empty; |
|||
} |
|||
|
|||
public override SolidColorBrush Interpolate(double p, SolidColorBrush o, SolidColorBrush n) => null; |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using System; |
|||
using Avalonia.Logging; |
|||
using Avalonia.Media; |
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="Thickness"/> properties.
|
|||
/// </summary>
|
|||
public class ThicknessAnimator : Animator<Thickness> |
|||
{ |
|||
public override Thickness Interpolate(double progress, Thickness oldValue, Thickness newValue) |
|||
{ |
|||
return ((newValue - oldValue) * progress) + oldValue; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using System; |
|||
using Avalonia.Logging; |
|||
using Avalonia.Media; |
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="Vector"/> properties.
|
|||
/// </summary>
|
|||
public class VectorAnimator : Animator<Vector> |
|||
{ |
|||
public override Vector Interpolate(double progress, Vector oldValue, Vector newValue) |
|||
{ |
|||
return ((newValue - oldValue) * progress) + oldValue; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Reactive.Linq; |
|||
|
|||
namespace Avalonia.Animation |
|||
{ |
|||
/// <summary>
|
|||
/// Transition class that handles <see cref="AvaloniaProperty"/> with <see cref="CornerRadius"/> type.
|
|||
/// </summary>
|
|||
public class CornerRadiusTransition : Transition<CornerRadius> |
|||
{ |
|||
/// <inheritdocs/>
|
|||
public override IObservable<CornerRadius> DoTransition(IObservable<double> progress, CornerRadius oldValue, CornerRadius newValue) |
|||
{ |
|||
return progress |
|||
.Select(p => |
|||
{ |
|||
var f = Easing.Ease(p); |
|||
|
|||
var deltaTL = newValue.TopLeft - oldValue.TopLeft; |
|||
var deltaTR = newValue.TopRight - oldValue.TopRight; |
|||
var deltaBR = newValue.BottomRight - oldValue.BottomRight; |
|||
var deltaBL = newValue.BottomLeft - oldValue.BottomLeft; |
|||
|
|||
var nTL = f * deltaTL + oldValue.TopLeft; |
|||
var nTR = f * deltaTR + oldValue.TopRight; |
|||
var nBR = f * deltaBR + oldValue.BottomRight; |
|||
var nBL = f * deltaBL + oldValue.BottomLeft; |
|||
|
|||
return new CornerRadius(nTL, nTR, nBR, nBL); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Reactive.Linq; |
|||
|
|||
namespace Avalonia.Animation |
|||
{ |
|||
/// <summary>
|
|||
/// Transition class that handles <see cref="AvaloniaProperty"/> with <see cref="Size"/> type.
|
|||
/// </summary>
|
|||
public class SizeTransition : Transition<Size> |
|||
{ |
|||
/// <inheritdocs/>
|
|||
public override IObservable<Size> DoTransition(IObservable<double> progress, Size oldValue, Size newValue) |
|||
{ |
|||
return progress |
|||
.Select(p => |
|||
{ |
|||
var f = Easing.Ease(p); |
|||
return ((newValue - oldValue) * f) + oldValue; |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue