committed by
GitHub
177 changed files with 3174 additions and 549 deletions
@ -1,6 +1,6 @@ |
|||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<ItemGroup> |
|||
<PackageReference Include="HarfBuzzSharp" Version="2.6.1.7" /> |
|||
<PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="HarfBuzzSharp.NativeAssets.Linux" Version="2.6.1.7" /> |
|||
<PackageReference Include="HarfBuzzSharp" Version="2.8.2-preview.155" /> |
|||
<PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="HarfBuzzSharp.NativeAssets.Linux" Version="2.8.2-preview.155" /> |
|||
</ItemGroup> |
|||
</Project> |
|||
|
|||
@ -1,6 +1,6 @@ |
|||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<ItemGroup> |
|||
<PackageReference Include="SkiaSharp" Version="2.80.2" /> |
|||
<PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="SkiaSharp.NativeAssets.Linux" Version="2.80.2" /> |
|||
<PackageReference Include="SkiaSharp" Version="2.88.0-preview.155" /> |
|||
<PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="SkiaSharp.NativeAssets.Linux" Version="2.88.0-preview.155" /> |
|||
</ItemGroup> |
|||
</Project> |
|||
|
|||
@ -1,6 +1,5 @@ |
|||
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 |
|||
Total Issues: 3 |
|||
|
|||
@ -1,13 +1,9 @@ |
|||
using System.Reflection; |
|||
using System.Runtime.CompilerServices; |
|||
using Avalonia.Metadata; |
|||
#if SIGNED_BUILD
|
|||
|
|||
[assembly: InternalsVisibleTo("Avalonia.Controls.DataGrid.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")] |
|||
[assembly: InternalsVisibleTo("Avalonia.DesignerSupport, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")] |
|||
#else
|
|||
[assembly: InternalsVisibleTo("Avalonia.Controls.DataGrid.UnitTests")] |
|||
[assembly: InternalsVisibleTo("Avalonia.DesignerSupport")] |
|||
#endif
|
|||
|
|||
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Controls")] |
|||
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Controls.Collections")] |
|||
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Controls.Primitives")] |
|||
|
|||
@ -1,9 +1,7 @@ |
|||
using System.Runtime.CompilerServices; |
|||
using Avalonia.Metadata; |
|||
#if SIGNED_BUILD
|
|||
|
|||
[assembly: InternalsVisibleTo("Avalonia.Layout.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")] |
|||
#else
|
|||
[assembly: InternalsVisibleTo("Avalonia.Layout.UnitTests")] |
|||
#endif
|
|||
|
|||
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Layout")] |
|||
|
|||
|
|||
@ -0,0 +1,26 @@ |
|||
#nullable enable |
|||
using System; |
|||
|
|||
namespace Avalonia.LogicalTree |
|||
{ |
|||
/// <summary>
|
|||
/// Event args for <see cref="IChildIndexProvider.ChildIndexChanged"/> event.
|
|||
/// </summary>
|
|||
public class ChildIndexChangedEventArgs : EventArgs |
|||
{ |
|||
public ChildIndexChangedEventArgs() |
|||
{ |
|||
} |
|||
|
|||
public ChildIndexChangedEventArgs(ILogical child) |
|||
{ |
|||
Child = child; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Logical child which index was changed.
|
|||
/// If null, all children should be reset.
|
|||
/// </summary>
|
|||
public ILogical? Child { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
#nullable enable |
|||
using System; |
|||
|
|||
namespace Avalonia.LogicalTree |
|||
{ |
|||
/// <summary>
|
|||
/// Child's index and total count information provider used by list-controls (ListBox, StackPanel, etc.)
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// Used by nth-child and nth-last-child selectors.
|
|||
/// </remarks>
|
|||
public interface IChildIndexProvider |
|||
{ |
|||
/// <summary>
|
|||
/// Gets child's actual index in order of the original source.
|
|||
/// </summary>
|
|||
/// <param name="child">Logical child.</param>
|
|||
/// <returns>Index or -1 if child was not found.</returns>
|
|||
int GetChildIndex(ILogical child); |
|||
|
|||
/// <summary>
|
|||
/// Total children count or null if source is infinite.
|
|||
/// Some Avalonia features might not work if <see cref="TryGetTotalCount"/> returns false, for instance: nth-last-child selector.
|
|||
/// </summary>
|
|||
bool TryGetTotalCount(out int count); |
|||
|
|||
/// <summary>
|
|||
/// Notifies subscriber when child's index or total count was changed.
|
|||
/// </summary>
|
|||
event EventHandler<ChildIndexChangedEventArgs>? ChildIndexChanged; |
|||
} |
|||
} |
|||
@ -1,12 +1,9 @@ |
|||
using System.Reflection; |
|||
using System.Runtime.CompilerServices; |
|||
using Avalonia.Metadata; |
|||
|
|||
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Controls")] |
|||
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.LogicalTree")] |
|||
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Styling")] |
|||
#if SIGNED_BUILD
|
|||
|
|||
[assembly: InternalsVisibleTo("Avalonia.Styling.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")] |
|||
#else
|
|||
[assembly: InternalsVisibleTo("Avalonia.Styling.UnitTests")] |
|||
#endif
|
|||
|
|||
|
|||
@ -0,0 +1,56 @@ |
|||
#nullable enable |
|||
using Avalonia.LogicalTree; |
|||
|
|||
namespace Avalonia.Styling.Activators |
|||
{ |
|||
/// <summary>
|
|||
/// An <see cref="IStyleActivator"/> which is active when control's index was changed.
|
|||
/// </summary>
|
|||
internal sealed class NthChildActivator : StyleActivatorBase |
|||
{ |
|||
private readonly ILogical _control; |
|||
private readonly IChildIndexProvider _provider; |
|||
private readonly int _step; |
|||
private readonly int _offset; |
|||
private readonly bool _reversed; |
|||
|
|||
public NthChildActivator( |
|||
ILogical control, |
|||
IChildIndexProvider provider, |
|||
int step, int offset, bool reversed) |
|||
{ |
|||
_control = control; |
|||
_provider = provider; |
|||
_step = step; |
|||
_offset = offset; |
|||
_reversed = reversed; |
|||
} |
|||
|
|||
protected override void Initialize() |
|||
{ |
|||
PublishNext(IsMatching()); |
|||
_provider.ChildIndexChanged += ChildIndexChanged; |
|||
} |
|||
|
|||
protected override void Deinitialize() |
|||
{ |
|||
_provider.ChildIndexChanged -= ChildIndexChanged; |
|||
} |
|||
|
|||
private void ChildIndexChanged(object sender, ChildIndexChangedEventArgs e) |
|||
{ |
|||
// Run matching again if:
|
|||
// 1. Selector is reversed, so other item insertion/deletion might affect total count without changing subscribed item index.
|
|||
// 2. e.Child is null, when all children indeces were changed.
|
|||
// 3. Subscribed child index was changed.
|
|||
if (_reversed |
|||
|| e.Child is null |
|||
|| e.Child == _control) |
|||
{ |
|||
PublishNext(IsMatching()); |
|||
} |
|||
} |
|||
|
|||
private bool IsMatching() => NthChildSelector.Evaluate(_control, _provider, _step, _offset, _reversed).IsMatch; |
|||
} |
|||
} |
|||
@ -0,0 +1,145 @@ |
|||
#nullable enable |
|||
using System; |
|||
using System.Text; |
|||
using Avalonia.LogicalTree; |
|||
using Avalonia.Styling.Activators; |
|||
|
|||
namespace Avalonia.Styling |
|||
{ |
|||
/// <summary>
|
|||
/// The :nth-child() pseudo-class matches elements based on their position in a group of siblings.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// Element indices are 1-based.
|
|||
/// </remarks>
|
|||
public class NthChildSelector : Selector |
|||
{ |
|||
private const string NthChildSelectorName = "nth-child"; |
|||
private const string NthLastChildSelectorName = "nth-last-child"; |
|||
private readonly Selector? _previous; |
|||
private readonly bool _reversed; |
|||
|
|||
internal protected NthChildSelector(Selector? previous, int step, int offset, bool reversed) |
|||
{ |
|||
_previous = previous; |
|||
Step = step; |
|||
Offset = offset; |
|||
_reversed = reversed; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Creates an instance of <see cref="NthChildSelector"/>
|
|||
/// </summary>
|
|||
/// <param name="previous">Previous selector.</param>
|
|||
/// <param name="step">Position step.</param>
|
|||
/// <param name="offset">Initial index offset.</param>
|
|||
public NthChildSelector(Selector? previous, int step, int offset) |
|||
: this(previous, step, offset, false) |
|||
{ |
|||
|
|||
} |
|||
|
|||
public override bool InTemplate => _previous?.InTemplate ?? false; |
|||
|
|||
public override bool IsCombinator => false; |
|||
|
|||
public override Type? TargetType => _previous?.TargetType; |
|||
|
|||
public int Step { get; } |
|||
public int Offset { get; } |
|||
|
|||
protected override SelectorMatch Evaluate(IStyleable control, bool subscribe) |
|||
{ |
|||
if (!(control is ILogical logical)) |
|||
{ |
|||
return SelectorMatch.NeverThisType; |
|||
} |
|||
|
|||
var controlParent = logical.LogicalParent; |
|||
|
|||
if (controlParent is IChildIndexProvider childIndexProvider) |
|||
{ |
|||
return subscribe |
|||
? new SelectorMatch(new NthChildActivator(logical, childIndexProvider, Step, Offset, _reversed)) |
|||
: Evaluate(logical, childIndexProvider, Step, Offset, _reversed); |
|||
} |
|||
else |
|||
{ |
|||
return SelectorMatch.NeverThisInstance; |
|||
} |
|||
} |
|||
|
|||
internal static SelectorMatch Evaluate( |
|||
ILogical logical, IChildIndexProvider childIndexProvider, |
|||
int step, int offset, bool reversed) |
|||
{ |
|||
var index = childIndexProvider.GetChildIndex(logical); |
|||
if (index < 0) |
|||
{ |
|||
return SelectorMatch.NeverThisInstance; |
|||
} |
|||
|
|||
if (reversed) |
|||
{ |
|||
if (childIndexProvider.TryGetTotalCount(out var totalCountValue)) |
|||
{ |
|||
index = totalCountValue - index; |
|||
} |
|||
else |
|||
{ |
|||
return SelectorMatch.NeverThisInstance; |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
// nth child index is 1-based
|
|||
index += 1; |
|||
} |
|||
|
|||
var n = Math.Sign(step); |
|||
|
|||
var diff = index - offset; |
|||
var match = diff == 0 || (Math.Sign(diff) == n && diff % step == 0); |
|||
|
|||
return match ? SelectorMatch.AlwaysThisInstance : SelectorMatch.NeverThisInstance; |
|||
} |
|||
|
|||
protected override Selector? MovePrevious() => _previous; |
|||
|
|||
public override string ToString() |
|||
{ |
|||
var expectedCapacity = NthLastChildSelectorName.Length + 8; |
|||
var stringBuilder = new StringBuilder(_previous?.ToString(), expectedCapacity); |
|||
|
|||
stringBuilder.Append(':'); |
|||
stringBuilder.Append(_reversed ? NthLastChildSelectorName : NthChildSelectorName); |
|||
stringBuilder.Append('('); |
|||
|
|||
var hasStep = false; |
|||
if (Step != 0) |
|||
{ |
|||
hasStep = true; |
|||
stringBuilder.Append(Step); |
|||
stringBuilder.Append('n'); |
|||
} |
|||
|
|||
if (Offset > 0) |
|||
{ |
|||
if (hasStep) |
|||
{ |
|||
stringBuilder.Append('+'); |
|||
} |
|||
stringBuilder.Append(Offset); |
|||
} |
|||
else if (Offset < 0) |
|||
{ |
|||
stringBuilder.Append('-'); |
|||
stringBuilder.Append(-Offset); |
|||
} |
|||
|
|||
stringBuilder.Append(')'); |
|||
|
|||
return stringBuilder.ToString(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
#nullable enable |
|||
|
|||
namespace Avalonia.Styling |
|||
{ |
|||
/// <summary>
|
|||
/// The :nth-child() pseudo-class matches elements based on their position among a group of siblings, counting from the end.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// Element indices are 1-based.
|
|||
/// </remarks>
|
|||
public class NthLastChildSelector : NthChildSelector |
|||
{ |
|||
/// <summary>
|
|||
/// Creates an instance of <see cref="NthLastChildSelector"/>
|
|||
/// </summary>
|
|||
/// <param name="previous">Previous selector.</param>
|
|||
/// <param name="step">Position step.</param>
|
|||
/// <param name="offset">Initial index offset, counting from the end.</param>
|
|||
public NthLastChildSelector(Selector? previous, int step, int offset) : base(previous, step, offset, true) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue