diff --git a/samples/ControlCatalog/ViewModels/TransitioningContentControlPageViewModel.cs b/samples/ControlCatalog/ViewModels/TransitioningContentControlPageViewModel.cs index 83892247e61..93857fd8993 100644 --- a/samples/ControlCatalog/ViewModels/TransitioningContentControlPageViewModel.cs +++ b/samples/ControlCatalog/ViewModels/TransitioningContentControlPageViewModel.cs @@ -293,10 +293,10 @@ public async Task Start(Visual? from, Visual? to, bool forward, CancellationToke /// /// Any one of the parameters may be null, but not both. /// - private static IVisual GetVisualParent(IVisual? from, IVisual? to) + private static Visual GetVisualParent(Visual? from, Visual? to) { - var p1 = (from ?? to)!.VisualParent; - var p2 = (to ?? from)!.VisualParent; + var p1 = (from ?? to)!.GetVisualParent(); + var p2 = (to ?? from)!.GetVisualParent(); if (p1 != null && p2 != null && p1 != p2) { diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs index 3b29dbc726e..4150b529469 100644 --- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs +++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs @@ -109,7 +109,7 @@ public IRenderer CreateRenderer(IRenderRoot root) => ? new CompositingRenderer(root, AndroidPlatform.Compositor) : AndroidPlatform.Options.UseDeferredRendering ? new DeferredRenderer(root, AvaloniaLocator.Current.GetRequiredService()) { RenderOnlyOnRenderThread = true } - : new ImmediateRenderer(root); + : new ImmediateRenderer((Visual)root); public virtual void Hide() { diff --git a/src/Avalonia.Base/Animation/PageSlide.cs b/src/Avalonia.Base/Animation/PageSlide.cs index b22bc8b2435..609441ae8cf 100644 --- a/src/Avalonia.Base/Animation/PageSlide.cs +++ b/src/Avalonia.Base/Animation/PageSlide.cs @@ -157,7 +157,7 @@ public virtual async Task Start(Visual? from, Visual? to, bool forward, Cancella /// /// Any one of the parameters may be null, but not both. /// - protected static IVisual GetVisualParent(IVisual? from, IVisual? to) + protected static Visual GetVisualParent(Visual? from, Visual? to) { var p1 = (from ?? to)!.VisualParent; var p2 = (to ?? from)!.VisualParent; diff --git a/src/Avalonia.Base/AttachedProperty.cs b/src/Avalonia.Base/AttachedProperty.cs index 12c569c452f..a43194153ca 100644 --- a/src/Avalonia.Base/AttachedProperty.cs +++ b/src/Avalonia.Base/AttachedProperty.cs @@ -34,7 +34,7 @@ public AttachedProperty( /// /// The owner type. /// The property. - public new AttachedProperty AddOwner() where TOwner : IAvaloniaObject + public new AttachedProperty AddOwner() where TOwner : AvaloniaObject { AvaloniaPropertyRegistry.Instance.Register(typeof(TOwner), this); return this; diff --git a/src/Avalonia.Base/AvaloniaObject.cs b/src/Avalonia.Base/AvaloniaObject.cs index 68c8f19f190..a3a732428ea 100644 --- a/src/Avalonia.Base/AvaloniaObject.cs +++ b/src/Avalonia.Base/AvaloniaObject.cs @@ -16,7 +16,7 @@ namespace Avalonia /// /// This class is analogous to DependencyObject in WPF. /// - public class AvaloniaObject : IAvaloniaObject, IAvaloniaObjectDebug, INotifyPropertyChanged + public class AvaloniaObject : IAvaloniaObjectDebug, INotifyPropertyChanged { private readonly ValueStore _values; private AvaloniaObject? _inheritanceParent; diff --git a/src/Avalonia.Base/AvaloniaObjectExtensions.cs b/src/Avalonia.Base/AvaloniaObjectExtensions.cs index 9644063da78..867d6215a58 100644 --- a/src/Avalonia.Base/AvaloniaObjectExtensions.cs +++ b/src/Avalonia.Base/AvaloniaObjectExtensions.cs @@ -36,7 +36,7 @@ public static IBinding ToBinding(this IObservable source) /// /// The subscription to is created using a weak reference. /// - public static IObservable GetObservable(this IAvaloniaObject o, AvaloniaProperty property) + public static IObservable GetObservable(this AvaloniaObject o, AvaloniaProperty property) { return new AvaloniaPropertyObservable( o ?? throw new ArgumentNullException(nameof(o)), @@ -56,7 +56,7 @@ public static IBinding ToBinding(this IObservable source) /// /// The subscription to is created using a weak reference. /// - public static IObservable GetObservable(this IAvaloniaObject o, AvaloniaProperty property) + public static IObservable GetObservable(this AvaloniaObject o, AvaloniaProperty property) { return new AvaloniaPropertyObservable( o ?? throw new ArgumentNullException(nameof(o)), @@ -76,7 +76,7 @@ public static IObservable GetObservable(this IAvaloniaObject o, AvaloniaPr /// The subscription to is created using a weak reference. /// public static IObservable> GetBindingObservable( - this IAvaloniaObject o, + this AvaloniaObject o, AvaloniaProperty property) { return new AvaloniaPropertyBindingObservable( @@ -98,7 +98,7 @@ public static IObservable GetObservable(this IAvaloniaObject o, AvaloniaPr /// The subscription to is created using a weak reference. /// public static IObservable> GetBindingObservable( - this IAvaloniaObject o, + this AvaloniaObject o, AvaloniaProperty property) { return new AvaloniaPropertyBindingObservable( @@ -115,11 +115,11 @@ public static IObservable> GetBindingObservable( /// The property. /// /// An observable which when subscribed pushes the property changed event args - /// each time a event is raised + /// each time a event is raised /// for the specified property. /// public static IObservable GetPropertyChangedObservable( - this IAvaloniaObject o, + this AvaloniaObject o, AvaloniaProperty property) { return new AvaloniaPropertyChangedObservable( @@ -140,7 +140,7 @@ public static IObservable GetPropertyChangedOb /// property. /// public static ISubject GetSubject( - this IAvaloniaObject o, + this AvaloniaObject o, AvaloniaProperty property, BindingPriority priority = BindingPriority.LocalValue) { @@ -163,7 +163,7 @@ public static IObservable GetPropertyChangedOb /// property. /// public static ISubject GetSubject( - this IAvaloniaObject o, + this AvaloniaObject o, AvaloniaProperty property, BindingPriority priority = BindingPriority.LocalValue) { @@ -185,7 +185,7 @@ public static ISubject GetSubject( /// property. /// public static ISubject> GetBindingSubject( - this IAvaloniaObject o, + this AvaloniaObject o, AvaloniaProperty property, BindingPriority priority = BindingPriority.LocalValue) { @@ -214,7 +214,7 @@ public static ISubject GetSubject( /// property. /// public static ISubject> GetBindingSubject( - this IAvaloniaObject o, + this AvaloniaObject o, AvaloniaProperty property, BindingPriority priority = BindingPriority.LocalValue) { @@ -241,7 +241,7 @@ public static ISubject> GetBindingSubject( /// A disposable which can be used to terminate the binding. /// public static IDisposable Bind( - this IAvaloniaObject target, + this AvaloniaObject target, AvaloniaProperty property, IObservable> source, BindingPriority priority = BindingPriority.LocalValue) @@ -250,17 +250,12 @@ public static IDisposable Bind( property = property ?? throw new ArgumentNullException(nameof(property)); source = source ?? throw new ArgumentNullException(nameof(source)); - if (target is AvaloniaObject ao) + return property switch { - return property switch - { - StyledPropertyBase styled => ao.Bind(styled, source, priority), - DirectPropertyBase direct => ao.Bind(direct, source), - _ => throw new NotSupportedException("Unsupported AvaloniaProperty type."), - }; - } - - throw new NotSupportedException("Custom implementations of IAvaloniaObject not supported."); + StyledPropertyBase styled => target.Bind(styled, source, priority), + DirectPropertyBase direct => target.Bind(direct, source), + _ => throw new NotSupportedException("Unsupported AvaloniaProperty type."), + }; } /// @@ -274,22 +269,17 @@ public static IDisposable Bind( /// A disposable which can be used to terminate the binding. /// public static IDisposable Bind( - this IAvaloniaObject target, + this AvaloniaObject target, AvaloniaProperty property, IObservable source, BindingPriority priority = BindingPriority.LocalValue) { - if (target is AvaloniaObject ao) + return property switch { - return property switch - { - StyledPropertyBase styled => ao.Bind(styled, source, priority), - DirectPropertyBase direct => ao.Bind(direct, source), - _ => throw new NotSupportedException("Unsupported AvaloniaProperty type."), - }; - } - - throw new NotSupportedException("Custom implementations of IAvaloniaObject not supported."); + StyledPropertyBase styled => target.Bind(styled, source, priority), + DirectPropertyBase direct => target.Bind(direct, source), + _ => throw new NotSupportedException("Unsupported AvaloniaProperty type."), + }; } /// @@ -306,7 +296,7 @@ public static IDisposable Bind( /// /// An which can be used to cancel the binding. public static IDisposable Bind( - this IAvaloniaObject target, + this AvaloniaObject target, AvaloniaProperty property, IBinding binding, object? anchor = null) @@ -340,23 +330,17 @@ public static IDisposable Bind( /// The object. /// The property. /// The value. - public static T GetValue(this IAvaloniaObject target, AvaloniaProperty property) + public static T GetValue(this AvaloniaObject target, AvaloniaProperty property) { target = target ?? throw new ArgumentNullException(nameof(target)); property = property ?? throw new ArgumentNullException(nameof(property)); - if (target is AvaloniaObject ao) + return property switch { - return property switch - { - StyledPropertyBase styled => ao.GetValue(styled), - DirectPropertyBase direct => ao.GetValue(direct), - _ => throw new NotSupportedException("Unsupported AvaloniaProperty type.") - }; - - } - - throw new NotSupportedException("Custom implementations of IAvaloniaObject not supported."); + StyledPropertyBase styled => target.GetValue(styled), + DirectPropertyBase direct => target.GetValue(direct), + _ => throw new NotSupportedException("Unsupported AvaloniaProperty type.") + }; } /// @@ -372,15 +356,13 @@ public static T GetValue(this IAvaloniaObject target, AvaloniaProperty pro /// For direct properties returns the current value of the property. /// public static object? GetBaseValue( - this IAvaloniaObject target, + this AvaloniaObject target, AvaloniaProperty property) { target = target ?? throw new ArgumentNullException(nameof(target)); property = property ?? throw new ArgumentNullException(nameof(property)); - if (target is AvaloniaObject ao) - return property.RouteGetBaseValue(ao); - throw new NotSupportedException("Custom implementations of IAvaloniaObject not supported."); + return property.RouteGetBaseValue(target); } /// @@ -396,24 +378,18 @@ public static T GetValue(this IAvaloniaObject target, AvaloniaProperty pro /// For direct properties returns the current value of the property. /// public static Optional GetBaseValue( - this IAvaloniaObject target, + this AvaloniaObject target, AvaloniaProperty property) { target = target ?? throw new ArgumentNullException(nameof(target)); property = property ?? throw new ArgumentNullException(nameof(property)); - if (target is AvaloniaObject ao) + return property switch { - return property switch - { - StyledPropertyBase styled => ao.GetBaseValue(styled), - DirectPropertyBase direct => ao.GetValue(direct), - _ => throw new NotSupportedException("Unsupported AvaloniaProperty type.") - }; - - } - - throw new NotSupportedException("Custom implementations of IAvaloniaObject not supported."); + StyledPropertyBase styled => target.GetBaseValue(styled), + DirectPropertyBase direct => target.GetValue(direct), + _ => throw new NotSupportedException("Unsupported AvaloniaProperty type.") + }; } /// @@ -474,7 +450,7 @@ public BindingAdaptor(IObservable source) } public InstancedBinding? Initiate( - IAvaloniaObject target, + AvaloniaObject target, AvaloniaProperty? targetProperty, object? anchor = null, bool enableDataValidation = false) diff --git a/src/Avalonia.Base/AvaloniaProperty.cs b/src/Avalonia.Base/AvaloniaProperty.cs index f2e90bb6d78..2c89062e51a 100644 --- a/src/Avalonia.Base/AvaloniaProperty.cs +++ b/src/Avalonia.Base/AvaloniaProperty.cs @@ -38,7 +38,7 @@ protected AvaloniaProperty( Type valueType, Type ownerType, AvaloniaPropertyMetadata metadata, - Action? notifying = null) + Action? notifying = null) { _ = name ?? throw new ArgumentNullException(nameof(name)); @@ -145,7 +145,7 @@ protected AvaloniaProperty( /// will be true before the property change notifications are sent and false afterwards. This /// callback is intended to support Control.IsDataContextChanging. /// - public Action? Notifying { get; } + public Action? Notifying { get; } /// /// Gets the integer ID that represents this property. @@ -238,9 +238,9 @@ public static StyledProperty Register( bool inherits = false, BindingMode defaultBindingMode = BindingMode.OneWay, Func? validate = null, - Func? coerce = null, - Action? notifying = null) - where TOwner : IAvaloniaObject + Func? coerce = null, + Action? notifying = null) + where TOwner : AvaloniaObject { _ = name ?? throw new ArgumentNullException(nameof(name)); @@ -279,8 +279,8 @@ public static AttachedProperty RegisterAttached( bool inherits = false, BindingMode defaultBindingMode = BindingMode.OneWay, Func? validate = null, - Func? coerce = null) - where THost : IAvaloniaObject + Func? coerce = null) + where THost : AvaloniaObject { _ = name ?? throw new ArgumentNullException(nameof(name)); @@ -316,8 +316,8 @@ public static AttachedProperty RegisterAttached( bool inherits = false, BindingMode defaultBindingMode = BindingMode.OneWay, Func? validate = null, - Func? coerce = null) - where THost : IAvaloniaObject + Func? coerce = null) + where THost : AvaloniaObject { _ = name ?? throw new ArgumentNullException(nameof(name)); @@ -354,7 +354,7 @@ public static DirectProperty RegisterDirect( TValue unsetValue = default!, BindingMode defaultBindingMode = BindingMode.OneWay, bool enableDataValidation = false) - where TOwner : IAvaloniaObject + where TOwner : AvaloniaObject { _ = name ?? throw new ArgumentNullException(nameof(name)); _ = getter ?? throw new ArgumentNullException(nameof(getter)); @@ -415,7 +415,7 @@ public override int GetHashCode() /// /// The property metadata. /// - public AvaloniaPropertyMetadata GetMetadata() where T : IAvaloniaObject + public AvaloniaPropertyMetadata GetMetadata() where T : AvaloniaObject { return GetMetadata(typeof(T)); } diff --git a/src/Avalonia.Base/AvaloniaPropertyChangedEventArgs.cs b/src/Avalonia.Base/AvaloniaPropertyChangedEventArgs.cs index a3ca25bc45f..997a363c266 100644 --- a/src/Avalonia.Base/AvaloniaPropertyChangedEventArgs.cs +++ b/src/Avalonia.Base/AvaloniaPropertyChangedEventArgs.cs @@ -9,7 +9,7 @@ namespace Avalonia public abstract class AvaloniaPropertyChangedEventArgs : EventArgs { public AvaloniaPropertyChangedEventArgs( - IAvaloniaObject sender, + AvaloniaObject sender, BindingPriority priority) { Sender = sender; @@ -18,7 +18,7 @@ public AvaloniaPropertyChangedEventArgs( } internal AvaloniaPropertyChangedEventArgs( - IAvaloniaObject sender, + AvaloniaObject sender, BindingPriority priority, bool isEffectiveValueChange) { @@ -31,7 +31,7 @@ internal AvaloniaPropertyChangedEventArgs( /// Gets the that the property changed on. /// /// The sender object. - public IAvaloniaObject Sender { get; } + public AvaloniaObject Sender { get; } /// /// Gets the property that changed. diff --git a/src/Avalonia.Base/AvaloniaPropertyChangedEventArgs`1.cs b/src/Avalonia.Base/AvaloniaPropertyChangedEventArgs`1.cs index 2c7a597537b..70c75d24e71 100644 --- a/src/Avalonia.Base/AvaloniaPropertyChangedEventArgs`1.cs +++ b/src/Avalonia.Base/AvaloniaPropertyChangedEventArgs`1.cs @@ -16,7 +16,7 @@ public class AvaloniaPropertyChangedEventArgs : AvaloniaPropertyChangedEventA /// The new value of the property. /// The priority of the binding that produced the value. public AvaloniaPropertyChangedEventArgs( - IAvaloniaObject sender, + AvaloniaObject sender, AvaloniaProperty property, Optional oldValue, BindingValue newValue, @@ -26,7 +26,7 @@ public AvaloniaPropertyChangedEventArgs( } internal AvaloniaPropertyChangedEventArgs( - IAvaloniaObject sender, + AvaloniaObject sender, AvaloniaProperty property, Optional oldValue, BindingValue newValue, diff --git a/src/Avalonia.Base/AvaloniaPropertyRegistry.cs b/src/Avalonia.Base/AvaloniaPropertyRegistry.cs index 62265d3c591..6106c588804 100644 --- a/src/Avalonia.Base/AvaloniaPropertyRegistry.cs +++ b/src/Avalonia.Base/AvaloniaPropertyRegistry.cs @@ -189,7 +189,7 @@ public IReadOnlyList GetRegisteredInherited(Type type) /// /// The object. /// A collection of definitions. - public IReadOnlyList GetRegistered(IAvaloniaObject o) + public IReadOnlyList GetRegistered(AvaloniaObject o) { _ = o ?? throw new ArgumentNullException(nameof(o)); @@ -205,7 +205,7 @@ public IReadOnlyList GetRegistered(IAvaloniaObject o) /// The registered. /// public DirectPropertyBase GetRegisteredDirect( - IAvaloniaObject o, + AvaloniaObject o, DirectPropertyBase property) { return FindRegisteredDirect(o, property) ?? @@ -260,7 +260,7 @@ public DirectPropertyBase GetRegisteredDirect( /// /// The property name contains a '.'. /// - public AvaloniaProperty? FindRegistered(IAvaloniaObject o, string name) + public AvaloniaProperty? FindRegistered(AvaloniaObject o, string name) { _ = o ?? throw new ArgumentNullException(nameof(o)); _ = name ?? throw new ArgumentNullException(nameof(name)); @@ -277,7 +277,7 @@ public DirectPropertyBase GetRegisteredDirect( /// The registered property or null if no matching property found. /// public DirectPropertyBase? FindRegisteredDirect( - IAvaloniaObject o, + AvaloniaObject o, DirectPropertyBase property) { if (property.Owner == o.GetType()) @@ -362,7 +362,7 @@ public bool IsRegistered(object o, AvaloniaProperty property) /// The property. /// /// You won't usually want to call this method directly, instead use the - /// + /// /// method. /// public void Register(Type type, AvaloniaProperty property) @@ -413,7 +413,7 @@ public void Register(Type type, AvaloniaProperty property) /// The property. /// /// You won't usually want to call this method directly, instead use the - /// + /// /// method. /// public void RegisterAttached(Type type, AvaloniaProperty property) diff --git a/src/Avalonia.Base/AvaloniaProperty`1.cs b/src/Avalonia.Base/AvaloniaProperty`1.cs index 14acc2c47f0..5a0d69f3bf0 100644 --- a/src/Avalonia.Base/AvaloniaProperty`1.cs +++ b/src/Avalonia.Base/AvaloniaProperty`1.cs @@ -24,7 +24,7 @@ protected AvaloniaProperty( string name, Type ownerType, AvaloniaPropertyMetadata metadata, - Action? notifying = null) + Action? notifying = null) : base(name, typeof(TValue), ownerType, metadata, notifying) { _changed = new Subject>(); diff --git a/src/Avalonia.Base/ClassBindingManager.cs b/src/Avalonia.Base/ClassBindingManager.cs index e8b1cc301dd..589b9b2d01c 100644 --- a/src/Avalonia.Base/ClassBindingManager.cs +++ b/src/Avalonia.Base/ClassBindingManager.cs @@ -9,7 +9,7 @@ internal static class ClassBindingManager private static readonly Dictionary s_RegisteredProperties = new Dictionary(); - public static IDisposable Bind(IStyledElement target, string className, IBinding source, object anchor) + public static IDisposable Bind(StyledElement target, string className, IBinding source, object anchor) { if (!s_RegisteredProperties.TryGetValue(className, out var prop)) s_RegisteredProperties[className] = prop = RegisterClassProxyProperty(className); @@ -21,7 +21,7 @@ private static AvaloniaProperty RegisterClassProxyProperty(string className) var prop = AvaloniaProperty.Register("__AvaloniaReserved::Classes::" + className); prop.Changed.Subscribe(args => { - var classes = ((IStyledElement)args.Sender).Classes; + var classes = ((StyledElement)args.Sender).Classes; classes.Set(className, args.NewValue.GetValueOrDefault()); }); diff --git a/src/Avalonia.Base/Controls/Classes.cs b/src/Avalonia.Base/Controls/Classes.cs index c3d3fbca465..30c6fdefa3b 100644 --- a/src/Avalonia.Base/Controls/Classes.cs +++ b/src/Avalonia.Base/Controls/Classes.cs @@ -6,7 +6,7 @@ namespace Avalonia.Controls { /// - /// Holds a collection of style classes for an . + /// Holds a collection of style classes for an . /// /// /// Similar to CSS, each control may have any number of styling classes applied. diff --git a/src/Avalonia.Base/Controls/ISetInheritanceParent.cs b/src/Avalonia.Base/Controls/ISetInheritanceParent.cs index e85e0250053..9c83c96e3fa 100644 --- a/src/Avalonia.Base/Controls/ISetInheritanceParent.cs +++ b/src/Avalonia.Base/Controls/ISetInheritanceParent.cs @@ -17,6 +17,6 @@ public interface ISetInheritanceParent /// Sets the control's inheritance parent. /// /// The parent. - void SetParent(IAvaloniaObject? parent); + void SetParent(AvaloniaObject? parent); } } diff --git a/src/Avalonia.Base/Controls/ResourceNodeExtensions.cs b/src/Avalonia.Base/Controls/ResourceNodeExtensions.cs index 61216461077..0bf1073098d 100644 --- a/src/Avalonia.Base/Controls/ResourceNodeExtensions.cs +++ b/src/Avalonia.Base/Controls/ResourceNodeExtensions.cs @@ -2,6 +2,7 @@ using Avalonia.Data.Converters; using Avalonia.LogicalTree; using Avalonia.Reactive; +using Avalonia.Styling; #nullable enable @@ -49,7 +50,7 @@ public static bool TryFindResource(this IResourceHost control, object key, out o return true; } - current = (current as IStyledElement)?.StylingParent as IResourceNode; + current = (current as IStyleHost)?.StylingParent as IResourceNode; } value = null; diff --git a/src/Avalonia.Base/Data/BindingOperations.cs b/src/Avalonia.Base/Data/BindingOperations.cs index 4e47a720f0f..ceb3f71285b 100644 --- a/src/Avalonia.Base/Data/BindingOperations.cs +++ b/src/Avalonia.Base/Data/BindingOperations.cs @@ -9,7 +9,7 @@ public static class BindingOperations public static readonly object DoNothing = new DoNothingType(); /// - /// Applies an a property on an . + /// Applies an a property on an . /// /// The target object. /// The property to bind. @@ -22,7 +22,7 @@ public static class BindingOperations /// /// An which can be used to cancel the binding. public static IDisposable Apply( - IAvaloniaObject target, + AvaloniaObject target, AvaloniaProperty property, InstancedBinding binding, object? anchor) diff --git a/src/Avalonia.Base/Data/Core/AvaloniaPropertyAccessorNode.cs b/src/Avalonia.Base/Data/Core/AvaloniaPropertyAccessorNode.cs index 92ecdafa0c1..e340966983d 100644 --- a/src/Avalonia.Base/Data/Core/AvaloniaPropertyAccessorNode.cs +++ b/src/Avalonia.Base/Data/Core/AvaloniaPropertyAccessorNode.cs @@ -24,7 +24,7 @@ protected override bool SetTargetValueCore(object? value, BindingPriority priori { try { - if (Target.TryGetTarget(out var target) && target is IAvaloniaObject obj) + if (Target.TryGetTarget(out var target) && target is AvaloniaObject obj) { obj.SetValue(_property, value, priority); return true; @@ -39,7 +39,7 @@ protected override bool SetTargetValueCore(object? value, BindingPriority priori protected override void StartListeningCore(WeakReference reference) { - if (reference.TryGetTarget(out var target) && target is IAvaloniaObject obj) + if (reference.TryGetTarget(out var target) && target is AvaloniaObject obj) { _subscription = new AvaloniaPropertyObservable(obj, _property).Subscribe(ValueChanged); } diff --git a/src/Avalonia.Base/Data/IBinding.cs b/src/Avalonia.Base/Data/IBinding.cs index 7d44bf09b5a..01204c39c11 100644 --- a/src/Avalonia.Base/Data/IBinding.cs +++ b/src/Avalonia.Base/Data/IBinding.cs @@ -24,7 +24,7 @@ public interface IBinding /// A or null if the binding could not be resolved. /// InstancedBinding? Initiate( - IAvaloniaObject target, + AvaloniaObject target, AvaloniaProperty? targetProperty, object? anchor = null, bool enableDataValidation = false); diff --git a/src/Avalonia.Base/Data/IndexerBinding.cs b/src/Avalonia.Base/Data/IndexerBinding.cs index 6a33d0c4fc8..fcd179b9b21 100644 --- a/src/Avalonia.Base/Data/IndexerBinding.cs +++ b/src/Avalonia.Base/Data/IndexerBinding.cs @@ -3,7 +3,7 @@ public class IndexerBinding : IBinding { public IndexerBinding( - IAvaloniaObject source, + AvaloniaObject source, AvaloniaProperty property, BindingMode mode) { @@ -12,12 +12,12 @@ public IndexerBinding( Mode = mode; } - private IAvaloniaObject Source { get; } + private AvaloniaObject Source { get; } public AvaloniaProperty Property { get; } private BindingMode Mode { get; } public InstancedBinding? Initiate( - IAvaloniaObject target, + AvaloniaObject target, AvaloniaProperty? targetProperty, object? anchor = null, bool enableDataValidation = false) diff --git a/src/Avalonia.Base/Data/InstancedBinding.cs b/src/Avalonia.Base/Data/InstancedBinding.cs index 9ff319eddb6..a349486bf82 100644 --- a/src/Avalonia.Base/Data/InstancedBinding.cs +++ b/src/Avalonia.Base/Data/InstancedBinding.cs @@ -9,7 +9,7 @@ namespace Avalonia.Data /// /// Whereas an holds a description of a binding such as "Bind to the X /// property on a control's DataContext"; this class represents a binding that has been - /// *instanced* by calling + /// *instanced* by calling /// on a target object. /// public class InstancedBinding diff --git a/src/Avalonia.Base/Diagnostics/IAvaloniaObjectDebug.cs b/src/Avalonia.Base/Diagnostics/IAvaloniaObjectDebug.cs index 2d88203f670..75c1e3432b1 100644 --- a/src/Avalonia.Base/Diagnostics/IAvaloniaObjectDebug.cs +++ b/src/Avalonia.Base/Diagnostics/IAvaloniaObjectDebug.cs @@ -8,7 +8,7 @@ namespace Avalonia.Diagnostics public interface IAvaloniaObjectDebug { /// - /// Gets the subscriber list for the + /// Gets the subscriber list for the /// event. /// /// diff --git a/src/Avalonia.Base/DirectProperty.cs b/src/Avalonia.Base/DirectProperty.cs index a5905a6081a..729240e5a1a 100644 --- a/src/Avalonia.Base/DirectProperty.cs +++ b/src/Avalonia.Base/DirectProperty.cs @@ -15,7 +15,7 @@ namespace Avalonia /// allows the avalonia property system to read and write the current value. /// public class DirectProperty : DirectPropertyBase, IDirectPropertyAccessor - where TOwner : IAvaloniaObject + where TOwner : AvaloniaObject { /// /// Initializes a new instance of the class. @@ -151,13 +151,13 @@ public DirectProperty AddOwnerWithDataValidation( } /// - internal override TValue InvokeGetter(IAvaloniaObject instance) + internal override TValue InvokeGetter(AvaloniaObject instance) { return Getter((TOwner)instance); } /// - internal override void InvokeSetter(IAvaloniaObject instance, BindingValue value) + internal override void InvokeSetter(AvaloniaObject instance, BindingValue value) { if (Setter == null) { @@ -171,13 +171,13 @@ internal override void InvokeSetter(IAvaloniaObject instance, BindingValue - object? IDirectPropertyAccessor.GetValue(IAvaloniaObject instance) + object? IDirectPropertyAccessor.GetValue(AvaloniaObject instance) { return Getter((TOwner)instance); } /// - void IDirectPropertyAccessor.SetValue(IAvaloniaObject instance, object? value) + void IDirectPropertyAccessor.SetValue(AvaloniaObject instance, object? value) { if (Setter == null) { diff --git a/src/Avalonia.Base/DirectPropertyBase.cs b/src/Avalonia.Base/DirectPropertyBase.cs index 0a8fe198850..ec9eba6d61f 100644 --- a/src/Avalonia.Base/DirectPropertyBase.cs +++ b/src/Avalonia.Base/DirectPropertyBase.cs @@ -54,14 +54,14 @@ protected DirectPropertyBase( /// /// The instance. /// The property value. - internal abstract TValue InvokeGetter(IAvaloniaObject instance); + internal abstract TValue InvokeGetter(AvaloniaObject instance); /// /// Sets the value of the property on the instance. /// /// The instance. /// The value. - internal abstract void InvokeSetter(IAvaloniaObject instance, BindingValue value); + internal abstract void InvokeSetter(AvaloniaObject instance, BindingValue value); /// /// Gets the unset value for the property on the specified type. @@ -91,7 +91,7 @@ public TValue GetUnsetValue(Type type) /// /// The type. /// The metadata. - public void OverrideMetadata(DirectPropertyMetadata metadata) where T : IAvaloniaObject + public void OverrideMetadata(DirectPropertyMetadata metadata) where T : AvaloniaObject { base.OverrideMetadata(typeof(T), metadata); } diff --git a/src/Avalonia.Base/IAvaloniaObject.cs b/src/Avalonia.Base/IAvaloniaObject.cs deleted file mode 100644 index 3b0016903ba..00000000000 --- a/src/Avalonia.Base/IAvaloniaObject.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using Avalonia.Data; -using Avalonia.Metadata; - -namespace Avalonia -{ - /// - /// Interface for getting/setting values on an object. - /// - [NotClientImplementable] - public interface IAvaloniaObject - { - /// - /// Raised when a value changes on this object. - /// - event EventHandler? PropertyChanged; - - /// - /// Clears an 's local value. - /// - /// The property. - void ClearValue(AvaloniaProperty property); - - /// - /// Gets a value. - /// - /// The property. - /// The value. - object? GetValue(AvaloniaProperty property); - - /// - /// Checks whether a is animating. - /// - /// The property. - /// True if the property is animating, otherwise false. - bool IsAnimating(AvaloniaProperty property); - - /// - /// Checks whether a is set on this object. - /// - /// The property. - /// True if the property is set, otherwise false. - bool IsSet(AvaloniaProperty property); - - /// - /// Sets a value. - /// - /// The property. - /// The value. - /// The priority of the value. - /// - /// An if setting the property can be undone, otherwise null. - /// - IDisposable? SetValue( - AvaloniaProperty property, - object? value, - BindingPriority priority = BindingPriority.LocalValue); - - /// - /// Binds a to an observable. - /// - /// The property. - /// The observable. - /// The priority of the binding. - /// - /// A disposable which can be used to terminate the binding. - /// - IDisposable Bind( - AvaloniaProperty property, - IObservable source, - BindingPriority priority = BindingPriority.LocalValue); - - /// - /// Coerces the specified . - /// - /// The property. - void CoerceValue(AvaloniaProperty property); - } -} diff --git a/src/Avalonia.Base/IDataContextProvider.cs b/src/Avalonia.Base/IDataContextProvider.cs index 1d381cf4a51..79f9c979681 100644 --- a/src/Avalonia.Base/IDataContextProvider.cs +++ b/src/Avalonia.Base/IDataContextProvider.cs @@ -6,7 +6,7 @@ namespace Avalonia /// Defines an element with a data context that can be used for binding. /// [NotClientImplementable] - public interface IDataContextProvider : IAvaloniaObject + public interface IDataContextProvider { /// /// Gets or sets the element's data context. diff --git a/src/Avalonia.Base/IDirectPropertyAccessor.cs b/src/Avalonia.Base/IDirectPropertyAccessor.cs index 476a36f3725..016ca9a6fb5 100644 --- a/src/Avalonia.Base/IDirectPropertyAccessor.cs +++ b/src/Avalonia.Base/IDirectPropertyAccessor.cs @@ -24,13 +24,13 @@ internal interface IDirectPropertyAccessor /// /// The instance. /// The property value. - object? GetValue(IAvaloniaObject instance); + object? GetValue(AvaloniaObject instance); /// /// Sets the value of the property on the instance. /// /// The instance. /// The value. - void SetValue(IAvaloniaObject instance, object? value); + void SetValue(AvaloniaObject instance, object? value); } } diff --git a/src/Avalonia.Base/IStyledElement.cs b/src/Avalonia.Base/IStyledElement.cs deleted file mode 100644 index 4eed54de45d..00000000000 --- a/src/Avalonia.Base/IStyledElement.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.ComponentModel; -using Avalonia.Controls; -using Avalonia.LogicalTree; -using Avalonia.Metadata; -using Avalonia.Styling; - -namespace Avalonia -{ - [NotClientImplementable] - public interface IStyledElement : - IStyleable, - IStyleHost, - ILogical, - IResourceHost, - IDataContextProvider, - ISupportInitialize - { - /// - /// Occurs when the control has finished initialization. - /// - event EventHandler? Initialized; - - /// - /// Gets a value that indicates whether the element has finished initialization. - /// - bool IsInitialized { get; } - - /// - /// Gets or sets the control's styling classes. - /// - new Classes Classes { get; set; } - - /// - /// Gets the control's logical parent. - /// - IStyledElement? Parent { get; } - } -} diff --git a/src/Avalonia.Base/Input/AccessKeyHandler.cs b/src/Avalonia.Base/Input/AccessKeyHandler.cs index 60175ae588a..5695d27153c 100644 --- a/src/Avalonia.Base/Input/AccessKeyHandler.cs +++ b/src/Avalonia.Base/Input/AccessKeyHandler.cs @@ -182,13 +182,13 @@ protected virtual void OnKeyDown(object? sender, KeyEventArgs e) // find all controls who have registered that access key. var text = e.Key.ToString().ToUpper(); var matches = _registered - .Where(x => x.Item1 == text && x.Item2.IsEffectivelyVisible) + .Where(x => x.Item1 == text && ((Visual)x.Item2).IsEffectivelyVisible) .Select(x => x.Item2); // If the menu is open, only match controls in the menu's visual tree. if (menuIsOpen) { - matches = matches.Where(x => x is not null && MainMenu!.IsVisualAncestorOf(x)); + matches = matches.Where(x => x is not null && ((Visual)MainMenu!).IsVisualAncestorOf((Visual)x)); } var match = matches.FirstOrDefault(); diff --git a/src/Avalonia.Base/Input/DragDropDevice.cs b/src/Avalonia.Base/Input/DragDropDevice.cs index 3c91856dcd4..1e8035831ea 100644 --- a/src/Avalonia.Base/Input/DragDropDevice.cs +++ b/src/Avalonia.Base/Input/DragDropDevice.cs @@ -13,7 +13,8 @@ public class DragDropDevice : IDragDropDevice private Interactive? GetTarget(IInputRoot root, Point local) { - var target = root.InputHitTest(local)?.GetSelfAndVisualAncestors()?.OfType()?.FirstOrDefault(); + var hit = root.InputHitTest(local) as Visual; + var target = hit?.GetSelfAndVisualAncestors()?.OfType()?.FirstOrDefault(); if (target != null && DragDrop.GetAllowDrop(target)) return target; return null; @@ -24,7 +25,7 @@ private DragDropEffects RaiseDragEvent(Interactive? target, IInputRoot inputRoot if (target == null) return DragDropEffects.None; - var p = inputRoot.TranslatePoint(point, target); + var p = ((Visual)inputRoot).TranslatePoint(point, target); if (!p.HasValue) return DragDropEffects.None; diff --git a/src/Avalonia.Base/Input/DragEventArgs.cs b/src/Avalonia.Base/Input/DragEventArgs.cs index 41276e2f060..7a27c53023a 100644 --- a/src/Avalonia.Base/Input/DragEventArgs.cs +++ b/src/Avalonia.Base/Input/DragEventArgs.cs @@ -15,7 +15,7 @@ public class DragEventArgs : RoutedEventArgs public KeyModifiers KeyModifiers { get; private set; } - public Point GetPosition(IVisual relativeTo) + public Point GetPosition(Visual relativeTo) { var point = new Point(0, 0); diff --git a/src/Avalonia.Base/Input/FocusManager.cs b/src/Avalonia.Base/Input/FocusManager.cs index c7b5b8e27fb..2bf666af44b 100644 --- a/src/Avalonia.Base/Input/FocusManager.cs +++ b/src/Avalonia.Base/Input/FocusManager.cs @@ -185,7 +185,7 @@ public void RemoveFocusScope(IFocusScope scope) /// /// The element. /// True if the element can be focused. - private static bool CanFocus(IInputElement e) => e.Focusable && e.IsEffectivelyEnabled && e.IsVisible; + private static bool CanFocus(IInputElement e) => e.Focusable && e.IsEffectivelyEnabled && IsVisible(e); /// /// Gets the focus scope ancestors of the specified control, traversing popups. @@ -198,14 +198,15 @@ private static IEnumerable GetFocusScopeAncestors(IInputElement con while (c != null) { - var scope = c as IFocusScope; - - if (scope != null && c.VisualRoot?.IsVisible == true) + if (c is IFocusScope scope && + c is Visual v && + v.VisualRoot is Visual root && + root.IsVisible) { yield return scope; } - c = c.GetVisualParent() ?? + c = (c as Visual)?.GetVisualParent() ?? ((c as IHostedVisualTreeRoot)?.Host as IInputElement); } } @@ -221,11 +222,11 @@ private static void OnPreviewPointerPressed(object? sender, RoutedEventArgs e) return; var ev = (PointerPressedEventArgs)e; - var visual = (IVisual)sender; + var visual = (Visual)sender; if (sender == e.Source && ev.GetCurrentPoint(visual).Properties.IsLeftButtonPressed) { - IVisual? element = ev.Pointer?.Captured ?? e.Source as IInputElement; + Visual? element = ev.Pointer?.Captured as Visual ?? e.Source as Visual; while (element != null) { @@ -240,5 +241,7 @@ private static void OnPreviewPointerPressed(object? sender, RoutedEventArgs e) } } } + + private static bool IsVisible(IInputElement e) => (e as Visual)?.IsVisible ?? true; } } diff --git a/src/Avalonia.Base/Input/GestureRecognizers/GestureRecognizerCollection.cs b/src/Avalonia.Base/Input/GestureRecognizers/GestureRecognizerCollection.cs index 54ef0b1a687..a202d6b5bcf 100644 --- a/src/Avalonia.Base/Input/GestureRecognizers/GestureRecognizerCollection.cs +++ b/src/Avalonia.Base/Input/GestureRecognizers/GestureRecognizerCollection.cs @@ -35,8 +35,8 @@ public void Add(IGestureRecognizer recognizer) if (_inputElement is ILogical logicalParent && recognizer is ISetLogicalParent logical) { logical.SetParent(logicalParent); - if (recognizer is IStyleable styleableRecognizer - && _inputElement is IStyleable styleableParent) + if (recognizer is StyledElement styleableRecognizer + && _inputElement is StyledElement styleableParent) styleableRecognizer.Bind(StyledElement.TemplatedParentProperty, styleableParent.GetObservable(StyledElement.TemplatedParentProperty)); } diff --git a/src/Avalonia.Base/Input/GestureRecognizers/ScrollGestureRecognizer.cs b/src/Avalonia.Base/Input/GestureRecognizers/ScrollGestureRecognizer.cs index 4f5585ab6c6..7bcb81767d3 100644 --- a/src/Avalonia.Base/Input/GestureRecognizers/ScrollGestureRecognizer.cs +++ b/src/Avalonia.Base/Input/GestureRecognizers/ScrollGestureRecognizer.cs @@ -72,7 +72,7 @@ public void PointerPressed(PointerPressedEventArgs e) EndGesture(); _tracking = e.Pointer; _gestureId = ScrollGestureEventArgs.GetNextFreeId(); - _trackedRootPoint = e.GetPosition(_target); + _trackedRootPoint = e.GetPosition((Visual?)_target); } } @@ -86,7 +86,7 @@ public void PointerMoved(PointerEventArgs e) { if (e.Pointer == _tracking) { - var rootPoint = e.GetPosition(_target); + var rootPoint = e.GetPosition((Visual?)_target); if (!_scrolling) { if (CanHorizontallyScroll && Math.Abs(_trackedRootPoint.X - rootPoint.X) > ScrollStartDistance) diff --git a/src/Avalonia.Base/Input/Gestures.cs b/src/Avalonia.Base/Input/Gestures.cs index 82ed96d9820..496052ad353 100644 --- a/src/Avalonia.Base/Input/Gestures.cs +++ b/src/Avalonia.Base/Input/Gestures.cs @@ -43,7 +43,7 @@ public static class Gestures RoutedEvent.Register( "PointerSwipeGesture", RoutingStrategies.Bubble, typeof(Gestures)); - private static readonly WeakReference s_lastPress = new WeakReference(null); + private static readonly WeakReference s_lastPress = new WeakReference(null); private static Point s_lastPressPoint; static Gestures() @@ -52,32 +52,32 @@ static Gestures() InputElement.PointerReleasedEvent.RouteFinished.Subscribe(PointerReleased); } - public static void AddTappedHandler(IInteractive element, EventHandler handler) + public static void AddTappedHandler(Interactive element, EventHandler handler) { element.AddHandler(TappedEvent, handler); } - public static void AddDoubleTappedHandler(IInteractive element, EventHandler handler) + public static void AddDoubleTappedHandler(Interactive element, EventHandler handler) { element.AddHandler(DoubleTappedEvent, handler); } - public static void AddRightTappedHandler(IInteractive element, EventHandler handler) + public static void AddRightTappedHandler(Interactive element, EventHandler handler) { element.AddHandler(RightTappedEvent, handler); } - public static void RemoveTappedHandler(IInteractive element, EventHandler handler) + public static void RemoveTappedHandler(Interactive element, EventHandler handler) { element.RemoveHandler(TappedEvent, handler); } - public static void RemoveDoubleTappedHandler(IInteractive element, EventHandler handler) + public static void RemoveDoubleTappedHandler(Interactive element, EventHandler handler) { element.RemoveHandler(DoubleTappedEvent, handler); } - public static void RemoveRightTappedHandler(IInteractive element, EventHandler handler) + public static void RemoveRightTappedHandler(Interactive element, EventHandler handler) { element.RemoveHandler(RightTappedEvent, handler); } @@ -92,20 +92,22 @@ private static void PointerPressed(RoutedEventArgs ev) if (ev.Route == RoutingStrategies.Bubble) { var e = (PointerPressedEventArgs)ev; - var visual = (IVisual)ev.Source; + var visual = (Visual)ev.Source; if (e.ClickCount % 2 == 1) { s_isDoubleTapped = false; s_lastPress.SetTarget(ev.Source); - s_lastPressPoint = e.GetPosition((IVisual)ev.Source); + s_lastPressPoint = e.GetPosition((Visual)ev.Source); } else if (e.ClickCount % 2 == 0 && e.GetCurrentPoint(visual).Properties.IsLeftButtonPressed) { - if (s_lastPress.TryGetTarget(out var target) && target == e.Source) + if (s_lastPress.TryGetTarget(out var target) && + target == e.Source && + e.Source is Interactive i) { s_isDoubleTapped = true; - e.Source.RaiseEvent(new TappedEventArgs(DoubleTappedEvent, e)); + i.RaiseEvent(new TappedEventArgs(DoubleTappedEvent, e)); } } } @@ -119,9 +121,10 @@ private static void PointerReleased(RoutedEventArgs ev) if (s_lastPress.TryGetTarget(out var target) && target == e.Source && - e.InitialPressMouseButton is MouseButton.Left or MouseButton.Right) + e.InitialPressMouseButton is MouseButton.Left or MouseButton.Right && + e.Source is Interactive i) { - var point = e.GetCurrentPoint((IVisual)target); + var point = e.GetCurrentPoint((Visual)target); var settings = AvaloniaLocator.Current.GetService(); var tapSize = settings?.GetTapSize(point.Pointer.Type) ?? new Size(4, 4); var tapRect = new Rect(s_lastPressPoint, new Size()) @@ -131,13 +134,13 @@ private static void PointerReleased(RoutedEventArgs ev) { if (e.InitialPressMouseButton == MouseButton.Right) { - e.Source.RaiseEvent(new TappedEventArgs(RightTappedEvent, e)); + i.RaiseEvent(new TappedEventArgs(RightTappedEvent, e)); } //s_isDoubleTapped needed here to prevent invoking Tapped event when DoubleTapped is called. //This behaviour matches UWP behaviour. else if (s_isDoubleTapped == false) { - e.Source.RaiseEvent(new TappedEventArgs(TappedEvent, e)); + i.RaiseEvent(new TappedEventArgs(TappedEvent, e)); } } } diff --git a/src/Avalonia.Base/Input/IInputElement.cs b/src/Avalonia.Base/Input/IInputElement.cs index 43ac87d008d..6c20d20b4db 100644 --- a/src/Avalonia.Base/Input/IInputElement.cs +++ b/src/Avalonia.Base/Input/IInputElement.cs @@ -2,9 +2,6 @@ using System.Collections.Generic; using Avalonia.Interactivity; using Avalonia.Metadata; -using Avalonia.VisualTree; - -#nullable enable namespace Avalonia.Input { @@ -12,7 +9,7 @@ namespace Avalonia.Input /// Defines input-related functionality for a control. /// [NotClientImplementable] - public interface IInputElement : IInteractive, IVisual + public interface IInputElement { /// /// Occurs when the control receives focus. @@ -93,7 +90,12 @@ public interface IInputElement : IInteractive, IVisual /// value of this control and its parent controls. /// bool IsEffectivelyEnabled { get; } - + + /// + /// Gets a value indicating whether this control and all its parents are visible. + /// + bool IsEffectivelyVisible { get; } + /// /// Gets a value indicating whether keyboard focus is anywhere within the element or its visual tree child elements. /// @@ -123,5 +125,32 @@ public interface IInputElement : IInteractive, IVisual /// Gets the key bindings for the element. /// List KeyBindings { get; } + + /// + /// Adds a handler for the specified routed event. + /// + /// The routed event. + /// The handler. + /// The routing strategies to listen to. + /// Whether handled events should also be listened for. + /// A disposable that terminates the event subscription. + void AddHandler( + RoutedEvent routedEvent, + Delegate handler, + RoutingStrategies routes = RoutingStrategies.Direct | RoutingStrategies.Bubble, + bool handledEventsToo = false); + + /// + /// Removes a handler for the specified routed event. + /// + /// The routed event. + /// The handler. + void RemoveHandler(RoutedEvent routedEvent, Delegate handler); + + /// + /// Raises a routed event. + /// + /// The event args. + void RaiseEvent(RoutedEventArgs e); } } diff --git a/src/Avalonia.Base/Input/IMainMenu.cs b/src/Avalonia.Base/Input/IMainMenu.cs index 213a979c287..0010397c1ad 100644 --- a/src/Avalonia.Base/Input/IMainMenu.cs +++ b/src/Avalonia.Base/Input/IMainMenu.cs @@ -9,7 +9,7 @@ namespace Avalonia.Input /// Defines the interface for a window's main menu. /// [NotClientImplementable] - public interface IMainMenu : IVisual + public interface IMainMenu { /// /// Gets a value indicating whether the menu is open. diff --git a/src/Avalonia.Base/Input/InputExtensions.cs b/src/Avalonia.Base/Input/InputExtensions.cs index cbe36583e68..73dcef9e95a 100644 --- a/src/Avalonia.Base/Input/InputExtensions.cs +++ b/src/Avalonia.Base/Input/InputExtensions.cs @@ -12,7 +12,7 @@ namespace Avalonia.Input /// public static class InputExtensions { - private static readonly Func s_hitTestDelegate = IsHitTestVisible; + private static readonly Func s_hitTestDelegate = IsHitTestVisible; /// /// Returns the active input elements at a point on an . @@ -26,7 +26,8 @@ public static IEnumerable GetInputElementsAt(this IInputElement e { element = element ?? throw new ArgumentNullException(nameof(element)); - return element.GetVisualsAt(p, s_hitTestDelegate).Cast(); + return (element as Visual)?.GetVisualsAt(p, s_hitTestDelegate).Cast() ?? + Enumerable.Empty(); } /// @@ -39,7 +40,7 @@ public static IEnumerable GetInputElementsAt(this IInputElement e { element = element ?? throw new ArgumentNullException(nameof(element)); - return element.GetVisualAt(p, s_hitTestDelegate) as IInputElement; + return (element as Visual)?.GetVisualAt(p, s_hitTestDelegate) as IInputElement; } /// @@ -55,22 +56,22 @@ public static IEnumerable GetInputElementsAt(this IInputElement e public static IInputElement? InputHitTest( this IInputElement element, Point p, - Func filter) + Func filter) { element = element ?? throw new ArgumentNullException(nameof(element)); filter = filter ?? throw new ArgumentNullException(nameof(filter)); - return element.GetVisualAt(p, x => s_hitTestDelegate(x) && filter(x)) as IInputElement; + return (element as Visual)?.GetVisualAt(p, x => s_hitTestDelegate(x) && filter(x)) as IInputElement; } - private static bool IsHitTestVisible(IVisual visual) + private static bool IsHitTestVisible(Visual visual) { var element = visual as IInputElement; return element != null && - element.IsVisible && + visual.IsVisible && element.IsHitTestVisible && element.IsEffectivelyEnabled && - element.IsAttachedToVisualTree; + visual.IsAttachedToVisualTree; } } } diff --git a/src/Avalonia.Base/Input/KeyboardDevice.cs b/src/Avalonia.Base/Input/KeyboardDevice.cs index 0600b546184..9d23cc49d90 100644 --- a/src/Avalonia.Base/Input/KeyboardDevice.cs +++ b/src/Avalonia.Base/Input/KeyboardDevice.cs @@ -3,7 +3,6 @@ using Avalonia.Input.Raw; using Avalonia.Input.TextInput; using Avalonia.Interactivity; -using Avalonia.VisualTree; namespace Avalonia.Input { @@ -37,18 +36,21 @@ private void ClearFocusWithinAncestors(IInputElement? element) ie.IsKeyboardFocusWithin = false; } - el = (IInputElement?)el.VisualParent; + el = (IInputElement?)(el as Visual)?.VisualParent; } } private void ClearFocusWithin(IInputElement element, bool clearRoot) { - foreach (var visual in element.VisualChildren) + if (element is Visual v) { - if (visual is IInputElement el && el.IsKeyboardFocusWithin) + foreach (var visual in v.VisualChildren) { - ClearFocusWithin(el, true); - break; + if (visual is IInputElement el && el.IsKeyboardFocusWithin) + { + ClearFocusWithin(el, true); + break; + } } } @@ -81,7 +83,7 @@ private void SetIsFocusWithin(IInputElement? oldElement, IInputElement? newEleme break; } - el = el.VisualParent as IInputElement; + el = (el as Visual)?.VisualParent as IInputElement; } el = oldElement; @@ -100,18 +102,21 @@ private void SetIsFocusWithin(IInputElement? oldElement, IInputElement? newEleme ie.IsKeyboardFocusWithin = true; } - el = el.VisualParent as IInputElement; + el = (el as Visual)?.VisualParent as IInputElement; } } private void ClearChildrenFocusWithin(IInputElement element, bool clearRoot) { - foreach (var visual in element.VisualChildren) + if (element is Visual v) { - if (visual is IInputElement el && el.IsKeyboardFocusWithin) + foreach (var visual in v.VisualChildren) { - ClearChildrenFocusWithin(el, true); - break; + if (visual is IInputElement el && el.IsKeyboardFocusWithin) + { + ClearChildrenFocusWithin(el, true); + break; + } } } @@ -128,11 +133,11 @@ public void SetFocusedElement( { if (element != FocusedElement) { - var interactive = FocusedElement as IInteractive; + var interactive = FocusedElement as Interactive; if (FocusedElement != null && - (!FocusedElement.IsAttachedToVisualTree || - _focusedRoot != element?.VisualRoot as IInputRoot) && + (!((Visual)FocusedElement).IsAttachedToVisualTree || + _focusedRoot != ((Visual?)element)?.VisualRoot as IInputRoot) && _focusedRoot != null) { ClearChildrenFocusWithin(_focusedRoot, true); @@ -140,14 +145,14 @@ public void SetFocusedElement( SetIsFocusWithin(FocusedElement, element); _focusedElement = element; - _focusedRoot = _focusedElement?.VisualRoot as IInputRoot; + _focusedRoot = ((Visual?)_focusedElement)?.VisualRoot as IInputRoot; interactive?.RaiseEvent(new RoutedEventArgs { RoutedEvent = InputElement.LostFocusEvent, }); - interactive = element as IInteractive; + interactive = element as Interactive; interactive?.RaiseEvent(new GotFocusEventArgs { @@ -191,8 +196,8 @@ public void ProcessRawEvent(RawInputEventArgs e) KeyModifiers = keyInput.Modifiers.ToKeyModifiers(), Source = element, }; - - IVisual? currentHandler = element; + + var currentHandler = element as Visual; while (currentHandler != null && !ev.Handled && keyInput.Type == RawKeyEventType.KeyDown) { var bindings = (currentHandler as IInputElement)?.KeyBindings; diff --git a/src/Avalonia.Base/Input/KeyboardNavigation.cs b/src/Avalonia.Base/Input/KeyboardNavigation.cs index 042a9adf5fb..9d989d96d6b 100644 --- a/src/Avalonia.Base/Input/KeyboardNavigation.cs +++ b/src/Avalonia.Base/Input/KeyboardNavigation.cs @@ -68,7 +68,7 @@ public static int GetTabIndex(IInputElement element) /// The tab index. public static void SetTabIndex(IInputElement element, int value) { - ((IAvaloniaObject)element).SetValue(TabIndexProperty, value); + ((AvaloniaObject)element).SetValue(TabIndexProperty, value); } /// diff --git a/src/Avalonia.Base/Input/KeyboardNavigationHandler.cs b/src/Avalonia.Base/Input/KeyboardNavigationHandler.cs index f73203f6b70..b05d8f30bb9 100644 --- a/src/Avalonia.Base/Input/KeyboardNavigationHandler.cs +++ b/src/Avalonia.Base/Input/KeyboardNavigationHandler.cs @@ -50,7 +50,7 @@ public void SetOwner(IInputRoot owner) element = element ?? throw new ArgumentNullException(nameof(element)); // If there's a custom keyboard navigation handler as an ancestor, use that. - var custom = element.FindAncestorOfType(true); + var custom = (element as Visual)?.FindAncestorOfType(true); if (custom is object && HandlePreCustomNavigation(custom, element, direction, out var ce)) return ce; @@ -156,9 +156,9 @@ private static bool HandlePostCustomNavigation( NavigationDirection direction, [NotNullWhen(true)] out IInputElement? result) { - if (newElement is object) + if (newElement is Visual v) { - var customHandler = newElement.FindAncestorOfType(true); + var customHandler = v.FindAncestorOfType(true); if (customHandler is object) { diff --git a/src/Avalonia.Base/Input/MouseDevice.cs b/src/Avalonia.Base/Input/MouseDevice.cs index 8c107999113..71c1b2f1450 100644 --- a/src/Avalonia.Base/Input/MouseDevice.cs +++ b/src/Avalonia.Base/Input/MouseDevice.cs @@ -141,7 +141,7 @@ private bool MouseDown(IMouseDevice device, ulong timestamp, IInputElement root, _lastClickRect = new Rect(p, new Size()) .Inflate(new Thickness(doubleClickSize.Width / 2, doubleClickSize.Height / 2)); _lastMouseDownButton = properties.PointerUpdateKind.GetMouseButton(); - var e = new PointerPressedEventArgs(source, _pointer, root, p, timestamp, properties, inputModifiers, _clickCount); + var e = new PointerPressedEventArgs(source, _pointer, (Visual)root, p, timestamp, properties, inputModifiers, _clickCount); source.RaiseEvent(e); return e.Handled; } @@ -161,7 +161,7 @@ private bool MouseMove(IMouseDevice device, ulong timestamp, IInputRoot root, Po if (source is object) { - var e = new PointerEventArgs(InputElement.PointerMovedEvent, source, _pointer, root, + var e = new PointerEventArgs(InputElement.PointerMovedEvent, source, _pointer, (Visual)root, p, timestamp, properties, inputModifiers, intermediatePoints); source.RaiseEvent(e); @@ -181,7 +181,7 @@ private bool MouseUp(IMouseDevice device, ulong timestamp, IInputRoot root, Poin if (source is not null) { - var e = new PointerReleasedEventArgs(source, _pointer, root, p, timestamp, props, inputModifiers, + var e = new PointerReleasedEventArgs(source, _pointer, (Visual)root, p, timestamp, props, inputModifiers, _lastMouseDownButton); source?.RaiseEvent(e); @@ -204,7 +204,7 @@ private bool MouseWheel(IMouseDevice device, ulong timestamp, IInputRoot root, P if (source is not null) { - var e = new PointerWheelEventArgs(source, _pointer, root, p, timestamp, props, inputModifiers, delta); + var e = new PointerWheelEventArgs(source, _pointer, (Visual)root, p, timestamp, props, inputModifiers, delta); source?.RaiseEvent(e); return e.Handled; @@ -224,7 +224,7 @@ private bool GestureMagnify(IMouseDevice device, ulong timestamp, IInputRoot roo if (source != null) { var e = new PointerDeltaEventArgs(Gestures.PointerTouchPadGestureMagnifyEvent, source, - _pointer, root, p, timestamp, props, inputModifiers, delta); + _pointer, (Visual)root, p, timestamp, props, inputModifiers, delta); source?.RaiseEvent(e); return e.Handled; @@ -244,7 +244,7 @@ private bool GestureRotate(IMouseDevice device, ulong timestamp, IInputRoot root if (source != null) { var e = new PointerDeltaEventArgs(Gestures.PointerTouchPadGestureRotateEvent, source, - _pointer, root, p, timestamp, props, inputModifiers, delta); + _pointer, (Visual)root, p, timestamp, props, inputModifiers, delta); source?.RaiseEvent(e); return e.Handled; @@ -264,7 +264,7 @@ private bool GestureSwipe(IMouseDevice device, ulong timestamp, IInputRoot root, if (source != null) { var e = new PointerDeltaEventArgs(Gestures.PointerTouchPadGestureSwipeEvent, source, - _pointer, root, p, timestamp, props, inputModifiers, delta); + _pointer, (Visual)root, p, timestamp, props, inputModifiers, delta); source?.RaiseEvent(e); return e.Handled; diff --git a/src/Avalonia.Base/Input/Navigation/FocusExtensions.cs b/src/Avalonia.Base/Input/Navigation/FocusExtensions.cs index 83bcd9187a2..3cd4ca0d761 100644 --- a/src/Avalonia.Base/Input/Navigation/FocusExtensions.cs +++ b/src/Avalonia.Base/Input/Navigation/FocusExtensions.cs @@ -10,13 +10,21 @@ internal static class FocusExtensions /// /// The element. /// True if the element can be focused. - public static bool CanFocus(this IInputElement e) => e.Focusable && e.IsEffectivelyEnabled && e.IsVisible; + public static bool CanFocus(this IInputElement e) + { + var visible = (e as Visual)?.IsVisible ?? true; + return e.Focusable && e.IsEffectivelyEnabled && visible; + } /// /// Checks if descendants of the specified element can be focused. /// /// The element. /// True if descendants of the element can be focused. - public static bool CanFocusDescendants(this IInputElement e) => e.IsEffectivelyEnabled && e.IsVisible; + public static bool CanFocusDescendants(this IInputElement e) + { + var visible = (e as Visual)?.IsVisible ?? true; + return e.IsEffectivelyEnabled && visible; + } } } diff --git a/src/Avalonia.Base/Input/Navigation/TabNavigation.cs b/src/Avalonia.Base/Input/Navigation/TabNavigation.cs index cfd45f82628..d218867cf28 100644 --- a/src/Avalonia.Base/Input/Navigation/TabNavigation.cs +++ b/src/Avalonia.Base/Input/Navigation/TabNavigation.cs @@ -212,9 +212,10 @@ internal static class TabNavigation if (!IsFocusScope(e)) { // Verify if focusedElement is a visual descendant of e - if (focusedElement is IVisual visualFocusedElement && + if (focusedElement is Visual visualFocusedElement && + e is Visual v && visualFocusedElement != e && - e.IsVisualAncestorOf(visualFocusedElement)) + v.IsVisualAncestorOf(visualFocusedElement)) { return focusedElement; } @@ -236,7 +237,7 @@ internal static class TabNavigation if (uiElement is null || IsVisibleAndEnabled(uiElement)) { - if (e is IVisual elementAsVisual) + if (e is Visual elementAsVisual) { var children = elementAsVisual.VisualChildren; var count = children.Count; @@ -272,7 +273,7 @@ internal static class TabNavigation if (uiElement == null || IsVisibleAndEnabled(uiElement)) { - var elementAsVisual = e as IVisual; + var elementAsVisual = e as Visual; if (elementAsVisual != null) { @@ -385,7 +386,7 @@ internal static class TabNavigation private static IInputElement? GetNextSibling(IInputElement e) { - if (GetParent(e) is IVisual parentAsVisual && e is IVisual elementAsVisual) + if (GetParent(e) is Visual parentAsVisual && e is Visual elementAsVisual) { var children = parentAsVisual.VisualChildren; var count = children.Count; @@ -589,7 +590,7 @@ internal static class TabNavigation private static IInputElement? GetPreviousSibling(IInputElement e) { - if (GetParent(e) is IVisual parentAsVisual && e is IVisual elementAsVisual) + if (GetParent(e) is Visual parentAsVisual && e is Visual elementAsVisual) { var children = parentAsVisual.VisualChildren; var count = children.Count; @@ -646,7 +647,7 @@ private static IInputElement GetGroupParent(IInputElement element, bool includeC private static IInputElement? GetParent(IInputElement e) { // For Visual - go up the visual parent chain until we find Visual. - if (e is IVisual v) + if (e is Visual v) return v.FindAncestorOfType(); // This will need to be implemented when we have non-visual input elements. @@ -669,6 +670,7 @@ private static bool IsTabStop(IInputElement e) } private static bool IsTabStopOrGroup(IInputElement e) => IsTabStop(e) || IsGroup(e); - private static bool IsVisibleAndEnabled(IInputElement e) => e.IsVisible && e.IsEnabled; + private static bool IsVisible(IInputElement e) => (e as Visual)?.IsVisible ?? true; + private static bool IsVisibleAndEnabled(IInputElement e) => IsVisible(e) && e.IsEnabled; } } diff --git a/src/Avalonia.Base/Input/PenDevice.cs b/src/Avalonia.Base/Input/PenDevice.cs index 31f34566bed..d7d9bf8902b 100644 --- a/src/Avalonia.Base/Input/PenDevice.cs +++ b/src/Avalonia.Base/Input/PenDevice.cs @@ -91,7 +91,7 @@ private bool PenDown(Pointer pointer, ulong timestamp, _lastClickRect = new Rect(p, new Size()) .Inflate(new Thickness(doubleClickSize.Width / 2, doubleClickSize.Height / 2)); _lastMouseDownButton = properties.PointerUpdateKind.GetMouseButton(); - var e = new PointerPressedEventArgs(source, pointer, root, p, timestamp, properties, inputModifiers, _clickCount); + var e = new PointerPressedEventArgs(source, pointer, (Visual)root, p, timestamp, properties, inputModifiers, _clickCount); source.RaiseEvent(e); return e.Handled; } @@ -108,7 +108,7 @@ private bool PenMove(Pointer pointer, ulong timestamp, if (source is not null) { - var e = new PointerEventArgs(InputElement.PointerMovedEvent, source, pointer, root, + var e = new PointerEventArgs(InputElement.PointerMovedEvent, source, pointer, (Visual)root, p, timestamp, properties, inputModifiers, intermediatePoints); source.RaiseEvent(e); @@ -126,7 +126,7 @@ private bool PenUp(Pointer pointer, ulong timestamp, if (source is not null) { - var e = new PointerReleasedEventArgs(source, pointer, root, p, timestamp, properties, inputModifiers, + var e = new PointerReleasedEventArgs(source, pointer, (Visual)root, p, timestamp, properties, inputModifiers, _lastMouseDownButton); source?.RaiseEvent(e); diff --git a/src/Avalonia.Base/Input/Pointer.cs b/src/Avalonia.Base/Input/Pointer.cs index 3012f07f6a0..25adc359a20 100644 --- a/src/Avalonia.Base/Input/Pointer.cs +++ b/src/Avalonia.Base/Input/Pointer.cs @@ -21,10 +21,10 @@ public Pointer(int id, PointerType type, bool isPrimary) IInputElement? FindCommonParent(IInputElement? control1, IInputElement? control2) { - if (control1 == null || control2 == null) + if (control1 is not Visual c1 || control2 is not Visual c2) return null; - var seen = new HashSet(control1.GetSelfAndVisualAncestors().OfType()); - return control2.GetSelfAndVisualAncestors().OfType().FirstOrDefault(seen.Contains); + var seen = new HashSet(c1.GetSelfAndVisualAncestors().OfType()); + return c2.GetSelfAndVisualAncestors().OfType().FirstOrDefault(seen.Contains); } protected virtual void PlatformCapture(IInputElement? element) @@ -34,15 +34,15 @@ protected virtual void PlatformCapture(IInputElement? element) public void Capture(IInputElement? control) { - if (Captured != null) - Captured.DetachedFromVisualTree -= OnCaptureDetached; + if (Captured is Visual v1) + v1.DetachedFromVisualTree -= OnCaptureDetached; var oldCapture = Captured; Captured = control; PlatformCapture(control); - if (oldCapture != null) + if (oldCapture is Visual v2) { var commonParent = FindCommonParent(control, oldCapture); - foreach (var notifyTarget in oldCapture.GetSelfAndVisualAncestors().OfType()) + foreach (var notifyTarget in v2.GetSelfAndVisualAncestors().OfType()) { if (notifyTarget == commonParent) break; @@ -50,11 +50,11 @@ public void Capture(IInputElement? control) } } - if (Captured != null) - Captured.DetachedFromVisualTree += OnCaptureDetached; + if (Captured is Visual v3) + v3.DetachedFromVisualTree += OnCaptureDetached; } - IInputElement? GetNextCapture(IVisual parent) + IInputElement? GetNextCapture(Visual parent) { return parent as IInputElement ?? parent.FindAncestorOfType(); } diff --git a/src/Avalonia.Base/Input/PointerDeltaEventArgs.cs b/src/Avalonia.Base/Input/PointerDeltaEventArgs.cs index d5577d77af2..af0fa833826 100644 --- a/src/Avalonia.Base/Input/PointerDeltaEventArgs.cs +++ b/src/Avalonia.Base/Input/PointerDeltaEventArgs.cs @@ -7,8 +7,8 @@ public class PointerDeltaEventArgs : PointerEventArgs { public Vector Delta { get; set; } - internal PointerDeltaEventArgs(RoutedEvent routedEvent, IInteractive? source, - IPointer pointer, IVisual rootVisual, Point rootVisualPosition, ulong timestamp, + internal PointerDeltaEventArgs(RoutedEvent routedEvent, object? source, + IPointer pointer, Visual rootVisual, Point rootVisualPosition, ulong timestamp, PointerPointProperties properties, KeyModifiers modifiers, Vector delta) : base(routedEvent, source, pointer, rootVisual, rootVisualPosition, timestamp, properties, modifiers) diff --git a/src/Avalonia.Base/Input/PointerEventArgs.cs b/src/Avalonia.Base/Input/PointerEventArgs.cs index f84dec42cbd..d736253728d 100644 --- a/src/Avalonia.Base/Input/PointerEventArgs.cs +++ b/src/Avalonia.Base/Input/PointerEventArgs.cs @@ -8,15 +8,15 @@ namespace Avalonia.Input { public class PointerEventArgs : RoutedEventArgs { - private readonly IVisual? _rootVisual; + private readonly Visual? _rootVisual; private readonly Point _rootVisualPosition; private readonly PointerPointProperties _properties; private readonly Lazy?>? _previousPoints; internal PointerEventArgs(RoutedEvent routedEvent, - IInteractive? source, + object? source, IPointer pointer, - IVisual? rootVisual, Point rootVisualPosition, + Visual? rootVisual, Point rootVisualPosition, ulong timestamp, PointerPointProperties properties, KeyModifiers modifiers) @@ -30,11 +30,11 @@ internal PointerEventArgs(RoutedEvent routedEvent, Timestamp = timestamp; KeyModifiers = modifiers; } - + internal PointerEventArgs(RoutedEvent routedEvent, - IInteractive? source, + object? source, IPointer pointer, - IVisual? rootVisual, Point rootVisualPosition, + Visual? rootVisual, Point rootVisualPosition, ulong timestamp, PointerPointProperties properties, KeyModifiers modifiers, @@ -59,7 +59,7 @@ internal PointerEventArgs(RoutedEvent routedEvent, /// public KeyModifiers KeyModifiers { get; } - private Point GetPosition(Point pt, IVisual? relativeTo) + private Point GetPosition(Point pt, Visual? relativeTo) { if (_rootVisual == null) return default; @@ -74,14 +74,14 @@ private Point GetPosition(Point pt, IVisual? relativeTo) /// /// The control. /// The pointer position in the control's coordinates. - public Point GetPosition(IVisual? relativeTo) => GetPosition(_rootVisualPosition, relativeTo); + public Point GetPosition(Visual? relativeTo) => GetPosition(_rootVisualPosition, relativeTo); /// /// Returns the PointerPoint associated with the current event /// /// The visual which coordinate system to use. Pass null for toplevel coordinate system /// - public PointerPoint GetCurrentPoint(IVisual? relativeTo) + public PointerPoint GetCurrentPoint(Visual? relativeTo) => new PointerPoint(Pointer, GetPosition(relativeTo), _properties); /// @@ -89,7 +89,7 @@ public PointerPoint GetCurrentPoint(IVisual? relativeTo) /// /// The visual which coordinate system to use. Pass null for toplevel coordinate system /// - public IReadOnlyList GetIntermediatePoints(IVisual? relativeTo) + public IReadOnlyList GetIntermediatePoints(Visual? relativeTo) { var previousPoints = _previousPoints?.Value; if (previousPoints == null || previousPoints.Count == 0) @@ -125,9 +125,9 @@ public enum MouseButton public class PointerPressedEventArgs : PointerEventArgs { internal PointerPressedEventArgs( - IInteractive source, + object source, IPointer pointer, - IVisual rootVisual, Point rootVisualPosition, + Visual rootVisual, Point rootVisualPosition, ulong timestamp, PointerPointProperties properties, KeyModifiers modifiers, @@ -144,8 +144,8 @@ internal PointerPressedEventArgs( public class PointerReleasedEventArgs : PointerEventArgs { internal PointerReleasedEventArgs( - IInteractive source, IPointer pointer, - IVisual rootVisual, Point rootVisualPosition, ulong timestamp, + object source, IPointer pointer, + Visual rootVisual, Point rootVisualPosition, ulong timestamp, PointerPointProperties properties, KeyModifiers modifiers, MouseButton initialPressMouseButton) : base(InputElement.PointerReleasedEvent, source, pointer, rootVisual, rootVisualPosition, @@ -164,7 +164,7 @@ public class PointerCaptureLostEventArgs : RoutedEventArgs { public IPointer Pointer { get; } - internal PointerCaptureLostEventArgs(IInteractive source, IPointer pointer) : base(InputElement.PointerCaptureLostEvent) + internal PointerCaptureLostEventArgs(object source, IPointer pointer) : base(InputElement.PointerCaptureLostEvent) { Pointer = pointer; Source = source; diff --git a/src/Avalonia.Base/Input/PointerOverPreProcessor.cs b/src/Avalonia.Base/Input/PointerOverPreProcessor.cs index e367f9f74fc..7781255d891 100644 --- a/src/Avalonia.Base/Input/PointerOverPreProcessor.cs +++ b/src/Avalonia.Base/Input/PointerOverPreProcessor.cs @@ -44,7 +44,7 @@ public void OnNext(RawInputEventArgs value) && _lastPointer is (var lastPointer, var lastPosition)) { _lastPointer = null; - ClearPointerOver(lastPointer, args.Root, 0, args.Root.PointToClient(lastPosition), + ClearPointerOver(lastPointer, args.Root, 0, PointToClient(args.Root, lastPosition), new PointerPointProperties(args.InputModifiers, args.Type.ToUpdateKind()), args.InputModifiers.ToKeyModifiers()); } @@ -64,14 +64,14 @@ public void SceneInvalidated(Rect dirtyRect) { if (_lastPointer is (var pointer, var position)) { - var clientPoint = _inputRoot.PointToClient(position); + var clientPoint = PointToClient(_inputRoot, position); if (dirtyRect.Contains(clientPoint)) { var element = pointer.Captured ?? _inputRoot.InputHitTest(clientPoint); SetPointerOver(pointer, _inputRoot, element, 0, clientPoint, PointerPointProperties.None, KeyModifiers.None); } - else if (!_inputRoot.Bounds.Contains(clientPoint)) + else if (!((Visual)_inputRoot).Bounds.Contains(clientPoint)) { ClearPointerOver(pointer, _inputRoot, 0, clientPoint, PointerPointProperties.None, KeyModifiers.None); } @@ -82,7 +82,7 @@ private void ClearPointerOver() { if (_lastPointer is (var pointer, var position)) { - var clientPoint = _inputRoot.PointToClient(position); + var clientPoint = PointToClient(_inputRoot, position); ClearPointerOver(pointer, _inputRoot, 0, clientPoint, PointerPointProperties.None, KeyModifiers.None); } _lastPointer = null; @@ -101,10 +101,10 @@ private void ClearPointerOver(IPointer pointer, IInputRoot root, // Do not pass rootVisual, when we have unknown position, // so GetPosition won't return invalid values. var e = new PointerEventArgs(InputElement.PointerExitedEvent, element, pointer, - position.HasValue ? root : null, position.HasValue ? position.Value : default, + position.HasValue ? root as Visual : null, position.HasValue ? position.Value : default, timestamp, properties, inputModifiers); - if (element != null && !element.IsAttachedToVisualTree) + if (element is Visual v && !v.IsAttachedToVisualTree) { // element has been removed from visual tree so do top down cleanup if (root.IsPointerOver) @@ -117,7 +117,7 @@ private void ClearPointerOver(IPointer pointer, IInputRoot root, e.Source = element; e.Handled = false; element.RaiseEvent(e); - element = (IInputElement?)element.VisualParent; + element = GetVisualParent(element); } root.PointerOverElement = null; @@ -127,14 +127,18 @@ private void ClearPointerOver(IPointer pointer, IInputRoot root, private void ClearChildrenPointerOver(PointerEventArgs e, IInputElement element, bool clearRoot) { - foreach (IInputElement el in element.VisualChildren) + if (element is Visual v) { - if (el.IsPointerOver) + foreach (IInputElement el in v.VisualChildren) { - ClearChildrenPointerOver(e, el, true); - break; + if (el.IsPointerOver) + { + ClearChildrenPointerOver(e, el, true); + break; + } } } + if (clearRoot) { e.Source = element; @@ -160,7 +164,7 @@ private void SetPointerOver(IPointer pointer, IInputRoot root, IInputElement? el } } - _lastPointer = (pointer, root.PointToScreen(position)); + _lastPointer = (pointer, ((Visual)root).PointToScreen(position)); } private void SetPointerOverToElement(IPointer pointer, IInputRoot root, IInputElement element, @@ -177,14 +181,14 @@ private void SetPointerOverToElement(IPointer pointer, IInputRoot root, IInputEl branch = el; break; } - el = (IInputElement?)el.VisualParent; + el = GetVisualParent(el); } el = root.PointerOverElement; - var e = new PointerEventArgs(InputElement.PointerExitedEvent, el, pointer, root, position, + var e = new PointerEventArgs(InputElement.PointerExitedEvent, el, pointer, (Visual)root, position, timestamp, properties, inputModifiers); - if (el != null && branch != null && !el.IsAttachedToVisualTree) + if (el is Visual v && branch != null && !v.IsAttachedToVisualTree) { ClearChildrenPointerOver(e, branch, false); } @@ -194,7 +198,7 @@ private void SetPointerOverToElement(IPointer pointer, IInputRoot root, IInputEl e.Source = el; e.Handled = false; el.RaiseEvent(e); - el = (IInputElement?)el.VisualParent; + el = GetVisualParent(el); } el = root.PointerOverElement = element; @@ -206,8 +210,18 @@ private void SetPointerOverToElement(IPointer pointer, IInputRoot root, IInputEl e.Source = el; e.Handled = false; el.RaiseEvent(e); - el = (IInputElement?)el.VisualParent; + el = GetVisualParent(el); } } + + private static IInputElement? GetVisualParent(IInputElement e) + { + return (e as Visual)?.VisualParent as IInputElement; + } + + private static Point PointToClient(IInputRoot root, PixelPoint p) + { + return ((Visual)root).PointToClient(p); + } } } diff --git a/src/Avalonia.Base/Input/PointerWheelEventArgs.cs b/src/Avalonia.Base/Input/PointerWheelEventArgs.cs index 8a0412659b9..a3de0eaaea3 100644 --- a/src/Avalonia.Base/Input/PointerWheelEventArgs.cs +++ b/src/Avalonia.Base/Input/PointerWheelEventArgs.cs @@ -7,7 +7,7 @@ public class PointerWheelEventArgs : PointerEventArgs { public Vector Delta { get; set; } - internal PointerWheelEventArgs(IInteractive source, IPointer pointer, IVisual rootVisual, + internal PointerWheelEventArgs(object source, IPointer pointer, Visual rootVisual, Point rootVisualPosition, ulong timestamp, PointerPointProperties properties, KeyModifiers modifiers, Vector delta) : base(InputElement.PointerWheelChangedEvent, source, pointer, rootVisual, rootVisualPosition, diff --git a/src/Avalonia.Base/Input/TappedEventArgs.cs b/src/Avalonia.Base/Input/TappedEventArgs.cs index 8af6164fc17..3e15c4843a8 100644 --- a/src/Avalonia.Base/Input/TappedEventArgs.cs +++ b/src/Avalonia.Base/Input/TappedEventArgs.cs @@ -17,6 +17,6 @@ internal TappedEventArgs(RoutedEvent routedEvent, PointerEventArgs lastPointerEv public KeyModifiers KeyModifiers => lastPointerEventArgs.KeyModifiers; public ulong Timestamp => lastPointerEventArgs.Timestamp; - public Point GetPosition(IVisual? relativeTo) => lastPointerEventArgs.GetPosition(relativeTo); + public Point GetPosition(Visual? relativeTo) => lastPointerEventArgs.GetPosition(relativeTo); } } diff --git a/src/Avalonia.Base/Input/TextInput/ITextInputMethodClient.cs b/src/Avalonia.Base/Input/TextInput/ITextInputMethodClient.cs index 325d7457824..4a60f8a0465 100644 --- a/src/Avalonia.Base/Input/TextInput/ITextInputMethodClient.cs +++ b/src/Avalonia.Base/Input/TextInput/ITextInputMethodClient.cs @@ -16,7 +16,7 @@ public interface ITextInputMethodClient /// /// The visual that's showing the text /// - IVisual TextViewVisual { get; } + Visual TextViewVisual { get; } /// /// Should be fired when text-hosting visual is changed /// diff --git a/src/Avalonia.Base/Input/TextInput/InputMethodManager.cs b/src/Avalonia.Base/Input/TextInput/InputMethodManager.cs index 4734224da45..8a3f5b968e3 100644 --- a/src/Avalonia.Base/Input/TextInput/InputMethodManager.cs +++ b/src/Avalonia.Base/Input/TextInput/InputMethodManager.cs @@ -73,10 +73,13 @@ private void OnTextViewVisualChanged(object? sender, EventArgs e) private void UpdateCursorRect() { - if (_im == null || _client == null || _focusedElement?.VisualRoot == null) + if (_im == null || + _client == null || + _focusedElement is not Visual v || + v.VisualRoot is not Visual root) return; - var transform = _focusedElement.TransformToVisual(_focusedElement.VisualRoot); + var transform = v.TransformToVisual(root); if (transform == null) _im.SetCursorRect(default); else @@ -95,7 +98,7 @@ public void SetFocusedElement(IInputElement? element) return; _focusedElement = element; - var inputMethod = (element?.VisualRoot as ITextInputMethodRoot)?.InputMethod; + var inputMethod = ((element as Visual)?.VisualRoot as ITextInputMethodRoot)?.InputMethod; if (_im != inputMethod) { diff --git a/src/Avalonia.Base/Input/TextInput/TransformTrackingHelper.cs b/src/Avalonia.Base/Input/TextInput/TransformTrackingHelper.cs index 325c72bcb55..09716b42460 100644 --- a/src/Avalonia.Base/Input/TextInput/TransformTrackingHelper.cs +++ b/src/Avalonia.Base/Input/TextInput/TransformTrackingHelper.cs @@ -7,7 +7,7 @@ namespace Avalonia.Input.TextInput { class TransformTrackingHelper : IDisposable { - private IVisual? _visual; + private Visual? _visual; private bool _queuedForUpdate; private readonly EventHandler _propertyChangedHandler; private readonly List _propertyChangedSubscriptions = new List(); @@ -17,7 +17,7 @@ public TransformTrackingHelper() _propertyChangedHandler = PropertyChangedHandler; } - public void SetVisual(IVisual? visual) + public void SetVisual(Visual? visual) { Dispose(); _visual = visual; @@ -72,7 +72,7 @@ void UpdateMatrix() { Matrix? matrix = null; if (_visual != null && _visual.VisualRoot != null) - matrix = _visual.TransformToVisual(_visual.VisualRoot); + matrix = _visual.TransformToVisual((Visual)_visual.VisualRoot); if (Matrix != matrix) { Matrix = matrix; diff --git a/src/Avalonia.Base/Input/TouchDevice.cs b/src/Avalonia.Base/Input/TouchDevice.cs index c98944359d4..3f0d221a688 100644 --- a/src/Avalonia.Base/Input/TouchDevice.cs +++ b/src/Avalonia.Base/Input/TouchDevice.cs @@ -75,7 +75,7 @@ public void ProcessRawEvent(RawInputEventArgs ev) } target.RaiseEvent(new PointerPressedEventArgs(target, pointer, - args.Root, args.Position, ev.Timestamp, + (Visual)args.Root, args.Position, ev.Timestamp, new PointerPointProperties(GetModifiers(args.InputModifiers, true), updateKind), keyModifier, _clickCount)); } @@ -86,7 +86,7 @@ public void ProcessRawEvent(RawInputEventArgs ev) using (pointer) { target.RaiseEvent(new PointerReleasedEventArgs(target, pointer, - args.Root, args.Position, ev.Timestamp, + (Visual)args.Root, args.Position, ev.Timestamp, new PointerPointProperties(GetModifiers(args.InputModifiers, false), updateKind), keyModifier, MouseButton.Left)); } @@ -101,7 +101,7 @@ public void ProcessRawEvent(RawInputEventArgs ev) if (args.Type == RawPointerEventType.TouchUpdate) { - target.RaiseEvent(new PointerEventArgs(InputElement.PointerMovedEvent, target, pointer, args.Root, + target.RaiseEvent(new PointerEventArgs(InputElement.PointerMovedEvent, target, pointer, (Visual)args.Root, args.Position, ev.Timestamp, new PointerPointProperties(GetModifiers(args.InputModifiers, true), updateKind), keyModifier, args.IntermediatePoints)); diff --git a/src/Avalonia.Base/Interactivity/EventRoute.cs b/src/Avalonia.Base/Interactivity/EventRoute.cs index 8f826835dac..3491465a684 100644 --- a/src/Avalonia.Base/Interactivity/EventRoute.cs +++ b/src/Avalonia.Base/Interactivity/EventRoute.cs @@ -43,7 +43,7 @@ public EventRoute(RoutedEvent e) /// `DynamicInvoke` on the handler. /// public void Add( - IInteractive target, + Interactive target, Delegate handler, RoutingStrategies routes, bool handledEventsToo = false, @@ -60,7 +60,7 @@ public void Add( /// Adds a class handler to the route. /// /// The target on which the event should be raised. - public void AddClassHandler(IInteractive target) + public void AddClassHandler(Interactive target) { target = target ?? throw new ArgumentNullException(nameof(target)); @@ -73,7 +73,7 @@ public void AddClassHandler(IInteractive target) /// /// The event source. /// The event args. - public void RaiseEvent(IInteractive source, RoutedEventArgs e) + public void RaiseEvent(Interactive source, RoutedEventArgs e) { source = source ?? throw new ArgumentNullException(nameof(source)); e = e ?? throw new ArgumentNullException(nameof(e)); @@ -125,7 +125,7 @@ private void RaiseEventImpl(RoutedEventArgs e) throw new ArgumentException("Event source may not be null", nameof(e)); } - IInteractive? lastTarget = null; + Interactive? lastTarget = null; var start = 0; var end = _route.Count; var step = 1; @@ -177,7 +177,7 @@ private void RaiseEventImpl(RoutedEventArgs e) private readonly struct RouteItem { public RouteItem( - IInteractive target, + Interactive target, Delegate? handler, Action? adapter, RoutingStrategies routes, @@ -190,7 +190,7 @@ public RouteItem( HandledEventsToo = handledEventsToo; } - public IInteractive Target { get; } + public Interactive Target { get; } public Delegate? Handler { get; } public Action? Adapter { get; } public RoutingStrategies Routes { get; } diff --git a/src/Avalonia.Base/Interactivity/IInteractive.cs b/src/Avalonia.Base/Interactivity/IInteractive.cs deleted file mode 100644 index 980bf54f1f6..00000000000 --- a/src/Avalonia.Base/Interactivity/IInteractive.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using Avalonia.Metadata; - -#nullable enable - -namespace Avalonia.Interactivity -{ - /// - /// Interface for objects that raise routed events. - /// - [NotClientImplementable] - public interface IInteractive - { - /// - /// Gets the interactive parent of the object for bubbling and tunneling events. - /// - IInteractive? InteractiveParent { get; } - - /// - /// Adds a handler for the specified routed event. - /// - /// The routed event. - /// The handler. - /// The routing strategies to listen to. - /// Whether handled events should also be listened for. - /// A disposable that terminates the event subscription. - void AddHandler( - RoutedEvent routedEvent, - Delegate handler, - RoutingStrategies routes = RoutingStrategies.Direct | RoutingStrategies.Bubble, - bool handledEventsToo = false); - - /// - /// Removes a handler for the specified routed event. - /// - /// The routed event. - /// The handler. - void RemoveHandler(RoutedEvent routedEvent, Delegate handler); - - /// - /// Adds the object's handlers for a routed event to an event route. - /// - /// The event. - /// The event route. - void AddToEventRoute(RoutedEvent routedEvent, EventRoute route); - - /// - /// Raises a routed event. - /// - /// The event args. - void RaiseEvent(RoutedEventArgs e); - } -} diff --git a/src/Avalonia.Base/Interactivity/Interactive.cs b/src/Avalonia.Base/Interactivity/Interactive.cs index 75f74ed3b3c..821e00d7849 100644 --- a/src/Avalonia.Base/Interactivity/Interactive.cs +++ b/src/Avalonia.Base/Interactivity/Interactive.cs @@ -10,14 +10,14 @@ namespace Avalonia.Interactivity /// /// Base class for objects that raise routed events. /// - public class Interactive : Layoutable, IInteractive + public class Interactive : Layoutable { private Dictionary>? _eventHandlers; /// /// Gets the interactive parent of the object for bubbling and tunneling events. /// - IInteractive? IInteractive.InteractiveParent => ((IVisual)this).VisualParent as IInteractive; + protected internal virtual Interactive? InteractiveParent => VisualParent as Interactive; /// /// Adds a handler for the specified routed event. @@ -125,21 +125,6 @@ public void RaiseEvent(RoutedEventArgs e) route.RaiseEvent(this, e); } - void IInteractive.AddToEventRoute(RoutedEvent routedEvent, EventRoute route) - { - routedEvent = routedEvent ?? throw new ArgumentNullException(nameof(routedEvent)); - route = route ?? throw new ArgumentNullException(nameof(route)); - - if (_eventHandlers != null && - _eventHandlers.TryGetValue(routedEvent, out var subscriptions)) - { - foreach (var sub in subscriptions) - { - route.Add(this, sub.Handler, sub.Routes, sub.HandledEventsToo, sub.InvokeAdapter); - } - } - } - /// /// Builds an event route for a routed event. /// @@ -151,7 +136,7 @@ void IInteractive.AddToEventRoute(RoutedEvent routedEvent, EventRoute route) /// and should be avoided if there are no handlers for an event. In these cases you can call /// this method to build the event route and check the /// property to see if there are any handlers registered on the route. If there are, call - /// to raise the event. + /// to raise the event. /// protected EventRoute BuildEventRoute(RoutedEvent e) { @@ -163,7 +148,7 @@ protected EventRoute BuildEventRoute(RoutedEvent e) if (e.RoutingStrategies.HasAllFlags(RoutingStrategies.Bubble) || e.RoutingStrategies.HasAllFlags(RoutingStrategies.Tunnel)) { - IInteractive? element = this; + Interactive? element = this; while (element != null) { @@ -183,7 +168,7 @@ protected EventRoute BuildEventRoute(RoutedEvent e) result.AddClassHandler(this); } - ((IInteractive)this).AddToEventRoute(e, result); + AddToEventRoute(e, result); } return result; @@ -202,6 +187,21 @@ private void AddEventSubscription(RoutedEvent routedEvent, EventSubscription sub subscriptions.Add(subscription); } + private void AddToEventRoute(RoutedEvent routedEvent, EventRoute route) + { + routedEvent = routedEvent ?? throw new ArgumentNullException(nameof(routedEvent)); + route = route ?? throw new ArgumentNullException(nameof(route)); + + if (_eventHandlers != null && + _eventHandlers.TryGetValue(routedEvent, out var subscriptions)) + { + foreach (var sub in subscriptions) + { + route.Add(this, sub.Handler, sub.Routes, sub.HandledEventsToo, sub.InvokeAdapter); + } + } + } + private readonly struct EventSubscription { public EventSubscription( diff --git a/src/Avalonia.Base/Interactivity/InteractiveExtensions.cs b/src/Avalonia.Base/Interactivity/InteractiveExtensions.cs index ee6b623b5f6..b12cf64fdfe 100644 --- a/src/Avalonia.Base/Interactivity/InteractiveExtensions.cs +++ b/src/Avalonia.Base/Interactivity/InteractiveExtensions.cs @@ -5,7 +5,7 @@ namespace Avalonia.Interactivity { /// - /// Provides extension methods for the interface. + /// Provides extension methods for the interface. /// public static class InteractiveExtensions { @@ -19,7 +19,7 @@ public static class InteractiveExtensions /// The routing strategies to listen to. /// Whether handled events should also be listened for. /// A disposable that terminates the event subscription. - public static IDisposable AddDisposableHandler(this IInteractive o, RoutedEvent routedEvent, + public static IDisposable AddDisposableHandler(this Interactive o, RoutedEvent routedEvent, EventHandler handler, RoutingStrategies routes = RoutingStrategies.Direct | RoutingStrategies.Bubble, bool handledEventsToo = false) where TEventArgs : RoutedEventArgs @@ -31,6 +31,8 @@ public static IDisposable AddDisposableHandler(this IInteractive o, state => state.instance.RemoveHandler(state.routedEvent, state.handler)); } + public static Interactive? GetInteractiveParent(this Interactive o) => o.InteractiveParent; + /// /// Gets an observable for a . /// @@ -42,7 +44,7 @@ public static IDisposable AddDisposableHandler(this IInteractive o, /// An observable which fires each time the event is raised. /// public static IObservable GetObservable( - this IInteractive o, + this Interactive o, RoutedEvent routedEvent, RoutingStrategies routes = RoutingStrategies.Direct | RoutingStrategies.Bubble, bool handledEventsToo = false) diff --git a/src/Avalonia.Base/Interactivity/RoutedEvent.cs b/src/Avalonia.Base/Interactivity/RoutedEvent.cs index 37edb24cc1b..70468715381 100644 --- a/src/Avalonia.Base/Interactivity/RoutedEvent.cs +++ b/src/Avalonia.Base/Interactivity/RoutedEvent.cs @@ -116,7 +116,7 @@ public RoutedEvent(string name, RoutingStrategies routingStrategies, Type ownerT public IDisposable AddClassHandler( Action handler, RoutingStrategies routes = RoutingStrategies.Direct | RoutingStrategies.Bubble, - bool handledEventsToo = false) where TTarget : class, IInteractive + bool handledEventsToo = false) where TTarget : Interactive { void Adapter(object? sender, RoutedEventArgs e) { diff --git a/src/Avalonia.Base/Interactivity/RoutedEventArgs.cs b/src/Avalonia.Base/Interactivity/RoutedEventArgs.cs index 2b660e70809..17164bd3338 100644 --- a/src/Avalonia.Base/Interactivity/RoutedEventArgs.cs +++ b/src/Avalonia.Base/Interactivity/RoutedEventArgs.cs @@ -28,7 +28,7 @@ public RoutedEventArgs(RoutedEvent? routedEvent) /// /// The routed event associated with these event args. /// The source object that raised the routed event. - public RoutedEventArgs(RoutedEvent? routedEvent, IInteractive? source) + public RoutedEventArgs(RoutedEvent? routedEvent, object? source) { RoutedEvent = routedEvent; Source = source; @@ -55,6 +55,6 @@ public RoutedEventArgs(RoutedEvent? routedEvent, IInteractive? source) /// /// Gets or sets the source object that raised the routed event. /// - public IInteractive? Source { get; set; } + public object? Source { get; set; } } } diff --git a/src/Avalonia.Base/Layout/AttachedLayout.cs b/src/Avalonia.Base/Layout/AttachedLayout.cs index ece8bbe8052..950ea343191 100644 --- a/src/Avalonia.Base/Layout/AttachedLayout.cs +++ b/src/Avalonia.Base/Layout/AttachedLayout.cs @@ -43,7 +43,7 @@ public abstract class AttachedLayout : AvaloniaObject /// /// Initializes any per-container state the layout requires when it is attached to an - /// container. + /// container. /// /// /// The context object that facilitates communication between the layout and its host diff --git a/src/Avalonia.Base/Layout/ElementManager.cs b/src/Avalonia.Base/Layout/ElementManager.cs index 048e8eebee5..73d29510bdb 100644 --- a/src/Avalonia.Base/Layout/ElementManager.cs +++ b/src/Avalonia.Base/Layout/ElementManager.cs @@ -13,7 +13,7 @@ namespace Avalonia.Layout { internal class ElementManager { - private readonly List _realizedElements = new List(); + private readonly List _realizedElements = new List(); private readonly List _realizedElementLayoutBounds = new List(); private int _firstRealizedDataIndex; private VirtualizingLayoutContext? _context; @@ -69,9 +69,9 @@ public int GetRealizedElementCount() return IsVirtualizingContext ? _realizedElements.Count : _context!.ItemCount; } - public ILayoutable GetAt(int realizedIndex) + public Layoutable GetAt(int realizedIndex) { - ILayoutable? element; + Layoutable? element; if (IsVirtualizingContext) { @@ -99,7 +99,7 @@ public ILayoutable GetAt(int realizedIndex) return element; } - public void Add(ILayoutable element, int dataIndex) + public void Add(Layoutable element, int dataIndex) { if (_realizedElements.Count == 0) { @@ -110,7 +110,7 @@ public void Add(ILayoutable element, int dataIndex) _realizedElementLayoutBounds.Add(default); } - public void Insert(int realizedIndex, int dataIndex, ILayoutable? element) + public void Insert(int realizedIndex, int dataIndex, Layoutable? element) { if (realizedIndex == 0) { @@ -207,7 +207,7 @@ public bool IsDataIndexRealized(int index) public bool IsIndexValidInData(int currentIndex) => (uint)currentIndex < _context!.ItemCount; - public ILayoutable? GetRealizedElement(int dataIndex) + public Layoutable? GetRealizedElement(int dataIndex) { return IsVirtualizingContext ? GetAt(GetRealizedRangeIndexFromDataIndex(dataIndex)) : @@ -330,7 +330,7 @@ public void DataSourceChanged(object? source, NotifyCollectionChangedEventArgs a } } - public int GetElementDataIndex(ILayoutable suggestedAnchor) + public int GetElementDataIndex(Layoutable suggestedAnchor) { var it = _realizedElements.IndexOf(suggestedAnchor); return it != -1 ? GetDataIndexFromRealizedRangeIndex(it) : -1; diff --git a/src/Avalonia.Base/Layout/FlowLayoutAlgorithm.cs b/src/Avalonia.Base/Layout/FlowLayoutAlgorithm.cs index e6a95d1ffb5..c46c4ca98c5 100644 --- a/src/Avalonia.Base/Layout/FlowLayoutAlgorithm.cs +++ b/src/Avalonia.Base/Layout/FlowLayoutAlgorithm.cs @@ -144,7 +144,7 @@ public void OnItemsSourceChanged( } public Size MeasureElement( - ILayoutable element, + Layoutable element, int index, Size availableSize, VirtualizingLayoutContext context) @@ -512,9 +512,9 @@ private bool ShouldContinueFillingUpSpace( private Rect EstimateExtent(Size availableSize, string? layoutId) { - ILayoutable? firstRealizedElement = null; + Layoutable? firstRealizedElement = null; Rect firstBounds = new Rect(); - ILayoutable? lastRealizedElement = null; + Layoutable? lastRealizedElement = null; Rect lastBounds = new Rect(); int firstDataIndex = -1; int lastDataIndex = -1; @@ -727,7 +727,7 @@ private void SetLayoutOrigin() } } - public ILayoutable? GetElementIfRealized(int dataIndex) + public Layoutable? GetElementIfRealized(int dataIndex) { if (_elementManager.IsDataIndexRealized(dataIndex)) { @@ -737,7 +737,7 @@ private void SetLayoutOrigin() return null; } - public bool TryAddElement0(ILayoutable element) + public bool TryAddElement0(Layoutable element) { if (_elementManager.GetRealizedElementCount() == 0) { diff --git a/src/Avalonia.Base/Layout/IFlowLayoutAlgorithmDelegates.cs b/src/Avalonia.Base/Layout/IFlowLayoutAlgorithmDelegates.cs index e3eae0caf75..cb1601799ec 100644 --- a/src/Avalonia.Base/Layout/IFlowLayoutAlgorithmDelegates.cs +++ b/src/Avalonia.Base/Layout/IFlowLayoutAlgorithmDelegates.cs @@ -21,14 +21,14 @@ internal interface IFlowLayoutAlgorithmDelegates Rect Algorithm_GetExtent( Size availableSize, VirtualizingLayoutContext context, - ILayoutable? firstRealized, + Layoutable? firstRealized, int firstRealizedItemIndex, Rect firstRealizedLayoutBounds, - ILayoutable? lastRealized, + Layoutable? lastRealized, int lastRealizedItemIndex, Rect lastRealizedLayoutBounds); void Algorithm_OnElementMeasured( - ILayoutable element, + Layoutable element, int index, Size availableSize, Size measureSize, diff --git a/src/Avalonia.Base/Layout/ILayoutManager.cs b/src/Avalonia.Base/Layout/ILayoutManager.cs index 88d95c81fd1..38d46557e1c 100644 --- a/src/Avalonia.Base/Layout/ILayoutManager.cs +++ b/src/Avalonia.Base/Layout/ILayoutManager.cs @@ -18,13 +18,13 @@ public interface ILayoutManager : IDisposable /// Notifies the layout manager that a control requires a measure. /// /// The control. - void InvalidateMeasure(ILayoutable control); + void InvalidateMeasure(Layoutable control); /// /// Notifies the layout manager that a control requires an arrange. /// /// The control. - void InvalidateArrange(ILayoutable control); + void InvalidateArrange(Layoutable control); /// /// Executes a layout pass. @@ -48,12 +48,12 @@ public interface ILayoutManager : IDisposable /// Registers a control as wanting to receive effective viewport notifications. /// /// The control. - void RegisterEffectiveViewportListener(ILayoutable control); + void RegisterEffectiveViewportListener(Layoutable control); /// /// Registers a control as no longer wanting to receive effective viewport notifications. /// /// The control. - void UnregisterEffectiveViewportListener(ILayoutable control); + void UnregisterEffectiveViewportListener(Layoutable control); } } diff --git a/src/Avalonia.Base/Layout/ILayoutRoot.cs b/src/Avalonia.Base/Layout/ILayoutRoot.cs index df15fc1a1d8..c90ddb92197 100644 --- a/src/Avalonia.Base/Layout/ILayoutRoot.cs +++ b/src/Avalonia.Base/Layout/ILayoutRoot.cs @@ -6,7 +6,7 @@ namespace Avalonia.Layout /// Defines the root of a layoutable tree. /// [NotClientImplementable] - public interface ILayoutRoot : ILayoutable + public interface ILayoutRoot { /// /// The size available to lay out the controls. diff --git a/src/Avalonia.Base/Layout/ILayoutable.cs b/src/Avalonia.Base/Layout/ILayoutable.cs deleted file mode 100644 index d8b546b04ab..00000000000 --- a/src/Avalonia.Base/Layout/ILayoutable.cs +++ /dev/null @@ -1,122 +0,0 @@ -using Avalonia.Metadata; -using Avalonia.VisualTree; - -namespace Avalonia.Layout -{ - /// - /// Defines layout-related functionality for a control. - /// - [NotClientImplementable] - public interface ILayoutable : IVisual - { - /// - /// Gets the size that this element computed during the measure pass of the layout process. - /// - Size DesiredSize { get; } - - /// - /// Gets the width of the element. - /// - double Width { get; } - - /// - /// Gets the height of the element. - /// - double Height { get; } - - /// - /// Gets the minimum width of the element. - /// - double MinWidth { get; } - - /// - /// Gets the maximum width of the element. - /// - double MaxWidth { get; } - - /// - /// Gets the minimum height of the element. - /// - double MinHeight { get; } - - /// - /// Gets the maximum height of the element. - /// - double MaxHeight { get; } - - /// - /// Gets the margin around the element. - /// - Thickness Margin { get; } - - /// - /// Gets the element's preferred horizontal alignment in its parent. - /// - HorizontalAlignment HorizontalAlignment { get; } - - /// - /// Gets the element's preferred vertical alignment in its parent. - /// - VerticalAlignment VerticalAlignment { get; } - - /// - /// Gets a value indicating whether the control's layout measure is valid. - /// - bool IsMeasureValid { get; } - - /// - /// Gets a value indicating whether the control's layouts arrange is valid. - /// - bool IsArrangeValid { get; } - - /// - /// Gets the available size passed in the previous layout pass, if any. - /// - Size? PreviousMeasure { get; } - - /// - /// Gets the layout rect passed in the previous layout pass, if any. - /// - Rect? PreviousArrange { get; } - - /// - /// Creates the visual children of the control, if necessary - /// - void ApplyTemplate(); - - /// - /// Carries out a measure of the control. - /// - /// The available size for the control. - void Measure(Size availableSize); - - /// - /// Arranges the control and its children. - /// - /// The control's new bounds. - void Arrange(Rect rect); - - /// - /// Invalidates the measurement of the control and queues a new layout pass. - /// - void InvalidateMeasure(); - - /// - /// Invalidates the arrangement of the control and queues a new layout pass. - /// - void InvalidateArrange(); - - /// - /// Called when a child control's desired size changes. - /// - /// The child control. - void ChildDesiredSizeChanged(ILayoutable control); - - /// - /// Used by the to notify the control that its effective - /// viewport is changed. - /// - /// The viewport information. - void EffectiveViewportChanged(EffectiveViewportChangedEventArgs e); - } -} diff --git a/src/Avalonia.Base/Layout/LayoutContextAdapter.cs b/src/Avalonia.Base/Layout/LayoutContextAdapter.cs index 25132c28022..e347e2be8b2 100644 --- a/src/Avalonia.Base/Layout/LayoutContextAdapter.cs +++ b/src/Avalonia.Base/Layout/LayoutContextAdapter.cs @@ -38,8 +38,8 @@ protected override Point LayoutOriginCore protected override int ItemCountCore() => _nonVirtualizingContext.Children.Count; protected override object GetItemAtCore(int index) => _nonVirtualizingContext.Children[index]; - protected override ILayoutable GetOrCreateElementAtCore(int index, ElementRealizationOptions options) => + protected override Layoutable GetOrCreateElementAtCore(int index, ElementRealizationOptions options) => _nonVirtualizingContext.Children[index]; - protected override void RecycleElementCore(ILayoutable element) { } + protected override void RecycleElementCore(Layoutable element) { } } } diff --git a/src/Avalonia.Base/Layout/LayoutHelper.cs b/src/Avalonia.Base/Layout/LayoutHelper.cs index 0851dbaea92..c6cbda62557 100644 --- a/src/Avalonia.Base/Layout/LayoutHelper.cs +++ b/src/Avalonia.Base/Layout/LayoutHelper.cs @@ -16,15 +16,15 @@ public static class LayoutHelper public static double LayoutEpsilon { get; } = 0.00000153; /// - /// Calculates a control's size based on its , - /// , , - /// , and - /// . + /// Calculates a control's size based on its , + /// , , + /// , and + /// . /// /// The control. /// The space available for the control. /// The control's size. - public static Size ApplyLayoutConstraints(ILayoutable control, Size constraints) + public static Size ApplyLayoutConstraints(Layoutable control, Size constraints) { var minmax = new MinMax(control); @@ -33,7 +33,7 @@ public static Size ApplyLayoutConstraints(ILayoutable control, Size constraints) MathUtilities.Clamp(constraints.Height, minmax.MinHeight, minmax.MaxHeight)); } - public static Size MeasureChild(ILayoutable? control, Size availableSize, Thickness padding, + public static Size MeasureChild(Layoutable? control, Size availableSize, Thickness padding, Thickness borderThickness) { if (IsParentLayoutRounded(control, out double scale)) @@ -51,7 +51,7 @@ public static Size MeasureChild(ILayoutable? control, Size availableSize, Thickn return new Size().Inflate(padding + borderThickness); } - public static Size MeasureChild(ILayoutable? control, Size availableSize, Thickness padding) + public static Size MeasureChild(Layoutable? control, Size availableSize, Thickness padding) { if (IsParentLayoutRounded(control, out double scale)) { @@ -67,7 +67,7 @@ public static Size MeasureChild(ILayoutable? control, Size availableSize, Thickn return new Size(padding.Left + padding.Right, padding.Bottom + padding.Top); } - public static Size ArrangeChild(ILayoutable? child, Size availableSize, Thickness padding, Thickness borderThickness) + public static Size ArrangeChild(Layoutable? child, Size availableSize, Thickness padding, Thickness borderThickness) { if (IsParentLayoutRounded(child, out double scale)) { @@ -78,7 +78,7 @@ public static Size ArrangeChild(ILayoutable? child, Size availableSize, Thicknes return ArrangeChildInternal(child, availableSize, padding + borderThickness); } - public static Size ArrangeChild(ILayoutable? child, Size availableSize, Thickness padding) + public static Size ArrangeChild(Layoutable? child, Size availableSize, Thickness padding) { if(IsParentLayoutRounded(child, out double scale)) padding = RoundLayoutThickness(padding, scale, scale); @@ -86,18 +86,18 @@ public static Size ArrangeChild(ILayoutable? child, Size availableSize, Thicknes return ArrangeChildInternal(child, availableSize, padding); } - private static Size ArrangeChildInternal(ILayoutable? child, Size availableSize, Thickness padding) + private static Size ArrangeChildInternal(Layoutable? child, Size availableSize, Thickness padding) { child?.Arrange(new Rect(availableSize).Deflate(padding)); return availableSize; } - private static bool IsParentLayoutRounded(ILayoutable? child, out double scale) + private static bool IsParentLayoutRounded(Layoutable? child, out double scale) { - var layoutableParent = (ILayoutable?)child?.GetVisualParent(); + var layoutableParent = (child as Visual)?.GetVisualParent() as Layoutable; - if (layoutableParent == null || !((Layoutable)layoutableParent).UseLayoutRounding) + if (layoutableParent == null || !layoutableParent.UseLayoutRounding) { scale = 1.0; return false; @@ -110,11 +110,11 @@ private static bool IsParentLayoutRounded(ILayoutable? child, out double scale) /// /// Invalidates measure for given control and all visual children recursively. /// - public static void InvalidateSelfAndChildrenMeasure(ILayoutable control) + public static void InvalidateSelfAndChildrenMeasure(Layoutable control) { - void InnerInvalidateMeasure(IVisual target) + void InnerInvalidateMeasure(Visual target) { - if (target is ILayoutable targetLayoutable) + if (target is Layoutable targetLayoutable) { targetLayoutable.InvalidateMeasure(); } @@ -124,13 +124,14 @@ void InnerInvalidateMeasure(IVisual target) for (int i = 0; i < visualChildrenCount; i++) { - IVisual child = visualChildren[i]; + Visual child = visualChildren[i]; InnerInvalidateMeasure(child); } } - InnerInvalidateMeasure(control); + if (control is Visual v) + InnerInvalidateMeasure(v); } /// @@ -138,9 +139,9 @@ void InnerInvalidateMeasure(IVisual target) /// /// The control. /// Thrown when control has no root or returned layout scaling is invalid. - public static double GetLayoutScale(ILayoutable control) + public static double GetLayoutScale(Layoutable control) { - var visualRoot = control.VisualRoot; + var visualRoot = (control as Visual)?.VisualRoot; var result = (visualRoot as ILayoutRoot)?.LayoutScaling ?? 1.0; @@ -289,7 +290,7 @@ public static double RoundLayoutValueUp(double value, double dpiScale) /// private readonly struct MinMax { - public MinMax(ILayoutable e) + public MinMax(Layoutable e) { MaxHeight = e.MaxHeight; MinHeight = e.MinHeight; diff --git a/src/Avalonia.Base/Layout/LayoutManager.cs b/src/Avalonia.Base/Layout/LayoutManager.cs index 826947c39af..242d70821a0 100644 --- a/src/Avalonia.Base/Layout/LayoutManager.cs +++ b/src/Avalonia.Base/Layout/LayoutManager.cs @@ -16,9 +16,9 @@ namespace Avalonia.Layout public class LayoutManager : ILayoutManager, IDisposable { private const int MaxPasses = 3; - private readonly ILayoutRoot _owner; - private readonly LayoutQueue _toMeasure = new LayoutQueue(v => !v.IsMeasureValid); - private readonly LayoutQueue _toArrange = new LayoutQueue(v => !v.IsArrangeValid); + private readonly Layoutable _owner; + private readonly LayoutQueue _toMeasure = new LayoutQueue(v => !v.IsMeasureValid); + private readonly LayoutQueue _toArrange = new LayoutQueue(v => !v.IsArrangeValid); private readonly Action _executeLayoutPass; private List? _effectiveViewportChangedListeners; private bool _disposed; @@ -27,14 +27,14 @@ public class LayoutManager : ILayoutManager, IDisposable public LayoutManager(ILayoutRoot owner) { - _owner = owner ?? throw new ArgumentNullException(nameof(owner)); + _owner = owner as Layoutable ?? throw new ArgumentNullException(nameof(owner)); _executeLayoutPass = ExecuteQueuedLayoutPass; } public virtual event EventHandler? LayoutUpdated; /// - public virtual void InvalidateMeasure(ILayoutable control) + public virtual void InvalidateMeasure(Layoutable control) { control = control ?? throw new ArgumentNullException(nameof(control)); Dispatcher.UIThread.VerifyAccess(); @@ -65,7 +65,7 @@ public virtual void InvalidateMeasure(ILayoutable control) } /// - public virtual void InvalidateArrange(ILayoutable control) + public virtual void InvalidateArrange(Layoutable control) { control = control ?? throw new ArgumentNullException(nameof(control)); Dispatcher.UIThread.VerifyAccess(); @@ -203,7 +203,7 @@ public void Dispose() _toArrange.Dispose(); } - void ILayoutManager.RegisterEffectiveViewportListener(ILayoutable control) + void ILayoutManager.RegisterEffectiveViewportListener(Layoutable control) { _effectiveViewportChangedListeners ??= new List(); _effectiveViewportChangedListeners.Add(new EffectiveViewportChangedListener( @@ -211,7 +211,7 @@ void ILayoutManager.RegisterEffectiveViewportListener(ILayoutable control) CalculateEffectiveViewport(control))); } - void ILayoutManager.UnregisterEffectiveViewportListener(ILayoutable control) + void ILayoutManager.UnregisterEffectiveViewportListener(Layoutable control) { if (_effectiveViewportChangedListeners is object) { @@ -265,13 +265,13 @@ private void ExecuteArrangePass() } } - private void Measure(ILayoutable control) + private void Measure(Layoutable control) { // Controls closest to the visual root need to be arranged first. We don't try to store // ordered invalidation lists, instead we traverse the tree upwards, measuring the // controls closest to the root first. This has been shown by benchmarks to be the // fastest and most memory-efficient algorithm. - if (control.VisualParent is ILayoutable parent) + if (control.VisualParent is Layoutable parent) { Measure(parent); } @@ -283,7 +283,7 @@ private void Measure(ILayoutable control) { if (control is ILayoutRoot root) { - root.Measure(Size.Infinity); + control.Measure(Size.Infinity); } else if (control.PreviousMeasure.HasValue) { @@ -292,9 +292,9 @@ private void Measure(ILayoutable control) } } - private void Arrange(ILayoutable control) + private void Arrange(Layoutable control) { - if (control.VisualParent is ILayoutable parent) + if (control.VisualParent is Layoutable parent) { Arrange(parent); } @@ -304,7 +304,7 @@ private void Arrange(ILayoutable control) if (control is IEmbeddedLayoutRoot embeddedRoot) control.Arrange(new Rect(embeddedRoot.AllocatedSize)); else if (control is ILayoutRoot root) - control.Arrange(new Rect(root.DesiredSize)); + control.Arrange(new Rect(control.DesiredSize)); else if (control.PreviousArrange != null) { // Has been observed that PreviousArrange sometimes is null, probably a bug somewhere else. @@ -350,7 +350,7 @@ private bool RaiseEffectiveViewportChanged() if (viewport != l.Viewport) { - l.Listener.EffectiveViewportChanged(new EffectiveViewportChangedEventArgs(viewport)); + l.Listener.RaiseEffectiveViewportChanged(new EffectiveViewportChangedEventArgs(viewport)); l.Viewport = viewport; } } @@ -364,14 +364,14 @@ private bool RaiseEffectiveViewportChanged() return startCount != _toMeasure.Count + _toArrange.Count; } - private Rect CalculateEffectiveViewport(IVisual control) + private Rect CalculateEffectiveViewport(Visual control) { var viewport = new Rect(0, 0, double.PositiveInfinity, double.PositiveInfinity); CalculateEffectiveViewport(control, control, ref viewport); return viewport; } - private void CalculateEffectiveViewport(IVisual target, IVisual control, ref Rect viewport) + private void CalculateEffectiveViewport(Visual target, Visual control, ref Rect viewport) { // Recurse until the top level control. if (control.VisualParent is object) @@ -405,13 +405,13 @@ private void CalculateEffectiveViewport(IVisual target, IVisual control, ref Rec private class EffectiveViewportChangedListener { - public EffectiveViewportChangedListener(ILayoutable listener, Rect viewport) + public EffectiveViewportChangedListener(Layoutable listener, Rect viewport) { Listener = listener; Viewport = viewport; } - public ILayoutable Listener { get; } + public Layoutable Listener { get; } public Rect Viewport { get; set; } } } diff --git a/src/Avalonia.Base/Layout/Layoutable.cs b/src/Avalonia.Base/Layout/Layoutable.cs index 39edab3fc69..d1851488945 100644 --- a/src/Avalonia.Base/Layout/Layoutable.cs +++ b/src/Avalonia.Base/Layout/Layoutable.cs @@ -62,7 +62,7 @@ public enum VerticalAlignment /// /// Implements layout-related functionality for a control. /// - public class Layoutable : Visual, ILayoutable + public class Layoutable : Visual { /// /// Defines the property. @@ -323,15 +323,12 @@ public bool UseLayoutRounding set { SetValue(UseLayoutRoundingProperty, value); } } - /// - /// Gets the available size passed in the previous layout pass, if any. - /// - Size? ILayoutable.PreviousMeasure => _previousMeasure; + internal Size? PreviousMeasure => _previousMeasure; /// /// Gets the layout rect passed in the previous layout pass, if any. /// - Rect? ILayoutable.PreviousArrange => _previousArrange; + internal Rect? PreviousArrange => _previousArrange; /// /// Creates the visual children of the control, if necessary @@ -380,7 +377,7 @@ public void Measure(Size availableSize) if (DesiredSize != previousDesiredSize) { - this.GetVisualParent()?.ChildDesiredSizeChanged(this); + this.GetVisualParent()?.ChildDesiredSizeChanged(this); } } } @@ -423,7 +420,7 @@ public void InvalidateMeasure() IsMeasureValid = false; IsArrangeValid = false; - if (((ILayoutable)this).IsAttachedToVisualTree) + if (IsAttachedToVisualTree) { (VisualRoot as ILayoutRoot)?.LayoutManager.InvalidateMeasure(this); InvalidateVisual(); @@ -448,7 +445,7 @@ public void InvalidateArrange() } /// - void ILayoutable.ChildDesiredSizeChanged(ILayoutable control) + internal void ChildDesiredSizeChanged(Layoutable control) { if (!_measuring) { @@ -456,11 +453,11 @@ void ILayoutable.ChildDesiredSizeChanged(ILayoutable control) } } - void ILayoutable.EffectiveViewportChanged(EffectiveViewportChangedEventArgs e) + internal void RaiseEffectiveViewportChanged(EffectiveViewportChangedEventArgs e) { _effectiveViewportChanged?.Invoke(this, e); } - + /// /// Marks a property as affecting the control's measurement. /// @@ -471,7 +468,7 @@ void ILayoutable.EffectiveViewportChanged(EffectiveViewportChangedEventArgs e) /// property will cause to be called on the element. /// protected static void AffectsMeasure(params AvaloniaProperty[] properties) - where T : class, ILayoutable + where T : Layoutable { void Invalidate(AvaloniaPropertyChangedEventArgs e) { @@ -494,7 +491,7 @@ void Invalidate(AvaloniaPropertyChangedEventArgs e) /// property will cause to be called on the element. /// protected static void AffectsArrange(params AvaloniaProperty[] properties) - where T : class, ILayoutable + where T : Layoutable { void Invalidate(AvaloniaPropertyChangedEventArgs e) { @@ -596,9 +593,9 @@ protected virtual Size MeasureOverride(Size availableSize) for (var i = 0; i < visualCount; i++) { - IVisual visual = visualChildren[i]; + Visual visual = visualChildren[i]; - if (visual is ILayoutable layoutable) + if (visual is Layoutable layoutable) { layoutable.Measure(availableSize); width = Math.Max(width, layoutable.DesiredSize.Width); @@ -709,9 +706,9 @@ protected virtual Size ArrangeOverride(Size finalSize) for (var i = 0; i < visualCount; i++) { - IVisual visual = visualChildren[i]; + Visual visual = visualChildren[i]; - if (visual is ILayoutable layoutable) + if (visual is Layoutable layoutable) { layoutable.Arrange(arrangeRect); } @@ -778,7 +775,7 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang DesiredSize = default; // All changes to visibility cause the parent element to be notified. - this.GetVisualParent()?.ChildDesiredSizeChanged(this); + this.GetVisualParent()?.ChildDesiredSizeChanged(this); // We only invalidate outselves when visibility is changed to true. if (change.GetNewValue()) @@ -789,7 +786,7 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang } /// - protected sealed override void OnVisualParentChanged(IVisual? oldParent, IVisual? newParent) + protected sealed override void OnVisualParentChanged(Visual? oldParent, Visual? newParent) { LayoutHelper.InvalidateSelfAndChildrenMeasure(this); diff --git a/src/Avalonia.Base/Layout/NonVirtualizingLayoutContext.cs b/src/Avalonia.Base/Layout/NonVirtualizingLayoutContext.cs index 91348f5e6d0..78ce5c480ed 100644 --- a/src/Avalonia.Base/Layout/NonVirtualizingLayoutContext.cs +++ b/src/Avalonia.Base/Layout/NonVirtualizingLayoutContext.cs @@ -17,13 +17,13 @@ public abstract class NonVirtualizingLayoutContext : LayoutContext /// /// Gets the collection of child controls from the container that provides the context. /// - public IReadOnlyList Children => ChildrenCore; + public IReadOnlyList Children => ChildrenCore; /// /// Implements the behavior for getting the return value of in a /// derived or custom . /// - protected abstract IReadOnlyList ChildrenCore { get; } + protected abstract IReadOnlyList ChildrenCore { get; } internal VirtualizingLayoutContext GetVirtualizingContextAdapter() => _contextAdapter ??= new LayoutContextAdapter(this); diff --git a/src/Avalonia.Base/Layout/NonVirtualizingStackLayout.cs b/src/Avalonia.Base/Layout/NonVirtualizingStackLayout.cs index 6fa86019162..72ff1780ab7 100644 --- a/src/Avalonia.Base/Layout/NonVirtualizingStackLayout.cs +++ b/src/Avalonia.Base/Layout/NonVirtualizingStackLayout.cs @@ -59,7 +59,7 @@ protected internal override Size MeasureOverride( { var element = context.Children[i]; - if (!element.IsVisible) + if ((element as Visual)?.IsVisible == false) { continue; } @@ -100,7 +100,7 @@ protected internal override Size ArrangeOverride( { var element = context.Children[i]; - if (!element.IsVisible) + if ((element as Visual)?.IsVisible == false) { continue; } @@ -117,7 +117,7 @@ protected internal override Size ArrangeOverride( Math.Max(finalSize.Height, bounds.Height)); } - private static Rect LayoutVertical(ILayoutable element, double y, Size constraint) + private static Rect LayoutVertical(Layoutable element, double y, Size constraint) { var x = 0.0; var width = element.DesiredSize.Width; @@ -138,7 +138,7 @@ private static Rect LayoutVertical(ILayoutable element, double y, Size constrain return new Rect(x, y, width, element.DesiredSize.Height); } - private static Rect LayoutHorizontal(ILayoutable element, double x, Size constraint) + private static Rect LayoutHorizontal(Layoutable element, double x, Size constraint) { var y = 0.0; var height = element.DesiredSize.Height; diff --git a/src/Avalonia.Base/Layout/StackLayout.cs b/src/Avalonia.Base/Layout/StackLayout.cs index e3c2ab3817a..5c1797a7a41 100644 --- a/src/Avalonia.Base/Layout/StackLayout.cs +++ b/src/Avalonia.Base/Layout/StackLayout.cs @@ -78,10 +78,10 @@ public double Spacing internal Rect GetExtent( Size availableSize, VirtualizingLayoutContext context, - ILayoutable? firstRealized, + Layoutable? firstRealized, int firstRealizedItemIndex, Rect firstRealizedLayoutBounds, - ILayoutable? lastRealized, + Layoutable? lastRealized, int lastRealizedItemIndex, Rect lastRealizedLayoutBounds) { @@ -121,7 +121,7 @@ internal Rect GetExtent( } internal void OnElementMeasured( - ILayoutable element, + Layoutable element, int index, Size availableSize, Size measureSize, @@ -188,10 +188,10 @@ FlowLayoutAnchorInfo IFlowLayoutAlgorithmDelegates.Algorithm_GetAnchorForTargetE Rect IFlowLayoutAlgorithmDelegates.Algorithm_GetExtent( Size availableSize, VirtualizingLayoutContext context, - ILayoutable? firstRealized, + Layoutable? firstRealized, int firstRealizedItemIndex, Rect firstRealizedLayoutBounds, - ILayoutable? lastRealized, + Layoutable? lastRealized, int lastRealizedItemIndex, Rect lastRealizedLayoutBounds) { @@ -206,7 +206,7 @@ Rect IFlowLayoutAlgorithmDelegates.Algorithm_GetExtent( lastRealizedLayoutBounds); } - void IFlowLayoutAlgorithmDelegates.Algorithm_OnElementMeasured(ILayoutable element, int index, Size availableSize, Size measureSize, Size desiredSize, Size provisionalArrangeSize, VirtualizingLayoutContext context) + void IFlowLayoutAlgorithmDelegates.Algorithm_OnElementMeasured(Layoutable element, int index, Size availableSize, Size measureSize, Size desiredSize, Size provisionalArrangeSize, VirtualizingLayoutContext context) { OnElementMeasured( element, diff --git a/src/Avalonia.Base/Layout/UniformGridLayout.cs b/src/Avalonia.Base/Layout/UniformGridLayout.cs index a7880a1545e..225a491b60c 100644 --- a/src/Avalonia.Base/Layout/UniformGridLayout.cs +++ b/src/Avalonia.Base/Layout/UniformGridLayout.cs @@ -338,10 +338,10 @@ FlowLayoutAnchorInfo IFlowLayoutAlgorithmDelegates.Algorithm_GetAnchorForTargetE Rect IFlowLayoutAlgorithmDelegates.Algorithm_GetExtent( Size availableSize, VirtualizingLayoutContext context, - ILayoutable? firstRealized, + Layoutable? firstRealized, int firstRealizedItemIndex, Rect firstRealizedLayoutBounds, - ILayoutable? lastRealized, + Layoutable? lastRealized, int lastRealizedItemIndex, Rect lastRealizedLayoutBounds) { @@ -391,7 +391,7 @@ Rect IFlowLayoutAlgorithmDelegates.Algorithm_GetExtent( return extent; } - void IFlowLayoutAlgorithmDelegates.Algorithm_OnElementMeasured(ILayoutable element, int index, Size availableSize, Size measureSize, Size desiredSize, Size provisionalArrangeSize, VirtualizingLayoutContext context) + void IFlowLayoutAlgorithmDelegates.Algorithm_OnElementMeasured(Layoutable element, int index, Size availableSize, Size measureSize, Size desiredSize, Size provisionalArrangeSize, VirtualizingLayoutContext context) { } diff --git a/src/Avalonia.Base/Layout/UniformGridLayoutState.cs b/src/Avalonia.Base/Layout/UniformGridLayoutState.cs index 65cdf4c94ba..fe2fe474daf 100644 --- a/src/Avalonia.Base/Layout/UniformGridLayoutState.cs +++ b/src/Avalonia.Base/Layout/UniformGridLayoutState.cs @@ -18,7 +18,7 @@ public class UniformGridLayoutState // If it does not, then we need to do context.GetElement(0) at which point we have requested an element and are on point to clear it. // If we are responsible for clearing element 0 we keep m_cachedFirstElement valid. // If we are not (because FlowLayoutAlgorithm is holding it for us) then we just null out this field and use the one from FlowLayoutAlgorithm. - private ILayoutable? _cachedFirstElement; + private Layoutable? _cachedFirstElement; internal FlowLayoutAlgorithm FlowAlgorithm { get; } = new FlowLayoutAlgorithm(); internal double EffectiveItemWidth { get; private set; } @@ -91,7 +91,7 @@ internal void EnsureElementSize( } private void SetSize( - ILayoutable element, + Layoutable element, double layoutItemWidth, double layoutItemHeight, Size availableSize, diff --git a/src/Avalonia.Base/Layout/VirtualLayoutContextAdapter.cs b/src/Avalonia.Base/Layout/VirtualLayoutContextAdapter.cs index f0681875238..cc8cca54980 100644 --- a/src/Avalonia.Base/Layout/VirtualLayoutContextAdapter.cs +++ b/src/Avalonia.Base/Layout/VirtualLayoutContextAdapter.cs @@ -19,18 +19,18 @@ protected override object? LayoutStateCore set => _virtualizingContext.LayoutState = value; } - protected override IReadOnlyList ChildrenCore => + protected override IReadOnlyList ChildrenCore => _children ?? (_children = new ChildrenCollection(_virtualizingContext)); - private class ChildrenCollection : IReadOnlyList + private class ChildrenCollection : IReadOnlyList { private readonly VirtualizingLayoutContext _context; public ChildrenCollection(VirtualizingLayoutContext context) => _context = context; - public ILayoutable this[int index] => _context.GetOrCreateElementAt(index); + public Layoutable this[int index] => _context.GetOrCreateElementAt(index); public int Count => _context.ItemCount; IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() + public IEnumerator GetEnumerator() { for (var i = 0; i < Count; ++i) { diff --git a/src/Avalonia.Base/Layout/VirtualizingLayoutContext.cs b/src/Avalonia.Base/Layout/VirtualizingLayoutContext.cs index f48c9b0ef22..7fbef19d163 100644 --- a/src/Avalonia.Base/Layout/VirtualizingLayoutContext.cs +++ b/src/Avalonia.Base/Layout/VirtualizingLayoutContext.cs @@ -116,7 +116,7 @@ public abstract class VirtualizingLayoutContext : LayoutContext /// This method calls /// with options set to None. GetElementAtCore must be implemented in a derived class. /// - public ILayoutable GetOrCreateElementAt(int index) + public Layoutable GetOrCreateElementAt(int index) => GetOrCreateElementAtCore(index, ElementRealizationOptions.None); /// @@ -140,7 +140,7 @@ public ILayoutable GetOrCreateElementAt(int index) /// advanced layouts that choose to explicitly manage the realization and recycling of /// elements as a performance optimization. /// - public ILayoutable GetOrCreateElementAt(int index, ElementRealizationOptions options) + public Layoutable GetOrCreateElementAt(int index, ElementRealizationOptions options) => GetOrCreateElementAtCore(index, options); /// @@ -148,10 +148,10 @@ public ILayoutable GetOrCreateElementAt(int index, ElementRealizationOptions opt /// /// The element to clear. /// - /// This method calls , which must be implemented + /// This method calls , which must be implemented /// in a derived class. /// - public void RecycleElement(ILayoutable element) => RecycleElementCore(element); + public void RecycleElement(Layoutable element) => RecycleElementCore(element); /// /// When implemented in a derived class, retrieves the number of items in the data. @@ -180,14 +180,14 @@ public ILayoutable GetOrCreateElementAt(int index, ElementRealizationOptions opt /// A value of that specifies whether to suppress /// automatic recycling of the retrieved element or force creation of a new element. /// - protected abstract ILayoutable GetOrCreateElementAtCore(int index, ElementRealizationOptions options); + protected abstract Layoutable GetOrCreateElementAtCore(int index, ElementRealizationOptions options); /// /// When implemented in a derived class, clears the specified UIElement and allows it to be /// either re-used or released. /// /// The element to clear. - protected abstract void RecycleElementCore(ILayoutable element); + protected abstract void RecycleElementCore(Layoutable element); internal NonVirtualizingLayoutContext GetNonVirtualizingContextAdapter() => _contextAdapter ?? (_contextAdapter = new VirtualLayoutContextAdapter(this)); diff --git a/src/Avalonia.Base/Layout/WrapLayout/WrapItem.cs b/src/Avalonia.Base/Layout/WrapLayout/WrapItem.cs index e823ade6d42..7a44f034f5b 100644 --- a/src/Avalonia.Base/Layout/WrapLayout/WrapItem.cs +++ b/src/Avalonia.Base/Layout/WrapLayout/WrapItem.cs @@ -20,6 +20,6 @@ public WrapItem(int index) public UvMeasure? Position { get; internal set; } - public ILayoutable? Element { get; internal set; } + public Layoutable? Element { get; internal set; } } } diff --git a/src/Avalonia.Base/Media/IVisualBrush.cs b/src/Avalonia.Base/Media/IVisualBrush.cs index b8900bbd737..6662613ff4b 100644 --- a/src/Avalonia.Base/Media/IVisualBrush.cs +++ b/src/Avalonia.Base/Media/IVisualBrush.cs @@ -4,7 +4,7 @@ namespace Avalonia.Media { /// - /// Paints an area with an . + /// Paints an area with an . /// [NotClientImplementable] public interface IVisualBrush : ITileBrush @@ -12,6 +12,6 @@ public interface IVisualBrush : ITileBrush /// /// Gets the visual to draw. /// - IVisual Visual { get; } + Visual Visual { get; } } } diff --git a/src/Avalonia.Base/Media/Imaging/RenderTargetBitmap.cs b/src/Avalonia.Base/Media/Imaging/RenderTargetBitmap.cs index 94a5abd9180..c4508c3f5cb 100644 --- a/src/Avalonia.Base/Media/Imaging/RenderTargetBitmap.cs +++ b/src/Avalonia.Base/Media/Imaging/RenderTargetBitmap.cs @@ -44,7 +44,7 @@ private RenderTargetBitmap(IRef impl) : base(impl) /// Renders a visual to the . /// /// The visual to render. - public void Render(IVisual visual) => ImmediateRenderer.Render(visual, this); + public void Render(Visual visual) => ImmediateRenderer.Render(visual, this); /// /// Creates a platform-specific implementation for a . diff --git a/src/Avalonia.Base/Media/Immutable/ImmutableVisualBrush.cs b/src/Avalonia.Base/Media/Immutable/ImmutableVisualBrush.cs index b436dcdb5e5..1e0133c9b74 100644 --- a/src/Avalonia.Base/Media/Immutable/ImmutableVisualBrush.cs +++ b/src/Avalonia.Base/Media/Immutable/ImmutableVisualBrush.cs @@ -25,7 +25,7 @@ internal class ImmutableVisualBrush : ImmutableTileBrush, IVisualBrush /// The tile mode. /// Controls the quality of interpolation. public ImmutableVisualBrush( - IVisual visual, + Visual visual, AlignmentX alignmentX = AlignmentX.Center, AlignmentY alignmentY = AlignmentY.Center, RelativeRect? destinationRect = null, @@ -62,6 +62,6 @@ public ImmutableVisualBrush(IVisualBrush source) } /// - public IVisual Visual { get; } + public Visual Visual { get; } } } diff --git a/src/Avalonia.Base/Media/VisualBrush.cs b/src/Avalonia.Base/Media/VisualBrush.cs index c665507652b..8dce79cf115 100644 --- a/src/Avalonia.Base/Media/VisualBrush.cs +++ b/src/Avalonia.Base/Media/VisualBrush.cs @@ -4,15 +4,15 @@ namespace Avalonia.Media { /// - /// Paints an area with an . + /// Paints an area with an . /// public class VisualBrush : TileBrush, IVisualBrush { /// /// Defines the property. /// - public static readonly StyledProperty VisualProperty = - AvaloniaProperty.Register(nameof(Visual)); + public static readonly StyledProperty VisualProperty = + AvaloniaProperty.Register(nameof(Visual)); static VisualBrush() { @@ -30,7 +30,7 @@ public VisualBrush() /// Initializes a new instance of the class. /// /// The visual to draw. - public VisualBrush(IVisual visual) + public VisualBrush(Visual visual) { Visual = visual; } @@ -38,7 +38,7 @@ public VisualBrush(IVisual visual) /// /// Gets or sets the visual to draw. /// - public IVisual Visual + public Visual Visual { get { return GetValue(VisualProperty); } set { SetValue(VisualProperty, value); } diff --git a/src/Avalonia.Base/PropertyStore/EffectiveValue`1.cs b/src/Avalonia.Base/PropertyStore/EffectiveValue`1.cs index 1d8f6b8408b..93fffb37555 100644 --- a/src/Avalonia.Base/PropertyStore/EffectiveValue`1.cs +++ b/src/Avalonia.Base/PropertyStore/EffectiveValue`1.cs @@ -262,7 +262,7 @@ private void SetAndRaiseCore( private class UncommonFields { - public Func? _coerce; + public Func? _coerce; public T? _uncoercedValue; public T? _uncoercedBaseValue; } diff --git a/src/Avalonia.Base/PropertyStore/UntypedValueUtils.cs b/src/Avalonia.Base/PropertyStore/UntypedValueUtils.cs index acaecc0d522..a75ff27164c 100644 --- a/src/Avalonia.Base/PropertyStore/UntypedValueUtils.cs +++ b/src/Avalonia.Base/PropertyStore/UntypedValueUtils.cs @@ -23,18 +23,6 @@ public static BindingValue ConvertAndValidate( return v; } - public static bool TryConvertAndValidate( - AvaloniaProperty property, - object? value, - out object? result) - { - if (TypeUtilities.TryConvertImplicit(property.PropertyType, value, out result)) - return ((IStyledPropertyAccessor)property).ValidateValue(result); - - result = default; - return false; - } - public static bool TryConvertAndValidate( StyledPropertyBase property, object? value, diff --git a/src/Avalonia.Base/Reactive/AvaloniaPropertyBindingObservable.cs b/src/Avalonia.Base/Reactive/AvaloniaPropertyBindingObservable.cs index 9f038214c4e..0789684efff 100644 --- a/src/Avalonia.Base/Reactive/AvaloniaPropertyBindingObservable.cs +++ b/src/Avalonia.Base/Reactive/AvaloniaPropertyBindingObservable.cs @@ -6,15 +6,15 @@ namespace Avalonia.Reactive { internal class AvaloniaPropertyBindingObservable : LightweightObservableBase>, IDescription { - private readonly WeakReference _target; + private readonly WeakReference _target; private readonly AvaloniaProperty _property; private BindingValue _value = BindingValue.Unset; public AvaloniaPropertyBindingObservable( - IAvaloniaObject target, + AvaloniaObject target, AvaloniaProperty property) { - _target = new WeakReference(target); + _target = new WeakReference(target); _property = property; } diff --git a/src/Avalonia.Base/Reactive/AvaloniaPropertyChangedObservable.cs b/src/Avalonia.Base/Reactive/AvaloniaPropertyChangedObservable.cs index dc29ddbdff2..fa876a89068 100644 --- a/src/Avalonia.Base/Reactive/AvaloniaPropertyChangedObservable.cs +++ b/src/Avalonia.Base/Reactive/AvaloniaPropertyChangedObservable.cs @@ -6,14 +6,14 @@ internal class AvaloniaPropertyChangedObservable : LightweightObservableBase, IDescription { - private readonly WeakReference _target; + private readonly WeakReference _target; private readonly AvaloniaProperty _property; public AvaloniaPropertyChangedObservable( - IAvaloniaObject target, + AvaloniaObject target, AvaloniaProperty property) { - _target = new WeakReference(target); + _target = new WeakReference(target); _property = property; } diff --git a/src/Avalonia.Base/Reactive/AvaloniaPropertyObservable.cs b/src/Avalonia.Base/Reactive/AvaloniaPropertyObservable.cs index cafce58c9ce..a4fa587a50e 100644 --- a/src/Avalonia.Base/Reactive/AvaloniaPropertyObservable.cs +++ b/src/Avalonia.Base/Reactive/AvaloniaPropertyObservable.cs @@ -6,15 +6,15 @@ namespace Avalonia.Reactive { internal class AvaloniaPropertyObservable : LightweightObservableBase, IDescription { - private readonly WeakReference _target; + private readonly WeakReference _target; private readonly AvaloniaProperty _property; private Optional _value; public AvaloniaPropertyObservable( - IAvaloniaObject target, + AvaloniaObject target, AvaloniaProperty property) { - _target = new WeakReference(target); + _target = new WeakReference(target); _property = property; } @@ -49,31 +49,23 @@ private void PropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e) { if (e.Property == _property) { - if (e.Sender is AvaloniaObject ao) - { - T newValue; - - if (e is AvaloniaPropertyChangedEventArgs typed) - { - newValue = AvaloniaObjectExtensions.GetValue(ao, typed.Property); - } - else - { - newValue = (T)e.Sender.GetValue(e.Property)!; - } + T newValue; - if (!_value.HasValue || - !EqualityComparer.Default.Equals(newValue, _value.Value)) - { - _value = newValue; - PublishNext(_value.Value!); - } + if (e is AvaloniaPropertyChangedEventArgs typed) + { + newValue = AvaloniaObjectExtensions.GetValue(e.Sender, typed.Property); } else { - throw new NotSupportedException("Custom implementations of IAvaloniaObject not supported."); + newValue = (T)e.Sender.GetValue(e.Property)!; } + if (!_value.HasValue || + !EqualityComparer.Default.Equals(newValue, _value.Value)) + { + _value = newValue; + PublishNext(_value.Value!); + } } } } diff --git a/src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs b/src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs index 38d9b34937b..6130f369837 100644 --- a/src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs +++ b/src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs @@ -45,7 +45,7 @@ public CompositingRenderer(IRenderRoot root, _compositor = compositor; _recordingContext = new DrawingContext(_recorder); CompositionTarget = compositor.CreateCompositionTarget(root.CreateRenderTarget); - CompositionTarget.Root = ((Visual)root!.VisualRoot!).AttachToCompositor(compositor); + CompositionTarget.Root = ((Visual)root).AttachToCompositor(compositor); _update = Update; } @@ -75,7 +75,7 @@ void QueueUpdate() } /// - public void AddDirty(IVisual visual) + public void AddDirty(Visual visual) { if (_updating) throw new InvalidOperationException("Visual was invalidated during the render pass"); @@ -84,7 +84,7 @@ public void AddDirty(IVisual visual) } /// - public IEnumerable HitTest(Point p, IVisual root, Func? filter) + public IEnumerable HitTest(Point p, Visual root, Func? filter) { Func? f = null; if (filter != null) @@ -109,14 +109,14 @@ public IEnumerable HitTest(Point p, IVisual root, Func? } /// - public IVisual? HitTestFirst(Point p, IVisual root, Func? filter) + public Visual? HitTestFirst(Point p, Visual root, Func? filter) { // TODO: Optimize return HitTest(p, root, filter).FirstOrDefault(); } /// - public void RecalculateChildren(IVisual visual) + public void RecalculateChildren(Visual visual) { if (_updating) throw new InvalidOperationException("Visual was invalidated during the render pass"); @@ -130,9 +130,9 @@ private void SyncChildren(Visual v) if(v.CompositionVisual == null) return; var compositionChildren = v.CompositionVisual.Children; - var visualChildren = (AvaloniaList)v.GetVisualChildren(); + var visualChildren = (AvaloniaList)v.GetVisualChildren(); - PooledList<(IVisual visual, int index)>? sortedChildren = null; + PooledList<(Visual visual, int index)>? sortedChildren = null; if (v.HasNonUniformZIndexChildren && visualChildren.Count > 1) { sortedChildren = new (visualChildren.Count); diff --git a/src/Avalonia.Base/Rendering/DeferredRenderer.cs b/src/Avalonia.Base/Rendering/DeferredRenderer.cs index 4236763e3b6..971702269c2 100644 --- a/src/Avalonia.Base/Rendering/DeferredRenderer.cs +++ b/src/Avalonia.Base/Rendering/DeferredRenderer.cs @@ -22,14 +22,14 @@ public class DeferredRenderer : RendererBase, IRenderer, IRenderLoopTask, IVisua { private readonly IDispatcher? _dispatcher; private readonly IRenderLoop? _renderLoop; - private readonly IVisual _root; + private readonly Visual _root; private readonly ISceneBuilder _sceneBuilder; private bool _running; private bool _disposed; private volatile IRef? _scene; private DirtyVisuals? _dirty; - private HashSet? _recalculateChildren; + private HashSet? _recalculateChildren; private IRef? _overlay; private int _lastSceneId = -1; private DisplayDirtyRects _dirtyRectsDisplay = new DisplayDirtyRects(); @@ -56,7 +56,7 @@ public DeferredRenderer( IDeferredRendererLock? rendererLock = null) : base(true) { _dispatcher = dispatcher ?? Dispatcher.UIThread; - _root = root ?? throw new ArgumentNullException(nameof(root)); + _root = root as Visual ?? throw new ArgumentNullException(nameof(root)); _sceneBuilder = sceneBuilder ?? new SceneBuilder(); Layers = new RenderLayers(); _renderLoop = renderLoop; @@ -74,7 +74,7 @@ public DeferredRenderer( /// This constructor is intended to be used for unit testing. /// public DeferredRenderer( - IVisual root, + Visual root, IRenderTarget renderTarget, ISceneBuilder? sceneBuilder = null) : base(true) { @@ -116,7 +116,7 @@ public DeferredRenderer( internal IRenderTarget? RenderTarget { get; private set; } /// - public void AddDirty(IVisual visual) + public void AddDirty(Visual visual) { _dirty?.Add(visual); } @@ -142,7 +142,7 @@ public void Dispose() DisposeRenderTarget(); } - public void RecalculateChildren(IVisual visual) => _recalculateChildren?.Add(visual); + public void RecalculateChildren(Visual visual) => _recalculateChildren?.Add(visual); void DisposeRenderTarget() { @@ -163,17 +163,17 @@ void DisposeRenderTarget() } /// - public IEnumerable HitTest(Point p, IVisual root, Func? filter) + public IEnumerable HitTest(Point p, Visual root, Func? filter) { EnsureCanHitTest(); //It's safe to access _scene here without a lock since //it's only changed from UI thread which we are currently on - return _scene?.Item.HitTest(p, root, filter) ?? Enumerable.Empty(); + return _scene?.Item.HitTest(p, root, filter) ?? Enumerable.Empty(); } /// - public IVisual? HitTestFirst(Point p, IVisual root, Func? filter) + public Visual? HitTestFirst(Point p, Visual root, Func? filter) { EnsureCanHitTest(); @@ -414,7 +414,7 @@ internal void Render(bool forceComposite) } - private void Render(IDrawingContextImpl context, VisualNode node, IVisual? layer, Rect clipBounds) + private void Render(IDrawingContextImpl context, VisualNode node, Visual? layer, Rect clipBounds) { if (layer == null || node.LayerRoot == layer) { @@ -643,7 +643,7 @@ private void UpdateSceneIfNeeded() if (_dirty == null) { _dirty = new DirtyVisuals(); - _recalculateChildren = new HashSet(); + _recalculateChildren = new HashSet(); _sceneBuilder.UpdateAll(scene); } else diff --git a/src/Avalonia.Base/Rendering/DirtyVisuals.cs b/src/Avalonia.Base/Rendering/DirtyVisuals.cs index 999b12e810c..dfadbdf6147 100644 --- a/src/Avalonia.Base/Rendering/DirtyVisuals.cs +++ b/src/Avalonia.Base/Rendering/DirtyVisuals.cs @@ -13,10 +13,10 @@ namespace Avalonia.Rendering /// visual. TODO: We probably want to put an upper limit on the number of visuals that can be /// stored and if we reach that limit, assume all visuals are dirty. /// - internal class DirtyVisuals : IEnumerable + internal class DirtyVisuals : IEnumerable { - private SortedDictionary> _inner = new SortedDictionary>(); - private Dictionary _index = new Dictionary(); + private SortedDictionary> _inner = new SortedDictionary>(); + private Dictionary _index = new Dictionary(); private int _enumerating; /// @@ -28,14 +28,14 @@ internal class DirtyVisuals : IEnumerable /// Adds a visual to the dirty list. /// /// The dirty visual. - public void Add(IVisual visual) + public void Add(Visual visual) { if (_enumerating > 0) { throw new InvalidOperationException("Visual was invalidated during a render pass"); } - var distance = visual.CalculateDistanceFromAncestor(visual.VisualRoot); + var distance = visual.CalculateDistanceFromAncestor((Visual?)visual.GetVisualRoot()); if (_index.TryGetValue(visual, out var existingDistance)) { @@ -50,7 +50,7 @@ public void Add(IVisual visual) if (!_inner.TryGetValue(distance, out var list)) { - list = new List(); + list = new List(); _inner.Add(distance, list); } @@ -76,7 +76,7 @@ public void Clear() /// Gets the dirty visuals, in ascending order of distance to their root. /// /// A collection of visuals. - public IEnumerator GetEnumerator() + public IEnumerator GetEnumerator() { _enumerating++; try diff --git a/src/Avalonia.Base/Rendering/ICustomSimpleHitTest.cs b/src/Avalonia.Base/Rendering/ICustomSimpleHitTest.cs index 354a344ffe1..fae595413fd 100644 --- a/src/Avalonia.Base/Rendering/ICustomSimpleHitTest.cs +++ b/src/Avalonia.Base/Rendering/ICustomSimpleHitTest.cs @@ -24,10 +24,10 @@ public interface ICustomHitTest : ICustomSimpleHitTest public static class CustomSimpleHitTestExtensions { - public static bool HitTestCustom(this IVisual visual, Point point) + public static bool HitTestCustom(this Visual visual, Point point) => (visual as ICustomSimpleHitTest)?.HitTest(point) ?? visual.TransformedBounds?.Contains(point) == true; - public static bool HitTestCustom(this IEnumerable children, Point point) + public static bool HitTestCustom(this IEnumerable children, Point point) => children.Any(ctrl => ctrl.HitTestCustom(point)); } } diff --git a/src/Avalonia.Base/Rendering/IRenderRoot.cs b/src/Avalonia.Base/Rendering/IRenderRoot.cs index 1aa44158b26..aa06ce7bedd 100644 --- a/src/Avalonia.Base/Rendering/IRenderRoot.cs +++ b/src/Avalonia.Base/Rendering/IRenderRoot.cs @@ -8,7 +8,7 @@ namespace Avalonia.Rendering /// Represents the root of a renderable tree. /// [NotClientImplementable] - public interface IRenderRoot : IVisual + public interface IRenderRoot { /// /// Gets the client size of the window. diff --git a/src/Avalonia.Base/Rendering/IRenderer.cs b/src/Avalonia.Base/Rendering/IRenderer.cs index 8d6aabf440e..cb36aad7cc7 100644 --- a/src/Avalonia.Base/Rendering/IRenderer.cs +++ b/src/Avalonia.Base/Rendering/IRenderer.cs @@ -34,7 +34,7 @@ public interface IRenderer : IDisposable /// Mark a visual as dirty and needing re-rendering. /// /// The visual. - void AddDirty(IVisual visual); + void AddDirty(Visual visual); /// /// Hit tests a location to find the visuals at the specified point. @@ -46,7 +46,7 @@ public interface IRenderer : IDisposable /// children will be excluded from the results. /// /// The visuals at the specified point, topmost first. - IEnumerable HitTest(Point p, IVisual root, Func filter); + IEnumerable HitTest(Point p, Visual root, Func filter); /// /// Hit tests a location to find first visual at the specified point. @@ -58,13 +58,13 @@ public interface IRenderer : IDisposable /// children will be excluded from the results. /// /// The visual at the specified point, topmost first. - IVisual? HitTestFirst(Point p, IVisual root, Func filter); + Visual? HitTestFirst(Point p, Visual root, Func filter); /// /// Informs the renderer that the z-ordering of a visual's children has changed. /// /// The visual. - void RecalculateChildren(IVisual visual); + void RecalculateChildren(Visual visual); /// /// Called when a resize notification is received by the control being rendered. diff --git a/src/Avalonia.Base/Rendering/ImmediateRenderer.cs b/src/Avalonia.Base/Rendering/ImmediateRenderer.cs index 79ef52586d8..9e1582ed431 100644 --- a/src/Avalonia.Base/Rendering/ImmediateRenderer.cs +++ b/src/Avalonia.Base/Rendering/ImmediateRenderer.cs @@ -18,7 +18,7 @@ namespace Avalonia.Rendering /// public class ImmediateRenderer : RendererBase, IRenderer, IVisualBrushRenderer { - private readonly IVisual _root; + private readonly Visual _root; private readonly IRenderRoot? _renderRoot; private bool _updateTransformedBounds = true; private IRenderTarget? _renderTarget; @@ -27,13 +27,13 @@ public class ImmediateRenderer : RendererBase, IRenderer, IVisualBrushRenderer /// Initializes a new instance of the class. /// /// The control to render. - public ImmediateRenderer(IVisual root) + public ImmediateRenderer(Visual root) { _root = root ?? throw new ArgumentNullException(nameof(root)); _renderRoot = root as IRenderRoot; } - private ImmediateRenderer(IVisual root, bool updateTransformedBounds) + private ImmediateRenderer(Visual root, bool updateTransformedBounds) { _root = root ?? throw new ArgumentNullException(nameof(root)); _renderRoot = root as IRenderRoot; @@ -102,7 +102,7 @@ public void Resized(Size size) /// /// The visual. /// The render target. - public static void Render(IVisual visual, IRenderTarget target) + public static void Render(Visual visual, IRenderTarget target) { using (var renderer = new ImmediateRenderer(visual, updateTransformedBounds: false)) using (var context = new DrawingContext(target.CreateDrawingContext(renderer))) @@ -116,7 +116,7 @@ public static void Render(IVisual visual, IRenderTarget target) /// /// The visual. /// The drawing context. - public static void Render(IVisual visual, DrawingContext context) + public static void Render(Visual visual, DrawingContext context) { using (var renderer = new ImmediateRenderer(visual, updateTransformedBounds: false)) { @@ -125,7 +125,7 @@ public static void Render(IVisual visual, DrawingContext context) } /// - public void AddDirty(IVisual visual) + public void AddDirty(Visual visual) { if (visual.Bounds != Rect.Empty) { @@ -162,18 +162,18 @@ public void Dispose() } /// - public IEnumerable HitTest(Point p, IVisual root, Func filter) + public IEnumerable HitTest(Point p, Visual root, Func filter) { return HitTest(root, p, filter); } - public IVisual? HitTestFirst(Point p, IVisual root, Func filter) + public Visual? HitTestFirst(Point p, Visual root, Func filter) { return HitTest(root, p, filter).FirstOrDefault(); } /// - public void RecalculateChildren(IVisual visual) => AddDirty(visual); + public void RecalculateChildren(Visual visual) => AddDirty(visual); /// public void Start() @@ -199,21 +199,21 @@ void IVisualBrushRenderer.RenderVisualBrush(IDrawingContextImpl context, IVisual Render(new DrawingContext(context), visual, visual.Bounds); } - internal static void Render(IVisual visual, DrawingContext context, bool updateTransformedBounds) + internal static void Render(Visual visual, DrawingContext context, bool updateTransformedBounds) { using var renderer = new ImmediateRenderer(visual, updateTransformedBounds); renderer.Render(context, visual, visual.Bounds); } - private static void ClearTransformedBounds(IVisual visual) + private static void ClearTransformedBounds(Visual visual) { foreach (var e in visual.GetSelfAndVisualDescendants()) { - visual.TransformedBounds = null; + visual.SetTransformedBounds(null); } } - private static Rect GetTransformedBounds(IVisual visual) + private static Rect GetTransformedBounds(Visual visual) { if (visual.RenderTransform == null) { @@ -228,10 +228,10 @@ private static Rect GetTransformedBounds(IVisual visual) } } - private static IEnumerable HitTest( - IVisual visual, + private static IEnumerable HitTest( + Visual visual, Point p, - Func? filter) + Func? filter) { _ = visual ?? throw new ArgumentNullException(nameof(visual)); @@ -266,7 +266,7 @@ private static IEnumerable HitTest( } } - private void Render(DrawingContext context, IVisual visual, Rect clipRect) + private void Render(DrawingContext context, Visual visual, Rect clipRect) { var opacity = visual.Opacity; var clipToBounds = visual.ClipToBounds; @@ -329,11 +329,11 @@ private void Render(DrawingContext context, IVisual visual, Rect clipRect) #pragma warning restore 0618 if (_updateTransformedBounds) - visual.TransformedBounds = transformed; + visual.SetTransformedBounds(transformed); var childrenEnumerable = visual.HasNonUniformZIndexChildren ? visual.VisualChildren.OrderBy(x => x, ZIndexComparer.Instance) - : (IEnumerable)visual.VisualChildren; + : (IEnumerable)visual.VisualChildren; foreach (var child in childrenEnumerable) { diff --git a/src/Avalonia.Base/Rendering/RenderLayer.cs b/src/Avalonia.Base/Rendering/RenderLayer.cs index 768e832fe51..d1e3fcafb10 100644 --- a/src/Avalonia.Base/Rendering/RenderLayer.cs +++ b/src/Avalonia.Base/Rendering/RenderLayer.cs @@ -11,7 +11,7 @@ public RenderLayer( IDrawingContextImpl drawingContext, Size size, double scaling, - IVisual layerRoot) + Visual layerRoot) { Bitmap = RefCountable.Create(drawingContext.CreateLayer(size)); Size = size; @@ -24,7 +24,7 @@ public RenderLayer( public bool IsEmpty { get; set; } public double Scaling { get; private set; } public Size Size { get; private set; } - public IVisual LayerRoot { get; } + public Visual LayerRoot { get; } public void RecreateBitmap(IDrawingContextImpl drawingContext, Size size, double scaling) { diff --git a/src/Avalonia.Base/Rendering/RenderLayers.cs b/src/Avalonia.Base/Rendering/RenderLayers.cs index 75838868355..eff81e6bbf2 100644 --- a/src/Avalonia.Base/Rendering/RenderLayers.cs +++ b/src/Avalonia.Base/Rendering/RenderLayers.cs @@ -3,17 +3,16 @@ using System.Diagnostics.CodeAnalysis; using Avalonia.Platform; using Avalonia.Rendering.SceneGraph; -using Avalonia.VisualTree; namespace Avalonia.Rendering { public class RenderLayers : IEnumerable { private readonly List _inner = new List(); - private readonly Dictionary _index = new Dictionary(); + private readonly Dictionary _index = new Dictionary(); public int Count => _inner.Count; - public RenderLayer this[IVisual layerRoot] => _index[layerRoot]; + public RenderLayer this[Visual layerRoot] => _index[layerRoot]; public void Update(Scene scene, IDrawingContextImpl context) { @@ -59,7 +58,7 @@ public void Clear() _inner.Clear(); } - public bool TryGetValue(IVisual layerRoot, [NotNullWhen(true)] out RenderLayer? value) + public bool TryGetValue(Visual layerRoot, [NotNullWhen(true)] out RenderLayer? value) { return _index.TryGetValue(layerRoot, out value); } diff --git a/src/Avalonia.Base/Rendering/SceneGraph/ISceneBuilder.cs b/src/Avalonia.Base/Rendering/SceneGraph/ISceneBuilder.cs index dd993fbb8c2..f469fdbfe8b 100644 --- a/src/Avalonia.Base/Rendering/SceneGraph/ISceneBuilder.cs +++ b/src/Avalonia.Base/Rendering/SceneGraph/ISceneBuilder.cs @@ -19,6 +19,6 @@ public interface ISceneBuilder /// The scene. /// The visual to update. /// True if changes were made, otherwise false. - bool Update(Scene scene, IVisual visual); + bool Update(Scene scene, Visual visual); } -} \ No newline at end of file +} diff --git a/src/Avalonia.Base/Rendering/SceneGraph/IVisualNode.cs b/src/Avalonia.Base/Rendering/SceneGraph/IVisualNode.cs index e0422363464..59a032748d1 100644 --- a/src/Avalonia.Base/Rendering/SceneGraph/IVisualNode.cs +++ b/src/Avalonia.Base/Rendering/SceneGraph/IVisualNode.cs @@ -2,19 +2,18 @@ using System.Collections.Generic; using Avalonia.Platform; using Avalonia.Utilities; -using Avalonia.VisualTree; namespace Avalonia.Rendering.SceneGraph { /// - /// Represents a node in the low-level scene graph representing an . + /// Represents a node in the low-level scene graph representing a . /// public interface IVisualNode : IDisposable { /// /// Gets the visual to which the node relates. /// - IVisual Visual { get; } + Visual Visual { get; } /// /// Gets the parent scene graph node. diff --git a/src/Avalonia.Base/Rendering/SceneGraph/Scene.cs b/src/Avalonia.Base/Rendering/SceneGraph/Scene.cs index c4362990189..2da8923497b 100644 --- a/src/Avalonia.Base/Rendering/SceneGraph/Scene.cs +++ b/src/Avalonia.Base/Rendering/SceneGraph/Scene.cs @@ -13,24 +13,24 @@ namespace Avalonia.Rendering.SceneGraph /// public class Scene : IDisposable { - private readonly Dictionary _index; + private readonly Dictionary _index; private readonly TaskCompletionSource _rendered = new TaskCompletionSource(); /// /// Initializes a new instance of the class. /// /// The root visual to draw. - public Scene(IVisual rootVisual) + public Scene(Visual rootVisual) : this( new VisualNode(rootVisual, null), - new Dictionary(), + new Dictionary(), new SceneLayers(rootVisual), 0) { _index.Add(rootVisual, Root); } - private Scene(VisualNode root, Dictionary index, SceneLayers layers, int generation) + private Scene(VisualNode root, Dictionary index, SceneLayers layers, int generation) { _ = root ?? throw new ArgumentNullException(nameof(root)); @@ -87,7 +87,7 @@ public void Add(IVisualNode node) /// The cloned scene. public Scene CloneScene() { - var index = new Dictionary(_index.Count); + var index = new Dictionary(_index.Count); var root = Clone((VisualNode)Root, null, index); var result = new Scene(root, index, Layers.Clone(), Generation + 1) @@ -115,7 +115,7 @@ public void Dispose() /// /// The node representing the visual or null if it could not be found. /// - public IVisualNode? FindNode(IVisual visual) + public IVisualNode? FindNode(Visual visual) { _index.TryGetValue(visual, out var node); return node; @@ -128,10 +128,10 @@ public void Dispose() /// The root of the subtree to search. /// A filter. May be null. /// The visuals at the specified point. - public IEnumerable HitTest(Point p, IVisual root, Func? filter) + public IEnumerable HitTest(Point p, Visual root, Func? filter) { var node = FindNode(root); - return (node != null) ? new HitTestEnumerable(node, filter, p, Root) : Enumerable.Empty(); + return (node != null) ? new HitTestEnumerable(node, filter, p, Root) : Enumerable.Empty(); } /// @@ -141,7 +141,7 @@ public IEnumerable HitTest(Point p, IVisual root, Func? /// The root of the subtree to search. /// A filter. May be null. /// The visual at the specified point. - public IVisual? HitTestFirst(Point p, IVisual root, Func? filter) + public Visual? HitTestFirst(Point p, Visual root, Func? filter) { var node = FindNode(root); return (node != null) ? HitTestFirst(node, p, filter) : null; @@ -160,7 +160,7 @@ public void Remove(IVisualNode node) node.Dispose(); } - private VisualNode Clone(VisualNode source, IVisualNode? parent, Dictionary index) + private VisualNode Clone(VisualNode source, IVisualNode? parent, Dictionary index) { var result = source.Clone(parent); @@ -184,7 +184,7 @@ private VisualNode Clone(VisualNode source, IVisualNode? parent, Dictionary? filter) + private Visual HitTestFirst(IVisualNode root, Point p, Func? filter) { using var enumerator = new HitTestEnumerator(root, filter, p, Root); @@ -193,14 +193,14 @@ private IVisual HitTestFirst(IVisualNode root, Point p, Func? fil return enumerator.Current; } - private class HitTestEnumerable : IEnumerable + private class HitTestEnumerable : IEnumerable { private readonly IVisualNode _root; - private readonly Func? _filter; + private readonly Func? _filter; private readonly IVisualNode _sceneRoot; private readonly Point _point; - public HitTestEnumerable(IVisualNode root, Func? filter, Point point, IVisualNode sceneRoot) + public HitTestEnumerable(IVisualNode root, Func? filter, Point point, IVisualNode sceneRoot) { _root = root; _filter = filter; @@ -208,7 +208,7 @@ public HitTestEnumerable(IVisualNode root, Func? filter, Point po _sceneRoot = sceneRoot; } - public IEnumerator GetEnumerator() + public IEnumerator GetEnumerator() { return new HitTestEnumerator(_root, _filter, _point, _sceneRoot); } @@ -219,15 +219,15 @@ IEnumerator IEnumerable.GetEnumerator() } } - private struct HitTestEnumerator : IEnumerator + private struct HitTestEnumerator : IEnumerator { private readonly PooledStack _nodeStack; - private readonly Func? _filter; + private readonly Func? _filter; private readonly IVisualNode _sceneRoot; - private IVisual? _current; + private Visual? _current; private readonly Point _point; - public HitTestEnumerator(IVisualNode root, Func? filter, Point point, IVisualNode sceneRoot) + public HitTestEnumerator(IVisualNode root, Func? filter, Point point, IVisualNode sceneRoot) { _nodeStack = new PooledStack(); _nodeStack.Push(new Entry(root, false, null, true)); @@ -282,7 +282,7 @@ public void Reset() throw new NotSupportedException(); } - public IVisual Current => _current!; + public Visual Current => _current!; object IEnumerator.Current => Current; diff --git a/src/Avalonia.Base/Rendering/SceneGraph/SceneBuilder.cs b/src/Avalonia.Base/Rendering/SceneGraph/SceneBuilder.cs index 0ceb44ed757..86b42c0c4b0 100644 --- a/src/Avalonia.Base/Rendering/SceneGraph/SceneBuilder.cs +++ b/src/Avalonia.Base/Rendering/SceneGraph/SceneBuilder.cs @@ -30,7 +30,7 @@ public void UpdateAll(Scene scene) } /// - public bool Update(Scene scene, IVisual visual) + public bool Update(Scene scene, Visual visual) { _ = scene ?? throw new ArgumentNullException(nameof(scene)); _ = visual ?? throw new ArgumentNullException(nameof(visual)); @@ -120,7 +120,7 @@ public bool Update(Scene scene, IVisual visual) return false; } - private static VisualNode? FindExistingAncestor(Scene scene, IVisual visual) + private static VisualNode? FindExistingAncestor(Scene scene, Visual visual) { var node = scene.FindNode(visual); @@ -151,7 +151,7 @@ private static VisualNode FindFirstDeadAncestor(Scene scene, IVisualNode node) return (VisualNode)node; } - private static object GetOrCreateChildNode(Scene scene, IVisual child, VisualNode parent) + private static object GetOrCreateChildNode(Scene scene, Visual child, VisualNode parent) { var result = (VisualNode?)scene.FindNode(child); @@ -259,11 +259,11 @@ private static void Update(DrawingContext context, Scene scene, VisualNode node, catch { } var transformed = new TransformedBounds(new Rect(visual.Bounds.Size), clip, node.Transform); - visual.TransformedBounds = transformed; + visual.SetTransformedBounds(transformed); if (forceRecurse) { - var visualChildren = (IList) visual.VisualChildren; + var visualChildren = (IList) visual.VisualChildren; node.TryPreallocateChildren(visualChildren.Count); @@ -278,7 +278,7 @@ private static void Update(DrawingContext context, Scene scene, VisualNode node, if (visual.HasNonUniformZIndexChildren) { - var sortedChildren = new (IVisual visual, int index)[count]; + var sortedChildren = new (Visual visual, int index)[count]; for (var i = 0; i < count; i++) { @@ -352,7 +352,7 @@ private void UpdateSize(Scene scene) } } - private static VisualNode CreateNode(Scene scene, IVisual visual, VisualNode parent) + private static VisualNode CreateNode(Scene scene, Visual visual, VisualNode parent) { var node = new VisualNode(visual, parent); node.LayerRoot = parent.LayerRoot; @@ -379,7 +379,7 @@ private static void Deindex(Scene scene, VisualNode node) scene.Layers[node.LayerRoot!].Dirty.Add(node.Bounds); - node.Visual.TransformedBounds = null; + node.Visual.SetTransformedBounds(null); if (node.LayerRoot == node.Visual && node.Visual != scene.Root.Visual) { @@ -455,7 +455,7 @@ private static void PropagateLayer(VisualNode node, SceneLayer layer, SceneLayer } // HACK: Disabled layers because they're broken in current renderer. See #2244. - private static bool ShouldStartLayer(IVisual visual) => false; + private static bool ShouldStartLayer(Visual visual) => false; private static IGeometryImpl? CreateLayerGeometryClip(VisualNode node) { diff --git a/src/Avalonia.Base/Rendering/SceneGraph/SceneLayer.cs b/src/Avalonia.Base/Rendering/SceneGraph/SceneLayer.cs index e9474f6e987..a5e3b88188a 100644 --- a/src/Avalonia.Base/Rendering/SceneGraph/SceneLayer.cs +++ b/src/Avalonia.Base/Rendering/SceneGraph/SceneLayer.cs @@ -1,6 +1,5 @@ using Avalonia.Media; using Avalonia.Platform; -using Avalonia.VisualTree; namespace Avalonia.Rendering.SceneGraph { @@ -14,7 +13,7 @@ public class SceneLayer /// /// The visual at the root of the layer. /// The distance from the scene root. - public SceneLayer(IVisual layerRoot, int distanceFromRoot) + public SceneLayer(Visual layerRoot, int distanceFromRoot) { LayerRoot = layerRoot; Dirty = new DirtyRects(); @@ -39,7 +38,7 @@ public SceneLayer Clone() /// /// Gets the visual at the root of the layer. /// - public IVisual LayerRoot { get; } + public Visual LayerRoot { get; } /// /// Gets the distance of the layer root from the root of the scene. diff --git a/src/Avalonia.Base/Rendering/SceneGraph/SceneLayers.cs b/src/Avalonia.Base/Rendering/SceneGraph/SceneLayers.cs index 16d704e5f67..8a997c5ace7 100644 --- a/src/Avalonia.Base/Rendering/SceneGraph/SceneLayers.cs +++ b/src/Avalonia.Base/Rendering/SceneGraph/SceneLayers.cs @@ -10,15 +10,15 @@ namespace Avalonia.Rendering.SceneGraph /// public class SceneLayers : IEnumerable { - private readonly IVisual _root; + private readonly Visual _root; private readonly List _inner; - private readonly Dictionary _index; + private readonly Dictionary _index; /// /// Initializes a new instance of the class. /// /// The scene's root visual. - public SceneLayers(IVisual root) : this(root, 0) + public SceneLayers(Visual root) : this(root, 0) { } @@ -27,12 +27,12 @@ public SceneLayers(IVisual root) : this(root, 0) /// /// The scene's root visual. /// Initial layer capacity. - public SceneLayers(IVisual root, int capacity) + public SceneLayers(Visual root, int capacity) { _root = root; _inner = new List(capacity); - _index = new Dictionary(capacity); + _index = new Dictionary(capacity); } /// @@ -71,14 +71,14 @@ public bool HasDirty /// /// The layer's root visual. /// The layer. - public SceneLayer this[IVisual visual] => _index[visual]; + public SceneLayer this[Visual visual] => _index[visual]; /// /// Adds a layer to the scene. /// /// The root visual of the layer. /// The created layer. - public SceneLayer Add(IVisual layerRoot) + public SceneLayer Add(Visual layerRoot) { _ = layerRoot ?? throw new ArgumentNullException(nameof(layerRoot)); @@ -115,7 +115,7 @@ public SceneLayers Clone() /// /// True if a layer exists with the specified root visual, otherwise false. /// - public bool Exists(IVisual layerRoot) + public bool Exists(Visual layerRoot) { _ = layerRoot ?? throw new ArgumentNullException(nameof(layerRoot)); @@ -127,7 +127,7 @@ public bool Exists(IVisual layerRoot) /// /// The root visual. /// The layer if found, otherwise null. - public SceneLayer? Find(IVisual layerRoot) + public SceneLayer? Find(Visual layerRoot) { _index.TryGetValue(layerRoot, out var result); return result; @@ -138,7 +138,7 @@ public bool Exists(IVisual layerRoot) /// /// The root visual. /// The layer. - public SceneLayer GetOrAdd(IVisual layerRoot) + public SceneLayer GetOrAdd(Visual layerRoot) { _ = layerRoot ?? throw new ArgumentNullException(nameof(layerRoot)); @@ -155,7 +155,7 @@ public SceneLayer GetOrAdd(IVisual layerRoot) /// /// The root visual. /// True if a matching layer was removed, otherwise false. - public bool Remove(IVisual layerRoot) + public bool Remove(Visual layerRoot) { _ = layerRoot ?? throw new ArgumentNullException(nameof(layerRoot)); diff --git a/src/Avalonia.Base/Rendering/SceneGraph/VisualNode.cs b/src/Avalonia.Base/Rendering/SceneGraph/VisualNode.cs index 8a2f1f5073f..4eec214f4f6 100644 --- a/src/Avalonia.Base/Rendering/SceneGraph/VisualNode.cs +++ b/src/Avalonia.Base/Rendering/SceneGraph/VisualNode.cs @@ -30,7 +30,7 @@ internal class VisualNode : IVisualNode /// /// The visual that this node represents. /// The parent scene graph node, if any. - public VisualNode(IVisual visual, IVisualNode? parent) + public VisualNode(Visual visual, IVisualNode? parent) { Visual = visual ?? throw new ArgumentNullException(nameof(visual)); Parent = parent; @@ -39,7 +39,7 @@ public VisualNode(IVisual visual, IVisualNode? parent) } /// - public IVisual Visual { get; } + public Visual Visual { get; } /// public IVisualNode? Parent { get; } @@ -98,7 +98,7 @@ public double Opacity /// public bool OpacityChanged { get; private set; } - public IVisual? LayerRoot { get; set; } + public Visual? LayerRoot { get; set; } /// public IReadOnlyList Children => _children ?? EmptyChildren; diff --git a/src/Avalonia.Base/Rendering/ZIndexComparer.cs b/src/Avalonia.Base/Rendering/ZIndexComparer.cs index 4566b905c48..c9240668b49 100644 --- a/src/Avalonia.Base/Rendering/ZIndexComparer.cs +++ b/src/Avalonia.Base/Rendering/ZIndexComparer.cs @@ -4,11 +4,11 @@ namespace Avalonia.Rendering { - public class ZIndexComparer : IComparer + public class ZIndexComparer : IComparer { public static readonly ZIndexComparer Instance = new ZIndexComparer(); - public static readonly Comparison ComparisonInstance = Instance.Compare; + public static readonly Comparison ComparisonInstance = Instance.Compare; - public int Compare(IVisual? x, IVisual? y) => (x?.ZIndex ?? 0).CompareTo(y?.ZIndex ?? 0); + public int Compare(Visual? x, Visual? y) => (x?.ZIndex ?? 0).CompareTo(y?.ZIndex ?? 0); } } diff --git a/src/Avalonia.Base/StyledElement.cs b/src/Avalonia.Base/StyledElement.cs index 187edd83351..6fa2027e1eb 100644 --- a/src/Avalonia.Base/StyledElement.cs +++ b/src/Avalonia.Base/StyledElement.cs @@ -25,7 +25,15 @@ namespace Avalonia /// - Implements to form part of a logical tree. /// - A collection of class strings for custom styling. /// - public class StyledElement : Animatable, IDataContextProvider, IStyledElement, ISetLogicalParent, ISetInheritanceParent + public class StyledElement : Animatable, + IDataContextProvider, + ILogical, + IResourceHost, + IStyleHost, + IStyleable, + ISetLogicalParent, + ISetInheritanceParent, + ISupportInitialize { /// /// Defines the property. @@ -45,14 +53,14 @@ public class StyledElement : Animatable, IDataContextProvider, IStyledElement, I /// /// Defines the property. /// - public static readonly DirectProperty ParentProperty = - AvaloniaProperty.RegisterDirect(nameof(Parent), o => o.Parent); + public static readonly DirectProperty ParentProperty = + AvaloniaProperty.RegisterDirect(nameof(Parent), o => o.Parent); /// /// Defines the property. /// - public static readonly DirectProperty TemplatedParentProperty = - AvaloniaProperty.RegisterDirect( + public static readonly DirectProperty TemplatedParentProperty = + AvaloniaProperty.RegisterDirect( nameof(TemplatedParent), o => o.TemplatedParent, (o ,v) => o.TemplatedParent = v); @@ -73,7 +81,7 @@ public class StyledElement : Animatable, IDataContextProvider, IStyledElement, I private Styles? _styles; private bool _stylesApplied; private bool _themeApplied; - private ITemplatedControl? _templatedParent; + private AvaloniaObject? _templatedParent; private bool _dataContextUpdating; private ControlTheme? _implicitTheme; @@ -233,7 +241,7 @@ public IResourceDictionary Resources /// /// Gets the styled element whose lookless template this styled element is part of. /// - public ITemplatedControl? TemplatedParent + public AvaloniaObject? TemplatedParent { get => _templatedParent; internal set => SetAndRaise(TemplatedParentProperty, ref _templatedParent, value); @@ -251,7 +259,7 @@ public ControlTheme? Theme /// /// Gets the styled element's logical children. /// - protected IAvaloniaList LogicalChildren + protected internal IAvaloniaList LogicalChildren { get { @@ -284,7 +292,7 @@ protected IAvaloniaList LogicalChildren /// /// Gets the styled element's logical parent. /// - public IStyledElement? Parent { get; private set; } + public StyledElement? Parent { get; private set; } /// /// Gets the styled element's logical parent. @@ -451,7 +459,7 @@ void ISetLogicalParent.SetParent(ILogical? parent) InheritanceParent = parent as AvaloniaObject; } - Parent = (IStyledElement?)parent; + Parent = (StyledElement?)parent; if (_logicalRoot != null) { @@ -482,8 +490,8 @@ void ISetLogicalParent.SetParent(ILogical? parent) #nullable disable RaisePropertyChanged( ParentProperty, - new Optional(old), - new BindingValue(Parent), + new Optional(old), + new BindingValue(Parent), BindingPriority.LocalValue); #nullable enable } @@ -493,14 +501,9 @@ void ISetLogicalParent.SetParent(ILogical? parent) /// Sets the styled element's inheritance parent. /// /// The parent. - void ISetInheritanceParent.SetParent(IAvaloniaObject? parent) + void ISetInheritanceParent.SetParent(AvaloniaObject? parent) { - InheritanceParent = parent switch - { - AvaloniaObject ao => ao, - null => null, - _ => throw new NotSupportedException("Custom implementations of IAvaloniaObject not supported.") - }; + InheritanceParent = parent; } void IStyleHost.StylesAdded(IReadOnlyList styles) @@ -674,7 +677,7 @@ internal virtual void InvalidateStyles(bool recurse) } } - private static void DataContextNotifying(IAvaloniaObject o, bool updateStarted) + private static void DataContextNotifying(AvaloniaObject o, bool updateStarted) { if (o is StyledElement element) { diff --git a/src/Avalonia.Base/StyledElementExtensions.cs b/src/Avalonia.Base/StyledElementExtensions.cs index 0c5a5f7438a..d530dae8d4e 100644 --- a/src/Avalonia.Base/StyledElementExtensions.cs +++ b/src/Avalonia.Base/StyledElementExtensions.cs @@ -5,7 +5,7 @@ namespace Avalonia { public static class StyledElementExtensions { - public static IDisposable BindClass(this IStyledElement target, string className, IBinding source, object anchor) => + public static IDisposable BindClass(this StyledElement target, string className, IBinding source, object anchor) => ClassBindingManager.Bind(target, className, source, anchor); } } diff --git a/src/Avalonia.Base/StyledProperty.cs b/src/Avalonia.Base/StyledProperty.cs index d00a675d0fa..019ed09c20f 100644 --- a/src/Avalonia.Base/StyledProperty.cs +++ b/src/Avalonia.Base/StyledProperty.cs @@ -22,7 +22,7 @@ public StyledProperty( StyledPropertyMetadata metadata, bool inherits = false, Func? validate = null, - Action? notifying = null) + Action? notifying = null) : base(name, ownerType, metadata, inherits, validate, notifying) { } @@ -42,7 +42,7 @@ internal StyledProperty(StyledPropertyBase source, Type ownerType) /// /// The type of the additional owner. /// The property. - public StyledProperty AddOwner() where TOwner : IAvaloniaObject + public StyledProperty AddOwner() where TOwner : AvaloniaObject { AvaloniaPropertyRegistry.Instance.Register(typeof(TOwner), this); return this; diff --git a/src/Avalonia.Base/StyledPropertyBase.cs b/src/Avalonia.Base/StyledPropertyBase.cs index 6fb2f79918b..150d0dceca0 100644 --- a/src/Avalonia.Base/StyledPropertyBase.cs +++ b/src/Avalonia.Base/StyledPropertyBase.cs @@ -30,7 +30,7 @@ protected StyledPropertyBase( StyledPropertyMetadata metadata, bool inherits = false, Func? validate = null, - Action? notifying = null) + Action? notifying = null) : base(name, ownerType, metadata, notifying) { _inherits = inherits; @@ -74,7 +74,7 @@ protected StyledPropertyBase(StyledPropertyBase source, Type ownerType) /// internal bool HasCoercion { get; private set; } - public TValue CoerceValue(IAvaloniaObject instance, TValue baseValue) + public TValue CoerceValue(AvaloniaObject instance, TValue baseValue) { var metadata = GetMetadata(instance.GetType()); @@ -114,7 +114,7 @@ public TValue GetDefaultValue(Type type) /// /// The type. /// The default value. - public void OverrideDefaultValue(TValue defaultValue) where T : IAvaloniaObject + public void OverrideDefaultValue(TValue defaultValue) where T : AvaloniaObject { OverrideDefaultValue(typeof(T), defaultValue); } @@ -134,7 +134,7 @@ public void OverrideDefaultValue(Type type, TValue defaultValue) /// /// The type. /// The metadata. - public void OverrideMetadata(StyledPropertyMetadata metadata) where T : IAvaloniaObject + public void OverrideMetadata(StyledPropertyMetadata metadata) where T : AvaloniaObject { base.OverrideMetadata(typeof(T), metadata); } diff --git a/src/Avalonia.Base/StyledPropertyMetadata`1.cs b/src/Avalonia.Base/StyledPropertyMetadata`1.cs index 0a389602280..c71973fde8b 100644 --- a/src/Avalonia.Base/StyledPropertyMetadata`1.cs +++ b/src/Avalonia.Base/StyledPropertyMetadata`1.cs @@ -19,7 +19,7 @@ public class StyledPropertyMetadata : AvaloniaPropertyMetadata, IStyledP public StyledPropertyMetadata( Optional defaultValue = default, BindingMode defaultBindingMode = BindingMode.Default, - Func? coerce = null) + Func? coerce = null) : base(defaultBindingMode) { _defaultValue = defaultValue; @@ -34,7 +34,7 @@ public StyledPropertyMetadata( /// /// Gets the value coercion callback, if any. /// - public Func? CoerceValue { get; private set; } + public Func? CoerceValue { get; private set; } object? IStyledPropertyMetadata.DefaultValue => DefaultValue; diff --git a/src/Avalonia.Base/Styling/Activators/PropertyEqualsActivator.cs b/src/Avalonia.Base/Styling/Activators/PropertyEqualsActivator.cs index 388671f3f7c..20a4c11f791 100644 --- a/src/Avalonia.Base/Styling/Activators/PropertyEqualsActivator.cs +++ b/src/Avalonia.Base/Styling/Activators/PropertyEqualsActivator.cs @@ -7,13 +7,13 @@ namespace Avalonia.Styling.Activators /// internal class PropertyEqualsActivator : StyleActivatorBase, IObserver { - private readonly IStyleable _control; + private readonly StyledElement _control; private readonly AvaloniaProperty _property; private readonly object? _value; private IDisposable? _subscription; public PropertyEqualsActivator( - IStyleable control, + StyledElement control, AvaloniaProperty property, object? value) { diff --git a/src/Avalonia.Base/Styling/ChildSelector.cs b/src/Avalonia.Base/Styling/ChildSelector.cs index a6093bf0266..400ba185304 100644 --- a/src/Avalonia.Base/Styling/ChildSelector.cs +++ b/src/Avalonia.Base/Styling/ChildSelector.cs @@ -37,13 +37,13 @@ public override string ToString(Style? owner) return _selectorString; } - protected override SelectorMatch Evaluate(IStyleable control, IStyle? parent, bool subscribe) + protected override SelectorMatch Evaluate(StyledElement control, IStyle? parent, bool subscribe) { var controlParent = ((ILogical)control).LogicalParent; if (controlParent != null) { - var parentMatch = _parent.Match((IStyleable)controlParent, parent, subscribe); + var parentMatch = _parent.Match((StyledElement)controlParent, parent, subscribe); if (parentMatch.Result == SelectorMatchResult.Sometimes) { diff --git a/src/Avalonia.Base/Styling/ControlTheme.cs b/src/Avalonia.Base/Styling/ControlTheme.cs index 5fc900d2cb5..22c8f615778 100644 --- a/src/Avalonia.Base/Styling/ControlTheme.cs +++ b/src/Avalonia.Base/Styling/ControlTheme.cs @@ -37,7 +37,7 @@ internal override void SetParent(StyleBase? parent) throw new InvalidOperationException("ControlThemes cannot be added as a nested style."); } - internal SelectorMatchResult TryAttach(IStyleable target, FrameType type) + internal SelectorMatchResult TryAttach(StyledElement target, FrameType type) { Debug.Assert(type is FrameType.Theme or FrameType.TemplatedParentTheme); @@ -46,7 +46,7 @@ internal SelectorMatchResult TryAttach(IStyleable target, FrameType type) if (TargetType is null) throw new InvalidOperationException("ControlTheme has no TargetType."); - if (HasSettersOrAnimations && TargetType.IsAssignableFrom(target.StyleKey)) + if (HasSettersOrAnimations && TargetType.IsAssignableFrom(((IStyleable)target).StyleKey)) { Attach(target, null, type); return SelectorMatchResult.AlwaysThisType; diff --git a/src/Avalonia.Base/Styling/DescendentSelector.cs b/src/Avalonia.Base/Styling/DescendentSelector.cs index 728dd08301e..a056f3ba8b9 100644 --- a/src/Avalonia.Base/Styling/DescendentSelector.cs +++ b/src/Avalonia.Base/Styling/DescendentSelector.cs @@ -35,7 +35,7 @@ public override string ToString(Style? owner) return _selectorString; } - protected override SelectorMatch Evaluate(IStyleable control, IStyle? parent, bool subscribe) + protected override SelectorMatch Evaluate(StyledElement control, IStyle? parent, bool subscribe) { var c = (ILogical)control; var descendantMatches = new OrActivatorBuilder(); @@ -46,7 +46,7 @@ protected override SelectorMatch Evaluate(IStyleable control, IStyle? parent, bo if (c is IStyleable) { - var match = _parent.Match((IStyleable)c, parent, subscribe); + var match = _parent.Match((StyledElement)c, parent, subscribe); if (match.Result == SelectorMatchResult.Sometimes) { diff --git a/src/Avalonia.Base/Styling/ISetter.cs b/src/Avalonia.Base/Styling/ISetter.cs index 87ba6c56806..22af90b4463 100644 --- a/src/Avalonia.Base/Styling/ISetter.cs +++ b/src/Avalonia.Base/Styling/ISetter.cs @@ -19,6 +19,6 @@ public interface ISetter /// This method should return an which can be used to apply /// the setter to the specified control. /// - ISetterInstance Instance(IStyleInstance styleInstance, IStyleable target); + ISetterInstance Instance(IStyleInstance styleInstance, StyledElement target); } } diff --git a/src/Avalonia.Base/Styling/IStyleable.cs b/src/Avalonia.Base/Styling/IStyleable.cs index 8ee1f001b6f..a6cc2c0f766 100644 --- a/src/Avalonia.Base/Styling/IStyleable.cs +++ b/src/Avalonia.Base/Styling/IStyleable.cs @@ -8,7 +8,7 @@ namespace Avalonia.Styling /// Interface for styleable elements. /// [NotClientImplementable] - public interface IStyleable : IAvaloniaObject, INamed + public interface IStyleable : INamed { /// /// Gets the list of classes for the control. @@ -23,6 +23,6 @@ public interface IStyleable : IAvaloniaObject, INamed /// /// Gets the template parent of this element if the control comes from a template. /// - ITemplatedControl? TemplatedParent { get; } + AvaloniaObject? TemplatedParent { get; } } } diff --git a/src/Avalonia.Base/Styling/ITemplatedControl.cs b/src/Avalonia.Base/Styling/ITemplatedControl.cs deleted file mode 100644 index 68989c8a5ec..00000000000 --- a/src/Avalonia.Base/Styling/ITemplatedControl.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Avalonia.Metadata; - -namespace Avalonia.Styling -{ - [NotClientImplementable] - public interface ITemplatedControl : IAvaloniaObject - { - } -} diff --git a/src/Avalonia.Base/Styling/NestingSelector.cs b/src/Avalonia.Base/Styling/NestingSelector.cs index dd627a7db90..980bf129076 100644 --- a/src/Avalonia.Base/Styling/NestingSelector.cs +++ b/src/Avalonia.Base/Styling/NestingSelector.cs @@ -13,7 +13,7 @@ internal class NestingSelector : Selector public override string ToString(Style? owner) => owner?.Parent?.ToString() ?? "^"; - protected override SelectorMatch Evaluate(IStyleable control, IStyle? parent, bool subscribe) + protected override SelectorMatch Evaluate(StyledElement control, IStyle? parent, bool subscribe) { if (parent is Style s && s.Selector is not null) { @@ -23,7 +23,7 @@ protected override SelectorMatch Evaluate(IStyleable control, IStyle? parent, bo { if (theme.TargetType is null) throw new InvalidOperationException("ControlTheme has no TargetType."); - return theme.TargetType.IsAssignableFrom(control.StyleKey) ? + return theme.TargetType.IsAssignableFrom(((IStyleable)control).StyleKey) ? SelectorMatch.AlwaysThisType : SelectorMatch.NeverThisType; } diff --git a/src/Avalonia.Base/Styling/NotSelector.cs b/src/Avalonia.Base/Styling/NotSelector.cs index 4491762b8f5..f6b1288ac51 100644 --- a/src/Avalonia.Base/Styling/NotSelector.cs +++ b/src/Avalonia.Base/Styling/NotSelector.cs @@ -45,7 +45,7 @@ public override string ToString(Style? owner) return _selectorString; } - protected override SelectorMatch Evaluate(IStyleable control, IStyle? parent, bool subscribe) + protected override SelectorMatch Evaluate(StyledElement control, IStyle? parent, bool subscribe) { var innerResult = _argument.Match(control, parent, subscribe); diff --git a/src/Avalonia.Base/Styling/NthChildSelector.cs b/src/Avalonia.Base/Styling/NthChildSelector.cs index 9191d2eaa5e..ccfc2c781df 100644 --- a/src/Avalonia.Base/Styling/NthChildSelector.cs +++ b/src/Avalonia.Base/Styling/NthChildSelector.cs @@ -48,7 +48,7 @@ public NthChildSelector(Selector? previous, int step, int offset) public int Step { get; } public int Offset { get; } - protected override SelectorMatch Evaluate(IStyleable control, IStyle? parent, bool subscribe) + protected override SelectorMatch Evaluate(StyledElement control, IStyle? parent, bool subscribe) { if (!(control is ILogical logical)) { diff --git a/src/Avalonia.Base/Styling/OrSelector.cs b/src/Avalonia.Base/Styling/OrSelector.cs index 0c48b76ded8..c5ef9a0b2b0 100644 --- a/src/Avalonia.Base/Styling/OrSelector.cs +++ b/src/Avalonia.Base/Styling/OrSelector.cs @@ -66,7 +66,7 @@ public override string ToString(Style? owner) return _selectorString; } - protected override SelectorMatch Evaluate(IStyleable control, IStyle? parent, bool subscribe) + protected override SelectorMatch Evaluate(StyledElement control, IStyle? parent, bool subscribe) { var activators = new OrActivatorBuilder(); var neverThisInstance = false; diff --git a/src/Avalonia.Base/Styling/PropertyEqualsSelector.cs b/src/Avalonia.Base/Styling/PropertyEqualsSelector.cs index 7d58bab4a35..8ef8e750dc8 100644 --- a/src/Avalonia.Base/Styling/PropertyEqualsSelector.cs +++ b/src/Avalonia.Base/Styling/PropertyEqualsSelector.cs @@ -74,7 +74,7 @@ public override string ToString(Style? owner) } /// - protected override SelectorMatch Evaluate(IStyleable control, IStyle? parent, bool subscribe) + protected override SelectorMatch Evaluate(StyledElement control, IStyle? parent, bool subscribe) { if (subscribe) { diff --git a/src/Avalonia.Base/Styling/PropertySetterInstance.cs b/src/Avalonia.Base/Styling/PropertySetterInstance.cs index 9028224cc16..68a9b8aafe4 100644 --- a/src/Avalonia.Base/Styling/PropertySetterInstance.cs +++ b/src/Avalonia.Base/Styling/PropertySetterInstance.cs @@ -13,7 +13,7 @@ namespace Avalonia.Styling internal class PropertySetterInstance : SingleSubscriberObservableBase>, ISetterInstance { - private readonly IStyleable _target; + private readonly StyledElement _target; private readonly StyledPropertyBase? _styledProperty; private readonly DirectPropertyBase? _directProperty; private readonly T _value; @@ -21,7 +21,7 @@ internal class PropertySetterInstance : SingleSubscriberObservableBase property, T value) { @@ -31,7 +31,7 @@ public PropertySetterInstance( } public PropertySetterInstance( - IStyleable target, + StyledElement target, DirectPropertyBase property, T value) { diff --git a/src/Avalonia.Base/Styling/Selector.cs b/src/Avalonia.Base/Styling/Selector.cs index 7f5ee483518..c83950f72d9 100644 --- a/src/Avalonia.Base/Styling/Selector.cs +++ b/src/Avalonia.Base/Styling/Selector.cs @@ -41,7 +41,7 @@ public abstract class Selector /// or simply return an immediate result. /// /// A . - public SelectorMatch Match(IStyleable control, IStyle? parent = null, bool subscribe = true) + public SelectorMatch Match(StyledElement control, IStyle? parent = null, bool subscribe = true) { // First match the selector until a combinator is found. Selectors are stored from // right-to-left, so MatchUntilCombinator reverses this order because the type selector @@ -88,7 +88,7 @@ public SelectorMatch Match(IStyleable control, IStyle? parent = null, bool subsc /// or simply return an immediate result. /// /// A . - protected abstract SelectorMatch Evaluate(IStyleable control, IStyle? parent, bool subscribe); + protected abstract SelectorMatch Evaluate(StyledElement control, IStyle? parent, bool subscribe); /// /// Moves to the previous selector. @@ -127,7 +127,7 @@ internal virtual void ValidateNestingSelector(bool inControlTheme) } private static SelectorMatch MatchUntilCombinator( - IStyleable control, + StyledElement control, Selector start, IStyle? parent, bool subscribe, @@ -144,7 +144,7 @@ private static SelectorMatch MatchUntilCombinator( } private static SelectorMatchResult Match( - IStyleable control, + StyledElement control, Selector selector, IStyle? parent, bool subscribe, diff --git a/src/Avalonia.Base/Styling/Setter.cs b/src/Avalonia.Base/Styling/Setter.cs index 92b35c93008..1c6d5f7f221 100644 --- a/src/Avalonia.Base/Styling/Setter.cs +++ b/src/Avalonia.Base/Styling/Setter.cs @@ -64,7 +64,7 @@ public object? Value void IValueEntry.Unsubscribe() { } - ISetterInstance ISetter.Instance(IStyleInstance instance, IStyleable target) + ISetterInstance ISetter.Instance(IStyleInstance instance, StyledElement target) { if (target is not AvaloniaObject ao) throw new InvalidOperationException("Don't know how to instance a style on this type."); @@ -119,7 +119,7 @@ private ISetterInstance SetBinding(StyleInstance instance, AvaloniaObject target } } - private ISetterInstance SetDirectValue(IStyleable target) + private ISetterInstance SetDirectValue(StyledElement target) { target.SetValue(Property!, Value); return _direct ??= new DirectPropertySetterInstance(); diff --git a/src/Avalonia.Base/Styling/Style.cs b/src/Avalonia.Base/Styling/Style.cs index 15d8a9fe2e1..a5d89392e97 100644 --- a/src/Avalonia.Base/Styling/Style.cs +++ b/src/Avalonia.Base/Styling/Style.cs @@ -59,7 +59,7 @@ internal override void SetParent(StyleBase? parent) base.SetParent(parent); } - internal SelectorMatchResult TryAttach(IStyleable target, object? host, FrameType type) + internal SelectorMatchResult TryAttach(StyledElement target, object? host, FrameType type) { _ = target ?? throw new ArgumentNullException(nameof(target)); diff --git a/src/Avalonia.Base/Styling/StyleBase.cs b/src/Avalonia.Base/Styling/StyleBase.cs index 83fcf04d2ff..e8fc40ca4c3 100644 --- a/src/Avalonia.Base/Styling/StyleBase.cs +++ b/src/Avalonia.Base/Styling/StyleBase.cs @@ -92,7 +92,7 @@ public bool TryGetResource(object key, out object? result) return false; } - internal ValueFrame Attach(IStyleable target, IStyleActivator? activator, FrameType type) + internal ValueFrame Attach(StyledElement target, IStyleActivator? activator, FrameType type) { if (target is not AvaloniaObject ao) throw new InvalidOperationException("Styles can only be applied to AvaloniaObjects."); diff --git a/src/Avalonia.Base/Styling/Styles.cs b/src/Avalonia.Base/Styling/Styles.cs index f22bbc0eae3..1b1886335f9 100644 --- a/src/Avalonia.Base/Styling/Styles.cs +++ b/src/Avalonia.Base/Styling/Styles.cs @@ -226,7 +226,7 @@ void IResourceProvider.RemoveOwner(IResourceHost owner) } } - internal SelectorMatchResult TryAttach(IStyleable target, object? host) + internal SelectorMatchResult TryAttach(StyledElement target, object? host) { var result = SelectorMatchResult.NeverThisType; diff --git a/src/Avalonia.Base/Styling/TemplateSelector.cs b/src/Avalonia.Base/Styling/TemplateSelector.cs index 82d934ee346..b253efc6d29 100644 --- a/src/Avalonia.Base/Styling/TemplateSelector.cs +++ b/src/Avalonia.Base/Styling/TemplateSelector.cs @@ -36,9 +36,9 @@ public override string ToString(Style? owner) return _selectorString; } - protected override SelectorMatch Evaluate(IStyleable control, IStyle? parent, bool subscribe) + protected override SelectorMatch Evaluate(StyledElement control, IStyle? parent, bool subscribe) { - var templatedParent = control.TemplatedParent as IStyleable; + var templatedParent = control.TemplatedParent as StyledElement; if (templatedParent == null) { diff --git a/src/Avalonia.Base/Styling/TypeNameAndClassSelector.cs b/src/Avalonia.Base/Styling/TypeNameAndClassSelector.cs index 4e225985d2a..7883fd23ab3 100644 --- a/src/Avalonia.Base/Styling/TypeNameAndClassSelector.cs +++ b/src/Avalonia.Base/Styling/TypeNameAndClassSelector.cs @@ -95,11 +95,11 @@ public override string ToString(Style? owner) } /// - protected override SelectorMatch Evaluate(IStyleable control, IStyle? parent, bool subscribe) + protected override SelectorMatch Evaluate(StyledElement control, IStyle? parent, bool subscribe) { if (TargetType != null) { - var controlType = control.StyleKey ?? control.GetType(); + var controlType = ((IStyleable)control).StyleKey ?? control.GetType(); if (IsConcreteType) { diff --git a/src/Avalonia.Base/Visual.cs b/src/Avalonia.Base/Visual.cs index 2bb4a29b3ca..f4fecc7c7ad 100644 --- a/src/Avalonia.Base/Visual.cs +++ b/src/Avalonia.Base/Visual.cs @@ -28,7 +28,7 @@ namespace Avalonia /// extension methods defined in . /// [UsableDuringInitialization] - public class Visual : StyledElement, IVisual + public class Visual : StyledElement { /// /// Defines the property. @@ -90,10 +90,10 @@ public class Visual : StyledElement, IVisual AvaloniaProperty.Register(nameof(RenderTransformOrigin), defaultValue: RelativePoint.Center); /// - /// Defines the property. + /// Defines the property. /// - public static readonly DirectProperty VisualParentProperty = - AvaloniaProperty.RegisterDirect(nameof(IVisual.VisualParent), o => o._visualParent); + public static readonly DirectProperty VisualParentProperty = + AvaloniaProperty.RegisterDirect(nameof(VisualParent), o => o._visualParent); /// /// Defines the property. @@ -109,7 +109,7 @@ public class Visual : StyledElement, IVisual private Rect _bounds; private TransformedBounds? _transformedBounds; private IRenderRoot? _visualRoot; - private IVisual? _visualParent; + private Visual? _visualParent; private bool _hasMirrorTransform; private TargetWeakEventSubscriber? _affectsRenderWeakSubscriber; @@ -137,7 +137,7 @@ public Visual() // Disable transitions until we're added to the visual tree. DisableTransitions(); - var visualChildren = new AvaloniaList(); + var visualChildren = new AvaloniaList(); visualChildren.ResetBehavior = ResetBehavior.Remove; visualChildren.Validate = visual => ValidateVisualChild(visual); visualChildren.CollectionChanged += VisualChildrenChanged; @@ -193,7 +193,7 @@ public bool IsEffectivelyVisible { get { - IVisual? node = this; + Visual? node = this; while (node != null) { @@ -280,7 +280,7 @@ public int ZIndex /// /// Gets the control's child visuals. /// - protected IAvaloniaList VisualChildren + protected internal IAvaloniaList VisualChildren { get; private set; @@ -289,7 +289,7 @@ protected IAvaloniaList VisualChildren /// /// Gets the root of the visual tree, if the control is attached to a visual tree. /// - protected IRenderRoot? VisualRoot => _visualRoot ?? (this as IRenderRoot); + protected internal IRenderRoot? VisualRoot => _visualRoot ?? (this as IRenderRoot); internal CompositionDrawListVisual? CompositionVisual { get; private set; } internal CompositionVisual? ChildCompositionVisual { get; set; } @@ -299,28 +299,12 @@ protected IAvaloniaList VisualChildren /// /// Gets a value indicating whether this control is attached to a visual root. /// - bool IVisual.IsAttachedToVisualTree => VisualRoot != null; - - /// - /// Gets the control's child controls. - /// - IAvaloniaReadOnlyList IVisual.VisualChildren => VisualChildren; + internal bool IsAttachedToVisualTree => VisualRoot != null; /// /// Gets the control's parent visual. /// - IVisual? IVisual.VisualParent => _visualParent; - - /// - /// Gets the root of the visual tree, if the control is attached to a visual tree. - /// - IRenderRoot? IVisual.VisualRoot => VisualRoot; - - TransformedBounds? IVisual.TransformedBounds - { - get { return _transformedBounds; } - set { SetAndRaise(TransformedBoundsProperty, ref _transformedBounds, value); } - } + internal Visual? VisualParent => _visualParent; /// /// Invalidates the visual and queues a repaint. @@ -434,7 +418,7 @@ protected virtual void OnAttachedToVisualTreeCore(VisualTreeAttachmentEventArgs AttachedToVisualTree?.Invoke(this, e); InvalidateVisual(); - if (ZIndex != 0 && this.GetVisualParent() is Visual parent) + if (ZIndex != 0 && VisualParent is Visual parent) parent.HasNonUniformZIndexChildren = true; var visualChildren = VisualChildren; @@ -467,6 +451,11 @@ internal CompositionVisual AttachToCompositor(Compositor compositor) return CompositionVisual; } + internal void SetTransformedBounds(TransformedBounds? value) + { + SetAndRaise(TransformedBoundsProperty, ref _transformedBounds, value); + } + /// /// Calls the method /// for this control and all of its visual descendants. @@ -531,13 +520,9 @@ protected virtual void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e) /// /// The old visual parent. /// The new visual parent. - protected virtual void OnVisualParentChanged(IVisual? oldParent, IVisual? newParent) + protected virtual void OnVisualParentChanged(Visual? oldParent, Visual? newParent) { - RaisePropertyChanged( - VisualParentProperty, - new Optional(oldParent), - new BindingValue(newParent), - BindingPriority.LocalValue); + RaisePropertyChanged(VisualParentProperty, oldParent, newParent, BindingPriority.LocalValue); } internal override ParametrizedLogger? GetBindingWarningLogger( @@ -591,7 +576,7 @@ private static void RenderTransformChanged(AvaloniaPropertyChangedEventArgs e) /// Ensures a visual child is not null and not already parented. /// /// The visual child. - private static void ValidateVisualChild(IVisual c) + private static void ValidateVisualChild(Visual c) { if (c == null) { @@ -610,7 +595,7 @@ private static void ValidateVisualChild(IVisual c) /// The event args. private static void ZIndexChanged(AvaloniaPropertyChangedEventArgs e) { - var sender = e.Sender as IVisual; + var sender = e.Sender as Visual; var parent = sender?.VisualParent; if (sender?.ZIndex != 0 && parent is Visual parentVisual) parentVisual.HasNonUniformZIndexChildren = true; diff --git a/src/Avalonia.Base/VisualExtensions.cs b/src/Avalonia.Base/VisualExtensions.cs index 7a5bbb105cb..e8dc5465d69 100644 --- a/src/Avalonia.Base/VisualExtensions.cs +++ b/src/Avalonia.Base/VisualExtensions.cs @@ -4,7 +4,7 @@ namespace Avalonia { /// - /// Extension methods for . + /// Extension methods for . /// public static class VisualExtensions { @@ -14,12 +14,12 @@ public static class VisualExtensions /// The visual. /// The point in screen coordinates. /// The point in client coordinates. - public static Point PointToClient(this IVisual visual, PixelPoint point) + public static Point PointToClient(this Visual visual, PixelPoint point) { var root = visual.VisualRoot ?? - throw new ArgumentException("Control does not belong to a visual tree.", nameof(visual)); + throw new ArgumentException("Control does not belong to a visual tree.", nameof(visual)); var rootPoint = root.PointToClient(point); - return root.TranslatePoint(rootPoint, visual)!.Value; + return ((Visual)root).TranslatePoint(rootPoint, visual)!.Value; } /// @@ -28,12 +28,12 @@ public static Point PointToClient(this IVisual visual, PixelPoint point) /// The visual. /// The point in client coordinates. /// The point in screen coordinates. - public static PixelPoint PointToScreen(this IVisual visual, Point point) + public static PixelPoint PointToScreen(this Visual visual, Point point) { var root = visual.VisualRoot ?? throw new ArgumentException("Control does not belong to a visual tree.", nameof(visual)); - var p = visual.TranslatePoint(point, root); - return visual.VisualRoot.PointToScreen(p!.Value); + var p = visual.TranslatePoint(point, (Visual)root); + return root.PointToScreen(p!.Value); } /// @@ -46,7 +46,7 @@ public static PixelPoint PointToScreen(this IVisual visual, Point point) /// A containing the transform or null if the visuals don't share a /// common ancestor. /// - public static Matrix? TransformToVisual(this IVisual from, IVisual to) + public static Matrix? TransformToVisual(this Visual from, Visual to) { var common = from.FindCommonVisualAncestor(to); @@ -76,7 +76,7 @@ public static PixelPoint PointToScreen(this IVisual visual, Point point) /// A point value, now relative to the target visual rather than this source element, or null if the /// two elements have no common ancestor. /// - public static Point? TranslatePoint(this IVisual visual, Point point, IVisual relativeTo) + public static Point? TranslatePoint(this Visual visual, Point point, Visual relativeTo) { var transform = visual.TransformToVisual(relativeTo); @@ -94,10 +94,10 @@ public static PixelPoint PointToScreen(this IVisual visual, Point point) /// The ancestor visual. /// The visual. /// The transform. - private static Matrix GetOffsetFrom(IVisual ancestor, IVisual visual) + private static Matrix GetOffsetFrom(Visual ancestor, Visual visual) { var result = Matrix.Identity; - IVisual? v = visual; + Visual? v = visual; while (v != ancestor) { diff --git a/src/Avalonia.Base/VisualTree/IHostedVisualTreeRoot.cs b/src/Avalonia.Base/VisualTree/IHostedVisualTreeRoot.cs index aec093c5743..9c33b1ffb9b 100644 --- a/src/Avalonia.Base/VisualTree/IHostedVisualTreeRoot.cs +++ b/src/Avalonia.Base/VisualTree/IHostedVisualTreeRoot.cs @@ -11,6 +11,6 @@ public interface IHostedVisualTreeRoot /// /// The visual tree host. /// - IVisual? Host { get; } + Visual? Host { get; } } } diff --git a/src/Avalonia.Base/VisualTree/IVisual.cs b/src/Avalonia.Base/VisualTree/IVisual.cs deleted file mode 100644 index fdd2d187b83..00000000000 --- a/src/Avalonia.Base/VisualTree/IVisual.cs +++ /dev/null @@ -1,129 +0,0 @@ -using System; -using Avalonia.Collections; -using Avalonia.Media; -using Avalonia.Metadata; -using Avalonia.Rendering; - -namespace Avalonia.VisualTree -{ - /// - /// Represents control that has a visual on-screen representation. - /// - /// - /// The interface defines the interface required for a renderer to - /// render a control. You should not usually need to reference this interface unless - /// you are writing a renderer; instead use the extension methods defined in - /// to traverse the visual tree. This interface is - /// implemented by . It should not be necessary to implement it - /// anywhere else. - /// - [NotClientImplementable] - public interface IVisual - { - /// - /// Raised when the control is attached to a rooted visual tree. - /// - event EventHandler? AttachedToVisualTree; - - /// - /// Raised when the control is detached from a rooted visual tree. - /// - event EventHandler? DetachedFromVisualTree; - - /// - /// Gets the bounds of the control relative to its parent. - /// - Rect Bounds { get; } - - /// - /// Gets the bounds of the control relative to the window, accounting for rendering transforms. - /// - TransformedBounds? TransformedBounds { get; set; } - - /// - /// Gets a value indicating whether the control should be clipped to its bounds. - /// - bool ClipToBounds { get; set; } - - /// - /// Gets or sets the geometry clip for this visual. - /// - Geometry? Clip { get; set; } - - /// - /// Gets a value indicating whether this control is attached to a visual root. - /// - bool IsAttachedToVisualTree { get; } - - /// - /// Gets a value indicating whether this control and all its parents are visible. - /// - bool IsEffectivelyVisible { get; } - - /// - /// Gets or sets a value indicating whether this control is visible. - /// - bool IsVisible { get; set; } - - /// - /// Gets or sets the opacity of the control. - /// - double Opacity { get; set; } - - /// - /// Gets or sets the opacity mask for the control. - /// - IBrush? OpacityMask { get; set; } - - /// - /// Gets a value indicating whether to apply mirror transform on this control. - /// - bool HasMirrorTransform { get; } - - /// - /// Gets a value indicating whether to sort children when rendering this control - /// - bool HasNonUniformZIndexChildren { get; } - - /// - /// Gets or sets the render transform of the control. - /// - ITransform? RenderTransform { get; set; } - - /// - /// Gets or sets the render transform origin of the control. - /// - RelativePoint RenderTransformOrigin { get; set; } - - /// - /// Gets the control's child visuals. - /// - IAvaloniaReadOnlyList VisualChildren { get; } - - /// - /// Gets the control's parent visual. - /// - IVisual? VisualParent { get; } - - /// - /// Gets the root of the visual tree, if the control is attached to a visual tree. - /// - IRenderRoot? VisualRoot { get; } - - /// - /// Gets or sets the Z index of the node. - /// - int ZIndex { get; set; } - - /// - /// Invalidates the visual and queues a repaint. - /// - void InvalidateVisual(); - - /// - /// Renders the control to a . - /// - /// The context. - void Render(DrawingContext context); - } -} diff --git a/src/Avalonia.Base/VisualTree/VisualExtensions.cs b/src/Avalonia.Base/VisualTree/VisualExtensions.cs index a1b8894604e..b58db3b2761 100644 --- a/src/Avalonia.Base/VisualTree/VisualExtensions.cs +++ b/src/Avalonia.Base/VisualTree/VisualExtensions.cs @@ -19,9 +19,9 @@ public static class VisualExtensions /// The number of steps from the visual to the ancestor or -1 if /// is not a descendent of . /// - public static int CalculateDistanceFromAncestor(this IVisual visual, IVisual? ancestor) + public static int CalculateDistanceFromAncestor(this Visual visual, Visual? ancestor) { - IVisual? v = visual ?? throw new ArgumentNullException(nameof(visual)); + Visual? v = visual ?? throw new ArgumentNullException(nameof(visual)); var result = 0; while (v != null && v != ancestor) @@ -41,9 +41,9 @@ public static int CalculateDistanceFromAncestor(this IVisual visual, IVisual? an /// /// The number of steps from the visual to the root. /// - public static int CalculateDistanceFromRoot(IVisual visual) + public static int CalculateDistanceFromRoot(Visual visual) { - IVisual? v = visual ?? throw new ArgumentNullException(nameof(visual)); + Visual? v = visual ?? throw new ArgumentNullException(nameof(visual)); var result = 0; v = v?.VisualParent; @@ -64,18 +64,18 @@ public static int CalculateDistanceFromRoot(IVisual visual) /// The first visual. /// The second visual. /// The common ancestor, or null if not found. - public static IVisual? FindCommonVisualAncestor(this IVisual visual, IVisual target) + public static Visual? FindCommonVisualAncestor(this Visual visual, Visual target) { - IVisual? v = visual ?? throw new ArgumentNullException(nameof(visual)); + Visual? v = visual ?? throw new ArgumentNullException(nameof(visual)); if (target is null) { return null; } - IVisual? t = target; + Visual? t = target; - void GoUpwards(ref IVisual? node, int count) + void GoUpwards(ref Visual? node, int count) { for (int i = 0; i < count; ++i) { @@ -104,8 +104,8 @@ void GoUpwards(ref IVisual? node, int count) while (v != null && t != null) { - IVisual? firstParent = v.VisualParent; - IVisual? secondParent = t.VisualParent; + Visual? firstParent = v.VisualParent; + Visual? secondParent = t.VisualParent; if (firstParent == secondParent) { @@ -120,13 +120,13 @@ void GoUpwards(ref IVisual? node, int count) } /// - /// Enumerates the ancestors of an in the visual tree. + /// Enumerates the ancestors of an in the visual tree. /// /// The visual. /// The visual's ancestors. - public static IEnumerable GetVisualAncestors(this IVisual visual) + public static IEnumerable GetVisualAncestors(this Visual visual) { - IVisual? v = visual ?? throw new ArgumentNullException(nameof(visual)); + Visual? v = visual ?? throw new ArgumentNullException(nameof(visual)); v = v.VisualParent; @@ -144,14 +144,14 @@ public static IEnumerable GetVisualAncestors(this IVisual visual) /// The visual. /// If given visual should be included in search. /// First ancestor of given type. - public static T? FindAncestorOfType(this IVisual visual, bool includeSelf = false) where T : class + public static T? FindAncestorOfType(this Visual visual, bool includeSelf = false) where T : class { if (visual is null) { return null; } - IVisual? parent = includeSelf ? visual : visual.VisualParent; + Visual? parent = includeSelf ? visual : visual.VisualParent; while (parent != null) { @@ -173,7 +173,7 @@ public static IEnumerable GetVisualAncestors(this IVisual visual) /// The visual. /// If given visual should be included in search. /// First descendant of given type. - public static T? FindDescendantOfType(this IVisual visual, bool includeSelf = false) where T : class + public static T? FindDescendantOfType(this Visual visual, bool includeSelf = false) where T : class { if (visual is null) { @@ -189,11 +189,11 @@ public static IEnumerable GetVisualAncestors(this IVisual visual) } /// - /// Enumerates an and its ancestors in the visual tree. + /// Enumerates an and its ancestors in the visual tree. /// /// The visual. /// The visual and its ancestors. - public static IEnumerable GetSelfAndVisualAncestors(this IVisual visual) + public static IEnumerable GetSelfAndVisualAncestors(this Visual visual) { _ = visual ?? throw new ArgumentNullException(nameof(visual)); @@ -211,7 +211,7 @@ public static IEnumerable GetSelfAndVisualAncestors(this IVisual visual /// The root visual to test. /// The point. /// The visual at the requested point. - public static IVisual? GetVisualAt(this IVisual visual, Point p) + public static Visual? GetVisualAt(this Visual visual, Point p) { _ = visual ?? throw new ArgumentNullException(nameof(visual)); @@ -228,7 +228,7 @@ public static IEnumerable GetSelfAndVisualAncestors(this IVisual visual /// children will be excluded from the results. /// /// The visual at the requested point. - public static IVisual? GetVisualAt(this IVisual visual, Point p, Func filter) + public static Visual? GetVisualAt(this Visual visual, Point p, Func filter) { _ = visual ?? throw new ArgumentNullException(nameof(visual)); @@ -239,7 +239,7 @@ public static IEnumerable GetSelfAndVisualAncestors(this IVisual visual return null; } - var rootPoint = visual.TranslatePoint(p, root); + var rootPoint = visual.TranslatePoint(p, (Visual)root); if (rootPoint.HasValue) { @@ -255,8 +255,8 @@ public static IEnumerable GetSelfAndVisualAncestors(this IVisual visual /// The root visual to test. /// The point. /// The visuals at the requested point. - public static IEnumerable GetVisualsAt( - this IVisual visual, + public static IEnumerable GetVisualsAt( + this Visual visual, Point p) { _ = visual ?? throw new ArgumentNullException(nameof(visual)); @@ -274,10 +274,10 @@ public static IEnumerable GetVisualsAt( /// children will be excluded from the results. /// /// The visuals at the requested point. - public static IEnumerable GetVisualsAt( - this IVisual visual, + public static IEnumerable GetVisualsAt( + this Visual visual, Point p, - Func filter) + Func filter) { _ = visual ?? throw new ArgumentNullException(nameof(visual)); @@ -285,41 +285,41 @@ public static IEnumerable GetVisualsAt( if (root is null) { - return Array.Empty(); + return Array.Empty(); } - var rootPoint = visual.TranslatePoint(p, root); + var rootPoint = visual.TranslatePoint(p, (Visual)root); if (rootPoint.HasValue) { return root.Renderer.HitTest(rootPoint.Value, visual, filter); } - return Enumerable.Empty(); + return Enumerable.Empty(); } /// - /// Enumerates the children of an in the visual tree. + /// Enumerates the children of an in the visual tree. /// /// The visual. /// The visual children. - public static IEnumerable GetVisualChildren(this IVisual visual) + public static IEnumerable GetVisualChildren(this Visual visual) { return visual.VisualChildren; } /// - /// Enumerates the descendants of an in the visual tree. + /// Enumerates the descendants of an in the visual tree. /// /// The visual. /// The visual's ancestors. - public static IEnumerable GetVisualDescendants(this IVisual visual) + public static IEnumerable GetVisualDescendants(this Visual visual) { - foreach (IVisual child in visual.VisualChildren) + foreach (Visual child in visual.VisualChildren) { yield return child; - foreach (IVisual descendant in child.GetVisualDescendants()) + foreach (Visual descendant in child.GetVisualDescendants()) { yield return descendant; } @@ -327,11 +327,11 @@ public static IEnumerable GetVisualDescendants(this IVisual visual) } /// - /// Enumerates an and its descendants in the visual tree. + /// Enumerates an and its descendants in the visual tree. /// /// The visual. /// The visual and its ancestors. - public static IEnumerable GetSelfAndVisualDescendants(this IVisual visual) + public static IEnumerable GetSelfAndVisualDescendants(this Visual visual) { yield return visual; @@ -342,36 +342,36 @@ public static IEnumerable GetSelfAndVisualDescendants(this IVisual visu } /// - /// Gets the visual parent of an . + /// Gets the visual parent of an . /// /// The visual. /// The parent, or null if the visual is unparented. - public static IVisual? GetVisualParent(this IVisual visual) + public static Visual? GetVisualParent(this Visual visual) { return visual.VisualParent; } /// - /// Gets the visual parent of an . + /// Gets the visual parent of an . /// /// The type of the visual parent. /// The visual. /// /// The parent, or null if the visual is unparented or its parent is not of type . /// - public static T? GetVisualParent(this IVisual visual) where T : class + public static T? GetVisualParent(this Visual visual) where T : class { return visual.VisualParent as T; } /// - /// Gets the root visual for an . + /// Gets the root visual for an . /// /// The visual. /// /// The root visual or null if the visual is not rooted. /// - public static IRenderRoot? GetVisualRoot(this IVisual visual) + public static IRenderRoot? GetVisualRoot(this Visual visual) { _ = visual ?? throw new ArgumentNullException(nameof(visual)); @@ -379,7 +379,12 @@ public static IEnumerable GetSelfAndVisualDescendants(this IVisual visu } /// - /// Tests whether an is an ancestor of another visual. + /// Returns a value indicating whether this control is attached to a visual root. + /// + public static bool IsAttachedToVisualTree(this Visual visual) => visual.IsAttachedToVisualTree; + + /// + /// Tests whether an is an ancestor of another visual. /// /// The visual. /// The potential descendant. @@ -387,9 +392,9 @@ public static IEnumerable GetSelfAndVisualDescendants(this IVisual visu /// True if is an ancestor of ; /// otherwise false. /// - public static bool IsVisualAncestorOf(this IVisual visual, IVisual target) + public static bool IsVisualAncestorOf(this Visual visual, Visual target) { - IVisual? current = target?.VisualParent; + Visual? current = target?.VisualParent; while (current != null) { @@ -404,7 +409,7 @@ public static bool IsVisualAncestorOf(this IVisual visual, IVisual target) return false; } - public static IEnumerable SortByZIndex(this IEnumerable elements) + public static IEnumerable SortByZIndex(this IEnumerable elements) { return elements .Select((element, index) => new ZOrderElement @@ -417,14 +422,14 @@ public static IEnumerable SortByZIndex(this IEnumerable elemen .Select(x => x.Element!); } - private static T? FindDescendantOfTypeCore(IVisual visual) where T : class + private static T? FindDescendantOfTypeCore(Visual visual) where T : class { var visualChildren = visual.VisualChildren; var visualChildrenCount = visualChildren.Count; for (var i = 0; i < visualChildrenCount; i++) { - IVisual child = visualChildren[i]; + Visual child = visualChildren[i]; if (child is T result) { @@ -444,7 +449,7 @@ public static IEnumerable SortByZIndex(this IEnumerable elemen private class ZOrderElement : IComparable { - public IVisual? Element { get; set; } + public Visual? Element { get; set; } public int Index { get; set; } public int ZIndex { get; set; } diff --git a/src/Avalonia.Base/VisualTree/VisualLocator.cs b/src/Avalonia.Base/VisualTree/VisualLocator.cs index 940c87bafad..cb5ef4945ce 100644 --- a/src/Avalonia.Base/VisualTree/VisualLocator.cs +++ b/src/Avalonia.Base/VisualTree/VisualLocator.cs @@ -6,18 +6,18 @@ namespace Avalonia.VisualTree { public class VisualLocator { - public static IObservable Track(IVisual relativeTo, int ancestorLevel, Type? ancestorType = null) + public static IObservable Track(Visual relativeTo, int ancestorLevel, Type? ancestorType = null) { return new VisualTracker(relativeTo, ancestorLevel, ancestorType); } - private class VisualTracker : LightweightObservableBase + private class VisualTracker : LightweightObservableBase { - private readonly IVisual _relativeTo; + private readonly Visual _relativeTo; private readonly int _ancestorLevel; private readonly Type? _ancestorType; - public VisualTracker(IVisual relativeTo, int ancestorLevel, Type? ancestorType) + public VisualTracker(Visual relativeTo, int ancestorLevel, Type? ancestorType) { _relativeTo = relativeTo; _ancestorLevel = ancestorLevel; @@ -36,14 +36,14 @@ protected override void Deinitialize() _relativeTo.DetachedFromVisualTree -= AttachedDetached; } - protected override void Subscribed(IObserver observer, bool first) + protected override void Subscribed(IObserver observer, bool first) { observer.OnNext(GetResult()); } private void AttachedDetached(object? sender, VisualTreeAttachmentEventArgs e) => PublishNext(GetResult()); - private IVisual? GetResult() + private Visual? GetResult() { if (_relativeTo.IsAttachedToVisualTree) { diff --git a/src/Avalonia.Base/VisualTreeAttachmentEventArgs.cs b/src/Avalonia.Base/VisualTreeAttachmentEventArgs.cs index 57a9340be8e..c0e8b1613f4 100644 --- a/src/Avalonia.Base/VisualTreeAttachmentEventArgs.cs +++ b/src/Avalonia.Base/VisualTreeAttachmentEventArgs.cs @@ -1,6 +1,5 @@ using System; using Avalonia.Rendering; -using Avalonia.VisualTree; namespace Avalonia { @@ -15,7 +14,7 @@ public class VisualTreeAttachmentEventArgs : EventArgs /// /// The parent that the visual is being attached to or detached from. /// The root visual. - public VisualTreeAttachmentEventArgs(IVisual parent, IRenderRoot root) + public VisualTreeAttachmentEventArgs(Visual parent, IRenderRoot root) { Parent = parent ?? throw new ArgumentNullException(nameof(parent)); Root = root ?? throw new ArgumentNullException(nameof(root)); @@ -24,7 +23,7 @@ public VisualTreeAttachmentEventArgs(IVisual parent, IRenderRoot root) /// /// Gets the parent that the visual is being attached to or detached from. /// - public IVisual Parent { get; } + public Visual Parent { get; } /// /// Gets the root of the visual tree that the visual is being attached to or detached from. diff --git a/src/Avalonia.Controls.ColorPicker/ColorView/ColorView.cs b/src/Avalonia.Controls.ColorPicker/ColorView/ColorView.cs index 89f1afb1acd..977b1f5c842 100644 --- a/src/Avalonia.Controls.ColorPicker/ColorView/ColorView.cs +++ b/src/Avalonia.Controls.ColorPicker/ColorView/ColorView.cs @@ -329,7 +329,7 @@ protected virtual HsvColor OnCoerceHsvColor(HsvColor value) /// The instance. /// The value to coerce. /// The coerced/validated value. - private static Color CoerceColor(IAvaloniaObject instance, Color value) + private static Color CoerceColor(AvaloniaObject instance, Color value) { if (instance is ColorView colorView) { @@ -345,7 +345,7 @@ private static Color CoerceColor(IAvaloniaObject instance, Color value) /// The instance. /// The value to coerce. /// The coerced/validated value. - private static HsvColor CoerceHsvColor(IAvaloniaObject instance, HsvColor value) + private static HsvColor CoerceHsvColor(AvaloniaObject instance, HsvColor value) { if (instance is ColorView colorView) { diff --git a/src/Avalonia.Controls.DataGrid/DataGrid.cs b/src/Avalonia.Controls.DataGrid/DataGrid.cs index 5b6fbfe09fc..454678c64b4 100644 --- a/src/Avalonia.Controls.DataGrid/DataGrid.cs +++ b/src/Avalonia.Controls.DataGrid/DataGrid.cs @@ -33,7 +33,7 @@ namespace Avalonia.Controls /// /// Displays data in a customizable grid. /// - [TemplatePart(DATAGRID_elementBottomRightCornerHeaderName, typeof(IVisual))] + [TemplatePart(DATAGRID_elementBottomRightCornerHeaderName, typeof(Visual))] [TemplatePart(DATAGRID_elementColumnHeadersPresenterName, typeof(DataGridColumnHeadersPresenter))] [TemplatePart(DATAGRID_elementFrozenColumnScrollBarSpacerName, typeof(Control))] [TemplatePart(DATAGRID_elementHorizontalScrollbarName, typeof(ScrollBar))] @@ -91,7 +91,7 @@ public partial class DataGrid : TemplatedControl private INotifyCollectionChanged _topLevelGroup; private ContentControl _clipboardContentControl; - private IVisual _bottomRightCorner; + private Visual _bottomRightCorner; private DataGridColumnHeadersPresenter _columnHeadersPresenter; private DataGridRowsPresenter _rowsPresenter; private ScrollBar _vScrollBar; @@ -122,7 +122,7 @@ public partial class DataGrid : TemplatedControl private bool _executingLostFocusActions; private bool _flushCurrentCellChanged; private bool _focusEditingControl; - private IVisual _focusedObject; + private Visual _focusedObject; private byte _horizontalScrollChangesIgnored; private DataGridRow _focusedRow; private bool _ignoreNextScrollBarsLayout; @@ -566,13 +566,13 @@ public ScrollBarVisibility VerticalScrollBarVisibility set { SetValue(VerticalScrollBarVisibilityProperty, value); } } - public static readonly StyledProperty> DropLocationIndicatorTemplateProperty = - AvaloniaProperty.Register>(nameof(DropLocationIndicatorTemplate)); + public static readonly StyledProperty> DropLocationIndicatorTemplateProperty = + AvaloniaProperty.Register>(nameof(DropLocationIndicatorTemplate)); /// /// Gets or sets the template that is used when rendering the column headers. /// - public ITemplate DropLocationIndicatorTemplate + public ITemplate DropLocationIndicatorTemplate { get { return GetValue(DropLocationIndicatorTemplateProperty); } set { SetValue(DropLocationIndicatorTemplateProperty, value); } @@ -2514,7 +2514,7 @@ protected override void OnApplyTemplate(TemplateAppliedEventArgs e) _topLeftCornerHeader = e.NameScope.Find(DATAGRID_elementTopLeftCornerHeaderName); EnsureTopLeftCornerHeader(); // EnsureTopLeftCornerHeader checks for a null _topLeftCornerHeader; _topRightCornerHeader = e.NameScope.Find(DATAGRID_elementTopRightCornerHeaderName); - _bottomRightCorner = e.NameScope.Find(DATAGRID_elementBottomRightCornerHeaderName); + _bottomRightCorner = e.NameScope.Find(DATAGRID_elementBottomRightCornerHeaderName); } /// @@ -3173,7 +3173,7 @@ internal bool WaitForLostFocus(Action action) if (EditingRow != null && EditingColumnIndex != -1 && !_executingLostFocusActions) { DataGridColumn editingColumn = ColumnsItemsInternal[EditingColumnIndex]; - IControl editingElement = editingColumn.GetCellContent(EditingRow); + Control editingElement = editingColumn.GetCellContent(EditingRow); if (editingElement != null && editingElement.ContainsChild(_focusedObject)) { Debug.Assert(_lostFocusActions != null); @@ -3913,7 +3913,7 @@ private void DataGrid_GotFocus(object sender, RoutedEventArgs e) // Keep track of which row contains the newly focused element DataGridRow focusedRow = null; - IVisual focusedElement = e.Source as IVisual; + Visual focusedElement = e.Source as Visual; _focusedObject = focusedElement; while (focusedElement != null) { @@ -3966,7 +3966,7 @@ private void DataGrid_LostFocus(object sender, RoutedEventArgs e) { bool focusLeftDataGrid = true; bool dataGridWillReceiveRoutedEvent = true; - IVisual focusedObject = FocusManager.Instance.Current; + Visual focusedObject = FocusManager.Instance.Current as Visual; while (focusedObject != null) { @@ -3979,7 +3979,7 @@ private void DataGrid_LostFocus(object sender, RoutedEventArgs e) // Walk up the visual tree. If we hit the root, try using the framework element's // parent. We do this because Popups behave differently with respect to the visual tree, // and it could have a parent even if the VisualTreeHelper doesn't find it. - IVisual parent = focusedObject.GetVisualParent(); + Visual parent = focusedObject.GetVisualParent(); if (parent == null) { if (focusedObject is Control element) @@ -4592,7 +4592,7 @@ private void PopulateCellContent(bool isCellEdited, Debug.Assert(dataGridRow != null); Debug.Assert(dataGridCell != null); - IControl element = null; + Control element = null; DataGridBoundColumn dataGridBoundColumn = dataGridColumn as DataGridBoundColumn; if (isCellEdited) { diff --git a/src/Avalonia.Controls.DataGrid/DataGridBoundColumn.cs b/src/Avalonia.Controls.DataGrid/DataGridBoundColumn.cs index 97e247bdc61..ce74604f706 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridBoundColumn.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridBoundColumn.cs @@ -97,9 +97,9 @@ public override IBinding ClipboardContentBinding //TODO Rename //TODO Validation - protected sealed override IControl GenerateEditingElement(DataGridCell cell, object dataItem, out ICellEditBinding editBinding) + protected sealed override Control GenerateEditingElement(DataGridCell cell, object dataItem, out ICellEditBinding editBinding) { - IControl element = GenerateEditingElementDirect(cell, dataItem); + Control element = GenerateEditingElementDirect(cell, dataItem); editBinding = null; if (Binding != null) @@ -110,7 +110,7 @@ protected sealed override IControl GenerateEditingElement(DataGridCell cell, obj return element; } - private static ICellEditBinding BindEditingElement(IAvaloniaObject target, AvaloniaProperty property, IBinding binding) + private static ICellEditBinding BindEditingElement(AvaloniaObject target, AvaloniaProperty property, IBinding binding) { var result = binding.Initiate(target, property, enableDataValidation: true); @@ -131,7 +131,7 @@ private static ICellEditBinding BindEditingElement(IAvaloniaObject target, Avalo return null; } - protected abstract IControl GenerateEditingElementDirect(DataGridCell cell, object dataItem); + protected abstract Control GenerateEditingElementDirect(DataGridCell cell, object dataItem); protected AvaloniaProperty BindingTarget { get; set; } diff --git a/src/Avalonia.Controls.DataGrid/DataGridCheckBoxColumn.cs b/src/Avalonia.Controls.DataGrid/DataGridCheckBoxColumn.cs index 9826c15598a..6b1796e50b2 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridCheckBoxColumn.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridCheckBoxColumn.cs @@ -65,7 +65,7 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang /// /// The previous, unedited value in the cell being edited. /// - protected override void CancelCellEdit(IControl editingElement, object uneditedValue) + protected override void CancelCellEdit(Control editingElement, object uneditedValue) { if (editingElement is CheckBox editingCheckBox) { @@ -85,7 +85,7 @@ protected override void CancelCellEdit(IControl editingElement, object uneditedV /// /// A new control that is bound to the column's property value. /// - protected override IControl GenerateEditingElementDirect(DataGridCell cell, object dataItem) + protected override Control GenerateEditingElementDirect(DataGridCell cell, object dataItem) { var checkBox = new CheckBox { @@ -107,7 +107,7 @@ protected override IControl GenerateEditingElementDirect(DataGridCell cell, obje /// /// A new, read-only control that is bound to the column's property value. /// - protected override IControl GenerateElement(DataGridCell cell, object dataItem) + protected override Control GenerateElement(DataGridCell cell, object dataItem) { bool isEnabled = false; CheckBox checkBoxElement = new CheckBox(); @@ -148,7 +148,7 @@ protected override IControl GenerateElement(DataGridCell cell, object dataItem) /// /// The unedited value. /// - protected override object PrepareCellForEdit(IControl editingElement, RoutedEventArgs editingEventArgs) + protected override object PrepareCellForEdit(Control editingElement, RoutedEventArgs editingEventArgs) { if (editingElement is CheckBox editingCheckBox) { @@ -218,7 +218,7 @@ void OnLayoutUpdated(object sender, EventArgs e) /// Called by the DataGrid control when this column asks for its elements to be /// updated, because its CheckBoxContent or IsThreeState property changed. /// - protected internal override void RefreshCellContent(IControl element, string propertyName) + protected internal override void RefreshCellContent(Control element, string propertyName) { if (element == null) { diff --git a/src/Avalonia.Controls.DataGrid/DataGridColumn.cs b/src/Avalonia.Controls.DataGrid/DataGridColumn.cs index 191c3fc5b13..d417c877462 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridColumn.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridColumn.cs @@ -34,7 +34,7 @@ public abstract class DataGridColumn : AvaloniaObject private object _header; private IDataTemplate _headerTemplate; private DataGridColumnHeader _headerCell; - private IControl _editingElement; + private Control _editingElement; private ICellEditBinding _editBinding; private IBinding _clipboardContentBinding; private ControlTheme _cellTheme; @@ -636,7 +636,7 @@ internal object GetCellValue(object item, IBinding binding) return content; } - public IControl GetCellContent(DataGridRow dataGridRow) + public Control GetCellContent(DataGridRow dataGridRow) { Contract.Requires(dataGridRow != null); if (OwningGrid == null) @@ -648,13 +648,13 @@ public IControl GetCellContent(DataGridRow dataGridRow) DataGridCell dataGridCell = dataGridRow.Cells[Index]; if (dataGridCell != null) { - return dataGridCell.Content as IControl; + return dataGridCell.Content as Control; } } return null; } - public IControl GetCellContent(object dataItem) + public Control GetCellContent(object dataItem) { Contract.Requires(dataItem != null); if (OwningGrid == null) @@ -675,10 +675,10 @@ public IControl GetCellContent(object dataItem) /// element contained in a column /// Column that contains the element, or null if not found /// - public static DataGridColumn GetColumnContainingElement(IControl element) + public static DataGridColumn GetColumnContainingElement(Control element) { // Walk up the tree to find the DataGridCell or DataGridColumnHeader that contains the element - IVisual parent = element; + Visual parent = element; while (parent != null) { if (parent is DataGridCell cell) @@ -731,7 +731,7 @@ public void Sort(ListSortDirection direction) /// /// The previous, unedited value in the cell being edited. /// - protected virtual void CancelCellEdit(IControl editingElement, object uneditedValue) + protected virtual void CancelCellEdit(Control editingElement, object uneditedValue) { } /// @@ -747,7 +747,7 @@ protected virtual void CancelCellEdit(IControl editingElement, object uneditedVa /// /// A new editing element that is bound to the column's property value. /// - protected abstract IControl GenerateEditingElement(DataGridCell cell, object dataItem, out ICellEditBinding binding); + protected abstract Control GenerateEditingElement(DataGridCell cell, object dataItem, out ICellEditBinding binding); /// /// When overridden in a derived class, gets a read-only element that is bound to the column's @@ -762,7 +762,7 @@ protected virtual void CancelCellEdit(IControl editingElement, object uneditedVa /// /// A new, read-only element that is bound to the column's property value. /// - protected abstract IControl GenerateElement(DataGridCell cell, object dataItem); + protected abstract Control GenerateElement(DataGridCell cell, object dataItem); /// /// Called by a specific column type when one of its properties changed, @@ -786,7 +786,7 @@ protected void NotifyPropertyChanged(string propertyName) /// /// The unedited value. /// - protected abstract object PrepareCellForEdit(IControl editingElement, RoutedEventArgs editingEventArgs); + protected abstract object PrepareCellForEdit(Control editingElement, RoutedEventArgs editingEventArgs); /// /// Called by the DataGrid control when a column asked for its @@ -794,10 +794,10 @@ protected void NotifyPropertyChanged(string propertyName) /// /// Indicates the element that needs to be refreshed /// Indicates which property changed and caused this call - protected internal virtual void RefreshCellContent(IControl element, string propertyName) + protected internal virtual void RefreshCellContent(Control element, string propertyName) { } - internal void CancelCellEditInternal(IControl editingElement, object uneditedValue) + internal void CancelCellEditInternal(Control editingElement, object uneditedValue) { CancelCellEdit(editingElement, uneditedValue); } @@ -908,12 +908,12 @@ internal void EnsureWidth() SetWidthInternalNoCallback(CoerceWidth(Width)); } - internal IControl GenerateElementInternal(DataGridCell cell, object dataItem) + internal Control GenerateElementInternal(DataGridCell cell, object dataItem) { return GenerateElement(cell, dataItem); } - internal object PrepareCellForEditInternal(IControl editingElement, RoutedEventArgs editingEventArgs) + internal object PrepareCellForEditInternal(Control editingElement, RoutedEventArgs editingEventArgs) { var result = PrepareCellForEdit(editingElement, editingEventArgs); editingElement.Focus(); @@ -1062,7 +1062,7 @@ internal void SetWidthStarValue(double value) } //TODO Binding - internal IControl GenerateEditingElementInternal(DataGridCell cell, object dataItem) + internal Control GenerateEditingElementInternal(DataGridCell cell, object dataItem) { if (_editingElement == null) { diff --git a/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs b/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs index 740e3516f65..6473c9c0518 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs @@ -679,7 +679,7 @@ private void OnMouseMove_BeginReorder(Point mousePosition) dragIndicator.PseudoClasses.Add(":dragIndicator"); - IControl dropLocationIndicator = OwningGrid.DropLocationIndicatorTemplate?.Build(); + Control dropLocationIndicator = OwningGrid.DropLocationIndicatorTemplate?.Build(); // If the user didn't style the dropLocationIndicator's Height, default to the column header's height if (dropLocationIndicator != null && double.IsNaN(dropLocationIndicator.Height) && dropLocationIndicator is Control element) diff --git a/src/Avalonia.Controls.DataGrid/DataGridColumns.cs b/src/Avalonia.Controls.DataGrid/DataGridColumns.cs index 52f0ad75370..703bc0d9c31 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridColumns.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridColumns.cs @@ -1437,7 +1437,7 @@ private static void RefreshCellElement(DataGridColumn dataGridColumn, DataGridRo DataGridCell dataGridCell = dataGridRow.Cells[dataGridColumn.Index]; Debug.Assert(dataGridCell != null); - if (dataGridCell.Content is IControl element) + if (dataGridCell.Content is Control element) { dataGridColumn.RefreshCellContent(element, propertyName); } diff --git a/src/Avalonia.Controls.DataGrid/DataGridFillerColumn.cs b/src/Avalonia.Controls.DataGrid/DataGridFillerColumn.cs index defcc523c61..6a71d40960a 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridFillerColumn.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridFillerColumn.cs @@ -51,18 +51,18 @@ internal override DataGridColumnHeader CreateHeader() return headerCell; } - protected override IControl GenerateElement(DataGridCell cell, object dataItem) + protected override Control GenerateElement(DataGridCell cell, object dataItem) { return null; } - protected override IControl GenerateEditingElement(DataGridCell cell, object dataItem, out ICellEditBinding editBinding) + protected override Control GenerateEditingElement(DataGridCell cell, object dataItem, out ICellEditBinding editBinding) { editBinding = null; return null; } - protected override object PrepareCellForEdit(IControl editingElement, RoutedEventArgs editingEventArgs) + protected override object PrepareCellForEdit(Control editingElement, RoutedEventArgs editingEventArgs) { return null; } diff --git a/src/Avalonia.Controls.DataGrid/DataGridRow.cs b/src/Avalonia.Controls.DataGrid/DataGridRow.cs index cd22934ac0b..dfa6ea2e467 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridRow.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridRow.cs @@ -58,7 +58,7 @@ public class DataGridRow : TemplatedControl private bool _detailsLoaded; private bool _detailsVisibilityNotificationPending; - private IControl _detailsContent; + private Control _detailsContent; private IDisposable _detailsContentSizeSubscription; private DataGridDetailsPresenter _detailsElement; @@ -441,7 +441,7 @@ public int GetIndex() public static DataGridRow GetRowContainingElement(Control element) { // Walk up the tree to find the DataGridRow that contains the element - IVisual parent = element; + Visual parent = element; DataGridRow row = parent as DataGridRow; while ((parent != null) && (row == null)) { diff --git a/src/Avalonia.Controls.DataGrid/DataGridRows.cs b/src/Avalonia.Controls.DataGrid/DataGridRows.cs index 17a7eab2e03..6c997f62c1b 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridRows.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridRows.cs @@ -2966,13 +2966,13 @@ private void UpdateRowDetailsHeightEstimate() } // detailsElement is the FrameworkElement created by the DetailsTemplate - internal void OnUnloadingRowDetails(DataGridRow row, IControl detailsElement) + internal void OnUnloadingRowDetails(DataGridRow row, Control detailsElement) { OnUnloadingRowDetails(new DataGridRowDetailsEventArgs(row, detailsElement)); } // detailsElement is the FrameworkElement created by the DetailsTemplate - internal void OnLoadingRowDetails(DataGridRow row, IControl detailsElement) + internal void OnLoadingRowDetails(DataGridRow row, Control detailsElement) { OnLoadingRowDetails(new DataGridRowDetailsEventArgs(row, detailsElement)); } diff --git a/src/Avalonia.Controls.DataGrid/DataGridTemplateColumn.cs b/src/Avalonia.Controls.DataGrid/DataGridTemplateColumn.cs index 0e754d58153..ba285a701c9 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridTemplateColumn.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridTemplateColumn.cs @@ -62,7 +62,7 @@ private void OnCellTemplateChanged(AvaloniaPropertyChangedEventArgs e) var value = (IDataTemplate)e.NewValue; } - protected override IControl GenerateElement(DataGridCell cell, object dataItem) + protected override Control GenerateElement(DataGridCell cell, object dataItem) { if(CellTemplate != null) { @@ -78,7 +78,7 @@ protected override IControl GenerateElement(DataGridCell cell, object dataItem) } } - protected override IControl GenerateEditingElement(DataGridCell cell, object dataItem, out ICellEditBinding binding) + protected override Control GenerateEditingElement(DataGridCell cell, object dataItem, out ICellEditBinding binding) { binding = null; if(CellEditingTemplate != null) @@ -99,12 +99,12 @@ protected override IControl GenerateEditingElement(DataGridCell cell, object dat } } - protected override object PrepareCellForEdit(IControl editingElement, RoutedEventArgs editingEventArgs) + protected override object PrepareCellForEdit(Control editingElement, RoutedEventArgs editingEventArgs) { return null; } - protected internal override void RefreshCellContent(IControl element, string propertyName) + protected internal override void RefreshCellContent(Control element, string propertyName) { var cell = element.Parent as DataGridCell; if(propertyName == nameof(CellTemplate) && cell is not null) diff --git a/src/Avalonia.Controls.DataGrid/DataGridTextColumn.cs b/src/Avalonia.Controls.DataGrid/DataGridTextColumn.cs index 79247aa87f7..82da1c30383 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridTextColumn.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridTextColumn.cs @@ -147,7 +147,7 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang /// /// The element that the column displays for a cell in editing mode. /// The previous, unedited value in the cell being edited. - protected override void CancelCellEdit(IControl editingElement, object uneditedValue) + protected override void CancelCellEdit(Control editingElement, object uneditedValue) { if (editingElement is TextBox textBox) { @@ -162,7 +162,7 @@ protected override void CancelCellEdit(IControl editingElement, object uneditedV /// The cell that will contain the generated element. /// The data item represented by the row that contains the intended cell. /// A new control that is bound to the column's property value. - protected override IControl GenerateEditingElementDirect(DataGridCell cell, object dataItem) + protected override Control GenerateEditingElementDirect(DataGridCell cell, object dataItem) { var textBox = new TextBox { @@ -184,7 +184,7 @@ protected override IControl GenerateEditingElementDirect(DataGridCell cell, obje /// The cell that will contain the generated element. /// The data item represented by the row that contains the intended cell. /// A new, read-only element that is bound to the column's property value. - protected override IControl GenerateElement(DataGridCell cell, object dataItem) + protected override Control GenerateElement(DataGridCell cell, object dataItem) { var textBlockElement = new TextBlock { @@ -210,7 +210,7 @@ protected override IControl GenerateElement(DataGridCell cell, object dataItem) /// The element that the column displays for a cell in editing mode. /// Information about the user gesture that is causing a cell to enter editing mode. /// The unedited value. - protected override object PrepareCellForEdit(IControl editingElement, RoutedEventArgs editingEventArgs) + protected override object PrepareCellForEdit(Control editingElement, RoutedEventArgs editingEventArgs) { if (editingElement is TextBox textBox) { @@ -239,7 +239,7 @@ protected override object PrepareCellForEdit(IControl editingElement, RoutedEven /// Called by the DataGrid control when this column asks for its elements to be /// updated, because a property changed. /// - protected internal override void RefreshCellContent(IControl element, string propertyName) + protected internal override void RefreshCellContent(Control element, string propertyName) { if (element == null) { diff --git a/src/Avalonia.Controls.DataGrid/EventArgs.cs b/src/Avalonia.Controls.DataGrid/EventArgs.cs index 7590a8ed614..da591d266f2 100644 --- a/src/Avalonia.Controls.DataGrid/EventArgs.cs +++ b/src/Avalonia.Controls.DataGrid/EventArgs.cs @@ -345,7 +345,7 @@ public Control DragIndicator /// /// UIElement to display at the insertion position. If null and Handled = true, then do not display an insertion indicator. /// - public IControl DropLocationIndicator + public Control DropLocationIndicator { get; set; @@ -542,7 +542,7 @@ public class DataGridRowDetailsEventArgs : EventArgs /// /// The row that the event occurs for. /// The row details section as a framework element. - public DataGridRowDetailsEventArgs(DataGridRow row, IControl detailsElement) + public DataGridRowDetailsEventArgs(DataGridRow row, Control detailsElement) { Row = row; DetailsElement = detailsElement; @@ -551,7 +551,7 @@ public DataGridRowDetailsEventArgs(DataGridRow row, IControl detailsElement) /// /// Gets the row details section as a framework element. /// - public IControl DetailsElement + public Control DetailsElement { get; private set; diff --git a/src/Avalonia.Controls.DataGrid/Primitives/DataGridColumnHeadersPresenter.cs b/src/Avalonia.Controls.DataGrid/Primitives/DataGridColumnHeadersPresenter.cs index 108dc8ded7a..b34f52f47da 100644 --- a/src/Avalonia.Controls.DataGrid/Primitives/DataGridColumnHeadersPresenter.cs +++ b/src/Avalonia.Controls.DataGrid/Primitives/DataGridColumnHeadersPresenter.cs @@ -18,7 +18,7 @@ namespace Avalonia.Controls.Primitives public sealed class DataGridColumnHeadersPresenter : Panel, IChildIndexProvider { private Control _dragIndicator; - private IControl _dropLocationIndicator; + private Control _dropLocationIndicator; private EventHandler _childIndexChanged; /// @@ -68,7 +68,7 @@ internal Double DragIndicatorOffset /// /// The drop location indicator control. This value is null if no column is being dragged. /// - internal IControl DropLocationIndicator + internal Control DropLocationIndicator { get { diff --git a/src/Avalonia.Controls.DataGrid/Utils/TreeHelper.cs b/src/Avalonia.Controls.DataGrid/Utils/TreeHelper.cs index 24507082552..f4ba644ae67 100644 --- a/src/Avalonia.Controls.DataGrid/Utils/TreeHelper.cs +++ b/src/Avalonia.Controls.DataGrid/Utils/TreeHelper.cs @@ -17,7 +17,7 @@ internal static class TreeHelper /// Parent Visual /// Child Visual /// True if the parent element contains the child - internal static bool ContainsChild(this IVisual element, IVisual child) + internal static bool ContainsChild(this Visual element, Visual child) { if (element != null) { @@ -31,10 +31,10 @@ internal static bool ContainsChild(this IVisual element, IVisual child) // Walk up the visual tree. If we hit the root, try using the framework element's // parent. We do this because Popups behave differently with respect to the visual tree, // and it could have a parent even if the VisualTreeHelper doesn't find it. - IVisual parent = child.GetVisualParent(); + Visual parent = child.GetVisualParent(); if (parent == null) { - if (child is IControl childElement) + if (child is Control childElement) { parent = childElement.Parent; } @@ -52,9 +52,9 @@ internal static bool ContainsChild(this IVisual element, IVisual child) /// /// Parent Visual /// True if the currently focused element is within the visual tree of the parent - internal static bool ContainsFocusedElement(this IVisual element) + internal static bool ContainsFocusedElement(this Visual element) { - return (element == null) ? false : element.ContainsChild(FocusManager.Instance.Current); + return (element == null) ? false : element.ContainsChild(FocusManager.Instance.Current as Visual); } } } diff --git a/src/Avalonia.Controls/AutoCompleteBox/AutoCompleteBox.cs b/src/Avalonia.Controls/AutoCompleteBox/AutoCompleteBox.cs index a027b8b650d..e0d986f2b44 100644 --- a/src/Avalonia.Controls/AutoCompleteBox/AutoCompleteBox.cs +++ b/src/Avalonia.Controls/AutoCompleteBox/AutoCompleteBox.cs @@ -773,7 +773,7 @@ protected override void OnLostFocus(RoutedEventArgs e) /// otherwise, false. protected bool HasFocus() { - IVisual? focused = FocusManager.Instance?.Current; + Visual? focused = FocusManager.Instance?.Current as Visual; while (focused != null) { @@ -784,11 +784,11 @@ protected bool HasFocus() // This helps deal with popups that may not be in the same // visual tree - IVisual? parent = focused.GetVisualParent(); + Visual? parent = focused.GetVisualParent(); if (parent == null) { // Try the logical parent. - IControl? element = focused as IControl; + Control? element = focused as Control; if (element != null) { parent = element.Parent; diff --git a/src/Avalonia.Controls/Automation/AutomationProperties.cs b/src/Avalonia.Controls/Automation/AutomationProperties.cs index a192ef6420a..35f94722ce5 100644 --- a/src/Avalonia.Controls/Automation/AutomationProperties.cs +++ b/src/Avalonia.Controls/Automation/AutomationProperties.cs @@ -138,8 +138,8 @@ public static class AutomationProperties /// /// Defines the AutomationProperties.LabeledBy attached property. /// - public static readonly AttachedProperty LabeledByProperty = - AvaloniaProperty.RegisterAttached( + public static readonly AttachedProperty LabeledByProperty = + AvaloniaProperty.RegisterAttached( "LabeledBy", typeof(AutomationProperties)); @@ -503,7 +503,7 @@ public static string GetItemType(StyledElement element) /// /// Helper for setting LabeledBy property on a StyledElement. /// - public static void SetLabeledBy(StyledElement element, IControl value) + public static void SetLabeledBy(StyledElement element, Control value) { if (element == null) { @@ -516,7 +516,7 @@ public static void SetLabeledBy(StyledElement element, IControl value) /// /// Helper for reading LabeledBy property from a StyledElement. /// - public static IControl GetLabeledBy(StyledElement element) + public static Control GetLabeledBy(StyledElement element) { if (element == null) { diff --git a/src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs index 25172b2d1cb..e8fb6b75add 100644 --- a/src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs +++ b/src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs @@ -58,7 +58,7 @@ protected override IReadOnlyList GetOrCreateChildrenCore() protected virtual IReadOnlyList? GetChildrenCore() { - var children = ((IVisual)Owner).VisualChildren; + var children = Owner.VisualChildren; if (children.Count == 0) return null; @@ -176,10 +176,10 @@ private static Rect GetBounds(Control control) { var root = control.GetVisualRoot(); - if (root is null) + if (root is not Visual rootVisual) return default; - var transform = control.TransformToVisual(root); + var transform = control.TransformToVisual(rootVisual); if (!transform.HasValue) return default; @@ -190,7 +190,7 @@ private static Rect GetBounds(Control control) private void Initialize() { Owner.PropertyChanged += OwnerPropertyChanged; - var visualChildren = ((IVisual)Owner).VisualChildren; + var visualChildren = Owner.VisualChildren; visualChildren.CollectionChanged += VisualChildrenChanged; } diff --git a/src/Avalonia.Controls/Automation/Peers/SelectingItemsControlAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/SelectingItemsControlAutomationPeer.cs index 4626e30ff10..7ae0ba7244f 100644 --- a/src/Avalonia.Controls/Automation/Peers/SelectingItemsControlAutomationPeer.cs +++ b/src/Avalonia.Controls/Automation/Peers/SelectingItemsControlAutomationPeer.cs @@ -37,7 +37,7 @@ protected SelectingItemsControlAutomationPeer(SelectingItemsControl owner) { var container = owner.ItemContainerGenerator.ContainerFromIndex(i); - if (container is Control c && ((IVisual)c).IsAttachedToVisualTree) + if (container is Control c && c.IsAttachedToVisualTree) { var peer = GetOrCreate(c); diff --git a/src/Avalonia.Controls/Automation/Peers/WindowBaseAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/WindowBaseAutomationPeer.cs index 30b56bbd960..9ec65592fa2 100644 --- a/src/Avalonia.Controls/Automation/Peers/WindowBaseAutomationPeer.cs +++ b/src/Avalonia.Controls/Automation/Peers/WindowBaseAutomationPeer.cs @@ -53,8 +53,9 @@ protected void StopTrackingFocus() private void OnFocusChanged(IInputElement? focus) { var oldFocus = _focus; + var c = focus as Control; - _focus = focus?.VisualRoot == Owner ? focus as Control : null; + _focus = c?.VisualRoot == Owner ? c : null; if (_focus != oldFocus) { diff --git a/src/Avalonia.Controls/Calendar/CalendarItem.cs b/src/Avalonia.Controls/Calendar/CalendarItem.cs index eec3bdc9f25..032f4521115 100644 --- a/src/Avalonia.Controls/Calendar/CalendarItem.cs +++ b/src/Avalonia.Controls/Calendar/CalendarItem.cs @@ -41,7 +41,7 @@ public sealed class CalendarItem : TemplatedControl private Button? _headerButton; private Button? _nextButton; private Button? _previousButton; - private ITemplate? _dayTitleTemplate; + private ITemplate? _dayTitleTemplate; private DateTime _currentMonth; private bool _isMouseLeftButtonDown = false; @@ -62,13 +62,13 @@ public IBrush HeaderBackground get { return GetValue(HeaderBackgroundProperty); } set { SetValue(HeaderBackgroundProperty, value); } } - public static readonly DirectProperty?> DayTitleTemplateProperty = - AvaloniaProperty.RegisterDirect?>( + public static readonly DirectProperty?> DayTitleTemplateProperty = + AvaloniaProperty.RegisterDirect?>( nameof(DayTitleTemplate), o => o.DayTitleTemplate, (o,v) => o.DayTitleTemplate = v, defaultBindingMode: BindingMode.OneTime); - public ITemplate? DayTitleTemplate + public ITemplate? DayTitleTemplate { get { return _dayTitleTemplate; } set { SetAndRaise(DayTitleTemplateProperty, ref _dayTitleTemplate, value); } @@ -172,7 +172,7 @@ private void PopulateGrids() if (MonthView != null) { var childCount = Calendar.RowsPerMonth + Calendar.RowsPerMonth * Calendar.ColumnsPerMonth; - using var children = new PooledList(childCount); + using var children = new PooledList(childCount); for (int i = 0; i < Calendar.RowsPerMonth; i++) { @@ -217,7 +217,7 @@ private void PopulateGrids() if (YearView != null) { var childCount = Calendar.RowsPerYear * Calendar.ColumnsPerYear; - using var children = new PooledList(childCount); + using var children = new PooledList(childCount); EventHandler monthCalendarButtonMouseDown = Month_CalendarButtonMouseDown; EventHandler monthCalendarButtonMouseUp = Month_CalendarButtonMouseUp; diff --git a/src/Avalonia.Controls/Carousel.cs b/src/Avalonia.Controls/Carousel.cs index 28a4aa64363..572ec5a3d5a 100644 --- a/src/Avalonia.Controls/Carousel.cs +++ b/src/Avalonia.Controls/Carousel.cs @@ -27,8 +27,8 @@ public class Carousel : SelectingItemsControl /// The default value of for /// . /// - private static readonly ITemplate PanelTemplate = - new FuncTemplate(() => new Panel()); + private static readonly ITemplate PanelTemplate = + new FuncTemplate(() => new Panel()); /// /// Initializes static members of the class. diff --git a/src/Avalonia.Controls/ComboBox.cs b/src/Avalonia.Controls/ComboBox.cs index 54196bdf1a1..2b407cc42a7 100644 --- a/src/Avalonia.Controls/ComboBox.cs +++ b/src/Avalonia.Controls/ComboBox.cs @@ -29,8 +29,8 @@ public class ComboBox : SelectingItemsControl /// /// The default value for the property. /// - private static readonly FuncTemplate DefaultPanel = - new FuncTemplate(() => new VirtualizingStackPanel()); + private static readonly FuncTemplate DefaultPanel = + new FuncTemplate(() => new VirtualizingStackPanel()); /// /// Defines the property. @@ -275,7 +275,7 @@ protected override void OnPointerWheelChanged(PointerWheelEventArgs e) protected override void OnPointerPressed(PointerPressedEventArgs e) { base.OnPointerPressed(e); - if(!e.Handled && e.Source is IVisual source) + if(!e.Handled && e.Source is Visual source) { if (_popup?.IsInsidePopup(source) == true) { @@ -288,7 +288,7 @@ protected override void OnPointerPressed(PointerPressedEventArgs e) /// protected override void OnPointerReleased(PointerReleasedEventArgs e) { - if (!e.Handled && e.Source is IVisual source) + if (!e.Handled && e.Source is Visual source) { if (_popup?.IsInsidePopup(source) == true) { @@ -359,7 +359,7 @@ private void PopupOpened(object? sender, EventArgs e) toplevel.AddDisposableHandler(PointerWheelChangedEvent, (s, ev) => { //eat wheel scroll event outside dropdown popup while it's open - if (IsDropDownOpen && (ev.Source as IVisual)?.GetVisualRoot() == toplevel) + if (IsDropDownOpen && (ev.Source as Visual)?.GetVisualRoot() == toplevel) { ev.Handled = true; } @@ -368,7 +368,7 @@ private void PopupOpened(object? sender, EventArgs e) this.GetObservable(IsVisibleProperty).Subscribe(IsVisibleChanged).DisposeWith(_subscriptionsOnOpen); - foreach (var parent in this.GetVisualAncestors().OfType()) + foreach (var parent in this.GetVisualAncestors().OfType()) { parent.GetObservable(IsVisibleProperty).Subscribe(IsVisibleChanged).DisposeWith(_subscriptionsOnOpen); } @@ -410,7 +410,7 @@ private void TryFocusSelectedItem() } } - private bool CanFocus(IControl control) => control.Focusable && control.IsEffectivelyEnabled && control.IsVisible; + private bool CanFocus(Control control) => control.Focusable && control.IsEffectivelyEnabled && control.IsVisible; private void UpdateSelectionBoxItem(object? item) { @@ -421,7 +421,7 @@ private void UpdateSelectionBoxItem(object? item) item = contentControl.Content; } - var control = item as IControl; + var control = item as Control; if (control != null) { @@ -456,7 +456,7 @@ private void UpdateFlowDirection() { if ((rectangle.Fill as VisualBrush)?.Visual is Control content) { - var flowDirection = (((IVisual)content!).VisualParent as Control)?.FlowDirection ?? + var flowDirection = (((Visual)content!).VisualParent as Control)?.FlowDirection ?? FlowDirection.LeftToRight; rectangle.FlowDirection = flowDirection; } diff --git a/src/Avalonia.Controls/ContextMenu.cs b/src/Avalonia.Controls/ContextMenu.cs index 7b35e35278d..020a6de5390 100644 --- a/src/Avalonia.Controls/ContextMenu.cs +++ b/src/Avalonia.Controls/ContextMenu.cs @@ -77,8 +77,8 @@ public class ContextMenu : MenuBase, ISetterValue, IPopupHostProvider public static readonly StyledProperty PlacementTargetProperty = Popup.PlacementTargetProperty.AddOwner(); - private static readonly ITemplate DefaultPanel = - new FuncTemplate(() => new StackPanel { Orientation = Orientation.Vertical }); + private static readonly ITemplate DefaultPanel = + new FuncTemplate(() => new StackPanel { Orientation = Orientation.Vertical }); private Popup? _popup; private List? _attachedControls; private IInputElement? _previousFocus; diff --git a/src/Avalonia.Controls/Control.cs b/src/Avalonia.Controls/Control.cs index beaee34b076..063e6ae7c8f 100644 --- a/src/Avalonia.Controls/Control.cs +++ b/src/Avalonia.Controls/Control.cs @@ -26,13 +26,13 @@ namespace Avalonia.Controls /// - A property to allow user-defined data to be attached to the control. /// - and other context menu related members. /// - public class Control : InputElement, IControl, INamed, IVisualBrushInitialize, ISetterValue + public class Control : InputElement, IDataTemplateHost, INamed, IVisualBrushInitialize, ISetterValue { /// /// Defines the property. /// - public static readonly StyledProperty?> FocusAdornerProperty = - AvaloniaProperty.Register?>(nameof(FocusAdorner)); + public static readonly StyledProperty?> FocusAdornerProperty = + AvaloniaProperty.Register?>(nameof(FocusAdorner)); /// /// Defines the property. @@ -114,13 +114,13 @@ public class Control : InputElement, IControl, INamed, IVisualBrushInitialize, I private bool _isLoaded = false; private DataTemplates? _dataTemplates; - private IControl? _focusAdorner; + private Control? _focusAdorner; private AutomationPeer? _automationPeer; /// /// Gets or sets the control's focus adorner. /// - public ITemplate? FocusAdorner + public ITemplate? FocusAdorner { get => GetValue(FocusAdornerProperty); set => SetValue(FocusAdornerProperty, value); @@ -227,7 +227,7 @@ public event EventHandler? SizeChanged remove => RemoveHandler(SizeChangedEvent, value); } - public new IControl? Parent => (IControl?)base.Parent; + public new Control? Parent => (Control?)base.Parent; /// /// Gets the value of the attached on a control. @@ -283,7 +283,7 @@ void IVisualBrushInitialize.EnsureInitialized() { foreach (var i in this.GetSelfAndVisualDescendants()) { - var c = i as IControl; + var c = i as Control; if (c?.IsInitialized == false && c is ISupportInitialize init) { @@ -305,7 +305,7 @@ void IVisualBrushInitialize.EnsureInitialized() /// Gets the element that receives the focus adorner. /// /// The control that receives the focus adorner. - protected virtual IControl? GetTemplateFocusTarget() => this; + protected virtual Control? GetTemplateFocusTarget() => this; private static Action loadedProcessingAction = () => { @@ -472,7 +472,7 @@ protected override void OnLostFocus(RoutedEventArgs e) if (_focusAdorner?.Parent != null) { - var adornerLayer = (IPanel)_focusAdorner.Parent; + var adornerLayer = (Panel)_focusAdorner.Parent; adornerLayer.Children.Remove(_focusAdorner); _focusAdorner = null; } @@ -586,7 +586,7 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang } /// - /// Computes the value according to the + /// Computes the value according to the /// and /// public virtual void InvalidateMirrorTransform() @@ -597,7 +597,7 @@ public virtual void InvalidateMirrorTransform() bool bypassFlowDirectionPolicies = BypassFlowDirectionPolicies; bool parentBypassFlowDirectionPolicies = false; - var parent = ((IVisual)this).VisualParent as Control; + var parent = this.VisualParent as Control; if (parent != null) { parentFlowDirection = parent.FlowDirection; diff --git a/src/Avalonia.Controls/ControlExtensions.cs b/src/Avalonia.Controls/ControlExtensions.cs index 17186792940..bceeb58adb6 100644 --- a/src/Avalonia.Controls/ControlExtensions.cs +++ b/src/Avalonia.Controls/ControlExtensions.cs @@ -7,7 +7,7 @@ namespace Avalonia.Controls { /// - /// Adds common functionality to . + /// Adds common functionality to . /// public static class ControlExtensions { @@ -15,7 +15,7 @@ public static class ControlExtensions /// Tries to bring the control into view. /// /// The control. - public static void BringIntoView(this IControl control) + public static void BringIntoView(this Control control) { _ = control ?? throw new ArgumentNullException(nameof(control)); @@ -27,7 +27,7 @@ public static void BringIntoView(this IControl control) /// /// The control. /// The area of the control to being into view. - public static void BringIntoView(this IControl control, Rect rect) + public static void BringIntoView(this Control control, Rect rect) { _ = control ?? throw new ArgumentNullException(nameof(control)); @@ -51,7 +51,7 @@ public static void BringIntoView(this IControl control, Rect rect) /// The control to look in. /// The name of the control to find. /// The control or null if not found. - public static T? FindControl(this IControl control, string name) where T : class, IControl + public static T? FindControl(this Control control, string name) where T : Control { _ = control ?? throw new ArgumentNullException(nameof(control)); _ = name ?? throw new ArgumentNullException(nameof(name)); @@ -73,7 +73,7 @@ public static void BringIntoView(this IControl control, Rect rect) /// The control to look in. /// The name of the control to find. /// The control. - public static T GetControl(this IControl control, string name) where T : class, IControl + public static T GetControl(this Control control, string name) where T : Control { _ = control ?? throw new ArgumentNullException(nameof(control)); _ = name ?? throw new ArgumentNullException(nameof(name)); diff --git a/src/Avalonia.Controls/Controls.cs b/src/Avalonia.Controls/Controls.cs index a504b39196b..8b0e998f64e 100644 --- a/src/Avalonia.Controls/Controls.cs +++ b/src/Avalonia.Controls/Controls.cs @@ -6,7 +6,7 @@ namespace Avalonia.Controls /// /// A collection of s. /// - public class Controls : AvaloniaList + public class Controls : AvaloniaList { /// /// Initializes a new instance of the class. @@ -20,7 +20,7 @@ public Controls() /// Initializes a new instance of the class. /// /// The initial items in the collection. - public Controls(IEnumerable items) + public Controls(IEnumerable items) : base(items) { ResetBehavior = ResetBehavior.Remove; diff --git a/src/Avalonia.Controls/DateTimePickers/DateTimePickerPanel.cs b/src/Avalonia.Controls/DateTimePickers/DateTimePickerPanel.cs index 3fdfbee54d6..aa587bce727 100644 --- a/src/Avalonia.Controls/DateTimePickers/DateTimePickerPanel.cs +++ b/src/Avalonia.Controls/DateTimePickers/DateTimePickerPanel.cs @@ -545,7 +545,7 @@ private int CoerceSelected(int newValue) private void OnItemTapped(object? sender, TappedEventArgs e) { - if (e.Source is IVisual source && + if (e.Source is Visual source && GetItemFromSource(source) is ListBoxItem listBoxItem && listBoxItem.Tag is int tag) { @@ -555,7 +555,7 @@ private void OnItemTapped(object? sender, TappedEventArgs e) } //Helper to get ListBoxItem from pointerevent source - private ListBoxItem? GetItemFromSource(IVisual src) + private ListBoxItem? GetItemFromSource(Visual src) { var item = src; while (item != null && !(item is ListBoxItem)) @@ -565,9 +565,9 @@ private void OnItemTapped(object? sender, TappedEventArgs e) return (ListBoxItem?)item; } - public bool BringIntoView(IControl target, Rect targetRect) { return false; } + public bool BringIntoView(Control target, Rect targetRect) { return false; } - public IControl? GetControlInDirection(NavigationDirection direction, IControl? from) { return null; } + public Control? GetControlInDirection(NavigationDirection direction, Control? from) { return null; } public void RaiseScrollInvalidated(EventArgs e) { diff --git a/src/Avalonia.Controls/Decorator.cs b/src/Avalonia.Controls/Decorator.cs index bd866ee8d80..043fe48cc9f 100644 --- a/src/Avalonia.Controls/Decorator.cs +++ b/src/Avalonia.Controls/Decorator.cs @@ -11,8 +11,8 @@ public class Decorator : Control /// /// Defines the property. /// - public static readonly StyledProperty ChildProperty = - AvaloniaProperty.Register(nameof(Child)); + public static readonly StyledProperty ChildProperty = + AvaloniaProperty.Register(nameof(Child)); /// /// Defines the property. @@ -33,7 +33,7 @@ static Decorator() /// Gets or sets the decorated control. /// [Content] - public IControl? Child + public Control? Child { get { return GetValue(ChildProperty); } set { SetValue(ChildProperty, value); } diff --git a/src/Avalonia.Controls/Documents/InlineCollection.cs b/src/Avalonia.Controls/Documents/InlineCollection.cs index 5b68402f87e..12a096b105a 100644 --- a/src/Avalonia.Controls/Documents/InlineCollection.cs +++ b/src/Avalonia.Controls/Documents/InlineCollection.cs @@ -125,7 +125,7 @@ public void Add(string text) /// Adds a control wrapped inside a to the collection. /// /// The to be added control. - public void Add(IControl control) + public void Add(Control control) { Add(new InlineUIContainer(control)); } diff --git a/src/Avalonia.Controls/Documents/InlineRun.cs b/src/Avalonia.Controls/Documents/InlineRun.cs index 68c61ca3fa3..1090b1334a2 100644 --- a/src/Avalonia.Controls/Documents/InlineRun.cs +++ b/src/Avalonia.Controls/Documents/InlineRun.cs @@ -6,13 +6,13 @@ namespace Avalonia.Controls.Documents { internal class EmbeddedControlRun : DrawableTextRun { - public EmbeddedControlRun(IControl control, TextRunProperties properties) + public EmbeddedControlRun(Control control, TextRunProperties properties) { Control = control; Properties = properties; } - public IControl Control { get; } + public Control Control { get; } public override TextRunProperties? Properties { get; } diff --git a/src/Avalonia.Controls/Documents/InlineUIContainer.cs b/src/Avalonia.Controls/Documents/InlineUIContainer.cs index 7107fb7fedb..58afb24b5c0 100644 --- a/src/Avalonia.Controls/Documents/InlineUIContainer.cs +++ b/src/Avalonia.Controls/Documents/InlineUIContainer.cs @@ -15,8 +15,8 @@ public class InlineUIContainer : Inline /// /// Defines the property. /// - public static readonly StyledProperty ChildProperty = - AvaloniaProperty.Register(nameof(Child)); + public static readonly StyledProperty ChildProperty = + AvaloniaProperty.Register(nameof(Child)); static InlineUIContainer() { @@ -41,7 +41,7 @@ public InlineUIContainer() /// /// UIElement set as a child of this inline item /// - public InlineUIContainer(IControl child) + public InlineUIContainer(Control child) { Child = child; } @@ -50,7 +50,7 @@ public InlineUIContainer(IControl child) /// The content spanned by this TextElement. /// [Content] - public IControl Child + public Control Child { get => GetValue(ChildProperty); set => SetValue(ChildProperty, value); diff --git a/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevelImpl.cs b/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevelImpl.cs index 1c7bdb9b37a..4f808928572 100644 --- a/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevelImpl.cs +++ b/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevelImpl.cs @@ -22,7 +22,7 @@ public virtual void Dispose() IsDisposed = true; } - public IRenderer CreateRenderer(IRenderRoot root) => new ImmediateRenderer(root); + public IRenderer CreateRenderer(IRenderRoot root) => new ImmediateRenderer((Visual)root); public abstract void Invalidate(Rect rect); public abstract IEnumerable Surfaces { get; } diff --git a/src/Avalonia.Controls/Flyouts/FlyoutBase.cs b/src/Avalonia.Controls/Flyouts/FlyoutBase.cs index 65ec4cc54cf..3ff248f0beb 100644 --- a/src/Avalonia.Controls/Flyouts/FlyoutBase.cs +++ b/src/Avalonia.Controls/Flyouts/FlyoutBase.cs @@ -325,14 +325,14 @@ private void HandleTransientDismiss(RawInputEventArgs args) return; } - if (Popup?.Host is PopupRoot) + if (Popup?.Host is PopupRoot && pArgs.Root is Visual eventRoot) { // As long as the pointer stays within the enlargedPopupRect // the flyout stays open. If it leaves, close it // Despite working in screen coordinates, leaving the TopLevel // window will not close this (as pointer events stop), which // does match UWP - var pt = pArgs.Root.PointToScreen(pArgs.Position); + var pt = eventRoot.PointToScreen(pArgs.Position); if (!_enlargePopupRectScreenPixelRect?.Contains(pt) ?? false) { HideCore(false); @@ -587,7 +587,7 @@ private bool CancelOpening() return eventArgs.Cancel; } - internal static void SetPresenterClasses(IControl? presenter, Classes classes) + internal static void SetPresenterClasses(Control? presenter, Classes classes) { if(presenter is null) { diff --git a/src/Avalonia.Controls/Generators/IItemContainerGenerator.cs b/src/Avalonia.Controls/Generators/IItemContainerGenerator.cs index 79c77f25192..8f0e3c88c1f 100644 --- a/src/Avalonia.Controls/Generators/IItemContainerGenerator.cs +++ b/src/Avalonia.Controls/Generators/IItemContainerGenerator.cs @@ -102,13 +102,13 @@ public interface IItemContainerGenerator /// /// The index. /// The container, or null if no container created. - IControl? ContainerFromIndex(int index); + Control? ContainerFromIndex(int index); /// /// Gets the index of the specified container control. /// /// The container. /// The index of the container, or -1 if not found. - int IndexFromContainer(IControl? container); + int IndexFromContainer(Control? container); } } diff --git a/src/Avalonia.Controls/Generators/ItemContainerGenerator.cs b/src/Avalonia.Controls/Generators/ItemContainerGenerator.cs index 4ce48d2a066..d87422e57ea 100644 --- a/src/Avalonia.Controls/Generators/ItemContainerGenerator.cs +++ b/src/Avalonia.Controls/Generators/ItemContainerGenerator.cs @@ -19,7 +19,7 @@ public class ItemContainerGenerator : IItemContainerGenerator /// Initializes a new instance of the class. /// /// The owner control. - public ItemContainerGenerator(IControl owner) + public ItemContainerGenerator(Control owner) { Owner = owner ?? throw new ArgumentNullException(nameof(owner)); } @@ -52,7 +52,7 @@ public ItemContainerGenerator(IControl owner) /// /// Gets the owner control. /// - public IControl Owner { get; } + public Control Owner { get; } /// public virtual Type? ContainerType => null; @@ -159,7 +159,7 @@ public virtual IEnumerable Clear() } /// - public IControl? ContainerFromIndex(int index) + public Control? ContainerFromIndex(int index) { ItemContainerInfo? result; _containers.TryGetValue(index, out result); @@ -167,7 +167,7 @@ public virtual IEnumerable Clear() } /// - public int IndexFromContainer(IControl? container) + public int IndexFromContainer(Control? container) { foreach (var i in _containers) { @@ -185,9 +185,9 @@ public int IndexFromContainer(IControl? container) /// /// The item. /// The created container control. - protected virtual IControl? CreateContainer(object item) + protected virtual Control? CreateContainer(object item) { - var result = item as IControl; + var result = item as Control; if (result == null) { diff --git a/src/Avalonia.Controls/Generators/ItemContainerGenerator`1.cs b/src/Avalonia.Controls/Generators/ItemContainerGenerator`1.cs index 5e965a9d048..ad5bf0219ca 100644 --- a/src/Avalonia.Controls/Generators/ItemContainerGenerator`1.cs +++ b/src/Avalonia.Controls/Generators/ItemContainerGenerator`1.cs @@ -1,5 +1,4 @@ using System; -using Avalonia.Controls.Templates; using Avalonia.Data; namespace Avalonia.Controls.Generators @@ -8,7 +7,7 @@ namespace Avalonia.Controls.Generators /// Creates containers for items and maintains a list of created containers. /// /// The type of the container. - public class ItemContainerGenerator : ItemContainerGenerator where T : class, IControl, new() + public class ItemContainerGenerator : ItemContainerGenerator where T : Control, new() { /// /// Initializes a new instance of the class. @@ -17,7 +16,7 @@ namespace Avalonia.Controls.Generators /// The container's Content property. /// The container's ContentTemplate property. public ItemContainerGenerator( - IControl owner, + Control owner, AvaloniaProperty contentProperty, AvaloniaProperty? contentTemplateProperty) : base(owner) @@ -40,7 +39,7 @@ public ItemContainerGenerator( protected AvaloniaProperty? ContentTemplateProperty { get; } /// - protected override IControl? CreateContainer(object item) + protected override Control? CreateContainer(object item) { var container = item as T; @@ -63,7 +62,7 @@ public ItemContainerGenerator( container.SetValue(ContentProperty, item, BindingPriority.Style); } - if (!(item is IControl)) + if (!(item is Control)) { container.DataContext = item; } @@ -89,7 +88,7 @@ public override bool TryRecycle(int oldIndex, int newIndex, object item) container.SetValue(ContentProperty, item); - if (!(item is IControl)) + if (!(item is Control)) { container.DataContext = item; } diff --git a/src/Avalonia.Controls/Generators/ItemContainerInfo.cs b/src/Avalonia.Controls/Generators/ItemContainerInfo.cs index 31d9a5c02ed..047e457e7c3 100644 --- a/src/Avalonia.Controls/Generators/ItemContainerInfo.cs +++ b/src/Avalonia.Controls/Generators/ItemContainerInfo.cs @@ -14,7 +14,7 @@ public class ItemContainerInfo /// /// The index of the item in the collection. /// - public ItemContainerInfo(IControl container, object item, int index) + public ItemContainerInfo(Control container, object item, int index) { ContainerControl = container; Item = item; @@ -27,7 +27,7 @@ public ItemContainerInfo(IControl container, object item, int index) /// /// This will be null if is null. /// - public IControl ContainerControl { get; } + public Control ContainerControl { get; } /// /// Gets the item that the container represents. diff --git a/src/Avalonia.Controls/Generators/MenuItemContainerGenerator.cs b/src/Avalonia.Controls/Generators/MenuItemContainerGenerator.cs index bfcb474515e..0dcb6c05e16 100644 --- a/src/Avalonia.Controls/Generators/MenuItemContainerGenerator.cs +++ b/src/Avalonia.Controls/Generators/MenuItemContainerGenerator.cs @@ -6,13 +6,13 @@ public class MenuItemContainerGenerator : ItemContainerGenerator /// Initializes a new instance of the class. /// /// The owner control. - public MenuItemContainerGenerator(IControl owner) + public MenuItemContainerGenerator(Control owner) : base(owner, MenuItem.HeaderProperty, null) { } /// - protected override IControl? CreateContainer(object item) + protected override Control? CreateContainer(object item) { var separator = item as Separator; return separator != null ? separator : base.CreateContainer(item); diff --git a/src/Avalonia.Controls/Generators/TabItemContainerGenerator.cs b/src/Avalonia.Controls/Generators/TabItemContainerGenerator.cs index 4021b8436ad..b26b113fbbc 100644 --- a/src/Avalonia.Controls/Generators/TabItemContainerGenerator.cs +++ b/src/Avalonia.Controls/Generators/TabItemContainerGenerator.cs @@ -19,7 +19,7 @@ public TabItemContainerGenerator(TabControl owner) public new TabControl Owner { get; } - protected override IControl CreateContainer(object item) + protected override Control CreateContainer(object item) { var tabItem = (TabItem)base.CreateContainer(item)!; @@ -48,14 +48,14 @@ protected override IControl CreateContainer(object item) } else { - if (!(tabItem.DataContext is IControl)) + if (!(tabItem.DataContext is Control)) { tabItem.Header = tabItem.DataContext; } } } - if (!(tabItem.Content is IControl)) + if (!(tabItem.Content is Control)) { tabItem.Bind(TabItem.ContentTemplateProperty, new OwnerBinding( tabItem, diff --git a/src/Avalonia.Controls/Generators/TreeContainerIndex.cs b/src/Avalonia.Controls/Generators/TreeContainerIndex.cs index eb60fca3678..02b8e7003e2 100644 --- a/src/Avalonia.Controls/Generators/TreeContainerIndex.cs +++ b/src/Avalonia.Controls/Generators/TreeContainerIndex.cs @@ -15,9 +15,9 @@ namespace Avalonia.Controls.Generators /// public class TreeContainerIndex { - private readonly Dictionary> _itemToContainerSet = new Dictionary>(); - private readonly Dictionary _itemToContainer = new Dictionary(); - private readonly Dictionary _containerToItem = new Dictionary(); + private readonly Dictionary> _itemToContainerSet = new Dictionary>(); + private readonly Dictionary _itemToContainer = new Dictionary(); + private readonly Dictionary _containerToItem = new Dictionary(); /// /// Signaled whenever new containers are materialized. @@ -32,7 +32,7 @@ public class TreeContainerIndex /// /// Gets the currently materialized containers. /// - public IEnumerable Containers => _containerToItem.Keys; + public IEnumerable Containers => _containerToItem.Keys; /// /// Gets the items of currently materialized containers. @@ -44,7 +44,7 @@ public class TreeContainerIndex /// /// The item. /// The item container. - public void Add(object item, IControl container) + public void Add(object item, Control container) { _itemToContainer[item] = container; if (_itemToContainerSet.TryGetValue(item, out var set)) @@ -53,7 +53,7 @@ public void Add(object item, IControl container) } else { - _itemToContainerSet.Add(item, new HashSet { container }); + _itemToContainerSet.Add(item, new HashSet { container }); } _containerToItem.Add(container, item); @@ -68,7 +68,7 @@ public void Add(object item, IControl container) /// /// The item container. /// The DataContext object - private void RemoveContainer(IControl container, object item) + private void RemoveContainer(Control container, object item) { if (_itemToContainerSet.TryGetValue(item, out var set)) { @@ -89,7 +89,7 @@ private void RemoveContainer(IControl container, object item) /// Removes a container from the index. /// /// The item container. - public void Remove(IControl container) + public void Remove(Control container) { var item = _containerToItem[container]; _containerToItem.Remove(container); @@ -124,7 +124,7 @@ public void Remove(int startingIndex, IEnumerable containers) /// /// The item. /// The container, or null of not found. - public IControl? ContainerFromItem(object item) + public Control? ContainerFromItem(object item) { if (item != null) { @@ -148,7 +148,7 @@ public void Remove(int startingIndex, IEnumerable containers) /// /// The container. /// The item, or null of not found. - public object? ItemFromContainer(IControl? container) + public object? ItemFromContainer(Control? container) { if (container != null) { diff --git a/src/Avalonia.Controls/Generators/TreeItemContainerGenerator.cs b/src/Avalonia.Controls/Generators/TreeItemContainerGenerator.cs index 2d8cb05e035..b7111c0ef23 100644 --- a/src/Avalonia.Controls/Generators/TreeItemContainerGenerator.cs +++ b/src/Avalonia.Controls/Generators/TreeItemContainerGenerator.cs @@ -12,7 +12,7 @@ namespace Avalonia.Controls.Generators /// /// The type of the container. public class TreeItemContainerGenerator : ItemContainerGenerator, ITreeItemContainerGenerator - where T : class, IControl, new() + where T : Control, new() { private TreeView? _treeView; @@ -25,7 +25,7 @@ public class TreeItemContainerGenerator : ItemContainerGenerator, ITreeIte /// The container's Items property. /// The container's IsExpanded property. public TreeItemContainerGenerator( - IControl owner, + Control owner, AvaloniaProperty contentProperty, AvaloniaProperty contentTemplateProperty, AvaloniaProperty itemsProperty, @@ -53,7 +53,7 @@ public TreeItemContainerGenerator( protected AvaloniaProperty IsExpandedProperty { get; } /// - protected override IControl? CreateContainer(object? item) + protected override Control? CreateContainer(object? item) { var container = item as T; @@ -93,7 +93,7 @@ public TreeItemContainerGenerator( BindingOperations.Apply(result, ItemsProperty, itemsSelector, null); } - if (!(item is IControl)) + if (!(item is Control)) { result.DataContext = item; } @@ -149,7 +149,7 @@ class WrapperTreeDataTemplate : ITreeDataTemplate { private readonly IDataTemplate _inner; public WrapperTreeDataTemplate(IDataTemplate inner) => _inner = inner; - public IControl? Build(object? param) => _inner.Build(param); + public Control? Build(object? param) => _inner.Build(param); public bool Match(object? data) => _inner.Match(data); public InstancedBinding? ItemsSelector(object item) => null; } diff --git a/src/Avalonia.Controls/GridSplitter.cs b/src/Avalonia.Controls/GridSplitter.cs index 85dad894fdf..9bdefed6b68 100644 --- a/src/Avalonia.Controls/GridSplitter.cs +++ b/src/Avalonia.Controls/GridSplitter.cs @@ -53,8 +53,8 @@ public class GridSplitter : Thumb /// /// Defines the property. /// - public static readonly StyledProperty> PreviewContentProperty = - AvaloniaProperty.Register>(nameof(PreviewContent)); + public static readonly StyledProperty> PreviewContentProperty = + AvaloniaProperty.Register>(nameof(PreviewContent)); private static readonly Cursor s_columnSplitterCursor = new Cursor(StandardCursorType.SizeWestEast); private static readonly Cursor s_rowSplitterCursor = new Cursor(StandardCursorType.SizeNorthSouth); @@ -109,7 +109,7 @@ public double DragIncrement /// /// Gets or sets content that will be shown when is enabled and user starts resize operation. /// - public ITemplate PreviewContent + public ITemplate PreviewContent { get => GetValue(PreviewContentProperty); set => SetValue(PreviewContentProperty, value); @@ -336,7 +336,7 @@ private void SetupPreviewAdorner() return; } - IControl? builtPreviewContent = previewContent?.Build(); + Control? builtPreviewContent = previewContent?.Build(); _resizeData.Adorner = new PreviewAdorner(builtPreviewContent); @@ -696,7 +696,7 @@ private sealed class PreviewAdorner : Decorator private readonly TranslateTransform _translation; private readonly Decorator _decorator; - public PreviewAdorner(IControl? previewControl) + public PreviewAdorner(Control? previewControl) { // Add a decorator to perform translations. _translation = new TranslateTransform(); diff --git a/src/Avalonia.Controls/HotkeyManager.cs b/src/Avalonia.Controls/HotkeyManager.cs index bde1da509be..dc3c621db4c 100644 --- a/src/Avalonia.Controls/HotkeyManager.cs +++ b/src/Avalonia.Controls/HotkeyManager.cs @@ -14,7 +14,7 @@ class HotkeyCommandWrapper : ICommand { readonly WeakReference reference; - public HotkeyCommandWrapper(IControl control) + public HotkeyCommandWrapper(Control control) { reference = new WeakReference(control); } @@ -76,7 +76,7 @@ public void Execute(object? parameter) class Manager { - private readonly IControl _control; + private readonly Control _control; private TopLevel? _root; private IDisposable? _parentSub; private IDisposable? _hotkeySub; @@ -84,7 +84,7 @@ class Manager private readonly HotkeyCommandWrapper _wrapper; private KeyBinding? _binding; - public Manager(IControl control) + public Manager(Control control) { _control = control; _wrapper = new HotkeyCommandWrapper(_control); @@ -147,7 +147,7 @@ static HotKeyManager() if (args.NewValue.Value is null) return; - var control = args.Sender as IControl; + var control = args.Sender as Control; if (control is not IClickableControl) { Logging.Logger.TryGet(Logging.LogEventLevel.Warning, Logging.LogArea.Control)?.Log(control, diff --git a/src/Avalonia.Controls/IContentControl.cs b/src/Avalonia.Controls/IContentControl.cs index b4d8d0f574b..b2828c26e85 100644 --- a/src/Avalonia.Controls/IContentControl.cs +++ b/src/Avalonia.Controls/IContentControl.cs @@ -9,7 +9,7 @@ namespace Avalonia.Controls /// . /// [NotClientImplementable] - public interface IContentControl : IControl + public interface IContentControl { /// /// Gets or sets the content to display. diff --git a/src/Avalonia.Controls/IControl.cs b/src/Avalonia.Controls/IControl.cs deleted file mode 100644 index 3395fc1059e..00000000000 --- a/src/Avalonia.Controls/IControl.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Avalonia.Controls.Templates; -using Avalonia.Input; -using Avalonia.Layout; -using Avalonia.Metadata; -using Avalonia.VisualTree; - -namespace Avalonia.Controls -{ - /// - /// Interface for Avalonia controls. - /// - [NotClientImplementable] - public interface IControl : IVisual, - IDataTemplateHost, - ILayoutable, - IInputElement, - INamed, - IStyledElement - { - new IControl? Parent { get; } - } -} diff --git a/src/Avalonia.Controls/IMenu.cs b/src/Avalonia.Controls/IMenu.cs index d90c5ea7a8d..ddf29970143 100644 --- a/src/Avalonia.Controls/IMenu.cs +++ b/src/Avalonia.Controls/IMenu.cs @@ -1,5 +1,7 @@ using Avalonia.Controls.Platform; +using Avalonia.Input; using Avalonia.Metadata; +using Avalonia.Rendering; namespace Avalonia.Controls { @@ -7,7 +9,7 @@ namespace Avalonia.Controls /// Represents a or . /// [NotClientImplementable] - public interface IMenu : IMenuElement + public interface IMenu : IMenuElement, IInputElement { /// /// Gets the menu interaction handler. @@ -18,5 +20,10 @@ public interface IMenu : IMenuElement /// Gets a value indicating whether the menu is open. /// bool IsOpen { get; } + + /// + /// Gets the root of the visual tree, if the control is attached to a visual tree. + /// + IRenderRoot? VisualRoot { get; } } } diff --git a/src/Avalonia.Controls/IMenuElement.cs b/src/Avalonia.Controls/IMenuElement.cs index c13c20b6398..2a81d20bd97 100644 --- a/src/Avalonia.Controls/IMenuElement.cs +++ b/src/Avalonia.Controls/IMenuElement.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using Avalonia.Input; +using Avalonia.LogicalTree; using Avalonia.Metadata; namespace Avalonia.Controls @@ -8,7 +9,7 @@ namespace Avalonia.Controls /// Represents an or . /// [NotClientImplementable] - public interface IMenuElement : IControl + public interface IMenuElement : IInputElement, ILogical { /// /// Gets or sets the currently selected submenu item. diff --git a/src/Avalonia.Controls/IMenuItem.cs b/src/Avalonia.Controls/IMenuItem.cs index 9d7ef3c18d9..1257d336843 100644 --- a/src/Avalonia.Controls/IMenuItem.cs +++ b/src/Avalonia.Controls/IMenuItem.cs @@ -38,7 +38,7 @@ public interface IMenuItem : IMenuElement /// /// Gets the parent . /// - new IMenuElement? Parent { get; } + IMenuElement? Parent { get; } /// /// Raises a click event on the menu item. diff --git a/src/Avalonia.Controls/IPanel.cs b/src/Avalonia.Controls/IPanel.cs deleted file mode 100644 index 8f2564ec747..00000000000 --- a/src/Avalonia.Controls/IPanel.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Avalonia.Metadata; - -namespace Avalonia.Controls -{ - /// - /// Interface for controls that can contain multiple children. - /// - [NotClientImplementable] - public interface IPanel : IControl - { - /// - /// Gets the children of the . - /// - Controls Children { get; } - } -} diff --git a/src/Avalonia.Controls/IScrollAnchorProvider.cs b/src/Avalonia.Controls/IScrollAnchorProvider.cs index b3ce7ef9e80..07663b057c9 100644 --- a/src/Avalonia.Controls/IScrollAnchorProvider.cs +++ b/src/Avalonia.Controls/IScrollAnchorProvider.cs @@ -8,7 +8,7 @@ public interface IScrollAnchorProvider /// /// The currently chosen anchor element to use for scroll anchoring. /// - IControl? CurrentAnchor { get; } + Control? CurrentAnchor { get; } /// /// Registers a control as a potential scroll anchor candidate. @@ -16,7 +16,7 @@ public interface IScrollAnchorProvider /// /// A control within the subtree of the . /// - void RegisterAnchorCandidate(IControl element); + void RegisterAnchorCandidate(Control element); /// /// Unregisters a control as a potential scroll anchor candidate. @@ -24,6 +24,6 @@ public interface IScrollAnchorProvider /// /// A control within the subtree of the . /// - void UnregisterAnchorCandidate(IControl element); + void UnregisterAnchorCandidate(Control element); } } diff --git a/src/Avalonia.Controls/IVirtualizingPanel.cs b/src/Avalonia.Controls/IVirtualizingPanel.cs index 604a62dcb91..9cdbc69cfb9 100644 --- a/src/Avalonia.Controls/IVirtualizingPanel.cs +++ b/src/Avalonia.Controls/IVirtualizingPanel.cs @@ -5,8 +5,13 @@ namespace Avalonia.Controls /// /// A panel that can be used to virtualize items. /// - public interface IVirtualizingPanel : IPanel + public interface IVirtualizingPanel { + /// + /// Gets the children of the panel. + /// + Controls Children { get; } + /// /// Gets or sets the controller for the virtualizing panel. /// @@ -74,8 +79,8 @@ public interface IVirtualizingPanel : IPanel /// /// /// The implementation for this method should call - /// and also ensure that the next call to - /// calls + /// and also ensure that the next call to + /// calls /// on the next measure even if /// the available size hasn't changed. /// diff --git a/src/Avalonia.Controls/ItemsControl.cs b/src/Avalonia.Controls/ItemsControl.cs index e9ce7912a72..e6c3d67bf46 100644 --- a/src/Avalonia.Controls/ItemsControl.cs +++ b/src/Avalonia.Controls/ItemsControl.cs @@ -29,8 +29,8 @@ public class ItemsControl : TemplatedControl, IItemsPresenterHost, ICollectionCh /// /// The default value for the property. /// - private static readonly FuncTemplate DefaultPanel = - new FuncTemplate(() => new StackPanel()); + private static readonly FuncTemplate DefaultPanel = + new FuncTemplate(() => new StackPanel()); /// /// Defines the property. @@ -53,8 +53,8 @@ public class ItemsControl : TemplatedControl, IItemsPresenterHost, ICollectionCh /// /// Defines the property. /// - public static readonly StyledProperty> ItemsPanelProperty = - AvaloniaProperty.Register>(nameof(ItemsPanel), DefaultPanel); + public static readonly StyledProperty> ItemsPanelProperty = + AvaloniaProperty.Register>(nameof(ItemsPanel), DefaultPanel); /// /// Defines the property. @@ -156,7 +156,7 @@ public int ItemCount /// /// Gets or sets the panel used to display the items. /// - public ITemplate ItemsPanel + public ITemplate ItemsPanel { get { return GetValue(ItemsPanelProperty); } set { SetValue(ItemsPanelProperty, value); } @@ -348,7 +348,7 @@ protected override void OnKeyDown(KeyEventArgs e) return; } - IVisual? current = focus.Current; + Visual? current = focus.Current as Visual; while (current != null) { @@ -453,7 +453,7 @@ private void AddControlItemsToLogicalChildren(IEnumerable? items) { foreach (var i in items) { - var control = i as IControl; + var control = i as Control; if (control != null && !LogicalChildren.Contains(control)) { @@ -477,7 +477,7 @@ private void RemoveControlItemsFromLogicalChildren(IEnumerable? items) { foreach (var i in items) { - var control = i as IControl; + var control = i as Control; if (control != null) { diff --git a/src/Avalonia.Controls/LayoutTransformControl.cs b/src/Avalonia.Controls/LayoutTransformControl.cs index e896c13f252..5668b79e815 100644 --- a/src/Avalonia.Controls/LayoutTransformControl.cs +++ b/src/Avalonia.Controls/LayoutTransformControl.cs @@ -52,7 +52,7 @@ public bool UseRenderTransform set { SetValue(UseRenderTransformProperty, value); } } - public IControl? TransformRoot => Child; + public Control? TransformRoot => Child; /// /// Provides the behavior for the "Arrange" pass of layout. diff --git a/src/Avalonia.Controls/ListBox.cs b/src/Avalonia.Controls/ListBox.cs index 86118d7b00e..7e5981688ce 100644 --- a/src/Avalonia.Controls/ListBox.cs +++ b/src/Avalonia.Controls/ListBox.cs @@ -20,8 +20,8 @@ public class ListBox : SelectingItemsControl /// /// The default value for the property. /// - private static readonly FuncTemplate DefaultPanel = - new FuncTemplate(() => new VirtualizingStackPanel()); + private static readonly FuncTemplate DefaultPanel = + new FuncTemplate(() => new VirtualizingStackPanel()); /// /// Defines the property. @@ -149,7 +149,7 @@ protected override void OnPointerPressed(PointerPressedEventArgs e) { base.OnPointerPressed(e); - if (e.Source is IVisual source) + if (e.Source is Visual source) { var point = e.GetCurrentPoint(source); diff --git a/src/Avalonia.Controls/Menu.cs b/src/Avalonia.Controls/Menu.cs index 611811f1705..c50cce95899 100644 --- a/src/Avalonia.Controls/Menu.cs +++ b/src/Avalonia.Controls/Menu.cs @@ -14,8 +14,8 @@ namespace Avalonia.Controls /// public class Menu : MenuBase, IMainMenu { - private static readonly ITemplate DefaultPanel = - new FuncTemplate(() => new StackPanel { Orientation = Orientation.Horizontal }); + private static readonly ITemplate DefaultPanel = + new FuncTemplate(() => new StackPanel { Orientation = Orientation.Horizontal }); /// diff --git a/src/Avalonia.Controls/MenuBase.cs b/src/Avalonia.Controls/MenuBase.cs index 54cbc46a36c..bd7a2749c51 100644 --- a/src/Avalonia.Controls/MenuBase.cs +++ b/src/Avalonia.Controls/MenuBase.cs @@ -7,6 +7,7 @@ using Avalonia.Input; using Avalonia.Interactivity; using Avalonia.LogicalTree; +using Avalonia.Rendering; namespace Avalonia.Controls { @@ -74,6 +75,8 @@ public bool IsOpen /// IMenuInteractionHandler IMenu.InteractionHandler => InteractionHandler; + IRenderRoot? IMenu.VisualRoot => VisualRoot; + /// IMenuItem? IMenuElement.SelectedItem { @@ -86,8 +89,8 @@ public bool IsOpen } set { - SelectedIndex = value is not null ? - ItemContainerGenerator.IndexFromContainer(value) : -1; + SelectedIndex = value is Control c ? + ItemContainerGenerator.IndexFromContainer(c) : -1; } } diff --git a/src/Avalonia.Controls/MenuItem.cs b/src/Avalonia.Controls/MenuItem.cs index 11c42f2ef36..3e00cea4306 100644 --- a/src/Avalonia.Controls/MenuItem.cs +++ b/src/Avalonia.Controls/MenuItem.cs @@ -110,8 +110,8 @@ public class MenuItem : HeaderedSelectingItemsControl, IMenuItem, ISelectable, I /// /// The default value for the property. /// - private static readonly ITemplate DefaultPanel = - new FuncTemplate(() => new StackPanel()); + private static readonly ITemplate DefaultPanel = + new FuncTemplate(() => new StackPanel()); private ICommand? _command; private bool _commandCanExecute = true; @@ -323,7 +323,7 @@ public bool StaysOpenOnClick } set { - SelectedIndex = value is not null ? ItemContainerGenerator.IndexFromContainer(value) : -1; + SelectedIndex = value is Control c ? ItemContainerGenerator.IndexFromContainer(c) : -1; } } @@ -450,7 +450,7 @@ protected override void OnPointerEntered(PointerEventArgs e) base.OnPointerEntered(e); var point = e.GetCurrentPoint(null); - RaiseEvent(new PointerEventArgs(PointerEnteredItemEvent, this, e.Pointer, this.VisualRoot, point.Position, + RaiseEvent(new PointerEventArgs(PointerEnteredItemEvent, this, e.Pointer, (Visual?)VisualRoot, point.Position, e.Timestamp, point.Properties, e.KeyModifiers)); } @@ -460,7 +460,7 @@ protected override void OnPointerExited(PointerEventArgs e) base.OnPointerExited(e); var point = e.GetCurrentPoint(null); - RaiseEvent(new PointerEventArgs(PointerExitedItemEvent, this, e.Pointer, this.VisualRoot, point.Position, + RaiseEvent(new PointerEventArgs(PointerExitedItemEvent, this, e.Pointer, (Visual?)VisualRoot, point.Position, e.Timestamp, point.Properties, e.KeyModifiers)); } diff --git a/src/Avalonia.Controls/Mixins/SelectableMixin.cs b/src/Avalonia.Controls/Mixins/SelectableMixin.cs index fa964c00567..a04a741e3ed 100644 --- a/src/Avalonia.Controls/Mixins/SelectableMixin.cs +++ b/src/Avalonia.Controls/Mixins/SelectableMixin.cs @@ -38,7 +38,7 @@ public static class SelectableMixin /// The control type. /// The IsSelected property. public static void Attach(AvaloniaProperty isSelected) - where TControl : class, IControl + where TControl : Control { _ = isSelected ?? throw new ArgumentNullException(nameof(isSelected)); diff --git a/src/Avalonia.Controls/NativeControlHost.cs b/src/Avalonia.Controls/NativeControlHost.cs index 191b60f3035..bcf0866129f 100644 --- a/src/Avalonia.Controls/NativeControlHost.cs +++ b/src/Avalonia.Controls/NativeControlHost.cs @@ -21,7 +21,7 @@ public class NativeControlHost : Control protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) { _currentRoot = e.Root as TopLevel; - var visual = (IVisual)this; + var visual = (Visual)this; while (visual != null) { if (visual is Visual v) diff --git a/src/Avalonia.Controls/NumericUpDown/NumericUpDown.cs b/src/Avalonia.Controls/NumericUpDown/NumericUpDown.cs index 21373c6b76c..8ed6abd52bf 100644 --- a/src/Avalonia.Controls/NumericUpDown/NumericUpDown.cs +++ b/src/Avalonia.Controls/NumericUpDown/NumericUpDown.cs @@ -869,7 +869,7 @@ private void SetValueInternal(decimal? value) } } - private static decimal OnCoerceMaximum(IAvaloniaObject instance, decimal value) + private static decimal OnCoerceMaximum(AvaloniaObject instance, decimal value) { if (instance is NumericUpDown upDown) { @@ -879,7 +879,7 @@ private static decimal OnCoerceMaximum(IAvaloniaObject instance, decimal value) return value; } - private static decimal OnCoerceMinimum(IAvaloniaObject instance, decimal value) + private static decimal OnCoerceMinimum(AvaloniaObject instance, decimal value) { if (instance is NumericUpDown upDown) { @@ -889,7 +889,7 @@ private static decimal OnCoerceMinimum(IAvaloniaObject instance, decimal value) return value; } - private static decimal OnCoerceIncrement(IAvaloniaObject instance, decimal value) + private static decimal OnCoerceIncrement(AvaloniaObject instance, decimal value) { if (instance is NumericUpDown upDown) { diff --git a/src/Avalonia.Controls/Panel.cs b/src/Avalonia.Controls/Panel.cs index 2230b4b0d2c..7134e1b9e7e 100644 --- a/src/Avalonia.Controls/Panel.cs +++ b/src/Avalonia.Controls/Panel.cs @@ -16,7 +16,7 @@ namespace Avalonia.Controls /// Controls can be added to a by adding them to its /// collection. All children are layed out to fill the panel. /// - public class Panel : Control, IPanel, IChildIndexProvider + public class Panel : Control, IChildIndexProvider { /// /// Defines the property. @@ -84,7 +84,7 @@ public override void Render(DrawingContext context) /// /// The properties. protected static void AffectsParentArrange(params AvaloniaProperty[] properties) - where TPanel : class, IPanel + where TPanel : Panel { foreach (var property in properties) { @@ -97,7 +97,7 @@ protected static void AffectsParentArrange(params AvaloniaProperty[] pro /// /// The properties. protected static void AffectsParentMeasure(params AvaloniaProperty[] properties) - where TPanel : class, IPanel + where TPanel : Panel { foreach (var property in properties) { @@ -137,7 +137,7 @@ protected virtual void ChildrenChanged(object? sender, NotifyCollectionChangedEv for (var i = 0; i < e.OldItems!.Count; ++i) { var index = i + e.OldStartingIndex; - var child = (IControl)e.NewItems![i]!; + var child = (Control)e.NewItems![i]!; LogicalChildren[index] = child; VisualChildren[index] = child; } @@ -157,24 +157,24 @@ private protected virtual void InvalidateMeasureOnChildrenChanged() } private static void AffectsParentArrangeInvalidate(AvaloniaPropertyChangedEventArgs e) - where TPanel : class, IPanel + where TPanel : Panel { - var control = e.Sender as IControl; + var control = e.Sender as Control; var panel = control?.VisualParent as TPanel; panel?.InvalidateArrange(); } private static void AffectsParentMeasureInvalidate(AvaloniaPropertyChangedEventArgs e) - where TPanel : class, IPanel + where TPanel : Panel { - var control = e.Sender as IControl; + var control = e.Sender as Control; var panel = control?.VisualParent as TPanel; panel?.InvalidateMeasure(); } int IChildIndexProvider.GetChildIndex(ILogical child) { - return child is IControl control ? Children.IndexOf(control) : -1; + return child is Control control ? Children.IndexOf(control) : -1; } public bool TryGetTotalCount(out int count) diff --git a/src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs b/src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs index 16aeb2f559f..42779024d38 100644 --- a/src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs +++ b/src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs @@ -123,7 +123,7 @@ public virtual void Detach(IMenu menu) protected internal virtual void GotFocus(object? sender, GotFocusEventArgs e) { - var item = GetMenuItem(e.Source as IControl); + var item = GetMenuItem(e.Source as Control); if (item?.Parent != null) { @@ -133,7 +133,7 @@ protected internal virtual void GotFocus(object? sender, GotFocusEventArgs e) protected internal virtual void LostFocus(object? sender, RoutedEventArgs e) { - var item = GetMenuItem(e.Source as IControl); + var item = GetMenuItem(e.Source as Control); if (item != null) { @@ -143,7 +143,7 @@ protected internal virtual void LostFocus(object? sender, RoutedEventArgs e) protected internal virtual void KeyDown(object? sender, KeyEventArgs e) { - KeyDown(GetMenuItem(e.Source as IControl), e); + KeyDown(GetMenuItem(e.Source as Control), e); } protected internal virtual void KeyDown(IMenuItem? item, KeyEventArgs e) @@ -282,7 +282,7 @@ item.Parent.SelectedItem is object && protected internal virtual void AccessKeyPressed(object? sender, RoutedEventArgs e) { - var item = GetMenuItem(e.Source as IControl); + var item = GetMenuItem(e.Source as Control); if (item == null) { @@ -303,7 +303,7 @@ protected internal virtual void AccessKeyPressed(object? sender, RoutedEventArgs protected internal virtual void PointerEntered(object? sender, PointerEventArgs e) { - var item = GetMenuItem(e.Source as IControl); + var item = GetMenuItem(e.Source as Control); if (item?.Parent == null) { @@ -349,7 +349,7 @@ protected internal virtual void PointerEntered(object? sender, PointerEventArgs protected internal virtual void PointerMoved(object? sender, PointerEventArgs e) { // HACK: #8179 needs to be addressed to correctly implement it in the PointerPressed method. - var item = GetMenuItem(e.Source as IControl) as MenuItem; + var item = GetMenuItem(e.Source as Control) as MenuItem; if (item?.TransformedBounds == null) { return; @@ -364,7 +364,7 @@ protected internal virtual void PointerMoved(object? sender, PointerEventArgs e) protected internal virtual void PointerExited(object? sender, PointerEventArgs e) { - var item = GetMenuItem(e.Source as IControl); + var item = GetMenuItem(e.Source as Control); if (item?.Parent == null) { @@ -399,9 +399,9 @@ protected internal virtual void PointerExited(object? sender, PointerEventArgs e protected internal virtual void PointerPressed(object? sender, PointerPressedEventArgs e) { - var item = GetMenuItem(e.Source as IControl); + var item = GetMenuItem(e.Source as Control); - if (sender is IVisual visual && + if (sender is Visual visual && e.GetCurrentPoint(visual).Properties.IsLeftButtonPressed && item?.HasSubMenu == true) { if (item.IsSubMenuOpen) @@ -430,7 +430,7 @@ protected internal virtual void PointerPressed(object? sender, PointerPressedEve protected internal virtual void PointerReleased(object? sender, PointerReleasedEventArgs e) { - var item = GetMenuItem(e.Source as IControl); + var item = GetMenuItem(e.Source as Control); if (e.InitialPressMouseButton == MouseButton.Left && item?.HasSubMenu == false) { @@ -461,7 +461,7 @@ protected internal virtual void RootPointerPressed(object? sender, PointerPresse { if (Menu?.IsOpen == true) { - if (e.Source is ILogical control && !Menu.IsLogicalAncestorOf(control)) + if (e.Source is ILogical control && Menu.IsLogicalAncestorOf(control)) { Menu.Close(); } @@ -547,7 +547,7 @@ protected void SelectItemAndAncestors(IMenuItem item) } } - protected static IMenuItem? GetMenuItem(IControl? item) + protected static IMenuItem? GetMenuItem(Control? item) { while (true) { diff --git a/src/Avalonia.Controls/Platform/InProcessDragSource.cs b/src/Avalonia.Controls/Platform/InProcessDragSource.cs index 209d5f03dc2..676a1587a80 100644 --- a/src/Avalonia.Controls/Platform/InProcessDragSource.cs +++ b/src/Avalonia.Controls/Platform/InProcessDragSource.cs @@ -61,7 +61,7 @@ private DragDropEffects RaiseEventAndUpdateCursor(RawDragEventType type, IInputR _lastPosition = pt; RawDragEvent rawEvent = new RawDragEvent(_dragDrop, type, root, pt, _draggedData!, _allowedEffects, modifiers); - var tl = root.GetSelfAndVisualAncestors().OfType().FirstOrDefault(); + var tl = (root as Visual)?.GetSelfAndVisualAncestors().OfType().FirstOrDefault(); tl?.PlatformImpl?.Input?.Invoke(rawEvent); var effect = GetPreferredEffect(rawEvent.Effects & _allowedEffects, modifiers); @@ -200,8 +200,8 @@ void CheckDraggingAccepted(RawInputModifiers changedMouseButton) if (e.Root != _lastRoot) { - if (_lastRoot != null) - RaiseEventAndUpdateCursor(RawDragEventType.DragLeave, _lastRoot, _lastRoot.PointToClient(e.Root.PointToScreen(e.Position)), e.InputModifiers); + if (_lastRoot is Visual lr && e.Root is Visual r) + RaiseEventAndUpdateCursor(RawDragEventType.DragLeave, _lastRoot, lr.PointToClient(r.PointToScreen(e.Position)), e.InputModifiers); RaiseEventAndUpdateCursor(RawDragEventType.DragEnter, e.Root, e.Position, e.InputModifiers); } else diff --git a/src/Avalonia.Controls/Presenters/CarouselPresenter.cs b/src/Avalonia.Controls/Presenters/CarouselPresenter.cs index 87bbfce2a2e..7b435e287db 100644 --- a/src/Avalonia.Controls/Presenters/CarouselPresenter.cs +++ b/src/Avalonia.Controls/Presenters/CarouselPresenter.cs @@ -155,7 +155,7 @@ protected override void ItemsChanged(NotifyCollectionChangedEventArgs e) } } - protected override void PanelCreated(IPanel panel) + protected override void PanelCreated(Panel panel) { ItemsChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } @@ -171,8 +171,8 @@ private async Task MoveToPage(int fromIndex, int toIndex) if (fromIndex != toIndex) { var generator = ItemContainerGenerator; - IControl? from = null; - IControl? to = null; + Control? from = null; + Control? to = null; if (fromIndex != -1) { @@ -208,7 +208,7 @@ private async Task MoveToPage(int fromIndex, int toIndex) } } - private IControl? GetOrCreateContainer(int index) + private Control? GetOrCreateContainer(int index) { var container = ItemContainerGenerator.ContainerFromIndex(index); diff --git a/src/Avalonia.Controls/Presenters/ContentPresenter.cs b/src/Avalonia.Controls/Presenters/ContentPresenter.cs index 39888c12396..584dfea97fc 100644 --- a/src/Avalonia.Controls/Presenters/ContentPresenter.cs +++ b/src/Avalonia.Controls/Presenters/ContentPresenter.cs @@ -118,8 +118,8 @@ public class ContentPresenter : Control, IContentPresenter /// /// Defines the property. /// - public static readonly DirectProperty ChildProperty = - AvaloniaProperty.RegisterDirect( + public static readonly DirectProperty ChildProperty = + AvaloniaProperty.RegisterDirect( nameof(Child), o => o.Child); @@ -161,7 +161,7 @@ public class ContentPresenter : Control, IContentPresenter nameof(RecognizesAccessKey), cp => cp.RecognizesAccessKey, (cp, value) => cp.RecognizesAccessKey = value); - private IControl? _child; + private Control? _child; private bool _createdChild; private IRecyclingDataTemplate? _recyclingDataTemplate; private readonly BorderRenderHelper _borderRenderer = new BorderRenderHelper(); @@ -329,7 +329,7 @@ public int MaxLines /// /// Gets the control displayed by the presenter. /// - public IControl? Child + public Control? Child { get { return _child; } private set { SetAndRaise(ChildProperty, ref _child, value); } @@ -460,7 +460,7 @@ private void UpdateChild(object? content) } // Set the DataContext if the data isn't a control. - if (contentTemplate is { } || !(content is IControl)) + if (contentTemplate is { } || !(content is Control)) { DataContext = content; } @@ -544,16 +544,16 @@ public override void Render(DrawingContext context) /// Creates the child control. /// /// The child control or null. - protected virtual IControl? CreateChild() + protected virtual Control? CreateChild() { var content = Content; var oldChild = Child; return CreateChild(content, oldChild, ContentTemplate); } - private IControl? CreateChild(object? content, IControl? oldChild, IDataTemplate? template) + private Control? CreateChild(object? content, Control? oldChild, IDataTemplate? template) { - var newChild = content as IControl; + var newChild = content as Control; // We want to allow creating Child from the Template, if Content is null. // But it's important to not use DataTemplates, otherwise we will break content presenters in many places, diff --git a/src/Avalonia.Controls/Presenters/IContentPresenter.cs b/src/Avalonia.Controls/Presenters/IContentPresenter.cs index 673de4700b3..01aec3855f4 100644 --- a/src/Avalonia.Controls/Presenters/IContentPresenter.cs +++ b/src/Avalonia.Controls/Presenters/IContentPresenter.cs @@ -13,7 +13,7 @@ public interface IContentPresenter : IPresenter /// /// Gets the control displayed by the presenter. /// - IControl? Child { get; } + Control? Child { get; } /// /// Gets or sets the content to be displayed by the presenter. diff --git a/src/Avalonia.Controls/Presenters/IContentPresenterHost.cs b/src/Avalonia.Controls/Presenters/IContentPresenterHost.cs index 562638e94af..4c1e16ef728 100644 --- a/src/Avalonia.Controls/Presenters/IContentPresenterHost.cs +++ b/src/Avalonia.Controls/Presenters/IContentPresenterHost.cs @@ -17,7 +17,7 @@ namespace Avalonia.Controls.Presenters /// interface. /// [NotClientImplementable] - public interface IContentPresenterHost : ITemplatedControl + public interface IContentPresenterHost { /// /// Gets a collection describing the logical children of the host control. diff --git a/src/Avalonia.Controls/Presenters/IItemsPresenter.cs b/src/Avalonia.Controls/Presenters/IItemsPresenter.cs index 7cc72ef0a7e..dea8d4960e7 100644 --- a/src/Avalonia.Controls/Presenters/IItemsPresenter.cs +++ b/src/Avalonia.Controls/Presenters/IItemsPresenter.cs @@ -9,7 +9,7 @@ public interface IItemsPresenter : IPresenter { IEnumerable? Items { get; set; } - IPanel? Panel { get; } + Panel? Panel { get; } void ItemsChanged(NotifyCollectionChangedEventArgs e); diff --git a/src/Avalonia.Controls/Presenters/IItemsPresenterHost.cs b/src/Avalonia.Controls/Presenters/IItemsPresenterHost.cs index db11474871b..a73d2abb5f6 100644 --- a/src/Avalonia.Controls/Presenters/IItemsPresenterHost.cs +++ b/src/Avalonia.Controls/Presenters/IItemsPresenterHost.cs @@ -15,7 +15,7 @@ namespace Avalonia.Controls.Presenters /// interface. /// [NotClientImplementable] - public interface IItemsPresenterHost : ITemplatedControl + public interface IItemsPresenterHost { /// /// Registers an with a host control. diff --git a/src/Avalonia.Controls/Presenters/IPresenter.cs b/src/Avalonia.Controls/Presenters/IPresenter.cs index 0399983189f..dc1d40cdcd6 100644 --- a/src/Avalonia.Controls/Presenters/IPresenter.cs +++ b/src/Avalonia.Controls/Presenters/IPresenter.cs @@ -14,7 +14,7 @@ namespace Avalonia.Controls.Presenters /// of the presenter is not a part of the template. /// [NotClientImplementable] - public interface IPresenter : IControl, INamed + public interface IPresenter : INamed { } } diff --git a/src/Avalonia.Controls/Presenters/ItemContainerSync.cs b/src/Avalonia.Controls/Presenters/ItemContainerSync.cs index 81184f719e2..7346a074f30 100644 --- a/src/Avalonia.Controls/Presenters/ItemContainerSync.cs +++ b/src/Avalonia.Controls/Presenters/ItemContainerSync.cs @@ -110,7 +110,7 @@ private static IList AddContainers( } private static void RemoveContainers( - IPanel panel, + Panel panel, IEnumerable items) { foreach (var i in items) diff --git a/src/Avalonia.Controls/Presenters/ItemVirtualizer.cs b/src/Avalonia.Controls/Presenters/ItemVirtualizer.cs index 4c412e9a415..1f0f2a2f67f 100644 --- a/src/Avalonia.Controls/Presenters/ItemVirtualizer.cs +++ b/src/Avalonia.Controls/Presenters/ItemVirtualizer.cs @@ -32,7 +32,7 @@ public ItemVirtualizer(ItemsPresenter owner) if (panel != null) { - _subscriptions = panel.GetObservable(Panel.BoundsProperty) + _subscriptions = ((AvaloniaObject)panel).GetObservable(Panel.BoundsProperty) .Skip(1) .Subscribe(_ => InvalidateScroll()); } @@ -254,7 +254,7 @@ public virtual void UpdateControls() /// The movement direction. /// The control from which movement begins. /// The control. - public virtual IControl? GetControlInDirection(NavigationDirection direction, IControl? from) + public virtual Control? GetControlInDirection(NavigationDirection direction, Control? from) { return null; } diff --git a/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs b/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs index 4db2ec6d507..f010c46c1ab 100644 --- a/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs +++ b/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs @@ -226,7 +226,7 @@ public override void ItemsChanged(IEnumerable? items, NotifyCollectionChangedEve InvalidateScroll(); } - public override IControl? GetControlInDirection(NavigationDirection direction, IControl? from) + public override Control? GetControlInDirection(NavigationDirection direction, Control? from) { var generator = Owner.ItemContainerGenerator; var panel = VirtualizingPanel; @@ -313,8 +313,9 @@ private void CreateAndRemoveContainers() { var generator = Owner.ItemContainerGenerator; var panel = VirtualizingPanel; + var panelControl = (Control)panel; - if (!panel.IsFull && Items != null && panel.IsAttachedToVisualTree) + if (!panel.IsFull && Items != null && panelControl.IsAttachedToVisualTree) { var index = NextIndex; var step = 1; @@ -513,25 +514,26 @@ private void RemoveContainers(int count) /// /// The item index. /// The container that was brought into view. - private IControl? ScrollIntoViewCore(int index) + private Control? ScrollIntoViewCore(int index) { var panel = VirtualizingPanel; + var panelControl = (Control)panel; var generator = Owner.ItemContainerGenerator; var newOffset = -1.0; //better not trigger any container generation/recycle while or layout stuff //before panel is attached/visible - if (!panel.IsAttachedToVisualTree) + if (!panelControl.IsAttachedToVisualTree) { return null; } - if (!panel.IsMeasureValid && panel.PreviousMeasure.HasValue) + if (!panelControl.IsMeasureValid && panelControl.PreviousMeasure.HasValue) { //before any kind of scrolling we need to make sure panel measure is valid //or we risk get panel into not valid state //we make a preemptive quick measure so scrolling is valid - panel.Measure(panel.PreviousMeasure.Value); + panelControl.Measure(panelControl.PreviousMeasure.Value); } if (index >= 0 && index < ItemCount) @@ -567,17 +569,17 @@ private void RemoveContainers(int count) { OffsetValue = newOffset; } - + if (panel.ScrollDirection == Orientation.Vertical) { - if (container.Bounds.Y < panel.Bounds.Y || container.Bounds.Bottom > panel.Bounds.Bottom) + if (container.Bounds.Y < panelControl.Bounds.Y || container.Bounds.Bottom > panelControl.Bounds.Bottom) { OffsetValue += 1; } } else { - if (container.Bounds.X < panel.Bounds.X || container.Bounds.Right > panel.Bounds.Right) + if (container.Bounds.X < panelControl.Bounds.X || container.Bounds.Right > panelControl.Bounds.Right) { OffsetValue += 1; } diff --git a/src/Avalonia.Controls/Presenters/ItemsPresenter.cs b/src/Avalonia.Controls/Presenters/ItemsPresenter.cs index 265704ceaa2..924c4567f60 100644 --- a/src/Avalonia.Controls/Presenters/ItemsPresenter.cs +++ b/src/Avalonia.Controls/Presenters/ItemsPresenter.cs @@ -111,13 +111,13 @@ event EventHandler? ILogicalScrollable.ScrollInvalidated internal ItemVirtualizer? Virtualizer { get; private set; } /// - bool ILogicalScrollable.BringIntoView(IControl target, Rect targetRect) + bool ILogicalScrollable.BringIntoView(Control target, Rect targetRect) { return false; } /// - IControl? ILogicalScrollable.GetControlInDirection(NavigationDirection direction, IControl? from) + Control? ILogicalScrollable.GetControlInDirection(NavigationDirection direction, Control? from) { return Virtualizer?.GetControlInDirection(direction, from); } @@ -145,7 +145,7 @@ protected override Size ArrangeOverride(Size finalSize) } /// - protected override void PanelCreated(IPanel panel) + protected override void PanelCreated(Panel panel) { Virtualizer?.Dispose(); Virtualizer = ItemVirtualizer.Create(this); diff --git a/src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs b/src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs index 836433cdf82..38a2a5722c1 100644 --- a/src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs +++ b/src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs @@ -14,7 +14,7 @@ namespace Avalonia.Controls.Presenters /// /// Base class for controls that present items inside an . /// - public abstract class ItemsPresenterBase : Control, IItemsPresenter, ITemplatedControl, IChildIndexProvider + public abstract class ItemsPresenterBase : Control, IItemsPresenter, IChildIndexProvider { /// /// Defines the property. @@ -25,7 +25,7 @@ public abstract class ItemsPresenterBase : Control, IItemsPresenter, ITemplatedC /// /// Defines the property. /// - public static readonly StyledProperty> ItemsPanelProperty = + public static readonly StyledProperty> ItemsPanelProperty = ItemsControl.ItemsPanelProperty.AddOwner(); /// @@ -112,7 +112,7 @@ internal set /// /// Gets or sets a template which creates the used to display the items. /// - public ITemplate ItemsPanel + public ITemplate ItemsPanel { get { return GetValue(ItemsPanelProperty); } set { SetValue(ItemsPanelProperty, value); } @@ -139,7 +139,7 @@ public IBinding? DisplayMemberBinding /// /// Gets the panel used to display the items. /// - public IPanel? Panel + public Panel? Panel { get; private set; @@ -229,7 +229,7 @@ protected override Size ArrangeOverride(Size finalSize) /// Called when the is created. /// /// The panel. - protected virtual void PanelCreated(IPanel panel) + protected virtual void PanelCreated(Panel panel) { } @@ -290,7 +290,7 @@ private void TemplatedParentChanged(AvaloniaPropertyChangedEventArgs e) int IChildIndexProvider.GetChildIndex(ILogical child) { - if (child is IControl control && ItemContainerGenerator is { } generator) + if (child is Control control && ItemContainerGenerator is { } generator) { var index = ItemContainerGenerator.IndexFromContainer(control); diff --git a/src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs b/src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs index 189197dd58a..328facba0b4 100644 --- a/src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs +++ b/src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs @@ -73,8 +73,8 @@ public class ScrollContentPresenter : ContentPresenter, IPresenter, IScrollable, private IDisposable? _logicalScrollSubscription; private Size _viewport; private Dictionary? _activeLogicalGestureScrolls; - private List? _anchorCandidates; - private IControl? _anchorElement; + private List? _anchorCandidates; + private Control? _anchorElement; private Rect _anchorElementBounds; private bool _isAnchorElementDirty; @@ -158,7 +158,7 @@ public bool IsScrollChainingEnabled } /// - IControl? IScrollAnchorProvider.CurrentAnchor + Control? IScrollAnchorProvider.CurrentAnchor { get { @@ -173,7 +173,7 @@ public bool IsScrollChainingEnabled /// The target visual. /// The portion of the target visual to bring into view. /// True if the scroll offset was changed; otherwise false. - public bool BringDescendantIntoView(IVisual target, Rect targetRect) + public bool BringDescendantIntoView(Visual target, Rect targetRect) { if (Child?.IsEffectivelyVisible != true) { @@ -181,7 +181,7 @@ public bool BringDescendantIntoView(IVisual target, Rect targetRect) } var scrollable = Child as ILogicalScrollable; - var control = target as IControl; + var control = target as Control; if (scrollable?.IsLogicalScrollEnabled == true && control != null) { @@ -232,7 +232,7 @@ public bool BringDescendantIntoView(IVisual target, Rect targetRect) } /// - void IScrollAnchorProvider.RegisterAnchorCandidate(IControl element) + void IScrollAnchorProvider.RegisterAnchorCandidate(Control element) { if (!this.IsVisualAncestorOf(element)) { @@ -240,13 +240,13 @@ void IScrollAnchorProvider.RegisterAnchorCandidate(IControl element) "An anchor control must be a visual descendent of the ScrollContentPresenter."); } - _anchorCandidates ??= new List(); + _anchorCandidates ??= new List(); _anchorCandidates.Add(element); _isAnchorElementDirty = true; } /// - void IScrollAnchorProvider.UnregisterAnchorCandidate(IControl element) + void IScrollAnchorProvider.UnregisterAnchorCandidate(Control element) { _anchorCandidates?.Remove(element); _isAnchorElementDirty = true; @@ -496,7 +496,7 @@ private void BringIntoViewRequested(object? sender, RequestBringIntoViewEventArg private void ChildChanged(AvaloniaPropertyChangedEventArgs e) { - UpdateScrollableSubscription((IControl?)e.NewValue); + UpdateScrollableSubscription((Control?)e.NewValue); if (e.OldValue != null) { @@ -504,7 +504,7 @@ private void ChildChanged(AvaloniaPropertyChangedEventArgs e) } } - private void UpdateScrollableSubscription(IControl? child) + private void UpdateScrollableSubscription(Control? child) { var scrollable = child as ILogicalScrollable; @@ -564,7 +564,7 @@ private void EnsureAnchorElementSelection() _anchorElementBounds = default; _isAnchorElementDirty = false; - var bestCandidate = default(IControl); + var bestCandidate = default(Control); var bestCandidateDistance = double.MaxValue; // Find the anchor candidate that is scrolled closest to the top-left of this @@ -595,7 +595,7 @@ private void EnsureAnchorElementSelection() } } - private bool GetViewportBounds(IControl element, out Rect bounds) + private bool GetViewportBounds(Control element, out Rect bounds) { if (TranslateBounds(element, Child!, out var childBounds)) { @@ -612,7 +612,7 @@ private bool GetViewportBounds(IControl element, out Rect bounds) return false; } - private Rect TranslateBounds(IControl control, IControl to) + private Rect TranslateBounds(Control control, Control to) { if (TranslateBounds(control, to, out var bounds)) { @@ -622,7 +622,7 @@ private Rect TranslateBounds(IControl control, IControl to) throw new InvalidOperationException("The control's bounds could not be translated to the requested control."); } - private bool TranslateBounds(IControl control, IControl to, out Rect bounds) + private bool TranslateBounds(Control control, Control to, out Rect bounds) { if (!control.IsVisible) { diff --git a/src/Avalonia.Controls/Primitives/AdornerLayer.cs b/src/Avalonia.Controls/Primitives/AdornerLayer.cs index d557424fbb9..89abe1cdaa1 100644 --- a/src/Avalonia.Controls/Primitives/AdornerLayer.cs +++ b/src/Avalonia.Controls/Primitives/AdornerLayer.cs @@ -60,7 +60,7 @@ public static void SetAdornedElement(Visual adorner, Visual adorned) adorner.SetValue(AdornedElementProperty, adorned); } - public static AdornerLayer? GetAdornerLayer(IVisual visual) + public static AdornerLayer? GetAdornerLayer(Visual visual) { return visual.FindAncestorOfType()?.AdornerLayer; } @@ -232,7 +232,7 @@ private static void AdornedElementChanged(AvaloniaPropertyChangedEventArgsThe target visual. /// The portion of the target visual to bring into view. /// True if the scroll offset was changed; otherwise false. - bool BringIntoView(IControl target, Rect targetRect); + bool BringIntoView(Control target, Rect targetRect); /// /// Gets the next control in the specified direction. @@ -64,7 +64,7 @@ public interface ILogicalScrollable : IScrollable /// The movement direction. /// The control from which movement begins. /// The control. - IControl? GetControlInDirection(NavigationDirection direction, IControl? from); + Control? GetControlInDirection(NavigationDirection direction, Control? from); /// /// Raises the event. diff --git a/src/Avalonia.Controls/Primitives/IPopupHost.cs b/src/Avalonia.Controls/Primitives/IPopupHost.cs index bd2aa39621f..90fbdcdbec2 100644 --- a/src/Avalonia.Controls/Primitives/IPopupHost.cs +++ b/src/Avalonia.Controls/Primitives/IPopupHost.cs @@ -68,7 +68,7 @@ public interface IPopupHost : IDisposable, IFocusScope /// Gets the root of the visual tree in the case where the popup is presented using a /// separate visual tree. /// - IVisual? HostedVisualTreeRoot { get; } + Visual? HostedVisualTreeRoot { get; } /// /// Raised when the control's template is applied. @@ -88,7 +88,7 @@ public interface IPopupHost : IDisposable, IFocusScope /// /// The anchor rect. If null, the bounds of will be used. /// - void ConfigurePosition(IVisual target, PlacementMode placement, Point offset, + void ConfigurePosition(Visual target, PlacementMode placement, Point offset, PopupAnchor anchor = PopupAnchor.None, PopupGravity gravity = PopupGravity.None, PopupPositionerConstraintAdjustment constraintAdjustment = PopupPositionerConstraintAdjustment.All, @@ -98,7 +98,7 @@ void ConfigurePosition(IVisual target, PlacementMode placement, Point offset, /// Sets the control to display in the popup. /// /// - void SetChild(IControl? control); + void SetChild(Control? control); /// /// Shows the popup. diff --git a/src/Avalonia.Controls/Primitives/LightDismissOverlayLayer.cs b/src/Avalonia.Controls/Primitives/LightDismissOverlayLayer.cs index 04c30b0f339..8525f025a32 100644 --- a/src/Avalonia.Controls/Primitives/LightDismissOverlayLayer.cs +++ b/src/Avalonia.Controls/Primitives/LightDismissOverlayLayer.cs @@ -26,7 +26,7 @@ static LightDismissOverlayLayer() /// /// The visual. /// The light dismiss overlay, or null if none found. - public static LightDismissOverlayLayer? GetLightDismissOverlayLayer(IVisual visual) + public static LightDismissOverlayLayer? GetLightDismissOverlayLayer(Visual visual) { visual = visual ?? throw new ArgumentNullException(nameof(visual)); @@ -48,13 +48,13 @@ static LightDismissOverlayLayer() public bool HitTest(Point point) { - if (InputPassThroughElement is object) + if (InputPassThroughElement is Visual v) { - var hit = VisualRoot?.GetVisualAt(point, x => x != this); + var hit = ((Visual?)VisualRoot)?.GetVisualAt(point, x => x != this); if (hit is object) { - return !InputPassThroughElement.IsVisualAncestorOf(hit); + return !v.IsVisualAncestorOf(hit); } } diff --git a/src/Avalonia.Controls/Primitives/OverlayLayer.cs b/src/Avalonia.Controls/Primitives/OverlayLayer.cs index 468879edd12..91136cb295c 100644 --- a/src/Avalonia.Controls/Primitives/OverlayLayer.cs +++ b/src/Avalonia.Controls/Primitives/OverlayLayer.cs @@ -7,7 +7,7 @@ namespace Avalonia.Controls.Primitives public class OverlayLayer : Canvas, ICustomSimpleHitTest { public Size AvailableSize { get; private set; } - public static OverlayLayer? GetOverlayLayer(IVisual visual) + public static OverlayLayer? GetOverlayLayer(Visual visual) { foreach(var v in visual.GetVisualAncestors()) if(v is VisualLayerManager vlm) diff --git a/src/Avalonia.Controls/Primitives/OverlayPopupHost.cs b/src/Avalonia.Controls/Primitives/OverlayPopupHost.cs index 4765718c3bd..cd26ea4f6e4 100644 --- a/src/Avalonia.Controls/Primitives/OverlayPopupHost.cs +++ b/src/Avalonia.Controls/Primitives/OverlayPopupHost.cs @@ -9,7 +9,7 @@ namespace Avalonia.Controls.Primitives { - public class OverlayPopupHost : ContentControl, IPopupHost, IInteractive, IManagedPopupPositionerPopup + public class OverlayPopupHost : ContentControl, IPopupHost, IManagedPopupPositionerPopup { /// /// Defines the property. @@ -29,12 +29,12 @@ public OverlayPopupHost(OverlayLayer overlayLayer) _positioner = new ManagedPopupPositioner(this); } - public void SetChild(IControl? control) + public void SetChild(Control? control) { Content = control; } - public IVisual? HostedVisualTreeRoot => null; + public Visual? HostedVisualTreeRoot => null; public Transform? Transform { @@ -42,15 +42,14 @@ public Transform? Transform set => SetValue(TransformProperty, value); } - /// - IInteractive? IInteractive.InteractiveParent => Parent; - bool IPopupHost.Topmost { get => false; set { /* Not currently supported in overlay popups */ } } + protected internal override Interactive? InteractiveParent => Parent; + public void Dispose() => Hide(); @@ -66,7 +65,7 @@ public void Hide() _shown = false; } - public void ConfigurePosition(IVisual target, PlacementMode placement, Point offset, + public void ConfigurePosition(Visual target, PlacementMode placement, Point offset, PopupAnchor anchor = PopupAnchor.None, PopupGravity gravity = PopupGravity.None, PopupPositionerConstraintAdjustment constraintAdjustment = PopupPositionerConstraintAdjustment.All, Rect? rect = null) @@ -122,7 +121,7 @@ void IManagedPopupPositionerPopup.MoveAndResize(Point devicePoint, Size virtualS double IManagedPopupPositionerPopup.Scaling => 1; - public static IPopupHost CreatePopupHost(IVisual target, IAvaloniaDependencyResolver? dependencyResolver) + public static IPopupHost CreatePopupHost(Visual target, IAvaloniaDependencyResolver? dependencyResolver) { var platform = (target.GetVisualRoot() as TopLevel)?.PlatformImpl?.CreatePopup(); if (platform != null) diff --git a/src/Avalonia.Controls/Primitives/Popup.cs b/src/Avalonia.Controls/Primitives/Popup.cs index ccb81ba2765..337ff54985a 100644 --- a/src/Avalonia.Controls/Primitives/Popup.cs +++ b/src/Avalonia.Controls/Primitives/Popup.cs @@ -352,7 +352,7 @@ public void Open() return; } - var placementTarget = PlacementTarget ?? this.FindLogicalAncestorOfType(); + var placementTarget = PlacementTarget ?? this.FindLogicalAncestorOfType(); if (placementTarget == null) { @@ -546,7 +546,7 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang { if (change.Property == PlacementTargetProperty) { - var newTarget = change.GetNewValue() ?? this.FindLogicalAncestorOfType(); + var newTarget = change.GetNewValue() ?? this.FindLogicalAncestorOfType(); if (newTarget is null || newTarget.GetVisualRoot() != _openState.TopLevel) { @@ -566,7 +566,7 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang } } - private void UpdateHostPosition(IPopupHost popupHost, IControl placementTarget) + private void UpdateHostPosition(IPopupHost popupHost, Control placementTarget) { popupHost.ConfigurePosition( placementTarget, @@ -578,7 +578,7 @@ private void UpdateHostPosition(IPopupHost popupHost, IControl placementTarget) PlacementRect ?? new Rect(default, placementTarget.Bounds.Size)); } - private void UpdateHostSizing(IPopupHost popupHost, TopLevel topLevel, IControl placementTarget) + private void UpdateHostSizing(IPopupHost popupHost, TopLevel topLevel, Control placementTarget) { var scaleX = 1.0; var scaleY = 1.0; @@ -613,7 +613,7 @@ private void HandlePositionChange() { if (_openState != null) { - var placementTarget = PlacementTarget ?? this.FindLogicalAncestorOfType(); + var placementTarget = PlacementTarget ?? this.FindLogicalAncestorOfType(); if (placementTarget == null) return; _openState.PopupHost.ConfigurePosition( @@ -723,7 +723,7 @@ private void CloseCore() { if (PlacementTarget != null) { - var e = (IControl?)PlacementTarget; + var e = (Control?)PlacementTarget; while (e is object && (!e.Focusable || !e.IsEffectivelyEnabled || !e.IsVisible)) { @@ -737,7 +737,7 @@ private void CloseCore() } else { - var anc = this.FindLogicalAncestorOfType(); + var anc = this.FindLogicalAncestorOfType(); if (anc != null) { FocusManager.Instance?.Focus(anc); @@ -758,7 +758,7 @@ private void ListenForNonClientClick(RawInputEventArgs e) private void PointerPressedDismissOverlay(object? sender, PointerPressedEventArgs e) { - if (IsLightDismissEnabled && e.Source is IVisual v && !IsChildOrThis(v)) + if (IsLightDismissEnabled && e.Source is Visual v && !IsChildOrThis(v)) { CloseCore(); @@ -772,7 +772,7 @@ private void PointerPressedDismissOverlay(object? sender, PointerPressedEventArg private void PassThroughEvent(PointerPressedEventArgs e) { if (e.Source is LightDismissOverlayLayer layer && - layer.GetVisualRoot() is IInputElement root) + layer.GetVisualRoot() is InputElement root) { var p = e.GetCurrentPoint(root); var hit = root.InputHitTest(p.Position, x => x != layer); @@ -802,18 +802,18 @@ private void RootTemplateApplied(object? sender, TemplateAppliedEventArgs e) // If the Popup appears in a control template, then the child controls // that appear in the popup host need to have their TemplatedParent // properties set. - if (TemplatedParent != null && popupHost.Presenter != null) + if (TemplatedParent != null && popupHost.Presenter is Control presenter) { - popupHost.Presenter.ApplyTemplate(); + presenter.ApplyTemplate(); - var presenterSubscription = popupHost.Presenter.GetObservable(ContentPresenter.ChildProperty) + var presenterSubscription = presenter.GetObservable(ContentPresenter.ChildProperty) .Subscribe(SetTemplatedParentAndApplyChildTemplates); _openState.SetPresenterSubscription(presenterSubscription); } } - private void SetTemplatedParentAndApplyChildTemplates(IControl? control) + private void SetTemplatedParentAndApplyChildTemplates(Control? control) { if (control != null) { @@ -821,7 +821,7 @@ private void SetTemplatedParentAndApplyChildTemplates(IControl? control) } } - private bool IsChildOrThis(IVisual child) + private bool IsChildOrThis(Visual child) { if (_openState is null) { @@ -830,7 +830,7 @@ private bool IsChildOrThis(IVisual child) var popupHost = _openState.PopupHost; - IVisual? root = child.VisualRoot; + Visual? root = child.VisualRoot as Visual; while (root is IHostedVisualTreeRoot hostedRoot) { @@ -839,13 +839,13 @@ private bool IsChildOrThis(IVisual child) return true; } - root = hostedRoot.Host?.VisualRoot; + root = hostedRoot.Host?.VisualRoot as Visual; } return false; } - public bool IsInsidePopup(IVisual visual) + public bool IsInsidePopup(Visual visual) { if (_openState is null) { @@ -854,7 +854,7 @@ public bool IsInsidePopup(IVisual visual) var popupHost = _openState.PopupHost; - return popupHost != null && ((IVisual)popupHost).IsVisualAncestorOf(visual); + return popupHost != null && ((Visual)popupHost).IsVisualAncestorOf(visual); } public bool IsPointerOverPopup => ((IInputElement?)_openState?.PopupHost)?.IsPointerOver ?? false; @@ -921,7 +921,7 @@ private class PopupOpenState : IDisposable private readonly IDisposable _cleanup; private IDisposable? _presenterCleanup; - public PopupOpenState(IControl placementTarget, TopLevel topLevel, IPopupHost popupHost, IDisposable cleanup) + public PopupOpenState(Control placementTarget, TopLevel topLevel, IPopupHost popupHost, IDisposable cleanup) { PlacementTarget = placementTarget; TopLevel = topLevel; @@ -930,7 +930,7 @@ public PopupOpenState(IControl placementTarget, TopLevel topLevel, IPopupHost po } public TopLevel TopLevel { get; } - public IControl PlacementTarget { get; set; } + public Control PlacementTarget { get; set; } public IPopupHost PopupHost { get; } public void SetPresenterSubscription(IDisposable? presenterCleanup) diff --git a/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs b/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs index 615eb69fe33..17dfec118f1 100644 --- a/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs +++ b/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs @@ -448,7 +448,7 @@ static class PopupPositionerExtensions { public static void ConfigurePosition(ref this PopupPositionerParameters positionerParameters, TopLevel topLevel, - IVisual target, PlacementMode placement, Point offset, + Visual target, PlacementMode placement, Point offset, PopupAnchor anchor, PopupGravity gravity, PopupPositionerConstraintAdjustment constraintAdjustment, Rect? rect, FlowDirection flowDirection) diff --git a/src/Avalonia.Controls/Primitives/PopupRoot.cs b/src/Avalonia.Controls/Primitives/PopupRoot.cs index f7bf7c1a273..57ec864cada 100644 --- a/src/Avalonia.Controls/Primitives/PopupRoot.cs +++ b/src/Avalonia.Controls/Primitives/PopupRoot.cs @@ -12,7 +12,7 @@ namespace Avalonia.Controls.Primitives /// /// The root window of a . /// - public sealed class PopupRoot : WindowBase, IInteractive, IHostedVisualTreeRoot, IDisposable, IStyleHost, IPopupHost + public sealed class PopupRoot : WindowBase, IHostedVisualTreeRoot, IDisposable, IStyleHost, IPopupHost { /// /// Defines the property. @@ -72,12 +72,12 @@ public Transform? Transform /// /// Popup events are passed to their parent window. This facilitates this. /// - IInteractive? IInteractive.InteractiveParent => Parent; + protected internal override Interactive? InteractiveParent => Parent; /// /// Gets the control that is hosting the popup root. /// - IVisual? IHostedVisualTreeRoot.Host => Parent; + Visual? IHostedVisualTreeRoot.Host => Parent; /// /// Gets the styling parent of the popup root. @@ -98,7 +98,7 @@ private void UpdatePosition() PlatformImpl?.PopupPositioner.Update(_positionerParameters); } - public void ConfigurePosition(IVisual target, PlacementMode placement, Point offset, + public void ConfigurePosition(Visual target, PlacementMode placement, Point offset, PopupAnchor anchor = PopupAnchor.None, PopupGravity gravity = PopupGravity.None, PopupPositionerConstraintAdjustment constraintAdjustment = PopupPositionerConstraintAdjustment.All, @@ -111,9 +111,9 @@ public void ConfigurePosition(IVisual target, PlacementMode placement, Point off UpdatePosition(); } - public void SetChild(IControl? control) => Content = control; + public void SetChild(Control? control) => Content = control; - IVisual IPopupHost.HostedVisualTreeRoot => this; + Visual IPopupHost.HostedVisualTreeRoot => this; protected override Size MeasureOverride(Size availableSize) { diff --git a/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs b/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs index e03b02a4790..f8951b3fa31 100644 --- a/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs +++ b/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs @@ -386,11 +386,11 @@ public override void EndInit() /// /// The control that raised the event. /// The container or null if the event did not originate in a container. - protected IControl? GetContainerFromEventSource(IInteractive? eventSource) + protected Control? GetContainerFromEventSource(object? eventSource) { - for (var current = eventSource as IVisual; current != null; current = current.VisualParent) + for (var current = eventSource as Visual; current != null; current = current.VisualParent) { - if (current is IControl control && control.LogicalParent == this && + if (current is Control control && control.Parent == this && ItemContainerGenerator?.IndexFromContainer(control) != -1) { return control; @@ -645,10 +645,10 @@ protected bool MoveSelection(NavigationDirection direction, bool wrap) /// The direction to move. /// Whether to wrap when the selection reaches the first or last item. /// True if the selection was moved; otherwise false. - protected bool MoveSelection(IControl? from, NavigationDirection direction, bool wrap) + protected bool MoveSelection(Control? from, NavigationDirection direction, bool wrap) { if (Presenter?.Panel is INavigableContainer container && - GetNextControl(container, direction, from, wrap) is IControl next) + GetNextControl(container, direction, from, wrap) is Control next) { var index = ItemContainerGenerator?.IndexFromContainer(next) ?? -1; @@ -750,7 +750,7 @@ protected void UpdateSelection( /// Whether the event is a right-click. /// Wheter the event is a focus event protected void UpdateSelection( - IControl container, + Control container, bool select = true, bool rangeModifier = false, bool toggleModifier = false, @@ -780,7 +780,7 @@ protected void UpdateSelection( /// false. /// protected bool UpdateSelectionFromEventSource( - IInteractive? eventSource, + object? eventSource, bool select = true, bool rangeModifier = false, bool toggleModifier = false, @@ -892,7 +892,7 @@ private void AutoScrollToSelectedItemIfNecessary() !_hasScrolledToSelectedItem && Presenter is object && Selection.AnchorIndex >= 0 && - ((IVisual)this).IsAttachedToVisualTree) + IsAttachedToVisualTree) { ScrollIntoView(Selection.AnchorIndex); _hasScrolledToSelectedItem = true; @@ -906,9 +906,9 @@ Presenter is object && private void ContainerSelectionChanged(RoutedEventArgs e) { if (!_ignoreContainerSelectionChanged && - e.Source is IControl control && + e.Source is Control control && e.Source is ISelectable selectable && - control.LogicalParent == this && + control.Parent == this && ItemContainerGenerator?.IndexFromContainer(control) != -1) { UpdateSelection(control, selectable.IsSelected); @@ -926,7 +926,7 @@ e.Source is ISelectable selectable && /// The container. /// Whether the control is selected /// The previous selection state. - private bool MarkContainerSelected(IControl container, bool selected) + private bool MarkContainerSelected(Control container, bool selected) { try { @@ -955,7 +955,7 @@ private bool MarkContainerSelected(IControl container, bool selected) private void UpdateContainerSelection() { - if (Presenter?.Panel is IPanel panel) + if (Presenter?.Panel is Panel panel) { foreach (var container in panel.Children) { diff --git a/src/Avalonia.Controls/Primitives/TabStrip.cs b/src/Avalonia.Controls/Primitives/TabStrip.cs index f8f7674da81..d27b1faaed7 100644 --- a/src/Avalonia.Controls/Primitives/TabStrip.cs +++ b/src/Avalonia.Controls/Primitives/TabStrip.cs @@ -8,8 +8,8 @@ namespace Avalonia.Controls.Primitives { public class TabStrip : SelectingItemsControl { - private static readonly FuncTemplate DefaultPanel = - new FuncTemplate(() => new WrapPanel { Orientation = Orientation.Horizontal }); + private static readonly FuncTemplate DefaultPanel = + new FuncTemplate(() => new WrapPanel { Orientation = Orientation.Horizontal }); static TabStrip() { @@ -42,7 +42,7 @@ protected override void OnPointerPressed(PointerPressedEventArgs e) { base.OnPointerPressed(e); - if (e.Source is IVisual source) + if (e.Source is Visual source) { var point = e.GetCurrentPoint(source); diff --git a/src/Avalonia.Controls/Primitives/TemplatedControl.cs b/src/Avalonia.Controls/Primitives/TemplatedControl.cs index 17d90e6dd09..9a684c4534f 100644 --- a/src/Avalonia.Controls/Primitives/TemplatedControl.cs +++ b/src/Avalonia.Controls/Primitives/TemplatedControl.cs @@ -14,7 +14,7 @@ namespace Avalonia.Controls.Primitives /// /// A lookless control whose visual appearance is defined by its . /// - public class TemplatedControl : Control, ITemplatedControl + public class TemplatedControl : Control { /// /// Defines the property. @@ -307,7 +307,7 @@ public sealed override void ApplyTemplate() } /// - protected override IControl GetTemplateFocusTarget() + protected override Control GetTemplateFocusTarget() { foreach (Control child in this.GetTemplateChildren()) { @@ -380,7 +380,7 @@ protected virtual void OnTemplateChanged(AvaloniaPropertyChangedEventArgs e) /// /// The control. /// The templated parent to apply. - internal static void ApplyTemplatedParent(IStyledElement control, ITemplatedControl? templatedParent) + internal static void ApplyTemplatedParent(StyledElement control, AvaloniaObject? templatedParent) { control.SetValue(TemplatedParentProperty, templatedParent); @@ -389,7 +389,7 @@ internal static void ApplyTemplatedParent(IStyledElement control, ITemplatedCont for (var i = 0; i < count; i++) { - if (children[i] is IStyledElement child && child.TemplatedParent is null) + if (children[i] is StyledElement child && child.TemplatedParent is null) { ApplyTemplatedParent(child, templatedParent); } diff --git a/src/Avalonia.Controls/RelativePanel.cs b/src/Avalonia.Controls/RelativePanel.cs index ab8e0640283..af466eea488 100644 --- a/src/Avalonia.Controls/RelativePanel.cs +++ b/src/Avalonia.Controls/RelativePanel.cs @@ -21,7 +21,7 @@ public partial class RelativePanel : Panel if (dependency is Layoutable layoutable) { - if (Children.Contains((ILayoutable)layoutable)) + if (Children.Contains(layoutable)) return layoutable; throw new ArgumentException($"RelativePanel error: Element does not exist in the current context: {property.Name}"); diff --git a/src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs b/src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs index 3bc05938137..bc11c35fde2 100644 --- a/src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs +++ b/src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs @@ -258,7 +258,7 @@ protected void SetDpi(Vector dpi) protected virtual Size Measure(Size constraint) { - var l = (ILayoutable) InputRoot!; + var l = (Layoutable) InputRoot!; l.Measure(constraint); return l.DesiredSize; } diff --git a/src/Avalonia.Controls/Repeater/ElementFactory.cs b/src/Avalonia.Controls/Repeater/ElementFactory.cs index 6b776803d77..7862892943f 100644 --- a/src/Avalonia.Controls/Repeater/ElementFactory.cs +++ b/src/Avalonia.Controls/Repeater/ElementFactory.cs @@ -4,12 +4,12 @@ namespace Avalonia.Controls { public abstract class ElementFactory : IElementFactory { - public IControl Build(object? data) + public Control Build(object? data) { return GetElementCore(new ElementFactoryGetArgs { Data = data }); } - public IControl GetElement(ElementFactoryGetArgs args) + public Control GetElement(ElementFactoryGetArgs args) { return GetElementCore(args); } @@ -21,7 +21,7 @@ public void RecycleElement(ElementFactoryRecycleArgs args) RecycleElementCore(args); } - protected abstract IControl GetElementCore(ElementFactoryGetArgs args); + protected abstract Control GetElementCore(ElementFactoryGetArgs args); protected abstract void RecycleElementCore(ElementFactoryRecycleArgs args); } } diff --git a/src/Avalonia.Controls/Repeater/IElementFactory.cs b/src/Avalonia.Controls/Repeater/IElementFactory.cs index daab7e855f1..16f93695de1 100644 --- a/src/Avalonia.Controls/Repeater/IElementFactory.cs +++ b/src/Avalonia.Controls/Repeater/IElementFactory.cs @@ -15,10 +15,10 @@ public class ElementFactoryGetArgs public object? Data { get; set; } /// - /// Gets or sets the that is expected to be the parent of the + /// Gets or sets the that is expected to be the parent of the /// realized element from . /// - public IControl? Parent { get; set; } + public Control? Parent { get; set; } /// /// Gets or sets the index of the item that should be realized. @@ -33,16 +33,16 @@ public class ElementFactoryGetArgs public class ElementFactoryRecycleArgs { /// - /// Gets or sets the to recycle when calling + /// Gets or sets the to recycle when calling /// . /// - public IControl? Element { get; set; } + public Control? Element { get; set; } /// - /// Gets or sets the that is expected to be the parent of the + /// Gets or sets the that is expected to be the parent of the /// realized element from . /// - public IControl? Parent { get; set; } + public Control? Parent { get; set; } } /// @@ -51,13 +51,13 @@ public class ElementFactoryRecycleArgs public interface IElementFactory : IDataTemplate { /// - /// Gets an . + /// Gets an . /// /// The element args. - public IControl GetElement(ElementFactoryGetArgs args); + public Control GetElement(ElementFactoryGetArgs args); /// - /// Recycles an that was previously retrieved using + /// Recycles an that was previously retrieved using /// . /// /// The recycle args. diff --git a/src/Avalonia.Controls/Repeater/ItemTemplateWrapper.cs b/src/Avalonia.Controls/Repeater/ItemTemplateWrapper.cs index eb3b2ea787a..c25d15a27b9 100644 --- a/src/Avalonia.Controls/Repeater/ItemTemplateWrapper.cs +++ b/src/Avalonia.Controls/Repeater/ItemTemplateWrapper.cs @@ -13,10 +13,10 @@ internal class ItemTemplateWrapper : IElementFactory public ItemTemplateWrapper(IDataTemplate dataTemplate) => _dataTemplate = dataTemplate; - public IControl Build(object? param) => GetElement(null, param); + public Control Build(object? param) => GetElement(null, param); public bool Match(object? data) => _dataTemplate.Match(data); - public IControl GetElement(ElementFactoryGetArgs args) + public Control GetElement(ElementFactoryGetArgs args) { return GetElement(args.Parent, args.Data); } @@ -26,11 +26,11 @@ public void RecycleElement(ElementFactoryRecycleArgs args) RecycleElement(args.Parent, args.Element!); } - private IControl GetElement(IControl? parent, object? data) + private Control GetElement(Control? parent, object? data) { var selectedTemplate = _dataTemplate; var recyclePool = RecyclePool.GetPoolInstance(selectedTemplate); - IControl? element = null; + Control? element = null; if (recyclePool != null) { @@ -50,7 +50,7 @@ private IControl GetElement(IControl? parent, object? data) return element; } - private void RecycleElement(IControl? parent, IControl element) + private void RecycleElement(Control? parent, Control element) { var selectedTemplate = _dataTemplate; var recyclePool = RecyclePool.GetPoolInstance(selectedTemplate); diff --git a/src/Avalonia.Controls/Repeater/ItemsRepeater.cs b/src/Avalonia.Controls/Repeater/ItemsRepeater.cs index ae663defd32..41a0dc384f9 100644 --- a/src/Avalonia.Controls/Repeater/ItemsRepeater.cs +++ b/src/Avalonia.Controls/Repeater/ItemsRepeater.cs @@ -53,7 +53,7 @@ public class ItemsRepeater : Panel, IChildIndexProvider AvaloniaProperty.Register(nameof(VerticalCacheLength), 2.0); private static readonly StyledProperty VirtualizationInfoProperty = - AvaloniaProperty.RegisterAttached("VirtualizationInfo"); + AvaloniaProperty.RegisterAttached("VirtualizationInfo"); internal static readonly Rect InvalidRect = new Rect(-1, -1, -1, -1); internal static readonly Point ClearedElementsArrangePosition = new Point(-10000.0, -10000.0); @@ -156,9 +156,9 @@ public double VerticalCacheLength internal IElementFactory? ItemTemplateShim { get; set; } internal Point LayoutOrigin { get; set; } internal object? LayoutState { get; set; } - internal IControl? MadeAnchor => _viewportManager.MadeAnchor; + internal Control? MadeAnchor => _viewportManager.MadeAnchor; internal Rect RealizationWindow => _viewportManager.GetLayoutRealizationWindow(); - internal IControl? SuggestedAnchor => _viewportManager.SuggestedAnchor; + internal Control? SuggestedAnchor => _viewportManager.SuggestedAnchor; private bool IsProcessingCollectionChange => _processingItemsSourceChange != null; @@ -183,7 +183,7 @@ event EventHandler? IChildIndexProvider.ChildIndexCh int IChildIndexProvider.GetChildIndex(ILogical child) { - return child is IControl control + return child is Control control ? GetElementIndex(control) : -1; } @@ -205,7 +205,7 @@ bool IChildIndexProvider.TryGetTotalCount(out int count) public event EventHandler? ElementClearing; /// - /// Occurs for each realized when the index for the item it + /// Occurs for each realized when the index for the item it /// represents has changed. /// /// @@ -213,7 +213,7 @@ bool IChildIndexProvider.TryGetTotalCount(out int count) /// interactions on the child elements (such as selection or click), it is useful to be /// able to keep an up-to-date identifier for the backing data item. /// - /// This event is raised for each realized IControl where the index for the item it + /// This event is raised for each realized Control where the index for the item it /// represents has changed. For example, when another item is added or removed in the data /// source, the index for items that come after in the ordering will be impacted. /// @@ -230,7 +230,7 @@ bool IChildIndexProvider.TryGetTotalCount(out int count) /// /// Retrieves the index of the item from the data source that corresponds to the specified - /// . + /// . /// /// /// The element that corresponds to the item to get the index of. @@ -239,7 +239,7 @@ bool IChildIndexProvider.TryGetTotalCount(out int count) /// The index of the item from the data source that corresponds to the specified UIElement, /// or -1 if the element is not supported. /// - public int GetElementIndex(IControl element) => GetElementIndexImpl(element); + public int GetElementIndex(Control element) => GetElementIndexImpl(element); /// /// Retrieves the realized UIElement that corresponds to the item at the specified index in @@ -250,7 +250,7 @@ bool IChildIndexProvider.TryGetTotalCount(out int count) /// he UIElement that corresponds to the item at the specified index if the item is /// realized, or null if the item is not realized. /// - public IControl? TryGetElement(int index) => GetElementFromIndexImpl(index); + public Control? TryGetElement(int index) => GetElementFromIndexImpl(index); /// /// Retrieves the UIElement that corresponds to the item at the specified index in the @@ -258,21 +258,21 @@ bool IChildIndexProvider.TryGetTotalCount(out int count) /// /// The index of the item. /// - /// An that corresponds to the item at the specified index. If the + /// An that corresponds to the item at the specified index. If the /// item is not realized, a new UIElement is created. /// - public IControl GetOrCreateElement(int index) => GetOrCreateElementImpl(index); + public Control GetOrCreateElement(int index) => GetOrCreateElementImpl(index); - internal void PinElement(IControl element) => _viewManager.UpdatePin(element, true); + internal void PinElement(Control element) => _viewManager.UpdatePin(element, true); - internal void UnpinElement(IControl element) => _viewManager.UpdatePin(element, false); + internal void UnpinElement(Control element) => _viewManager.UpdatePin(element, false); - internal static VirtualizationInfo? TryGetVirtualizationInfo(IControl element) + internal static VirtualizationInfo? TryGetVirtualizationInfo(Control element) { return (element as AvaloniaObject)?.GetValue(VirtualizationInfoProperty); } - internal static VirtualizationInfo CreateAndInitializeVirtualizationInfo(IControl element) + internal static VirtualizationInfo CreateAndInitializeVirtualizationInfo(Control element) { if (TryGetVirtualizationInfo(element) != null) { @@ -284,7 +284,7 @@ internal static VirtualizationInfo CreateAndInitializeVirtualizationInfo(IContro return result; } - internal static VirtualizationInfo GetVirtualizationInfo(IControl element) + internal static VirtualizationInfo GetVirtualizationInfo(Control element) { if (element is AvaloniaObject ao) { @@ -299,7 +299,7 @@ internal static VirtualizationInfo GetVirtualizationInfo(IControl element) return result; } - throw new NotSupportedException("Custom implementations of IAvaloniaObject not supported."); + throw new NotSupportedException("Custom implementations of AvaloniaObject not supported."); } private protected override void InvalidateMeasureOnChildrenChanged() @@ -470,13 +470,13 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang base.OnPropertyChanged(change); } - internal IControl GetElementImpl(int index, bool forceCreate, bool suppressAutoRecycle) + internal Control GetElementImpl(int index, bool forceCreate, bool suppressAutoRecycle) { var element = _viewManager.GetElement(index, forceCreate, suppressAutoRecycle); return element; } - internal void ClearElementImpl(IControl element) + internal void ClearElementImpl(Control element) { // Clearing an element due to a collection change // is more strict in that pinned elements will be forcibly @@ -491,7 +491,7 @@ internal void ClearElementImpl(IControl element) _viewportManager.OnElementCleared(element, GetVirtualizationInfo(element)); } - private int GetElementIndexImpl(IControl element) + private int GetElementIndexImpl(Control element) { // Verify that element is actually a child of this ItemsRepeater var parent = element.GetVisualParent(); @@ -505,9 +505,9 @@ private int GetElementIndexImpl(IControl element) return -1; } - private IControl? GetElementFromIndexImpl(int index) + private Control? GetElementFromIndexImpl(int index) { - IControl? result = null; + Control? result = null; var children = Children; for (var i = 0; i < children.Count && result == null; ++i) @@ -523,7 +523,7 @@ private int GetElementIndexImpl(IControl element) return result; } - private IControl GetOrCreateElementImpl(int index) + private Control GetOrCreateElementImpl(int index) { if (index >= 0 && index >= (ItemsSourceView?.Count ?? 0)) { @@ -545,7 +545,7 @@ private IControl GetOrCreateElementImpl(int index) throw new InvalidOperationException("Cannot make an Anchor when there is no attached layout."); } - element = (IControl)GetLayoutContext().GetOrCreateElementAt(index); + element = (Control)GetLayoutContext().GetOrCreateElementAt(index); element.Measure(Size.Infinity); } @@ -555,7 +555,7 @@ private IControl GetOrCreateElementImpl(int index) return element!; } - internal void OnElementPrepared(IControl element, VirtualizationInfo virtInfo) + internal void OnElementPrepared(Control element, VirtualizationInfo virtInfo) { _viewportManager.OnElementPrepared(element, virtInfo); @@ -578,7 +578,7 @@ internal void OnElementPrepared(IControl element, VirtualizationInfo virtInfo) _childIndexChanged?.Invoke(this, new ChildIndexChangedEventArgs(element)); } - internal void OnElementClearing(IControl element) + internal void OnElementClearing(Control element) { if (ElementClearing != null) { @@ -597,7 +597,7 @@ internal void OnElementClearing(IControl element) _childIndexChanged?.Invoke(this, new ChildIndexChangedEventArgs(element)); } - internal void OnElementIndexChanged(IControl element, int oldIndex, int newIndex) + internal void OnElementIndexChanged(Control element, int oldIndex, int newIndex) { if (ElementIndexChanged != null) { diff --git a/src/Avalonia.Controls/Repeater/ItemsRepeaterElementClearingEventArgs.cs b/src/Avalonia.Controls/Repeater/ItemsRepeaterElementClearingEventArgs.cs index 75d50e52a61..3968543bb6e 100644 --- a/src/Avalonia.Controls/Repeater/ItemsRepeaterElementClearingEventArgs.cs +++ b/src/Avalonia.Controls/Repeater/ItemsRepeaterElementClearingEventArgs.cs @@ -12,13 +12,13 @@ namespace Avalonia.Controls /// public class ItemsRepeaterElementClearingEventArgs : EventArgs { - internal ItemsRepeaterElementClearingEventArgs(IControl element) => Element = element; + internal ItemsRepeaterElementClearingEventArgs(Control element) => Element = element; /// /// Gets the element that is being cleared for re-use. /// - public IControl Element { get; private set; } + public Control Element { get; private set; } - internal void Update(IControl element) => Element = element; + internal void Update(Control element) => Element = element; } } diff --git a/src/Avalonia.Controls/Repeater/ItemsRepeaterElementIndexChangedEventArgs.cs b/src/Avalonia.Controls/Repeater/ItemsRepeaterElementIndexChangedEventArgs.cs index 9f1c32bf64b..daa6aacaf4f 100644 --- a/src/Avalonia.Controls/Repeater/ItemsRepeaterElementIndexChangedEventArgs.cs +++ b/src/Avalonia.Controls/Repeater/ItemsRepeaterElementIndexChangedEventArgs.cs @@ -12,7 +12,7 @@ namespace Avalonia.Controls /// public class ItemsRepeaterElementIndexChangedEventArgs : EventArgs { - internal ItemsRepeaterElementIndexChangedEventArgs(IControl element, int oldIndex, int newIndex) + internal ItemsRepeaterElementIndexChangedEventArgs(Control element, int oldIndex, int newIndex) { Element = element; OldIndex = oldIndex; @@ -22,7 +22,7 @@ internal ItemsRepeaterElementIndexChangedEventArgs(IControl element, int oldInde /// /// Get the element for which the index changed. /// - public IControl Element { get; private set; } + public Control Element { get; private set; } /// /// Gets the index of the element after the change. @@ -34,7 +34,7 @@ internal ItemsRepeaterElementIndexChangedEventArgs(IControl element, int oldInde /// public int OldIndex { get; private set; } - internal void Update(IControl element, int oldIndex, int newIndex) + internal void Update(Control element, int oldIndex, int newIndex) { Element = element; NewIndex = newIndex; diff --git a/src/Avalonia.Controls/Repeater/ItemsRepeaterElementPreparedEventArgs.cs b/src/Avalonia.Controls/Repeater/ItemsRepeaterElementPreparedEventArgs.cs index 5a30dbcf2ad..95ca53864dc 100644 --- a/src/Avalonia.Controls/Repeater/ItemsRepeaterElementPreparedEventArgs.cs +++ b/src/Avalonia.Controls/Repeater/ItemsRepeaterElementPreparedEventArgs.cs @@ -10,7 +10,7 @@ namespace Avalonia.Controls /// public class ItemsRepeaterElementPreparedEventArgs { - internal ItemsRepeaterElementPreparedEventArgs(IControl element, int index) + internal ItemsRepeaterElementPreparedEventArgs(Control element, int index) { Element = element; Index = index; @@ -19,14 +19,14 @@ internal ItemsRepeaterElementPreparedEventArgs(IControl element, int index) /// /// Gets the prepared element. /// - public IControl Element { get; private set; } + public Control Element { get; private set; } /// /// Gets the index of the item the element was prepared for. /// public int Index { get; private set; } - internal void Update(IControl element, int index) + internal void Update(Control element, int index) { Element = element; Index = index; diff --git a/src/Avalonia.Controls/Repeater/RecyclePool.cs b/src/Avalonia.Controls/Repeater/RecyclePool.cs index cf2b40836ed..3e101dc631f 100644 --- a/src/Avalonia.Controls/Repeater/RecyclePool.cs +++ b/src/Avalonia.Controls/Repeater/RecyclePool.cs @@ -30,7 +30,7 @@ public class RecyclePool public static void SetPoolInstance(IDataTemplate dataTemplate, RecyclePool value) => s_pools.Add(dataTemplate, value); - public void PutElement(IControl element, string key, IControl? owner) + public void PutElement(Control element, string key, Control? owner) { var ownerAsPanel = EnsureOwnerIsPanelOrNull(owner); var elementInfo = new ElementInfo(element, ownerAsPanel); @@ -44,7 +44,7 @@ public void PutElement(IControl element, string key, IControl? owner) pool.Add(elementInfo); } - public IControl? TryGetElement(string key, IControl? owner) + public Control? TryGetElement(string key, Control? owner) { if (_elements.TryGetValue(key, out var elements)) { @@ -80,12 +80,12 @@ public void PutElement(IControl element, string key, IControl? owner) return null; } - internal string GetReuseKey(IControl element) => ((Control)element).GetValue(ReuseKeyProperty); - internal void SetReuseKey(IControl element, string value) => ((Control)element).SetValue(ReuseKeyProperty, value); + internal string GetReuseKey(Control element) => element.GetValue(ReuseKeyProperty); + internal void SetReuseKey(Control element, string value) => element.SetValue(ReuseKeyProperty, value); - private IPanel? EnsureOwnerIsPanelOrNull(IControl? owner) + private Panel? EnsureOwnerIsPanelOrNull(Control? owner) { - if (owner is IPanel panel) + if (owner is Panel panel) { return panel; } @@ -99,14 +99,14 @@ public void PutElement(IControl element, string key, IControl? owner) private class ElementInfo { - public ElementInfo(IControl element, IPanel? owner) + public ElementInfo(Control element, Panel? owner) { Element = element; Owner = owner; } - - public IControl Element { get; } - public IPanel? Owner { get;} + + public Control Element { get; } + public Panel? Owner { get;} } } } diff --git a/src/Avalonia.Controls/Repeater/RecyclingElementFactory.cs b/src/Avalonia.Controls/Repeater/RecyclingElementFactory.cs index c1baa66433a..35bd5aeecb1 100644 --- a/src/Avalonia.Controls/Repeater/RecyclingElementFactory.cs +++ b/src/Avalonia.Controls/Repeater/RecyclingElementFactory.cs @@ -9,7 +9,7 @@ public class SelectTemplateEventArgs : EventArgs { public string? TemplateKey { get; set; } public object? DataContext { get; internal set; } - public IControl? Owner { get; internal set; } + public Control? Owner { get; internal set; } } public class RecyclingElementFactory : ElementFactory @@ -37,7 +37,7 @@ public IDictionary Templates public event EventHandler? SelectTemplateKey; - protected override IControl GetElementCore(ElementFactoryGetArgs args) + protected override Control GetElementCore(ElementFactoryGetArgs args) { if (_templates == null || _templates.Count == 0) { @@ -85,7 +85,7 @@ protected override void RecycleElementCore(ElementFactoryRecycleArgs args) RecyclePool.PutElement(element, key, args.Parent); } - protected virtual string OnSelectTemplateKeyCore(object? dataContext, IControl? owner) + protected virtual string OnSelectTemplateKeyCore(object? dataContext, Control? owner) { if (SelectTemplateKey is object) { diff --git a/src/Avalonia.Controls/Repeater/RepeaterLayoutContext.cs b/src/Avalonia.Controls/Repeater/RepeaterLayoutContext.cs index 3370b368019..49c8b9ff92f 100644 --- a/src/Avalonia.Controls/Repeater/RepeaterLayoutContext.cs +++ b/src/Avalonia.Controls/Repeater/RepeaterLayoutContext.cs @@ -49,7 +49,7 @@ protected override int RecommendedAnchorIndexCore protected override int ItemCountCore() => _owner.ItemsSourceView?.Count ?? 0; - protected override ILayoutable GetOrCreateElementAtCore(int index, ElementRealizationOptions options) + protected override Layoutable GetOrCreateElementAtCore(int index, ElementRealizationOptions options) { return _owner.GetElementImpl( index, @@ -59,10 +59,10 @@ protected override ILayoutable GetOrCreateElementAtCore(int index, ElementRealiz protected override object GetItemAtCore(int index) => _owner.ItemsSourceView!.GetAt(index)!; - protected override void RecycleElementCore(ILayoutable element) + protected override void RecycleElementCore(Layoutable element) { - Logger.TryGet(LogEventLevel.Verbose, "Repeater")?.Log(this, "RepeaterLayout - RecycleElement: {Index}", _owner.GetElementIndex((IControl)element)); - _owner.ClearElementImpl((IControl)element); + Logger.TryGet(LogEventLevel.Verbose, "Repeater")?.Log(this, "RepeaterLayout - RecycleElement: {Index}", _owner.GetElementIndex((Control)element)); + _owner.ClearElementImpl((Control)element); } protected override Rect RealizationRectCore() => _owner.RealizationWindow; diff --git a/src/Avalonia.Controls/Repeater/UniqueIdElementPool.cs b/src/Avalonia.Controls/Repeater/UniqueIdElementPool.cs index 778b8bebcc0..5c7298d448e 100644 --- a/src/Avalonia.Controls/Repeater/UniqueIdElementPool.cs +++ b/src/Avalonia.Controls/Repeater/UniqueIdElementPool.cs @@ -10,14 +10,14 @@ namespace Avalonia.Controls { - internal class UniqueIdElementPool : IEnumerable> + internal class UniqueIdElementPool : IEnumerable> { - private readonly Dictionary _elementMap = new Dictionary(); + private readonly Dictionary _elementMap = new Dictionary(); private readonly ItemsRepeater _owner; public UniqueIdElementPool(ItemsRepeater owner) => _owner = owner; - public void Add(IControl element) + public void Add(Control element) { var virtInfo = ItemsRepeater.GetVirtualizationInfo(element); var key = virtInfo.UniqueId!; @@ -30,7 +30,7 @@ public void Add(IControl element) _elementMap.Add(key, element); } - public IControl? Remove(int index) + public Control? Remove(int index) { // Check if there is already a element in the mapping and if so, use it. string key = _owner.ItemsSourceView!.KeyFromIndex(index); @@ -48,7 +48,7 @@ public void Clear() _elementMap.Clear(); } - public IEnumerator> GetEnumerator() => _elementMap.GetEnumerator(); + public IEnumerator> GetEnumerator() => _elementMap.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } } diff --git a/src/Avalonia.Controls/Repeater/ViewManager.cs b/src/Avalonia.Controls/Repeater/ViewManager.cs index 12db48a2c25..2dff18cd047 100644 --- a/src/Avalonia.Controls/Repeater/ViewManager.cs +++ b/src/Avalonia.Controls/Repeater/ViewManager.cs @@ -22,7 +22,7 @@ internal sealed class ViewManager private readonly ItemsRepeater _owner; private readonly List _pinnedPool = new List(); private readonly UniqueIdElementPool _resetPool; - private IControl? _lastFocusedElement; + private Control? _lastFocusedElement; private bool _isDataSourceStableResetPending; private ElementFactoryGetArgs? _elementFactoryGetArgs; private ElementFactoryRecycleArgs? _elementFactoryRecycleArgs; @@ -36,7 +36,7 @@ public ViewManager(ItemsRepeater owner) _resetPool = new UniqueIdElementPool(owner); } - public IControl GetElement(int index, bool forceCreate, bool suppressAutoRecycle) + public Control GetElement(int index, bool forceCreate, bool suppressAutoRecycle) { var element = forceCreate ? null : GetElementIfAlreadyHeldByLayout(index); if (element == null) @@ -73,7 +73,7 @@ public IControl GetElement(int index, bool forceCreate, bool suppressAutoRecycle return element; } - public void ClearElement(IControl element, bool isClearedDueToCollectionChange) + public void ClearElement(Control element, bool isClearedDueToCollectionChange) { var virtInfo = ItemsRepeater.GetVirtualizationInfo(element); var index = virtInfo.Index; @@ -119,7 +119,7 @@ public void ClearElement(IControl element, bool isClearedDueToCollectionChange) // // In all of those three cases, we the ItemTemplateShim is NOT null. // Luckily when we create the items, we store whether we were the once setting the DataContext. - public void ClearElementToElementFactory(IControl element) + public void ClearElementToElementFactory(Control element) { _owner.OnElementClearing(element); @@ -179,14 +179,14 @@ private void MoveFocusFromClearedIndex(int clearedIndex) } } - IControl? FindFocusCandidate(int clearedIndex, out IControl? focusedChild) + Control? FindFocusCandidate(int clearedIndex, out Control? focusedChild) { // Walk through all the children and find elements with index before and after the cleared index. // Note that during a delete the next element would now have the same index. int previousIndex = int.MinValue; int nextIndex = int.MaxValue; - IControl? nextElement = null; - IControl? previousElement = null; + Control? nextElement = null; + Control? previousElement = null; foreach (var child in _owner.Children) { @@ -254,16 +254,16 @@ public void PrunePinnedElements() } } - public void UpdatePin(IControl element, bool addPin) + public void UpdatePin(Control element, bool addPin) { var parent = element.VisualParent; - var child = (IVisual)element; + var child = (Visual)element; while (parent != null) { if (parent is ItemsRepeater repeater) { - var virtInfo = ItemsRepeater.GetVirtualizationInfo((IControl)child); + var virtInfo = ItemsRepeater.GetVirtualizationInfo((Control)child); if (virtInfo.IsRealized) { if (addPin) @@ -482,9 +482,9 @@ public void OnOwnerArranged() // If an index that is realized is requested by the layout, we unfortunately have to walk the // children. Not ideal, but a reasonable default to provide consistent behavior between virtualizing // and non-virtualizing hosts. - private IControl? GetElementIfAlreadyHeldByLayout(int index) + private Control? GetElementIfAlreadyHeldByLayout(int index) { - IControl? element = null; + Control? element = null; bool cachedFirstLastIndicesInvalid = _firstRealizedElementIndexHeldByLayout == FirstRealizedElementIndexDefault; bool isRequestedIndexInRealizedRange = (_firstRealizedElementIndexHeldByLayout <= index && index <= _lastRealizedElementIndexHeldByLayout); @@ -518,9 +518,9 @@ public void OnOwnerArranged() return element; } - private IControl? GetElementFromUniqueIdResetPool(int index) + private Control? GetElementFromUniqueIdResetPool(int index) { - IControl? element = null; + Control? element = null; // See if you can get it from the reset pool. if (_isDataSourceStableResetPending) { @@ -541,9 +541,9 @@ public void OnOwnerArranged() return element; } - private IControl? GetElementFromPinnedElements(int index) + private Control? GetElementFromPinnedElements(int index) { - IControl? element = null; + Control? element = null; // See if you can find something among the pinned elements. for (var i = 0; i < _pinnedPool.Count; ++i) @@ -570,17 +570,17 @@ public void OnOwnerArranged() // There are several cases handled here with respect to which element gets returned and when DataContext is modified. // // 1. If there is no ItemTemplate: - // 1.1 If data is an IControl -> the data is returned - // 1.2 If data is not an IControl -> a default DataTemplate is used to fetch element and DataContext is set to data + // 1.1 If data is an Control -> the data is returned + // 1.2 If data is not an Control -> a default DataTemplate is used to fetch element and DataContext is set to data // // 2. If there is an ItemTemplate: - // 2.1 If data is not an IControl -> Element is fetched from ElementFactory and DataContext is set to the data - // 2.2 If data is an IControl: + // 2.1 If data is not an Control -> Element is fetched from ElementFactory and DataContext is set to the data + // 2.2 If data is an Control: // 2.2.1 If Element returned by the ElementFactory is the same as the data -> Element (a.k.a. data) is returned as is // 2.2.2 If Element returned by the ElementFactory is not the same as the data // -> Element that is fetched from the ElementFactory is returned and // DataContext is set to the data's DataContext (if it exists), otherwise it is set to the data itself - private IControl GetElementFromElementFactory(int index) + private Control GetElementFromElementFactory(int index) { // The view generator is the provider of last resort. var data = _owner.ItemsSourceView!.GetAt(index); @@ -598,11 +598,11 @@ IElementFactory GetElementFactory() return providedElementFactory; } - IControl GetElement() + Control GetElement() { if (providedElementFactory == null) { - if (data is IControl dataAsElement) + if (data is Control dataAsElement) { return dataAsElement; } @@ -670,7 +670,7 @@ IControl GetElement() return element; } - private bool ClearElementToUniqueIdResetPool(IControl element, VirtualizationInfo virtInfo) + private bool ClearElementToUniqueIdResetPool(Control element, VirtualizationInfo virtInfo) { if (_isDataSourceStableResetPending) { @@ -681,7 +681,7 @@ private bool ClearElementToUniqueIdResetPool(IControl element, VirtualizationInf return _isDataSourceStableResetPending; } - private bool ClearElementToPinnedPool(IControl element, VirtualizationInfo virtInfo, bool isClearedDueToCollectionChange) + private bool ClearElementToPinnedPool(Control element, VirtualizationInfo virtInfo, bool isClearedDueToCollectionChange) { bool moveToPinnedPool = !isClearedDueToCollectionChange && virtInfo.IsPinned; @@ -697,11 +697,9 @@ private bool ClearElementToPinnedPool(IControl element, VirtualizationInfo virtI private void UpdateFocusedElement() { - IControl? focusedElement = null; + Control? focusedElement = null; - var child = FocusManager.Instance?.Current; - - if (child != null) + if (FocusManager.Instance?.Current is Visual child) { var parent = child.VisualParent; var owner = _owner; @@ -712,7 +710,7 @@ private void UpdateFocusedElement() { if (parent is ItemsRepeater repeater) { - var element = child as IControl; + var element = child as Control; if (repeater == owner && element is not null && ItemsRepeater.GetVirtualizationInfo(element).IsRealized) @@ -723,7 +721,7 @@ element is not null && break; } - child = parent as IInputElement; + child = parent; parent = child?.VisualParent; } } @@ -758,7 +756,7 @@ private void EnsureEventSubscriptions() } } - private void UpdateElementIndex(IControl element, VirtualizationInfo virtInfo, int index) + private void UpdateElementIndex(Control element, VirtualizationInfo virtInfo, int index) { var oldIndex = virtInfo.Index; if (oldIndex != index) @@ -776,13 +774,13 @@ private void InvalidateRealizedIndicesHeldByLayout() private struct PinnedElementInfo { - public PinnedElementInfo(IControl element) + public PinnedElementInfo(Control element) { PinnedElement = element; VirtualizationInfo = ItemsRepeater.GetVirtualizationInfo(element); } - public IControl PinnedElement { get; } + public Control PinnedElement { get; } public VirtualizationInfo VirtualizationInfo { get; } } } diff --git a/src/Avalonia.Controls/Repeater/ViewportManager.cs b/src/Avalonia.Controls/Repeater/ViewportManager.cs index 7f03cc575ee..e24ed37f1e4 100644 --- a/src/Avalonia.Controls/Repeater/ViewportManager.cs +++ b/src/Avalonia.Controls/Repeater/ViewportManager.cs @@ -25,7 +25,7 @@ internal class ViewportManager private readonly ItemsRepeater _owner; private bool _ensuredScroller; private IScrollAnchorProvider? _scroller; - private IControl? _makeAnchorElement; + private Control? _makeAnchorElement; private bool _isAnchorOutsideRealizedRange; private Rect _visibleWindow; private Rect _layoutExtent; @@ -57,7 +57,7 @@ public ViewportManager(ItemsRepeater owner) _owner = owner; } - public IControl? SuggestedAnchor + public Control? SuggestedAnchor { get { @@ -75,7 +75,7 @@ public IControl? SuggestedAnchor // be a direct child of ours, or even an indirect child. We need to walk up the tree starting // from anchorElement to figure out what child of ours (if any) to use as the suggested element. var child = anchorElement; - var parent = child.VisualParent as IControl; + var parent = child.VisualParent as Control; while (parent != null) { @@ -86,7 +86,7 @@ public IControl? SuggestedAnchor } child = parent; - parent = parent.VisualParent as IControl; + parent = parent.VisualParent as Control; } } } @@ -97,7 +97,7 @@ public IControl? SuggestedAnchor public bool HasScroller => _scroller != null; - public IControl? MadeAnchor => _makeAnchorElement; + public Control? MadeAnchor => _makeAnchorElement; public double HorizontalCacheLength { @@ -213,7 +213,7 @@ public void SetLayoutExtent(Rect extent) // We just finished a measure pass and have a new extent. // Let's make sure the scrollers will run its arrange so that they track the anchor. - ((IControl?)_scroller)?.InvalidateArrange(); + ((Control?)_scroller)?.InvalidateArrange(); } public Point GetOrigin() => _layoutExtent.TopLeft; @@ -239,7 +239,7 @@ public void OnLayoutChanged(bool isVirtualizing) } } - public void OnElementPrepared(IControl element, VirtualizationInfo virtInfo) + public void OnElementPrepared(Control element, VirtualizationInfo virtInfo) { // WinUI registers the element as an anchor candidate here, but I feel that's in error: // at this point the element has not yet been positioned by the arrange pass so it will @@ -249,7 +249,7 @@ public void OnElementPrepared(IControl element, VirtualizationInfo virtInfo) virtInfo.IsRegisteredAsAnchorCandidate = false; } - public void OnElementCleared(IControl element, VirtualizationInfo virtInfo) + public void OnElementCleared(Control element, VirtualizationInfo virtInfo) { _scroller?.UnregisterAnchorCandidate(element); virtInfo.IsRegisteredAsAnchorCandidate = false; @@ -325,7 +325,7 @@ private void OnLayoutUpdated(object? sender, EventArgs args) } } - public void OnMakeAnchor(IControl? anchor, bool isAnchorOutsideRealizedRange) + public void OnMakeAnchor(Control? anchor, bool isAnchorOutsideRealizedRange) { if (_makeAnchorElement != anchor) { @@ -347,7 +347,7 @@ public void OnBringIntoViewRequested(RequestBringIntoViewEventArgs args) // get the targetChild - i.e the immediate child of this repeater that is being brought into view. // Note that the element being brought into view could be a descendant. - var targetChild = GetImmediateChildOfRepeater((IControl)args.TargetObject!); + var targetChild = GetImmediateChildOfRepeater((Control)args.TargetObject!); if (targetChild is null) { @@ -381,7 +381,7 @@ public void OnBringIntoViewRequested(RequestBringIntoViewEventArgs args) } } - public void RegisterScrollAnchorCandidate(IControl element, VirtualizationInfo virtInfo) + public void RegisterScrollAnchorCandidate(Control element, VirtualizationInfo virtInfo) { if (!virtInfo.IsRegisteredAsAnchorCandidate) { @@ -390,14 +390,14 @@ public void RegisterScrollAnchorCandidate(IControl element, VirtualizationInfo v } } - private IControl? GetImmediateChildOfRepeater(IControl descendant) + private Control? GetImmediateChildOfRepeater(Control descendant) { var targetChild = descendant; - var parent = (IControl?)descendant.VisualParent; + var parent = (Control?)descendant.VisualParent; while (parent != null && parent != _owner) { targetChild = parent; - parent = (IControl?)parent.VisualParent; + parent = (Control?)parent.VisualParent; } if (parent == null) diff --git a/src/Avalonia.Controls/RequestBringIntoViewEventArgs.cs b/src/Avalonia.Controls/RequestBringIntoViewEventArgs.cs index 5396ad67a72..a9c84cd4ece 100644 --- a/src/Avalonia.Controls/RequestBringIntoViewEventArgs.cs +++ b/src/Avalonia.Controls/RequestBringIntoViewEventArgs.cs @@ -5,7 +5,7 @@ namespace Avalonia.Controls { public class RequestBringIntoViewEventArgs : RoutedEventArgs { - public IVisual? TargetObject { get; set; } + public Visual? TargetObject { get; set; } public Rect TargetRect { get; set; } } diff --git a/src/Avalonia.Controls/Screens.cs b/src/Avalonia.Controls/Screens.cs index dde6b71e6e3..22f9c0832a0 100644 --- a/src/Avalonia.Controls/Screens.cs +++ b/src/Avalonia.Controls/Screens.cs @@ -53,7 +53,7 @@ public Screens(IScreenImpl iScreenImpl) return _iScreenImpl.ScreenFromPoint(point); } - public Screen? ScreenFromVisual(IVisual visual) + public Screen? ScreenFromVisual(Visual visual) { var tl = visual.PointToScreen(visual.Bounds.TopLeft); var br = visual.PointToScreen(visual.Bounds.BottomRight); diff --git a/src/Avalonia.Controls/ScrollViewer.cs b/src/Avalonia.Controls/ScrollViewer.cs index 535f9ae43ec..12fb9ba5c5c 100644 --- a/src/Avalonia.Controls/ScrollViewer.cs +++ b/src/Avalonia.Controls/ScrollViewer.cs @@ -344,7 +344,7 @@ protected bool CanVerticallyScroll } /// - public IControl? CurrentAnchor => (Presenter as IScrollAnchorProvider)?.CurrentAnchor; + public Control? CurrentAnchor => (Presenter as IScrollAnchorProvider)?.CurrentAnchor; /// /// Gets the maximum horizontal scrollbar value. @@ -615,13 +615,13 @@ public static void SetVerticalScrollBarVisibility(Control control, ScrollBarVisi } /// - public void RegisterAnchorCandidate(IControl element) + public void RegisterAnchorCandidate(Control element) { (Presenter as IScrollAnchorProvider)?.RegisterAnchorCandidate(element); } /// - public void UnregisterAnchorCandidate(IControl element) + public void UnregisterAnchorCandidate(Control element) { (Presenter as IScrollAnchorProvider)?.UnregisterAnchorCandidate(element); } @@ -633,7 +633,7 @@ protected override bool RegisterContentPresenter(IContentPresenter presenter) if (base.RegisterContentPresenter(presenter)) { - _childSubscription = Presenter? + _childSubscription = ((Control?)Presenter)? .GetObservable(ContentPresenter.ChildProperty) .Subscribe(ChildChanged); return true; @@ -660,7 +660,7 @@ private static double Max(double x, double y) return double.IsNaN(result) ? 0 : result; } - private void ChildChanged(IControl? child) + private void ChildChanged(Control? child) { if (_logicalScrollable is object) { diff --git a/src/Avalonia.Controls/SizeChangedEventArgs.cs b/src/Avalonia.Controls/SizeChangedEventArgs.cs index 2dc642b1638..85ea3b84721 100644 --- a/src/Avalonia.Controls/SizeChangedEventArgs.cs +++ b/src/Avalonia.Controls/SizeChangedEventArgs.cs @@ -23,7 +23,7 @@ public SizeChangedEventArgs(RoutedEvent? routedEvent) /// /// The routed event associated with these event args. /// The source object that raised the routed event. - public SizeChangedEventArgs(RoutedEvent? routedEvent, IInteractive? source) + public SizeChangedEventArgs(RoutedEvent? routedEvent, object? source) : base(routedEvent, source) { } @@ -37,7 +37,7 @@ public SizeChangedEventArgs(RoutedEvent? routedEvent, IInteractive? source) /// The new size (or bounds) of the object. public SizeChangedEventArgs( RoutedEvent? routedEvent, - IInteractive? source, + object? source, Size previousSize, Size newSize) : base(routedEvent, source) diff --git a/src/Avalonia.Controls/SplitView.cs b/src/Avalonia.Controls/SplitView.cs index c344dd795da..29add8720bd 100644 --- a/src/Avalonia.Controls/SplitView.cs +++ b/src/Avalonia.Controls/SplitView.cs @@ -368,7 +368,7 @@ private void PointerPressedOutside(object? sender, PointerPressedEventArgs e) return; } - var src = e.Source as IVisual; + var src = e.Source as Visual; while (src != null) { // Make assumption that if Popup is in visual tree, diff --git a/src/Avalonia.Controls/StackPanel.cs b/src/Avalonia.Controls/StackPanel.cs index 50c48d2bb0c..964a1055dfd 100644 --- a/src/Avalonia.Controls/StackPanel.cs +++ b/src/Avalonia.Controls/StackPanel.cs @@ -62,7 +62,7 @@ public Orientation Orientation /// The control. IInputElement? INavigableContainer.GetControl(NavigationDirection direction, IInputElement? from, bool wrap) { - var result = GetControlInDirection(direction, from as IControl); + var result = GetControlInDirection(direction, from as Control); if (result == null && wrap) { @@ -109,7 +109,7 @@ public Orientation Orientation /// The movement direction. /// The control from which movement begins. /// The control. - protected virtual IInputElement? GetControlInDirection(NavigationDirection direction, IControl? from) + protected virtual IInputElement? GetControlInDirection(NavigationDirection direction, Control? from) { var horiz = Orientation == Orientation.Horizontal; int index = from != null ? Children.IndexOf(from) : -1; @@ -278,7 +278,7 @@ protected override Size ArrangeOverride(Size finalSize) } internal virtual void ArrangeChild( - IControl child, + Control child, Rect rect, Size panelSize, Orientation orientation) diff --git a/src/Avalonia.Controls/TabControl.cs b/src/Avalonia.Controls/TabControl.cs index 63738716c0b..2e7059b8384 100644 --- a/src/Avalonia.Controls/TabControl.cs +++ b/src/Avalonia.Controls/TabControl.cs @@ -67,8 +67,8 @@ public class TabControl : SelectingItemsControl, IContentPresenterHost /// /// The default value for the property. /// - private static readonly FuncTemplate DefaultPanel = - new FuncTemplate(() => new WrapPanel()); + private static readonly FuncTemplate DefaultPanel = + new FuncTemplate(() => new WrapPanel()); /// /// Initializes static members of the class. diff --git a/src/Avalonia.Controls/TabItem.cs b/src/Avalonia.Controls/TabItem.cs index f68db4743bb..76680c04203 100644 --- a/src/Avalonia.Controls/TabItem.cs +++ b/src/Avalonia.Controls/TabItem.cs @@ -71,7 +71,7 @@ private void UpdateHeader(AvaloniaPropertyChangedEventArgs obj) } else { - if (!(obj.NewValue is IControl)) + if (!(obj.NewValue is Control)) { Header = obj.NewValue; } diff --git a/src/Avalonia.Controls/Templates/DataTemplateExtensions.cs b/src/Avalonia.Controls/Templates/DataTemplateExtensions.cs index 1dce00d5103..54d810da436 100644 --- a/src/Avalonia.Controls/Templates/DataTemplateExtensions.cs +++ b/src/Avalonia.Controls/Templates/DataTemplateExtensions.cs @@ -18,7 +18,7 @@ public static class DataTemplateExtensions /// /// The data template or null if no matching data template was found. public static IDataTemplate? FindDataTemplate( - this IControl control, + this Control control, object? data, IDataTemplate? primary = null) { diff --git a/src/Avalonia.Controls/Templates/FuncControlTemplate.cs b/src/Avalonia.Controls/Templates/FuncControlTemplate.cs index 3ed7abdfef5..64a883e88c6 100644 --- a/src/Avalonia.Controls/Templates/FuncControlTemplate.cs +++ b/src/Avalonia.Controls/Templates/FuncControlTemplate.cs @@ -7,18 +7,18 @@ namespace Avalonia.Controls.Templates /// /// A template for a . /// - public class FuncControlTemplate : FuncTemplate, IControlTemplate + public class FuncControlTemplate : FuncTemplate, IControlTemplate { /// /// Initializes a new instance of the class. /// /// The build function. - public FuncControlTemplate(Func build) + public FuncControlTemplate(Func build) : base(build) { } - public new ControlTemplateResult Build(ITemplatedControl param) + public new ControlTemplateResult Build(TemplatedControl param) { var (control, scope) = BuildWithNameScope(param); return new ControlTemplateResult(control, scope); diff --git a/src/Avalonia.Controls/Templates/FuncControlTemplate`2.cs b/src/Avalonia.Controls/Templates/FuncControlTemplate`2.cs index aad80af6521..be292ce0641 100644 --- a/src/Avalonia.Controls/Templates/FuncControlTemplate`2.cs +++ b/src/Avalonia.Controls/Templates/FuncControlTemplate`2.cs @@ -1,6 +1,5 @@ using System; using Avalonia.Controls.Primitives; -using Avalonia.Styling; namespace Avalonia.Controls.Templates { @@ -8,13 +7,13 @@ namespace Avalonia.Controls.Templates /// A template for a . /// /// The type of the lookless control. - public class FuncControlTemplate : FuncControlTemplate where T : ITemplatedControl + public class FuncControlTemplate : FuncControlTemplate where T : TemplatedControl { /// /// Initializes a new instance of the class. /// /// The build function. - public FuncControlTemplate(Func build) + public FuncControlTemplate(Func build) : base((x, s) => build((T)x, s)) { } diff --git a/src/Avalonia.Controls/Templates/FuncDataTemplate.cs b/src/Avalonia.Controls/Templates/FuncDataTemplate.cs index 10da2cfea37..cfd4234a271 100644 --- a/src/Avalonia.Controls/Templates/FuncDataTemplate.cs +++ b/src/Avalonia.Controls/Templates/FuncDataTemplate.cs @@ -7,7 +7,7 @@ namespace Avalonia.Controls.Templates /// /// Builds a control for a piece of data. /// - public class FuncDataTemplate : FuncTemplate, IRecyclingDataTemplate + public class FuncDataTemplate : FuncTemplate, IRecyclingDataTemplate { /// /// The default data template used in the case where no matching data template is found. @@ -69,7 +69,7 @@ public class FuncDataTemplate : FuncTemplate, IRecyclingData /// Whether the control can be recycled. public FuncDataTemplate( Type type, - Func build, + Func build, bool supportsRecycling = false) : this(o => IsInstance(o, type), build, supportsRecycling) { @@ -87,7 +87,7 @@ public FuncDataTemplate( /// Whether the control can be recycled. public FuncDataTemplate( Func match, - Func build, + Func build, bool supportsRecycling = false) : base(build) { @@ -120,7 +120,7 @@ public bool Match(object? data) /// The caller should ensure that any control passed to /// originated from the same data template. /// - public IControl? Build(object? data, IControl? existing) + public Control? Build(object? data, Control? existing) { return _supportsRecycling && existing is object ? existing : Build(data); } diff --git a/src/Avalonia.Controls/Templates/FuncDataTemplate`1.cs b/src/Avalonia.Controls/Templates/FuncDataTemplate`1.cs index 6076e774a72..2b063f12281 100644 --- a/src/Avalonia.Controls/Templates/FuncDataTemplate`1.cs +++ b/src/Avalonia.Controls/Templates/FuncDataTemplate`1.cs @@ -1,5 +1,4 @@ using System; - using Avalonia.Utilities; namespace Avalonia.Controls.Templates @@ -17,7 +16,7 @@ public class FuncDataTemplate : FuncDataTemplate /// A function which when passed an object of returns a control. /// /// Whether the control can be recycled. - public FuncDataTemplate(Func build, bool supportsRecycling = false) + public FuncDataTemplate(Func build, bool supportsRecycling = false) : base(o => TypeUtilities.CanCast(o), CastBuild(build), supportsRecycling) { } @@ -34,7 +33,7 @@ public FuncDataTemplate(Func build, bool supportsRecyc /// Whether the control can be recycled. public FuncDataTemplate( Func match, - Func build, + Func build, bool supportsRecycling = false) : base(CastMatch(match), CastBuild(build), supportsRecycling) { @@ -52,7 +51,7 @@ public FuncDataTemplate( /// Whether the control can be recycled. public FuncDataTemplate( Func match, - Func build, + Func build, bool supportsRecycling = false) : this(match, (a, _) => build(a), supportsRecycling) { diff --git a/src/Avalonia.Controls/Templates/FuncTemplate`1.cs b/src/Avalonia.Controls/Templates/FuncTemplate`1.cs index ec4e0776608..61da607a384 100644 --- a/src/Avalonia.Controls/Templates/FuncTemplate`1.cs +++ b/src/Avalonia.Controls/Templates/FuncTemplate`1.cs @@ -7,7 +7,7 @@ namespace Avalonia.Controls.Templates /// Creates a control from a . /// /// The type of control. - public class FuncTemplate : ITemplate where TControl : IControl + public class FuncTemplate : ITemplate where TControl : Control { private readonly Func _func; diff --git a/src/Avalonia.Controls/Templates/FuncTemplate`2.cs b/src/Avalonia.Controls/Templates/FuncTemplate`2.cs index a7288aba3e2..3bc8449f034 100644 --- a/src/Avalonia.Controls/Templates/FuncTemplate`2.cs +++ b/src/Avalonia.Controls/Templates/FuncTemplate`2.cs @@ -8,7 +8,7 @@ namespace Avalonia.Controls.Templates /// The type of the parameter. /// The type of control. public class FuncTemplate : ITemplate - where TControl : IControl? + where TControl : Control? { private readonly Func _func; diff --git a/src/Avalonia.Controls/Templates/FuncTreeDataTemplate.cs b/src/Avalonia.Controls/Templates/FuncTreeDataTemplate.cs index 50fed100d8a..18a5d0a62f2 100644 --- a/src/Avalonia.Controls/Templates/FuncTreeDataTemplate.cs +++ b/src/Avalonia.Controls/Templates/FuncTreeDataTemplate.cs @@ -24,7 +24,7 @@ public class FuncTreeDataTemplate : FuncDataTemplate, ITreeDataTemplate /// public FuncTreeDataTemplate( Type type, - Func build, + Func build, Func itemsSelector) : this(o => IsInstance(o, type), build, itemsSelector) { @@ -44,7 +44,7 @@ public FuncTreeDataTemplate( /// public FuncTreeDataTemplate( Func match, - Func build, + Func build, Func itemsSelector) : base(match, build) { diff --git a/src/Avalonia.Controls/Templates/IControlTemplate.cs b/src/Avalonia.Controls/Templates/IControlTemplate.cs index ab46884402c..67e861f6ab2 100644 --- a/src/Avalonia.Controls/Templates/IControlTemplate.cs +++ b/src/Avalonia.Controls/Templates/IControlTemplate.cs @@ -7,20 +7,20 @@ namespace Avalonia.Controls.Templates /// /// Interface representing a template used to build a . /// - public interface IControlTemplate : ITemplate + public interface IControlTemplate : ITemplate { } - public class ControlTemplateResult : TemplateResult + public class ControlTemplateResult : TemplateResult { - public IControl Control { get; } + public Control Control { get; } - public ControlTemplateResult(IControl control, INameScope nameScope) : base(control, nameScope) + public ControlTemplateResult(Control control, INameScope nameScope) : base(control, nameScope) { Control = control; } - public new void Deconstruct(out IControl control, out INameScope scope) + public new void Deconstruct(out Control control, out INameScope scope) { control = Control; scope = NameScope; diff --git a/src/Avalonia.Controls/Templates/IDataTemplate.cs b/src/Avalonia.Controls/Templates/IDataTemplate.cs index c81e4292930..cb7e981c65f 100644 --- a/src/Avalonia.Controls/Templates/IDataTemplate.cs +++ b/src/Avalonia.Controls/Templates/IDataTemplate.cs @@ -5,7 +5,7 @@ namespace Avalonia.Controls.Templates /// /// Interface representing a template used to build a control for a piece of data. /// - public interface IDataTemplate : ITemplate + public interface IDataTemplate : ITemplate { /// /// Checks to see if this data template matches the specified data. diff --git a/src/Avalonia.Controls/Templates/IRecyclingDataTemplate.cs b/src/Avalonia.Controls/Templates/IRecyclingDataTemplate.cs index c9f3fcc836f..2d4ce33dd97 100644 --- a/src/Avalonia.Controls/Templates/IRecyclingDataTemplate.cs +++ b/src/Avalonia.Controls/Templates/IRecyclingDataTemplate.cs @@ -18,6 +18,6 @@ public interface IRecyclingDataTemplate : IDataTemplate /// The caller should ensure that any control passed to /// originated from the same data template. /// - IControl? Build(object? data, IControl? existing); + Control? Build(object? data, Control? existing); } } diff --git a/src/Avalonia.Controls/Templates/ITemplate`1.cs b/src/Avalonia.Controls/Templates/ITemplate`1.cs index a450e14b834..5cd78b6fcff 100644 --- a/src/Avalonia.Controls/Templates/ITemplate`1.cs +++ b/src/Avalonia.Controls/Templates/ITemplate`1.cs @@ -6,7 +6,7 @@ namespace Avalonia.Controls /// Creates a control. /// /// The type of control. - public interface ITemplate : ITemplate where TControl : IControl? + public interface ITemplate : ITemplate where TControl : Control? { /// /// Creates the control. diff --git a/src/Avalonia.Controls/Templates/TemplateExtensions.cs b/src/Avalonia.Controls/Templates/TemplateExtensions.cs index 7656ccd9bb7..b8d90ae4586 100644 --- a/src/Avalonia.Controls/Templates/TemplateExtensions.cs +++ b/src/Avalonia.Controls/Templates/TemplateExtensions.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using Avalonia.Controls; +using Avalonia.Controls.Primitives; using Avalonia.Styling; using Avalonia.VisualTree; @@ -9,17 +10,17 @@ namespace Avalonia.Controls.Templates { public static class TemplateExtensions { - public static IEnumerable GetTemplateChildren(this ITemplatedControl control) + public static IEnumerable GetTemplateChildren(this TemplatedControl control) { - foreach (IControl child in GetTemplateChildren((IControl)control, control)) + foreach (Control child in GetTemplateChildren(control, control)) { yield return child; } } - private static IEnumerable GetTemplateChildren(IControl control, ITemplatedControl templatedParent) + private static IEnumerable GetTemplateChildren(Control control, TemplatedControl templatedParent) { - foreach (IControl child in control.GetVisualChildren()) + foreach (Control child in control.GetVisualChildren()) { var childTemplatedParent = child.TemplatedParent; diff --git a/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs b/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs index 5d5ffcc381f..6a797600111 100644 --- a/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs +++ b/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs @@ -13,7 +13,7 @@ internal class TextBoxTextInputMethodClient : ITextInputMethodClient private TextBox? _parent; private TextPresenter? _presenter; - public IVisual TextViewVisual => _presenter!; + public Visual TextViewVisual => _presenter!; public bool SupportsPreedit => true; diff --git a/src/Avalonia.Controls/TextChangedEventArgs.cs b/src/Avalonia.Controls/TextChangedEventArgs.cs index 77c609f19bc..14181542562 100644 --- a/src/Avalonia.Controls/TextChangedEventArgs.cs +++ b/src/Avalonia.Controls/TextChangedEventArgs.cs @@ -12,7 +12,7 @@ public TextChangedEventArgs(RoutedEvent? routedEvent) { } - public TextChangedEventArgs(RoutedEvent? routedEvent, IInteractive? source) + public TextChangedEventArgs(RoutedEvent? routedEvent, Interactive? source) : base(routedEvent, source) { } diff --git a/src/Avalonia.Controls/TextChangingEventArgs.cs b/src/Avalonia.Controls/TextChangingEventArgs.cs index 4dedbc927ba..09e7d5b2587 100644 --- a/src/Avalonia.Controls/TextChangingEventArgs.cs +++ b/src/Avalonia.Controls/TextChangingEventArgs.cs @@ -12,7 +12,7 @@ public TextChangingEventArgs(RoutedEvent? routedEvent) { } - public TextChangingEventArgs(RoutedEvent? routedEvent, IInteractive? source) + public TextChangingEventArgs(RoutedEvent? routedEvent, Interactive? source) : base(routedEvent, source) { } diff --git a/src/Avalonia.Controls/ToolTipService.cs b/src/Avalonia.Controls/ToolTipService.cs index c6efe10488c..9ec9013679f 100644 --- a/src/Avalonia.Controls/ToolTipService.cs +++ b/src/Avalonia.Controls/ToolTipService.cs @@ -125,7 +125,7 @@ private void Open(Control control) { StopTimer(); - if ((control as IVisual).IsAttachedToVisualTree) + if (control.IsAttachedToVisualTree) { ToolTip.SetIsOpen(control, true); } diff --git a/src/Avalonia.Controls/TopLevel.cs b/src/Avalonia.Controls/TopLevel.cs index 90af881adc0..0e04d92d6e2 100644 --- a/src/Avalonia.Controls/TopLevel.cs +++ b/src/Avalonia.Controls/TopLevel.cs @@ -540,7 +540,7 @@ private void SceneInvalidated(object? sender, SceneInvalidatedEventArgs e) void PlatformImpl_LostFocus() { - var focused = (IVisual?)FocusManager.Instance?.Current; + var focused = (Visual?)FocusManager.Instance?.Current; if (focused == null) return; while (focused.VisualParent != null) diff --git a/src/Avalonia.Controls/TreeView.cs b/src/Avalonia.Controls/TreeView.cs index d78f9c82ef4..2fa4a02fa21 100644 --- a/src/Avalonia.Controls/TreeView.cs +++ b/src/Avalonia.Controls/TreeView.cs @@ -282,7 +282,7 @@ private void SelectedItemsCollectionChanged(object? sender, NotifyCollectionChan break; case NotifyCollectionChangedAction.Reset: - foreach (IControl container in ItemContainerGenerator.Index!.Containers) + foreach (Control container in ItemContainerGenerator.Index!.Containers) { MarkContainerSelected(container, false); } @@ -375,7 +375,7 @@ private void UnsubscribeFromSelectedItems() { if (direction == NavigationDirection.Next || direction == NavigationDirection.Previous) { - if (!this.IsVisualAncestorOf(element)) + if (!this.IsVisualAncestorOf((Visual)element)) { var result = _selectedItem != null ? ItemContainerGenerator.Index!.ContainerFromItem(_selectedItem) : @@ -520,7 +520,7 @@ protected override void OnPointerPressed(PointerPressedEventArgs e) { base.OnPointerPressed(e); - if (e.Source is IVisual source) + if (e.Source is Visual source) { var point = e.GetCurrentPoint(source); @@ -545,7 +545,7 @@ protected override void OnPointerPressed(PointerPressedEventArgs e) /// Whether the toggle modifier is enabled (i.e. ctrl key). /// Whether the event is a right-click. protected void UpdateSelectionFromContainer( - IControl container, + Control container, bool select = true, bool rangeModifier = false, bool toggleModifier = false, @@ -558,7 +558,7 @@ protected void UpdateSelectionFromContainer( return; } - IControl? selectedContainer = null; + Control? selectedContainer = null; if (SelectedItem != null) { @@ -752,7 +752,7 @@ private List GetItemsInRange(TreeViewItem? from, TreeViewItem? to) /// false. /// protected bool UpdateSelectionFromEventSource( - IInteractive eventSource, + object eventSource, bool select = true, bool rangeModifier = false, bool toggleModifier = false, @@ -774,9 +774,9 @@ protected bool UpdateSelectionFromEventSource( /// /// The control that raised the event. /// The container or null if the event did not originate in a container. - protected TreeViewItem? GetContainerFromEventSource(IInteractive eventSource) + protected TreeViewItem? GetContainerFromEventSource(object eventSource) { - var item = ((IVisual)eventSource).GetSelfAndVisualAncestors() + var item = ((Visual)eventSource).GetSelfAndVisualAncestors() .OfType() .FirstOrDefault(); @@ -826,7 +826,7 @@ private void ContainerMaterialized(object? sender, ItemContainerEventArgs e) /// /// The container. /// Whether the control is selected - private void MarkContainerSelected(IControl container, bool selected) + private void MarkContainerSelected(Control container, bool selected) { if (container == null) { diff --git a/src/Avalonia.Controls/TreeViewItem.cs b/src/Avalonia.Controls/TreeViewItem.cs index 2f96e6911f8..9bfcf5adfab 100644 --- a/src/Avalonia.Controls/TreeViewItem.cs +++ b/src/Avalonia.Controls/TreeViewItem.cs @@ -13,7 +13,7 @@ namespace Avalonia.Controls /// /// An item in a . /// - [TemplatePart("PART_Header", typeof(IControl))] + [TemplatePart("PART_Header", typeof(Control))] [PseudoClasses(":pressed", ":selected")] public class TreeViewItem : HeaderedItemsControl, ISelectable { @@ -39,11 +39,11 @@ public class TreeViewItem : HeaderedItemsControl, ISelectable AvaloniaProperty.RegisterDirect( nameof(Level), o => o.Level); - private static readonly ITemplate DefaultPanel = - new FuncTemplate(() => new StackPanel()); + private static readonly ITemplate DefaultPanel = + new FuncTemplate(() => new StackPanel()); private TreeView? _treeView; - private IControl? _header; + private Control? _header; private bool _isExpanded; private int _level; private bool _templateApplied; @@ -198,7 +198,7 @@ protected override void OnKeyDown(KeyEventArgs e) protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { - _header = e.NameScope.Find("PART_Header"); + _header = e.NameScope.Find("PART_Header"); _templateApplied = true; if (_deferredBringIntoViewFlag) { diff --git a/src/Avalonia.Controls/Utils/AncestorFinder.cs b/src/Avalonia.Controls/Utils/AncestorFinder.cs index b15e072052e..d2e3feb55a6 100644 --- a/src/Avalonia.Controls/Utils/AncestorFinder.cs +++ b/src/Avalonia.Controls/Utils/AncestorFinder.cs @@ -10,15 +10,15 @@ public static class AncestorFinder { class FinderNode : IDisposable { - private readonly IStyledElement _control; + private readonly StyledElement _control; private readonly Type _ancestorType; - public IObservable Observable => _subject; - private readonly Subject _subject = new Subject(); + public IObservable Observable => _subject; + private readonly Subject _subject = new Subject(); private FinderNode? _child; private IDisposable? _disposable; - public FinderNode(IStyledElement control, Type ancestorType) + public FinderNode(StyledElement control, Type ancestorType) { _control = control; _ancestorType = ancestorType; @@ -29,7 +29,7 @@ public void Init() _disposable = _control.GetObservable(Control.ParentProperty).Subscribe(OnValueChanged); } - private void OnValueChanged(IStyledElement? next) + private void OnValueChanged(StyledElement? next) { if (next == null || _ancestorType.IsAssignableFrom(next.GetType())) _subject.OnNext(next); @@ -42,7 +42,7 @@ private void OnValueChanged(IStyledElement? next) } } - private void OnChildValueChanged(IStyledElement? control) => _subject.OnNext(control); + private void OnChildValueChanged(StyledElement? control) => _subject.OnNext(control); public void Dispose() @@ -53,15 +53,15 @@ public void Dispose() } } - public static IObservable Create(IStyledElement control) - where T : IStyledElement + public static IObservable Create(StyledElement control) + where T : StyledElement { return Create(control, typeof(T)).Select(x => (T?)x); } - public static IObservable Create(IStyledElement control, Type ancestorType) + public static IObservable Create(StyledElement control, Type ancestorType) { - return new AnonymousObservable(observer => + return new AnonymousObservable(observer => { var finder = new FinderNode(control, ancestorType); var subscription = finder.Observable.Subscribe(observer); diff --git a/src/Avalonia.Controls/Viewbox.cs b/src/Avalonia.Controls/Viewbox.cs index 07d877142e0..1c2ee7ec2cb 100644 --- a/src/Avalonia.Controls/Viewbox.cs +++ b/src/Avalonia.Controls/Viewbox.cs @@ -26,7 +26,7 @@ public class Viewbox : Control /// /// Defines the property /// - public static readonly StyledProperty ChildProperty = + public static readonly StyledProperty ChildProperty = Decorator.ChildProperty.AddOwner(); static Viewbox() @@ -69,7 +69,7 @@ public StretchDirection StretchDirection /// Gets or sets the child of the Viewbox /// [Content] - public IControl? Child + public Control? Child { get => GetValue(ChildProperty); set => SetValue(ChildProperty, value); @@ -91,7 +91,7 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang if (change.Property == ChildProperty) { - var (oldChild, newChild) = change.GetOldAndNewValue(); + var (oldChild, newChild) = change.GetOldAndNewValue(); if (oldChild is not null) { @@ -153,9 +153,9 @@ protected override Size ArrangeOverride(Size finalSize) /// private class ViewboxContainer : Control { - private IControl? _child; + private Control? _child; - public IControl? Child + public Control? Child { get => _child; set diff --git a/src/Avalonia.Controls/VirtualizingStackPanel.cs b/src/Avalonia.Controls/VirtualizingStackPanel.cs index 93fbf6d17bb..f7cf1b922d4 100644 --- a/src/Avalonia.Controls/VirtualizingStackPanel.cs +++ b/src/Avalonia.Controls/VirtualizingStackPanel.cs @@ -80,7 +80,7 @@ void IVirtualizingPanel.ForceInvalidateMeasure() protected override Size MeasureOverride(Size availableSize) { - if (_forceRemeasure || availableSize != ((ILayoutable)this).PreviousMeasure) + if (_forceRemeasure || availableSize != PreviousMeasure) { _forceRemeasure = false; _availableSpace = availableSize; @@ -110,7 +110,7 @@ protected override void ChildrenChanged(object? sender, NotifyCollectionChangedE switch (e.Action) { case NotifyCollectionChangedAction.Add: - foreach (IControl control in e.NewItems!) + foreach (Control control in e.NewItems!) { UpdateAdd(control); } @@ -118,7 +118,7 @@ protected override void ChildrenChanged(object? sender, NotifyCollectionChangedE break; case NotifyCollectionChangedAction.Remove: - foreach (IControl control in e.OldItems!) + foreach (Control control in e.OldItems!) { UpdateRemove(control); } @@ -127,7 +127,7 @@ protected override void ChildrenChanged(object? sender, NotifyCollectionChangedE } } - protected override IInputElement? GetControlInDirection(NavigationDirection direction, IControl? from) + protected override IInputElement? GetControlInDirection(NavigationDirection direction, Control? from) { var logicalScrollable = Parent as ILogicalScrollable; @@ -142,7 +142,7 @@ protected override void ChildrenChanged(object? sender, NotifyCollectionChangedE } internal override void ArrangeChild( - IControl child, + Control child, Rect rect, Size panelSize, Orientation orientation) @@ -191,7 +191,7 @@ internal override void ArrangeChild( } } - private void UpdateAdd(IControl child) + private void UpdateAdd(Control child) { var bounds = Bounds; var spacing = Spacing; @@ -213,7 +213,7 @@ private void UpdateAdd(IControl child) } } - private void UpdateRemove(IControl child) + private void UpdateRemove(Control child) { var bounds = Bounds; var spacing = Spacing; diff --git a/src/Avalonia.Controls/WrapPanel.cs b/src/Avalonia.Controls/WrapPanel.cs index b7061824f0a..0426291d675 100644 --- a/src/Avalonia.Controls/WrapPanel.cs +++ b/src/Avalonia.Controls/WrapPanel.cs @@ -84,7 +84,7 @@ public double ItemHeight var orientation = Orientation; var children = Children; bool horiz = orientation == Orientation.Horizontal; - int index = from is not null ? Children.IndexOf((IControl)from) : -1; + int index = from is not null ? Children.IndexOf((Control)from) : -1; switch (direction) { diff --git a/src/Avalonia.DesignerSupport/Remote/Stubs.cs b/src/Avalonia.DesignerSupport/Remote/Stubs.cs index 7d4a6518efd..71389be1a6f 100644 --- a/src/Avalonia.DesignerSupport/Remote/Stubs.cs +++ b/src/Avalonia.DesignerSupport/Remote/Stubs.cs @@ -61,7 +61,7 @@ public WindowStub(IWindowImpl parent = null) })); } - public IRenderer CreateRenderer(IRenderRoot root) => new ImmediateRenderer(root); + public IRenderer CreateRenderer(IRenderRoot root) => new ImmediateRenderer((Visual)root); public void Dispose() { } diff --git a/src/Avalonia.Diagnostics/Diagnostics/Controls/Application.cs b/src/Avalonia.Diagnostics/Diagnostics/Controls/Application.cs index 2ca8549cfad..42c5ea1fa92 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/Controls/Application.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/Controls/Application.cs @@ -10,7 +10,7 @@ class Application : AvaloniaObject { private readonly App _application; - private static readonly Version s_version = typeof(IAvaloniaObject).Assembly?.GetName()?.Version + private static readonly Version s_version = typeof(AvaloniaObject).Assembly?.GetName()?.Version ?? Version.Parse("0.0.00"); public event EventHandler? Closed; @@ -31,7 +31,7 @@ public Application(App application) RendererRoot = application.ApplicationLifetime switch { Lifetimes.IClassicDesktopStyleApplicationLifetime classic => classic.MainWindow?.Renderer, - Lifetimes.ISingleViewApplicationLifetime single => (single.MainView as VisualTree.IVisual)?.VisualRoot?.Renderer, + Lifetimes.ISingleViewApplicationLifetime single => (single.MainView as Visual)?.VisualRoot?.Renderer, _ => null }; } diff --git a/src/Avalonia.Diagnostics/Diagnostics/DevTools.cs b/src/Avalonia.Diagnostics/Diagnostics/DevTools.cs index 9029ddf2bd1..8eadcee6f9f 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/DevTools.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/DevTools.cs @@ -105,7 +105,7 @@ internal static IDisposable Attach(Application? application, DevToolsOptions opt private static IDisposable Open(Application? application, DevToolsOptions options, Window? owner = default) { - var focussedControl = KeyboardDevice.Instance?.FocusedElement as IControl; + var focussedControl = KeyboardDevice.Instance?.FocusedElement as Control; if (application is null) { throw new ArgumentNullException(nameof(application)); diff --git a/src/Avalonia.Diagnostics/Diagnostics/IScreenshotHandler.cs b/src/Avalonia.Diagnostics/Diagnostics/IScreenshotHandler.cs index 3503ab56b33..d1b3e08352b 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/IScreenshotHandler.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/IScreenshotHandler.cs @@ -12,6 +12,6 @@ public interface IScreenshotHandler /// Handle the Screenshot /// /// - Task Take(IControl control); + Task Take(Control control); } } diff --git a/src/Avalonia.Diagnostics/Diagnostics/Screenshots/BaseRenderToStreamHandler.cs b/src/Avalonia.Diagnostics/Diagnostics/Screenshots/BaseRenderToStreamHandler.cs index e80f1762587..acf2e012646 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/Screenshots/BaseRenderToStreamHandler.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/Screenshots/BaseRenderToStreamHandler.cs @@ -13,9 +13,9 @@ public abstract class BaseRenderToStreamHandler : IScreenshotHandler /// /// /// stream to render the control - protected abstract Task GetStream(IControl control); + protected abstract Task GetStream(Control control); - public async Task Take(IControl control) + public async Task Take(Control control) { using var output = await GetStream(control); if (output is { }) diff --git a/src/Avalonia.Diagnostics/Diagnostics/Screenshots/FilePickerHandler.cs b/src/Avalonia.Diagnostics/Diagnostics/Screenshots/FilePickerHandler.cs index 501746ffb06..444e65e623e 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/Screenshots/FilePickerHandler.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/Screenshots/FilePickerHandler.cs @@ -47,7 +47,7 @@ public FilePickerHandler(string? title /// public string Title { get; } = "Save Screenshot to ..."; - Window GetWindow(IControl control) + Window GetWindow(Control control) { var window = control.VisualRoot as Window; var app = Application.Current; @@ -58,7 +58,7 @@ Window GetWindow(IControl control) return window!; } - protected override async Task GetStream(IControl control) + protected override async Task GetStream(Control control) { var result = await GetWindow(control).StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions { diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewLocator.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewLocator.cs index 23fc5e3d939..6ddfb138f35 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/ViewLocator.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewLocator.cs @@ -7,7 +7,7 @@ namespace Avalonia.Diagnostics { internal class ViewLocator : IDataTemplate { - public IControl? Build(object? data) + public Control? Build(object? data) { if (data is null) return null; diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs index 71da543d707..0206ede277c 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs @@ -16,7 +16,7 @@ namespace Avalonia.Diagnostics.ViewModels { internal class ControlDetailsViewModel : ViewModelBase, IDisposable, IClassesChangedListener { - private readonly IAvaloniaObject _avaloniaObject; + private readonly AvaloniaObject _avaloniaObject; private IDictionary? _propertyIndex; private PropertyViewModel? _selectedProperty; private DataGridCollectionView? _propertiesView; @@ -29,16 +29,16 @@ internal class ControlDetailsViewModel : ViewModelBase, IDisposable, IClassesCha private string? _selectedEntityType; private bool _showImplementedInterfaces; - public ControlDetailsViewModel(TreePageViewModel treePage, IAvaloniaObject avaloniaObject) + public ControlDetailsViewModel(TreePageViewModel treePage, AvaloniaObject avaloniaObject) { _avaloniaObject = avaloniaObject; TreePage = treePage; - Layout = avaloniaObject is IVisual - ? new ControlLayoutViewModel((IVisual)avaloniaObject) + Layout = avaloniaObject is Visual + ? new ControlLayoutViewModel((Visual)avaloniaObject) : default; - NavigateToProperty(_avaloniaObject, (_avaloniaObject as IControl)?.Name ?? _avaloniaObject.ToString()); + NavigateToProperty(_avaloniaObject, (_avaloniaObject as Control)?.Name ?? _avaloniaObject.ToString()); AppliedStyles = new ObservableCollection(); PseudoClasses = new ObservableCollection(); @@ -447,7 +447,7 @@ public void NavigateToSelectedProperty() { case AvaloniaPropertyViewModel avaloniaProperty: - property = (_selectedEntity as IControl)?.GetValue(avaloniaProperty.Property); + property = (_selectedEntity as Control)?.GetValue(avaloniaProperty.Property); break; @@ -496,7 +496,7 @@ protected void NavigateToProperty(object o, string? entityName) switch (oldSelectedEntity) { - case IAvaloniaObject ao1: + case AvaloniaObject ao1: ao1.PropertyChanged -= ControlPropertyChanged; break; @@ -528,7 +528,7 @@ protected void NavigateToProperty(object o, string? entityName) switch (o) { - case IAvaloniaObject ao2: + case AvaloniaObject ao2: ao2.PropertyChanged += ControlPropertyChanged; break; @@ -546,7 +546,7 @@ internal void SelectProperty(AvaloniaProperty property) { NavigateToProperty( _avaloniaObject, - (_avaloniaObject as IControl)?.Name ?? _avaloniaObject.ToString()); + (_avaloniaObject as Control)?.Name ?? _avaloniaObject.ToString()); } if (PropertiesView is null) @@ -569,7 +569,7 @@ internal void UpdatePropertiesView(bool showImplementedInterfaces) { _showImplementedInterfaces = showImplementedInterfaces; SelectedProperty = null; - NavigateToProperty(_avaloniaObject, (_avaloniaObject as IControl)?.Name ?? _avaloniaObject.ToString()); + NavigateToProperty(_avaloniaObject, (_avaloniaObject as Control)?.Name ?? _avaloniaObject.ToString()); } } } diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlLayoutViewModel.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlLayoutViewModel.cs index a453fef2125..6b568062502 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlLayoutViewModel.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlLayoutViewModel.cs @@ -9,7 +9,7 @@ namespace Avalonia.Diagnostics.ViewModels { internal class ControlLayoutViewModel : ViewModelBase { - private readonly IVisual _control; + private readonly Visual _control; private Thickness _borderThickness; private double _height; private string? _heightConstraint; @@ -21,7 +21,7 @@ internal class ControlLayoutViewModel : ViewModelBase private double _width; private string? _widthConstraint; - public ControlLayoutViewModel(IVisual control) + public ControlLayoutViewModel(Visual control) { _control = control; diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/EventTreeNode.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/EventTreeNode.cs index e8de22710a0..7da43a51b74 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/EventTreeNode.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/EventTreeNode.cs @@ -65,7 +65,7 @@ private void HandleEvent(object? sender, RoutedEventArgs e) { if (!_isRegistered || IsEnabled == false) return; - if (sender is IVisual v && BelongsToDevTool(v)) + if (sender is Visual v && BelongsToDevTool(v)) return; var s = sender!; @@ -99,7 +99,7 @@ private void HandleRouteFinished(RoutedEventArgs e) { if (!_isRegistered || IsEnabled == false) return; - if (e.Source is IVisual v && BelongsToDevTool(v)) + if (e.Source is Visual v && BelongsToDevTool(v)) return; var s = e.Source; @@ -124,7 +124,7 @@ void handler() handler(); } - private static bool BelongsToDevTool(IVisual v) + private static bool BelongsToDevTool(Visual v) { var current = v; diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/EventsPageViewModel.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/EventsPageViewModel.cs index fbcedb2e749..c5868e0e0c3 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/EventsPageViewModel.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/EventsPageViewModel.cs @@ -78,7 +78,7 @@ public void EnableDefault() public void RequestTreeNavigateTo(EventChainLink navTarget) { - if (navTarget.Handler is IControl control) + if (navTarget.Handler is Control control) { _mainViewModel.RequestTreeNavigateTo(control, true); } diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/LogicalTreeNode.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/LogicalTreeNode.cs index e8a5076c361..e71f0bcaec4 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/LogicalTreeNode.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/LogicalTreeNode.cs @@ -10,7 +10,7 @@ namespace Avalonia.Diagnostics.ViewModels { internal class LogicalTreeNode : TreeNode { - public LogicalTreeNode(IAvaloniaObject avaloniaObject, TreeNode? parent) + public LogicalTreeNode(AvaloniaObject avaloniaObject, TreeNode? parent) : base(avaloniaObject, parent) { Children = avaloniaObject switch @@ -25,7 +25,7 @@ public LogicalTreeNode(IAvaloniaObject avaloniaObject, TreeNode? parent) public static LogicalTreeNode[] Create(object control) { - var logical = control as IAvaloniaObject; + var logical = control as AvaloniaObject; return logical != null ? new[] { new LogicalTreeNode(logical, null) } : Array.Empty(); } @@ -49,7 +49,7 @@ public override void Dispose() protected override void Initialize(AvaloniaList nodes) { _subscription = _control.LogicalChildren.ForEachItem( - (i, item) => nodes.Insert(i, new LogicalTreeNode((IAvaloniaObject)item, Owner)), + (i, item) => nodes.Insert(i, new LogicalTreeNode((AvaloniaObject)item, Owner)), (i, item) => nodes.RemoveAt(i), () => nodes.Clear()); } @@ -92,7 +92,7 @@ protected override void Initialize(AvaloniaList nodes) { return; } - nodes.Add(new LogicalTreeNode((IAvaloniaObject)s!,Owner)); + nodes.Add(new LogicalTreeNode((AvaloniaObject)s!,Owner)); }), Window.WindowClosedEvent.AddClassHandler(typeof(Window), (s,e)=> { diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/MainViewModel.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/MainViewModel.cs index 6b21b3f72b0..52535aa9910 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/MainViewModel.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/MainViewModel.cs @@ -147,7 +147,7 @@ private set { if (_content is TreePageViewModel oldTree && value is TreePageViewModel newTree && - oldTree?.SelectedNode?.Visual is IControl control) + oldTree?.SelectedNode?.Visual is Control control) { // HACK: We want to select the currently selected control in the new tree, but // to select nested nodes in TreeView, currently the TreeView has to be able to @@ -232,7 +232,7 @@ private void UpdateConsoleContext(ConsoleContext context) } } - public void SelectControl(IControl control) + public void SelectControl(Control control) { var tree = Content as TreePageViewModel; @@ -274,7 +274,7 @@ private void KeyboardPropertyChanged(object? sender, PropertyChangedEventArgs e) } } - public void RequestTreeNavigateTo(IControl control, bool isVisualTree) + public void RequestTreeNavigateTo(Control control, bool isVisualTree) { var tree = isVisualTree ? _visualTree : _logicalTree; @@ -296,13 +296,13 @@ public bool CanShot(object? parameter) { return Content is TreePageViewModel tree && tree.SelectedNode != null - && tree.SelectedNode.Visual is VisualTree.IVisual visual + && tree.SelectedNode.Visual is Visual visual && visual.VisualRoot != null; } public async void Shot(object? parameter) { - if ((Content as TreePageViewModel)?.SelectedNode?.Visual is IControl control + if ((Content as TreePageViewModel)?.SelectedNode?.Visual is Control control && _screenshotHandler is { } ) { diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreeNode.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreeNode.cs index 4fc55333d04..65bfd7fc362 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreeNode.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreeNode.cs @@ -15,7 +15,7 @@ internal abstract class TreeNode : ViewModelBase, IDisposable private string _classes; private bool _isExpanded; - protected TreeNode(IAvaloniaObject avaloniaObject, TreeNode? parent, string? customName = null) + protected TreeNode(AvaloniaObject avaloniaObject, TreeNode? parent, string? customName = null) { _classes = string.Empty; Parent = parent; @@ -24,7 +24,7 @@ protected TreeNode(IAvaloniaObject avaloniaObject, TreeNode? parent, string? cus Visual = visual!; FontWeight = IsRoot ? FontWeight.Bold : FontWeight.Normal; - if (visual is IControl control) + if (visual is Control control) { ElementName = control.Name; @@ -76,7 +76,7 @@ public string? ElementName get; } - public IAvaloniaObject Visual + public AvaloniaObject Visual { get; } diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreePageViewModel.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreePageViewModel.cs index ff3361dc41b..e916995baec 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreePageViewModel.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreePageViewModel.cs @@ -69,7 +69,7 @@ public void Dispose() _details?.Dispose(); } - public TreeNode? FindNode(IControl control) + public TreeNode? FindNode(Control control) { foreach (var node in Nodes) { @@ -84,10 +84,10 @@ public void Dispose() return null; } - public void SelectControl(IControl control) + public void SelectControl(Control control) { var node = default(TreeNode); - IControl? c = control; + Control? c = control; while (node == null && c != null) { @@ -95,7 +95,7 @@ public void SelectControl(IControl control) if (node == null) { - c = c.GetVisualParent(); + c = c.GetVisualParent(); } } @@ -115,7 +115,7 @@ private void ExpandNode(TreeNode? node) } } - private TreeNode? FindNode(TreeNode node, IControl control) + private TreeNode? FindNode(TreeNode node, Control control) { if (node.Visual == control) { diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/VisualTreeNode.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/VisualTreeNode.cs index 4a5cb0fd3f9..a1cd01c78b8 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/VisualTreeNode.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/VisualTreeNode.cs @@ -14,12 +14,12 @@ namespace Avalonia.Diagnostics.ViewModels { internal class VisualTreeNode : TreeNode { - public VisualTreeNode(IAvaloniaObject avaloniaObject, TreeNode? parent, string? customName = null) + public VisualTreeNode(AvaloniaObject avaloniaObject, TreeNode? parent, string? customName = null) : base(avaloniaObject, parent, customName) { Children = avaloniaObject switch { - IVisual visual => new VisualTreeNodeCollection(this, visual), + Visual visual => new VisualTreeNodeCollection(this, visual), Controls.Application host => new ApplicationHostVisuals(this, host), _ => TreeNodeCollection.Empty }; @@ -34,17 +34,17 @@ public VisualTreeNode(IAvaloniaObject avaloniaObject, TreeNode? parent, string? public static VisualTreeNode[] Create(object control) { - return control is IAvaloniaObject visual ? + return control is AvaloniaObject visual ? new[] { new VisualTreeNode(visual, null) } : Array.Empty(); } internal class VisualTreeNodeCollection : TreeNodeCollection { - private readonly IVisual _control; + private readonly Visual _control; private readonly CompositeDisposable _subscriptions = new CompositeDisposable(2); - public VisualTreeNodeCollection(TreeNode owner, IVisual control) + public VisualTreeNodeCollection(TreeNode owner, Visual control) : base(owner) { _control = control; @@ -55,7 +55,7 @@ public override void Dispose() _subscriptions.Dispose(); } - private static IObservable? GetHostedPopupRootObservable(IVisual visual) + private static IObservable? GetHostedPopupRootObservable(Visual visual) { static IObservable GetPopupHostObservable( IPopupHostProvider popupHostProvider, @@ -67,7 +67,7 @@ public override void Dispose() .StartWith(popupHostProvider.PopupHost) .Select(popupHost => { - if (popupHost is IControl control) + if (popupHost is Control control) return new PopupRoot( control, providerName != null ? $"{providerName} ({control.GetType().Name})" : null); @@ -141,20 +141,20 @@ protected override void Initialize(AvaloniaList nodes) _subscriptions.Add( _control.VisualChildren.ForEachItem( - (i, item) => nodes.Insert(i, new VisualTreeNode((IAvaloniaObject)item, Owner)), + (i, item) => nodes.Insert(i, new VisualTreeNode((AvaloniaObject)item, Owner)), (i, item) => nodes.RemoveAt(i), () => nodes.Clear())); } private struct PopupRoot { - public PopupRoot(IControl root, string? customName = null) + public PopupRoot(Control root, string? customName = null) { Root = root; CustomName = customName; } - public IControl Root { get; } + public Control Root { get; } public string? CustomName { get; } } } @@ -196,7 +196,7 @@ protected override void Initialize(AvaloniaList nodes) { return; } - nodes.Add(new VisualTreeNode((IAvaloniaObject)s!,Owner)); + nodes.Add(new VisualTreeNode((AvaloniaObject)s!,Owner)); }), Window.WindowClosedEvent.AddClassHandler(typeof(Window), (s,e)=> { diff --git a/src/Avalonia.Diagnostics/Diagnostics/Views/ConsoleView.xaml.cs b/src/Avalonia.Diagnostics/Diagnostics/Views/ConsoleView.xaml.cs index d9e7ffe5acc..01e85034954 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/Views/ConsoleView.xaml.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/Views/ConsoleView.xaml.cs @@ -32,7 +32,7 @@ private void InitializeComponent() private void HistoryChanged(object? sender, NotifyCollectionChangedEventArgs e) { - if (e.Action == NotifyCollectionChangedAction.Add && e.NewItems?[0] is IControl control) + if (e.Action == NotifyCollectionChangedAction.Add && e.NewItems?[0] is Control control) { DispatcherTimer.RunOnce(control.BringIntoView, TimeSpan.Zero); } diff --git a/src/Avalonia.Diagnostics/Diagnostics/Views/LayoutExplorerView.axaml.cs b/src/Avalonia.Diagnostics/Diagnostics/Views/LayoutExplorerView.axaml.cs index 4f6b3f0aad0..c81e3cadf45 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/Views/LayoutExplorerView.axaml.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/Views/LayoutExplorerView.axaml.cs @@ -100,7 +100,7 @@ void UpdateGuidelines(Visual area) } } - Point TranslateToRoot(Point point, IVisual from) + Point TranslateToRoot(Point point, Visual from) { return from.TranslatePoint(point, _layoutRoot) ?? default; } diff --git a/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml.cs b/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml.cs index e6e630112b7..13b8cf5e8a3 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml.cs @@ -39,7 +39,7 @@ public MainWindow() .Subscribe(RawKeyDown); _pointerSubscription = InputManager.Instance?.Process .OfType() - .Subscribe(x => _lastPointerPosition = x.Root.PointToScreen(x.Position)); + .Subscribe(x => _lastPointerPosition = ((Visual)x.Root).PointToScreen(x.Position)); _frozenPopupStates = new Dictionary(); @@ -118,11 +118,11 @@ private void InitializeComponent() AvaloniaXamlLoader.Load(this); } - private IControl? GetHoveredControl(TopLevel topLevel) + private Control? GetHoveredControl(TopLevel topLevel) { var point = topLevel.PointToClient(_lastPointerPosition); - return (IControl?)topLevel.GetVisualsAt(point, x => + return (Control?)topLevel.GetVisualsAt(point, x => { if (x is AdornerLayer || !x.IsVisible) { @@ -138,7 +138,7 @@ private static List GetPopupRoots(TopLevel root) { var popupRoots = new List(); - void ProcessProperty(IControl control, AvaloniaProperty property) + void ProcessProperty(Control control, AvaloniaProperty property) { if (control.GetValue(property) is IPopupHostProvider popupProvider && popupProvider.PopupHost is PopupRoot popupRoot) @@ -147,7 +147,7 @@ void ProcessProperty(IControl control, AvaloniaProperty property) } } - foreach (var control in root.GetVisualDescendants().OfType()) + foreach (var control in root.GetVisualDescendants().OfType()) { if (control is Popup p && p.Host is PopupRoot popupRoot) { @@ -190,7 +190,7 @@ private void RawKeyDown(RawKeyEventArgs e) case RawInputModifiers.Shift when (e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl): case RawInputModifiers.Shift | RawInputModifiers.Control: { - IControl? control = null; + Control? control = null; foreach (var popupRoot in GetPopupRoots(root)) { @@ -271,7 +271,7 @@ public void SetOptions(DevToolsOptions options) } } - internal void SelectedControl(IControl? control) + internal void SelectedControl(Control? control) { if (control is { }) { diff --git a/src/Avalonia.Diagnostics/Diagnostics/VisualExtensions.cs b/src/Avalonia.Diagnostics/Diagnostics/VisualExtensions.cs index a80ed2d4ef3..092e26c96d5 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/VisualExtensions.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/VisualExtensions.cs @@ -15,7 +15,7 @@ internal static class VisualExtensions /// Control to be rendered. /// Destination stream. /// Dpi quality. - public static void RenderTo(this IControl source, Stream destination, double dpi = 96) + public static void RenderTo(this Control source, Stream destination, double dpi = 96) { if (source.TransformedBounds == null) { @@ -29,7 +29,7 @@ public static void RenderTo(this IControl source, Stream destination, double dpi // get Visual root var root = (source.VisualRoot ?? source.GetVisualRoot()) - as IControl ?? source; + as Control ?? source; IDisposable? clipSetter = default; IDisposable? clipToBoundsSetter = default; diff --git a/src/Avalonia.Diagnostics/Diagnostics/VisualTreeDebug.cs b/src/Avalonia.Diagnostics/Diagnostics/VisualTreeDebug.cs index 13c8e070e80..f34fe6d1520 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/VisualTreeDebug.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/VisualTreeDebug.cs @@ -9,14 +9,14 @@ namespace Avalonia.Diagnostics { public static class VisualTreeDebug { - public static string PrintVisualTree(IVisual visual) + public static string PrintVisualTree(Visual visual) { var result = StringBuilderCache.Acquire(); PrintVisualTree(visual, result, 0); return StringBuilderCache.GetStringAndRelease(result); } - private static void PrintVisualTree(IVisual visual, StringBuilder builder, int indent) + private static void PrintVisualTree(Visual visual, StringBuilder builder, int indent) { Control? control = visual as Control; diff --git a/src/Avalonia.Native/AvaloniaNativeDragSource.cs b/src/Avalonia.Native/AvaloniaNativeDragSource.cs index f91a299b3b2..bec45c2d712 100644 --- a/src/Avalonia.Native/AvaloniaNativeDragSource.cs +++ b/src/Avalonia.Native/AvaloniaNativeDragSource.cs @@ -6,7 +6,6 @@ using Avalonia.Input.Platform; using Avalonia.Interactivity; using Avalonia.Native.Interop; -using Avalonia.Platform; using Avalonia.VisualTree; namespace Avalonia.Native @@ -19,15 +18,15 @@ public AvaloniaNativeDragSource(IAvaloniaNativeFactory factory) { _factory = factory; } - - TopLevel FindRoot(IInteractive interactive) + + private static TopLevel FindRoot(object? element) { - while (interactive != null && !(interactive is IVisual)) - interactive = interactive.InteractiveParent; - if (interactive == null) + while (element is Interactive interactive && element is not Visual) + element = interactive.GetInteractiveParent(); + if (element == null) return null; - var visual = (IVisual)interactive; - return visual.VisualRoot as TopLevel; + var visual = (Visual)element; + return visual.GetVisualRoot() as TopLevel; } class DndCallback : NativeCallbackBase, IAvnDndResultCallback diff --git a/src/Avalonia.Native/WindowImpl.cs b/src/Avalonia.Native/WindowImpl.cs index b5af927ea01..9de794ed538 100644 --- a/src/Avalonia.Native/WindowImpl.cs +++ b/src/Avalonia.Native/WindowImpl.cs @@ -122,7 +122,7 @@ protected override bool ChromeHitTest (RawPointerEventArgs e) { var visual = (_inputRoot as Window).Renderer.HitTestFirst(e.Position, _inputRoot as Window, x => { - if (x is IInputElement ie && (!ie.IsHitTestVisible || !ie.IsVisible)) + if (x is IInputElement ie && (!ie.IsHitTestVisible || !ie.IsEffectivelyVisible)) { return false; } diff --git a/src/Avalonia.Native/WindowImplBase.cs b/src/Avalonia.Native/WindowImplBase.cs index b74e4ec3b44..4744a201075 100644 --- a/src/Avalonia.Native/WindowImplBase.cs +++ b/src/Avalonia.Native/WindowImplBase.cs @@ -382,7 +382,7 @@ public IRenderer CreateRenderer(IRenderRoot root) return new DeferredRenderer(root, loop); } - return new ImmediateRenderer(root); + return new ImmediateRenderer((Visual)root); } public virtual void Dispose() diff --git a/src/Avalonia.ReactiveUI/AvaloniaActivationForViewFetcher.cs b/src/Avalonia.ReactiveUI/AvaloniaActivationForViewFetcher.cs index 9f69b4ee6e9..84048ffd497 100644 --- a/src/Avalonia.ReactiveUI/AvaloniaActivationForViewFetcher.cs +++ b/src/Avalonia.ReactiveUI/AvaloniaActivationForViewFetcher.cs @@ -17,7 +17,7 @@ public class AvaloniaActivationForViewFetcher : IActivationForViewFetcher /// public int GetAffinityForView(Type view) { - return typeof(IVisual).IsAssignableFrom(view) ? 10 : 0; + return typeof(Visual).IsAssignableFrom(view) ? 10 : 0; } /// @@ -25,7 +25,7 @@ public int GetAffinityForView(Type view) /// public IObservable GetActivationForView(IActivatableView view) { - if (!(view is IVisual visual)) return Observable.Return(false); + if (!(view is Visual visual)) return Observable.Return(false); if (view is Control control) return GetActivationForControl(control); return GetActivationForVisual(visual); } @@ -55,7 +55,7 @@ private IObservable GetActivationForControl(Control control) /// Listens to AttachedToVisualTree and DetachedFromVisualTree /// events for Avalonia IVisuals. /// - private IObservable GetActivationForVisual(IVisual visual) + private IObservable GetActivationForVisual(Visual visual) { var visualLoaded = Observable .FromEventPattern( diff --git a/src/Avalonia.ReactiveUI/ViewModelViewHost.cs b/src/Avalonia.ReactiveUI/ViewModelViewHost.cs index 0750fef0670..dc457580468 100644 --- a/src/Avalonia.ReactiveUI/ViewModelViewHost.cs +++ b/src/Avalonia.ReactiveUI/ViewModelViewHost.cs @@ -121,7 +121,7 @@ private void NavigateToViewModel(object? viewModel, string? contract) } viewInstance.ViewModel = viewModel; - if (viewInstance is IStyledElement styled) + if (viewInstance is StyledElement styled) styled.DataContext = viewModel; Content = viewInstance; } diff --git a/src/Avalonia.X11/X11ImmediateRendererProxy.cs b/src/Avalonia.X11/X11ImmediateRendererProxy.cs index 7280567bb34..293e5110f7f 100644 --- a/src/Avalonia.X11/X11ImmediateRendererProxy.cs +++ b/src/Avalonia.X11/X11ImmediateRendererProxy.cs @@ -14,7 +14,7 @@ public class X11ImmediateRendererProxy : IRenderer, IRenderLoopTask private bool _running; private object _lock = new object(); - public X11ImmediateRendererProxy(IVisual root, IRenderLoop loop) + public X11ImmediateRendererProxy(Visual root, IRenderLoop loop) { _loop = loop; _renderer = new ImmediateRenderer(root); @@ -45,24 +45,24 @@ public event EventHandler SceneInvalidated remove => _renderer.SceneInvalidated -= value; } - public void AddDirty(IVisual visual) + public void AddDirty(Visual visual) { lock (_lock) _invalidated = true; _renderer.AddDirty(visual); } - public IEnumerable HitTest(Point p, IVisual root, Func filter) + public IEnumerable HitTest(Point p, Visual root, Func filter) { return _renderer.HitTest(p, root, filter); } - public IVisual HitTestFirst(Point p, IVisual root, Func filter) + public Visual HitTestFirst(Point p, Visual root, Func filter) { return _renderer.HitTestFirst(p, root, filter); } - public void RecalculateChildren(IVisual visual) + public void RecalculateChildren(Visual visual) { _renderer.RecalculateChildren(visual); } diff --git a/src/Avalonia.X11/X11Window.cs b/src/Avalonia.X11/X11Window.cs index 0b5ae281f42..330494d5dcd 100644 --- a/src/Avalonia.X11/X11Window.cs +++ b/src/Avalonia.X11/X11Window.cs @@ -398,7 +398,7 @@ public IRenderer CreateRenderer(IRenderRoot root) { RenderOnlyOnRenderThread = true } - : (IRenderer)new X11ImmediateRendererProxy(root, loop); + : (IRenderer)new X11ImmediateRendererProxy((Visual)root, loop); } void OnEvent(ref XEvent ev) diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs index b4999136a48..e9d812a4657 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs @@ -57,7 +57,7 @@ public static (XamlLanguageTypeMappings language, XamlLanguageEmitMappings { "TemplateResultType" diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs index dd37ae6c930..13e41c08526 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs @@ -11,7 +11,6 @@ class AvaloniaXamlIlWellKnownTypes { public IXamlType RuntimeHelpers { get; } public IXamlType AvaloniaObject { get; } - public IXamlType IAvaloniaObject { get; } public IXamlType BindingPriority { get; } public IXamlType AvaloniaObjectExtensions { get; } public IXamlType AvaloniaProperty { get; } @@ -35,7 +34,6 @@ class AvaloniaXamlIlWellKnownTypes public IXamlType OnExtensionType { get; } public IXamlType UnsetValueType { get; } public IXamlType StyledElement { get; } - public IXamlType IStyledElement { get; } public IXamlType NameScope { get; } public IXamlMethod NameScopeSetNameScope { get; } public IXamlType INameScope { get; } @@ -117,7 +115,6 @@ public AvaloniaXamlIlWellKnownTypes(TransformerConfiguration cfg) XamlIlTypes = cfg.WellKnownTypes; AvaloniaObject = cfg.TypeSystem.GetType("Avalonia.AvaloniaObject"); - IAvaloniaObject = cfg.TypeSystem.GetType("Avalonia.IAvaloniaObject"); AvaloniaObjectExtensions = cfg.TypeSystem.GetType("Avalonia.AvaloniaObjectExtensions"); AvaloniaProperty = cfg.TypeSystem.GetType("Avalonia.AvaloniaProperty"); AvaloniaPropertyT = cfg.TypeSystem.GetType("Avalonia.AvaloniaProperty`1"); @@ -139,12 +136,12 @@ public AvaloniaXamlIlWellKnownTypes(TransformerConfiguration cfg) MarkupExtensionOptionAttribute = cfg.TypeSystem.GetType("Avalonia.Metadata.MarkupExtensionOptionAttribute"); MarkupExtensionDefaultOptionAttribute = cfg.TypeSystem.GetType("Avalonia.Metadata.MarkupExtensionDefaultOptionAttribute"); OnExtensionType = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.On"); - AvaloniaObjectBindMethod = AvaloniaObjectExtensions.FindMethod("Bind", IDisposable, false, IAvaloniaObject, + AvaloniaObjectBindMethod = AvaloniaObjectExtensions.FindMethod("Bind", IDisposable, false, AvaloniaObject, AvaloniaProperty, IBinding, cfg.WellKnownTypes.Object); UnsetValueType = cfg.TypeSystem.GetType("Avalonia.UnsetValueType"); StyledElement = cfg.TypeSystem.GetType("Avalonia.StyledElement"); - IStyledElement = cfg.TypeSystem.GetType("Avalonia.IStyledElement"); + StyledElement = cfg.TypeSystem.GetType("Avalonia.StyledElement"); INameScope = cfg.TypeSystem.GetType("Avalonia.Controls.INameScope"); INameScopeRegister = INameScope.GetMethod( new FindMethodMethodSignature("Register", XamlIlTypes.Void, @@ -223,7 +220,7 @@ public AvaloniaXamlIlWellKnownTypes(TransformerConfiguration cfg) StyledElementClassesProperty = StyledElement.Properties.First(x => x.Name == "Classes" && x.PropertyType.Equals(Classes)); ClassesBindMethod = cfg.TypeSystem.GetType("Avalonia.StyledElementExtensions") - .FindMethod( "BindClass", IDisposable, false, IStyledElement, + .FindMethod( "BindClass", IDisposable, false, StyledElement, cfg.WellKnownTypes.String, IBinding, cfg.WellKnownTypes.Object); diff --git a/src/Markup/Avalonia.Markup.Xaml/Extensions.cs b/src/Markup/Avalonia.Markup.Xaml/Extensions.cs index d937a83010a..92e3873dc45 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Extensions.cs +++ b/src/Markup/Avalonia.Markup.Xaml/Extensions.cs @@ -38,9 +38,9 @@ public static Type ResolveType(this IServiceProvider ctx, string namespacePrefix public static object GetDefaultAnchor(this IServiceProvider provider) { // If the target is not a control, so we need to find an anchor that will let us look - // up named controls and style resources. First look for the closest IControl in + // up named controls and style resources. First look for the closest Control in // the context. - object anchor = provider.GetFirstParent(); + object anchor = provider.GetFirstParent(); if (anchor is null) { diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindingExtension.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindingExtension.cs index 01251567503..9990ad4731f 100644 --- a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindingExtension.cs +++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindingExtension.cs @@ -35,7 +35,7 @@ public CompiledBindingExtension ProvideValue(IServiceProvider provider) }; } - protected override ExpressionObserver CreateExpressionObserver(IAvaloniaObject target, AvaloniaProperty targetProperty, object anchor, bool enableDataValidation) + protected override ExpressionObserver CreateExpressionObserver(AvaloniaObject target, AvaloniaProperty targetProperty, object anchor, bool enableDataValidation) { if (Source != null) { @@ -62,7 +62,7 @@ protected override ExpressionObserver CreateExpressionObserver(IAvaloniaObject t else { return CreateSourceObserver( - (target as IStyledElement) ?? (anchor as IStyledElement), + (target as StyledElement) ?? (anchor as StyledElement), Path.BuildExpression(enableDataValidation)); } } diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/FindVisualAncestorNode.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/FindVisualAncestorNode.cs index 5820f47fbb2..8ae6d52b128 100644 --- a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/FindVisualAncestorNode.cs +++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/FindVisualAncestorNode.cs @@ -33,7 +33,7 @@ public override string Description protected override void StartListeningCore(WeakReference reference) { - if (reference.TryGetTarget(out object target) && target is IVisual visual) + if (reference.TryGetTarget(out object target) && target is Visual visual) { _subscription = VisualLocator.Track(visual, _level, _ancestorType).Subscribe(ValueChanged); } diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/DynamicResourceExtension.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/DynamicResourceExtension.cs index 56b653ca47d..fb845cf4e64 100644 --- a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/DynamicResourceExtension.cs +++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/DynamicResourceExtension.cs @@ -31,9 +31,9 @@ public IBinding ProvideValue(IServiceProvider serviceProvider) var provideTarget = serviceProvider.GetService(); - if (!(provideTarget.TargetObject is IStyledElement)) + if (!(provideTarget.TargetObject is StyledElement)) { - _anchor = serviceProvider.GetFirstParent() ?? + _anchor = serviceProvider.GetFirstParent() ?? serviceProvider.GetFirstParent() ?? (object?)serviceProvider.GetFirstParent(); } @@ -42,7 +42,7 @@ public IBinding ProvideValue(IServiceProvider serviceProvider) } InstancedBinding? IBinding.Initiate( - IAvaloniaObject target, + AvaloniaObject target, AvaloniaProperty? targetProperty, object? anchor, bool enableDataValidation) diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StaticResourceExtension.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StaticResourceExtension.cs index f28f7bc6266..5bff9d9ca66 100644 --- a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StaticResourceExtension.cs +++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StaticResourceExtension.cs @@ -66,7 +66,7 @@ parent is IResourceProvider hack && previousWasControlTheme = parent is ControlTheme; } - if (provideTarget.TargetObject is IControl target && + if (provideTarget.TargetObject is Control target && provideTarget.TargetProperty is PropertyInfo property) { // This is stored locally to avoid allocating closure in the outer scope. @@ -80,7 +80,7 @@ parent is IResourceProvider hack && throw new KeyNotFoundException($"Static resource '{ResourceKey}' not found."); } - private object GetValue(IStyledElement control, Type targetType) + private object GetValue(StyledElement control, Type targetType) { return ColorToBrushConverter.Convert(control.FindResource(ResourceKey), targetType); } diff --git a/src/Markup/Avalonia.Markup.Xaml/Templates/ControlTemplate.cs b/src/Markup/Avalonia.Markup.Xaml/Templates/ControlTemplate.cs index 30c7c759922..6057e7ad054 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Templates/ControlTemplate.cs +++ b/src/Markup/Avalonia.Markup.Xaml/Templates/ControlTemplate.cs @@ -1,8 +1,7 @@ using System; -using Avalonia.Controls; +using Avalonia.Controls.Primitives; using Avalonia.Controls.Templates; using Avalonia.Metadata; -using Avalonia.Styling; namespace Avalonia.Markup.Xaml.Templates { @@ -14,6 +13,6 @@ public class ControlTemplate : IControlTemplate public Type TargetType { get; set; } - public ControlTemplateResult Build(ITemplatedControl control) => TemplateContent.Load(Content); + public ControlTemplateResult Build(TemplatedControl control) => TemplateContent.Load(Content); } } diff --git a/src/Markup/Avalonia.Markup.Xaml/Templates/DataTemplate.cs b/src/Markup/Avalonia.Markup.Xaml/Templates/DataTemplate.cs index 4da6b1b7911..d9009b84b10 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Templates/DataTemplate.cs +++ b/src/Markup/Avalonia.Markup.Xaml/Templates/DataTemplate.cs @@ -26,9 +26,9 @@ public bool Match(object data) } } - public IControl Build(object data) => Build(data, null); + public Control Build(object data) => Build(data, null); - public IControl Build(object data, IControl existing) + public Control Build(object data, Control existing) { return existing ?? TemplateContent.Load(Content)?.Control; } diff --git a/src/Markup/Avalonia.Markup.Xaml/Templates/ItemsPanelTemplate.cs b/src/Markup/Avalonia.Markup.Xaml/Templates/ItemsPanelTemplate.cs index c096ed7ed72..9e5da741356 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Templates/ItemsPanelTemplate.cs +++ b/src/Markup/Avalonia.Markup.Xaml/Templates/ItemsPanelTemplate.cs @@ -4,13 +4,13 @@ namespace Avalonia.Markup.Xaml.Templates { - public class ItemsPanelTemplate : ITemplate + public class ItemsPanelTemplate : ITemplate { [Content] [TemplateContent] public object Content { get; set; } - public IPanel Build() => (IPanel)TemplateContent.Load(Content)?.Control; + public Panel Build() => (Panel)TemplateContent.Load(Content)?.Control; object ITemplate.Build() => Build(); } diff --git a/src/Markup/Avalonia.Markup.Xaml/Templates/Template.cs b/src/Markup/Avalonia.Markup.Xaml/Templates/Template.cs index 45fae9cb28b..6dfa2755a61 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Templates/Template.cs +++ b/src/Markup/Avalonia.Markup.Xaml/Templates/Template.cs @@ -4,13 +4,13 @@ namespace Avalonia.Markup.Xaml.Templates { - public class Template : ITemplate + public class Template : ITemplate { [Content] [TemplateContent] public object Content { get; set; } - public IControl Build() => TemplateContent.Load(Content)?.Control; + public Control Build() => TemplateContent.Load(Content)?.Control; object ITemplate.Build() => Build(); } diff --git a/src/Markup/Avalonia.Markup.Xaml/Templates/TreeDataTemplate.cs b/src/Markup/Avalonia.Markup.Xaml/Templates/TreeDataTemplate.cs index 04e8b0a9c0e..339632cde8d 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Templates/TreeDataTemplate.cs +++ b/src/Markup/Avalonia.Markup.Xaml/Templates/TreeDataTemplate.cs @@ -50,7 +50,7 @@ public InstancedBinding ItemsSelector(object item) return null; } - public IControl Build(object data) + public Control Build(object data) { var visualTreeForItem = TemplateContent.Load(Content)?.Control; if (visualTreeForItem != null) diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs b/src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs index f547888d6e6..974d3006225 100644 --- a/src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs +++ b/src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs @@ -30,7 +30,7 @@ public static IResourceDictionary ResolveResourceInclude(string absoluteSource, public static Func DeferredTransformationFactoryV1(Func builder, IServiceProvider provider) { - return DeferredTransformationFactoryV2(builder, provider); + return DeferredTransformationFactoryV2(builder, provider); } public static Func DeferredTransformationFactoryV2(Func builder, @@ -46,8 +46,8 @@ public static Func DeferredTransformationFactoryV2( var obj = builder(new DeferredParentServiceProvider(sp, resourceNodes, rootObject, scope)); scope.Complete(); - if(typeof(T) == typeof(IControl)) - return new ControlTemplateResult((IControl)obj, scope); + if(typeof(T) == typeof(Control)) + return new ControlTemplateResult((Control)obj, scope); return new TemplateResult((T)obj, scope); }; diff --git a/src/Markup/Avalonia.Markup/Data/Binding.cs b/src/Markup/Avalonia.Markup/Data/Binding.cs index c56afbfedf9..19188d92173 100644 --- a/src/Markup/Avalonia.Markup/Data/Binding.cs +++ b/src/Markup/Avalonia.Markup/Data/Binding.cs @@ -61,7 +61,7 @@ public Binding(string path, BindingMode mode = BindingMode.Default) /// public Func? TypeResolver { get; set; } - protected override ExpressionObserver CreateExpressionObserver(IAvaloniaObject target, AvaloniaProperty? targetProperty, object? anchor, bool enableDataValidation) + protected override ExpressionObserver CreateExpressionObserver(AvaloniaObject target, AvaloniaProperty? targetProperty, object? anchor, bool enableDataValidation) { _ = target ?? throw new ArgumentNullException(nameof(target)); @@ -78,11 +78,11 @@ protected override ExpressionObserver CreateExpressionObserver(IAvaloniaObject t throw new InvalidOperationException("Could not parse binding expression."); } - IStyledElement GetSource() + StyledElement GetSource() { - return target as IStyledElement ?? - anchor as IStyledElement ?? - throw new ArgumentException("Could not find binding source: either target or anchor must be an IStyledElement."); + return target as StyledElement ?? + anchor as StyledElement ?? + throw new ArgumentException("Could not find binding source: either target or anchor must be an StyledElement."); } if (ElementName != null) diff --git a/src/Markup/Avalonia.Markup/Data/BindingBase.cs b/src/Markup/Avalonia.Markup/Data/BindingBase.cs index 0cffde6043c..09587a86095 100644 --- a/src/Markup/Avalonia.Markup/Data/BindingBase.cs +++ b/src/Markup/Avalonia.Markup/Data/BindingBase.cs @@ -75,14 +75,14 @@ public BindingBase(BindingMode mode = BindingMode.Default) public WeakReference? NameScope { get; set; } protected abstract ExpressionObserver CreateExpressionObserver( - IAvaloniaObject target, + AvaloniaObject target, AvaloniaProperty? targetProperty, object? anchor, bool enableDataValidation); /// public InstancedBinding? Initiate( - IAvaloniaObject target, + AvaloniaObject target, AvaloniaProperty? targetProperty, object? anchor = null, bool enableDataValidation = false) @@ -131,16 +131,19 @@ protected abstract ExpressionObserver CreateExpressionObserver( } protected ExpressionObserver CreateDataContextObserver( - IAvaloniaObject target, + AvaloniaObject target, ExpressionNode node, bool targetIsDataContext, object? anchor) { _ = target ?? throw new ArgumentNullException(nameof(target)); - if (!(target is IDataContextProvider)) + if (target is not IDataContextProvider) { - target = anchor as IDataContextProvider ?? throw new InvalidOperationException("Cannot find a DataContext to bind to."); + if (anchor is IDataContextProvider && anchor is AvaloniaObject ao) + target = ao; + else + throw new InvalidOperationException("Cannot find a DataContext to bind to."); } if (!targetIsDataContext) @@ -163,7 +166,7 @@ protected ExpressionObserver CreateDataContextObserver( } protected ExpressionObserver CreateElementObserver( - IStyledElement target, + StyledElement target, string elementName, ExpressionNode node) { @@ -179,7 +182,7 @@ protected ExpressionObserver CreateElementObserver( } protected ExpressionObserver CreateFindAncestorObserver( - IStyledElement target, + StyledElement target, RelativeSource relativeSource, ExpressionNode node) { @@ -197,7 +200,7 @@ protected ExpressionObserver CreateFindAncestorObserver( break; case TreeType.Visual: controlLocator = VisualLocator.Track( - (IVisual)target, + (Visual)target, relativeSource.AncestorLevel - 1, relativeSource.AncestorType); break; @@ -221,7 +224,7 @@ protected ExpressionObserver CreateSourceObserver( } protected ExpressionObserver CreateTemplatedParentObserver( - IAvaloniaObject target, + AvaloniaObject target, ExpressionNode node) { _ = target ?? throw new ArgumentNullException(nameof(target)); @@ -235,7 +238,7 @@ protected ExpressionObserver CreateTemplatedParentObserver( return result; } - protected IObservable GetParentDataContext(IAvaloniaObject target) + protected IObservable GetParentDataContext(AvaloniaObject target) { // The DataContext is based on the visual parent and not the logical parent: this may // seem counter intuitive considering the fact that property inheritance works on the logical @@ -246,17 +249,17 @@ protected ExpressionObserver CreateTemplatedParentObserver( return target.GetObservable(Visual.VisualParentProperty) .Select(x => { - return (x as IAvaloniaObject)?.GetObservable(StyledElement.DataContextProperty) ?? + return (x as AvaloniaObject)?.GetObservable(StyledElement.DataContextProperty) ?? Observable.Return((object?)null); }).Switch(); } private class UpdateSignal : SingleSubscriberObservableBase { - private readonly IAvaloniaObject _target; + private readonly AvaloniaObject _target; private readonly AvaloniaProperty _property; - public UpdateSignal(IAvaloniaObject target, AvaloniaProperty property) + public UpdateSignal(AvaloniaObject target, AvaloniaProperty property) { _target = target; _property = property; diff --git a/src/Markup/Avalonia.Markup/Data/MultiBinding.cs b/src/Markup/Avalonia.Markup/Data/MultiBinding.cs index c3317696011..4693b0c617e 100644 --- a/src/Markup/Avalonia.Markup/Data/MultiBinding.cs +++ b/src/Markup/Avalonia.Markup/Data/MultiBinding.cs @@ -67,7 +67,7 @@ public MultiBinding() /// public InstancedBinding? Initiate( - IAvaloniaObject target, + AvaloniaObject target, AvaloniaProperty? targetProperty, object? anchor = null, bool enableDataValidation = false) diff --git a/src/Markup/Avalonia.Markup/Data/TemplateBinding.cs b/src/Markup/Avalonia.Markup/Data/TemplateBinding.cs index 0d8925c6fa5..4dcdfb3c0e9 100644 --- a/src/Markup/Avalonia.Markup/Data/TemplateBinding.cs +++ b/src/Markup/Avalonia.Markup/Data/TemplateBinding.cs @@ -17,7 +17,7 @@ public class TemplateBinding : SingleSubscriberObservableBase, ISetterValue { private bool _isSetterValue; - private IStyledElement _target = default!; + private StyledElement _target = default!; private Type? _targetType; private bool _hasProducedValue; @@ -32,7 +32,7 @@ public TemplateBinding(AvaloniaProperty property) /// public InstancedBinding? Initiate( - IAvaloniaObject target, + AvaloniaObject target, AvaloniaProperty? targetProperty, object? anchor = null, bool enableDataValidation = false) @@ -45,7 +45,7 @@ public TemplateBinding(AvaloniaProperty property) // because the setter can outlive the control and cause a leak. if (_target == null && !_isSetterValue) { - _target = (IStyledElement)target; + _target = (StyledElement)target; _targetType = targetProperty?.PropertyType; return new InstancedBinding( @@ -94,7 +94,7 @@ public TemplateBinding(AvaloniaProperty property) void IObserver.OnNext(object? value) { - if (_target.TemplatedParent != null && Property != null) + if (_target.TemplatedParent is AvaloniaObject templatedParent && Property != null) { if (Converter != null) { @@ -107,7 +107,7 @@ public TemplateBinding(AvaloniaProperty property) // Use LocalValue priority here, as TemplatedParent doesn't make sense on controls // that aren't template children. - _target.TemplatedParent.SetValue(Property, value, BindingPriority.LocalValue); + templatedParent.SetValue(Property, value, BindingPriority.LocalValue); } } @@ -122,9 +122,9 @@ protected override void Subscribed() protected override void Unsubscribed() { - if (_target.TemplatedParent != null) + if (_target.TemplatedParent is AvaloniaObject templatedParent) { - _target.TemplatedParent.PropertyChanged -= TemplatedParentPropertyChanged; + templatedParent.PropertyChanged -= TemplatedParentPropertyChanged; } _target.PropertyChanged -= TargetPropertyChanged; @@ -132,10 +132,10 @@ protected override void Unsubscribed() private void PublishValue() { - if (_target.TemplatedParent != null) + if (_target.TemplatedParent is AvaloniaObject templatedParent) { var value = Property != null ? - _target.TemplatedParent.GetValue(Property) : + templatedParent.GetValue(Property) : _target.TemplatedParent; if (Converter is not null && _targetType is not null) @@ -155,9 +155,9 @@ private void PublishValue() private void TemplatedParentChanged() { - if (_target.TemplatedParent != null) + if (_target.TemplatedParent is AvaloniaObject templatedParent) { - _target.TemplatedParent.PropertyChanged += TemplatedParentPropertyChanged; + templatedParent.PropertyChanged += TemplatedParentPropertyChanged; } PublishValue(); @@ -167,7 +167,7 @@ private void TargetPropertyChanged(object? sender, AvaloniaPropertyChangedEventA { if (e.Property == StyledElement.TemplatedParentProperty) { - if (e.OldValue is IAvaloniaObject oldValue) + if (e.OldValue is AvaloniaObject oldValue) { oldValue.PropertyChanged -= TemplatedParentPropertyChanged; } diff --git a/src/Markup/Avalonia.Markup/Markup/Data/DelayedBinding.cs b/src/Markup/Avalonia.Markup/Markup/Data/DelayedBinding.cs index 3d6703daa3a..98a3f023b67 100644 --- a/src/Markup/Avalonia.Markup/Markup/Data/DelayedBinding.cs +++ b/src/Markup/Avalonia.Markup/Markup/Data/DelayedBinding.cs @@ -20,8 +20,8 @@ namespace Avalonia.Markup.Data /// public static class DelayedBinding { - private static ConditionalWeakTable> _entries = - new ConditionalWeakTable>(); + private static ConditionalWeakTable> _entries = + new ConditionalWeakTable>(); /// /// Adds a delayed binding to a control. @@ -29,7 +29,7 @@ public static class DelayedBinding /// The control. /// The property on the control to bind to. /// The binding. - public static void Add(IStyledElement target, AvaloniaProperty property, IBinding binding) + public static void Add(StyledElement target, AvaloniaProperty property, IBinding binding) { if (target.IsInitialized) { @@ -57,7 +57,7 @@ public static void Add(IStyledElement target, AvaloniaProperty property, IBindin /// The control. /// The property on the control to bind to. /// A function which returns the value. - public static void Add(IStyledElement target, PropertyInfo property, Func value) + public static void Add(StyledElement target, PropertyInfo property, Func value) { if (target.IsInitialized) { @@ -82,7 +82,7 @@ public static void Add(IStyledElement target, PropertyInfo property, Func /// The control. - public static void ApplyBindings(IStyledElement control) + public static void ApplyBindings(StyledElement control) { if (_entries.TryGetValue(control, out var entries)) { @@ -97,14 +97,14 @@ public static void ApplyBindings(IStyledElement control) private static void ApplyBindings(object? sender, EventArgs e) { - var target = (IStyledElement)sender!; + var target = (StyledElement)sender!; ApplyBindings(target); target.Initialized -= ApplyBindings; } private abstract class Entry { - public abstract void Apply(IStyledElement control); + public abstract void Apply(StyledElement control); } private class BindingEntry : Entry @@ -118,7 +118,7 @@ public BindingEntry(AvaloniaProperty property, IBinding binding) public IBinding Binding { get; } public AvaloniaProperty Property { get; } - public override void Apply(IStyledElement control) + public override void Apply(StyledElement control) { control.Bind(Property, Binding); } @@ -126,16 +126,16 @@ public override void Apply(IStyledElement control) private class ClrPropertyValueEntry : Entry { - public ClrPropertyValueEntry(PropertyInfo property, Func value) + public ClrPropertyValueEntry(PropertyInfo property, Func value) { Property = property; Value = value; } public PropertyInfo Property { get; } - public Func Value { get; } + public Func Value { get; } - public override void Apply(IStyledElement control) + public override void Apply(StyledElement control) { try { diff --git a/src/Windows/Avalonia.Win32.Interop/Wpf/WpfMouseDevice.cs b/src/Windows/Avalonia.Win32.Interop/Wpf/WpfMouseDevice.cs index ebfe8cde47a..2be9c1a558e 100644 --- a/src/Windows/Avalonia.Win32.Interop/Wpf/WpfMouseDevice.cs +++ b/src/Windows/Avalonia.Win32.Interop/Wpf/WpfMouseDevice.cs @@ -29,7 +29,7 @@ protected override void PlatformCapture(IInputElement control) { System.Windows.Input.Mouse.Capture(null); } - else if ((control.GetVisualRoot() as EmbeddableControlRoot)?.PlatformImpl != _impl) + else if (((control as Visual)?.GetVisualRoot() as EmbeddableControlRoot)?.PlatformImpl != _impl) throw new ArgumentException("Visual belongs to unknown toplevel"); else System.Windows.Input.Mouse.Capture(_impl); diff --git a/src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs b/src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs index 7435e3342eb..0814be24c04 100644 --- a/src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs +++ b/src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs @@ -89,7 +89,7 @@ private void OnSourceChanged(object sender, SourceChangedEventArgs e) public IRenderer CreateRenderer(IRenderRoot root) { - return new ImmediateRenderer(root); + return new ImmediateRenderer((Visual)root); } public void Dispose() diff --git a/src/Windows/Avalonia.Win32/Input/WindowsMouseDevice.cs b/src/Windows/Avalonia.Win32/Input/WindowsMouseDevice.cs index 224ffdc3fd2..cf1bdc1671b 100644 --- a/src/Windows/Avalonia.Win32/Input/WindowsMouseDevice.cs +++ b/src/Windows/Avalonia.Win32/Input/WindowsMouseDevice.cs @@ -34,7 +34,7 @@ public static WindowsMousePointer CreatePointer(out WindowsMousePointer pointer) protected override void PlatformCapture(IInputElement element) { - var hwnd = ((element?.GetVisualRoot() as TopLevel)?.PlatformImpl as WindowImpl) + var hwnd = (((element as Visual)?.GetVisualRoot() as TopLevel)?.PlatformImpl as WindowImpl) ?.Handle.Handle; if (hwnd.HasValue && hwnd != IntPtr.Zero) diff --git a/src/Windows/Avalonia.Win32/OleDropTarget.cs b/src/Windows/Avalonia.Win32/OleDropTarget.cs index 1c22fd025d2..b4eb6d88510 100644 --- a/src/Windows/Avalonia.Win32/OleDropTarget.cs +++ b/src/Windows/Avalonia.Win32/OleDropTarget.cs @@ -186,7 +186,7 @@ private void ReleaseDataObject() private Point GetDragLocation(UnmanagedMethods.POINT dragPoint) { var screenPt = new PixelPoint(dragPoint.X, dragPoint.Y); - return _target.PointToClient(screenPt); + return ((Visual)_target).PointToClient(screenPt); } protected override void Destroyed() diff --git a/src/Windows/Avalonia.Win32/WindowImpl.CustomCaptionProc.cs b/src/Windows/Avalonia.Win32/WindowImpl.CustomCaptionProc.cs index e864f321387..5414672498c 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.CustomCaptionProc.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.CustomCaptionProc.cs @@ -109,9 +109,9 @@ protected virtual IntPtr CustomCaptionProc(IntPtr hWnd, uint msg, IntPtr wParam, if (_owner is Window window) { - var visual = window.Renderer.HitTestFirst(position, _owner, x => + var visual = window.Renderer.HitTestFirst(position, (Visual)_owner, x => { - if (x is IInputElement ie && (!ie.IsHitTestVisible || !ie.IsVisible)) + if (x is IInputElement ie && (!ie.IsHitTestVisible || !ie.IsEffectivelyVisible)) { return false; } diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 42c576d01c7..800524f83c9 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -562,7 +562,7 @@ public IRenderer CreateRenderer(IRenderRoot root) RenderOnlyOnRenderThread = true } : (IRenderer)new DeferredRenderer(root, loop, rendererLock: _rendererLock) - : new ImmediateRenderer(root); + : new ImmediateRenderer((Visual)root); } public void Resize(Size value, PlatformResizeReason reason) diff --git a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Binding.cs b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Binding.cs index 6db339c4cde..c42cb0241b6 100644 --- a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Binding.cs +++ b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Binding.cs @@ -1245,7 +1245,7 @@ public TestOneTimeBinding(IObservable source) } public InstancedBinding Initiate( - IAvaloniaObject target, + AvaloniaObject target, AvaloniaProperty? targetProperty, object? anchor = null, bool enableDataValidation = false) diff --git a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Coercion.cs b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Coercion.cs index 2e1944fc767..2154bb63d0c 100644 --- a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Coercion.cs +++ b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Coercion.cs @@ -219,7 +219,7 @@ public int Inherited public List CoreChanges { get; } = new(); - public static int CoerceFoo(IAvaloniaObject instance, int value) + public static int CoerceFoo(AvaloniaObject instance, int value) { return Math.Min(((Class1)instance).MaxFoo, value); } @@ -261,7 +261,7 @@ public int Foo set => SetValue(FooProperty, value); } - public static int CoerceFoo(IAvaloniaObject instance, int value) + public static int CoerceFoo(AvaloniaObject instance, int value) { return -value; } diff --git a/tests/Avalonia.Base.UnitTests/AvaloniaPropertyTests.cs b/tests/Avalonia.Base.UnitTests/AvaloniaPropertyTests.cs index 232b6ccf73b..5733159a235 100644 --- a/tests/Avalonia.Base.UnitTests/AvaloniaPropertyTests.cs +++ b/tests/Avalonia.Base.UnitTests/AvaloniaPropertyTests.cs @@ -69,7 +69,7 @@ public void GetMetadata_Returns_Overridden_Value() public void OverrideMetadata_Should_Merge_Values() { var metadata = new AvaloniaPropertyMetadata(BindingMode.TwoWay); - var notify = (Action)((a, b) => { }); + var notify = (Action)((a, b) => { }); var overridden = new AvaloniaPropertyMetadata(); var target = new TestProperty("test", typeof(Class1), metadata); @@ -192,7 +192,7 @@ private class Class1 : AvaloniaObject public int NotifyCount { get; private set; } - private static void FooNotifying(IAvaloniaObject o, bool n) + private static void FooNotifying(AvaloniaObject o, bool n) { ++((Class1)o).NotifyCount; } diff --git a/tests/Avalonia.Base.UnitTests/Input/KeyboardDeviceTests.cs b/tests/Avalonia.Base.UnitTests/Input/KeyboardDeviceTests.cs index 07bfa0d2e62..74a91195817 100644 --- a/tests/Avalonia.Base.UnitTests/Input/KeyboardDeviceTests.cs +++ b/tests/Avalonia.Base.UnitTests/Input/KeyboardDeviceTests.cs @@ -33,14 +33,17 @@ public void Keypresses_Should_Be_Sent_To_Root_If_No_Focused_Element() public void Keypresses_Should_Be_Sent_To_Focused_Element() { var target = new KeyboardDevice(); - var focused = new Mock(); - var root = Mock.Of(); + var focused = new Control(); + var root = new TestRoot(); + var raised = 0; target.SetFocusedElement( - focused.Object, + focused, NavigationMethod.Unspecified, KeyModifiers.None); + focused.KeyDown += (s, e) => ++raised; + target.ProcessRawEvent( new RawKeyEventArgs( target, @@ -50,7 +53,7 @@ public void Keypresses_Should_Be_Sent_To_Focused_Element() Key.A, RawInputModifiers.None)); - focused.Verify(x => x.RaiseEvent(It.IsAny())); + Assert.Equal(1, raised); } [Fact] @@ -73,14 +76,17 @@ public void TextInput_Should_Be_Sent_To_Root_If_No_Focused_Element() public void TextInput_Should_Be_Sent_To_Focused_Element() { var target = new KeyboardDevice(); - var focused = new Mock(); - var root = Mock.Of(); + var focused = new Control(); + var root = new TestRoot(); + var raised = 0; target.SetFocusedElement( - focused.Object, + focused, NavigationMethod.Unspecified, KeyModifiers.None); + focused.TextInput += (s, e) => ++raised; + target.ProcessRawEvent( new RawTextInputEventArgs( target, @@ -88,7 +94,7 @@ public void TextInput_Should_Be_Sent_To_Focused_Element() root, "Foo")); - focused.Verify(x => x.RaiseEvent(It.IsAny())); + Assert.Equal(1, raised); } [Fact] @@ -135,25 +141,28 @@ public event EventHandler CanExecuteChanged { add { } remove { } } public void Control_Focus_Should_Be_Set_Before_FocusedElement_Raises_PropertyChanged() { var target = new KeyboardDevice(); - var focused = new Mock(); - var root = Mock.Of(); - var raised = 0; + var focused = new Control(); + var root = new TestRoot(); + var gotFocusRaised = 0; + var propertyChangedRaised = 0; + + focused.GotFocus += (s, e) => ++gotFocusRaised; target.PropertyChanged += (s, e) => { if (e.PropertyName == nameof(target.FocusedElement)) { - focused.Verify(x => x.RaiseEvent(It.IsAny())); - ++raised; + Assert.Equal(1, gotFocusRaised); + ++propertyChangedRaised; } }; target.SetFocusedElement( - focused.Object, + focused, NavigationMethod.Unspecified, KeyModifiers.None); - Assert.Equal(1, raised); + Assert.Equal(1, propertyChangedRaised); } } } diff --git a/tests/Avalonia.Base.UnitTests/Input/KeyboardNavigationTests_Tab.cs b/tests/Avalonia.Base.UnitTests/Input/KeyboardNavigationTests_Tab.cs index 7fd8cb345d3..34a9947d284 100644 --- a/tests/Avalonia.Base.UnitTests/Input/KeyboardNavigationTests_Tab.cs +++ b/tests/Avalonia.Base.UnitTests/Input/KeyboardNavigationTests_Tab.cs @@ -1171,7 +1171,7 @@ public void Respects_TabIndex_Moving_Forwards() do { - result.Add(((IControl)current).Name); + result.Add(((Control)current).Name); current = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Next); } while (current is object && current != start); @@ -1217,7 +1217,7 @@ public void Respects_TabIndex_Moving_Backwards() do { - result.Add(((IControl)current).Name); + result.Add(((Control)current).Name); current = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Previous); } while (current is object && current != start); diff --git a/tests/Avalonia.Base.UnitTests/Input/PointerTestsBase.cs b/tests/Avalonia.Base.UnitTests/Input/PointerTestsBase.cs index 1ca6678aef8..510adb37b51 100644 --- a/tests/Avalonia.Base.UnitTests/Input/PointerTestsBase.cs +++ b/tests/Avalonia.Base.UnitTests/Input/PointerTestsBase.cs @@ -14,12 +14,12 @@ namespace Avalonia.Base.UnitTests.Input; public abstract class PointerTestsBase { - protected static void SetHit(Mock renderer, IControl? hit) + protected static void SetHit(Mock renderer, Control? hit) { - renderer.Setup(x => x.HitTest(It.IsAny(), It.IsAny(), It.IsAny>())) - .Returns(hit is null ? Array.Empty() : new[] { hit }); + renderer.Setup(x => x.HitTest(It.IsAny(), It.IsAny(), It.IsAny>())) + .Returns(hit is null ? Array.Empty() : new[] { hit }); - renderer.Setup(x => x.HitTestFirst(It.IsAny(), It.IsAny(), It.IsAny>())) + renderer.Setup(x => x.HitTestFirst(It.IsAny(), It.IsAny(), It.IsAny>())) .Returns(hit); } @@ -41,7 +41,7 @@ protected static Mock CreateTopLevelImplMock(IRenderer renderer) return impl; } - protected static IInputRoot CreateInputRoot(IWindowImpl impl, IControl child) + protected static IInputRoot CreateInputRoot(IWindowImpl impl, Control child) { var root = new Window(impl) { @@ -66,7 +66,7 @@ protected static RawPointerEventArgs CreateRawPointerMovedArgs( protected static PointerEventArgs CreatePointerMovedArgs( IInputRoot root, IInputElement? source, Point? positition = null) { - return new PointerEventArgs(InputElement.PointerMovedEvent, source, new Mock().Object, root, + return new PointerEventArgs(InputElement.PointerMovedEvent, source, new Mock().Object, (Visual)root, positition ?? default, default, PointerPointProperties.None, KeyModifiers.None); } diff --git a/tests/Avalonia.Base.UnitTests/Interactivity/InteractiveTests.cs b/tests/Avalonia.Base.UnitTests/Interactivity/InteractiveTests.cs index 1ca7e9bd492..3f80599b28a 100644 --- a/tests/Avalonia.Base.UnitTests/Interactivity/InteractiveTests.cs +++ b/tests/Avalonia.Base.UnitTests/Interactivity/InteractiveTests.cs @@ -363,11 +363,11 @@ public void Removing_Control_In_Handler_Should_Not_Stop_Event() var invoked = new List(); EventHandler handler = (s, e) => invoked.Add(((TestInteractive)s).Name); var parent = CreateTree(ev, handler, RoutingStrategies.Bubble | RoutingStrategies.Tunnel); - var target = (IInteractive)parent.GetVisualChildren().Single(); + var target = (Interactive)parent.GetVisualChildren().Single(); EventHandler removeHandler = (s, e) => { - parent.Children = Array.Empty(); + parent.Children = Array.Empty(); }; target.AddHandler(ev, removeHandler); @@ -425,11 +425,11 @@ private class TestInteractive : Interactive public bool ClassHandlerInvoked { get; private set; } public new string Name { get; set; } - public IEnumerable Children + public IEnumerable Children { get { - return ((IVisual)this).VisualChildren.AsEnumerable(); + return ((Visual)this).VisualChildren.AsEnumerable(); } set diff --git a/tests/Avalonia.Base.UnitTests/Layout/FullLayoutTests.cs b/tests/Avalonia.Base.UnitTests/Layout/FullLayoutTests.cs index 1d6eead6dd7..4922fbe37bc 100644 --- a/tests/Avalonia.Base.UnitTests/Layout/FullLayoutTests.cs +++ b/tests/Avalonia.Base.UnitTests/Layout/FullLayoutTests.cs @@ -107,7 +107,7 @@ public void Test_ScrollViewer_With_TextBlock() } } - private static Point Position(IVisual v) + private static Point Position(Visual v) { return v.Bounds.Position; } diff --git a/tests/Avalonia.Base.UnitTests/Layout/LayoutManagerTests.cs b/tests/Avalonia.Base.UnitTests/Layout/LayoutManagerTests.cs index 37e07c244e0..21723ba182c 100644 --- a/tests/Avalonia.Base.UnitTests/Layout/LayoutManagerTests.cs +++ b/tests/Avalonia.Base.UnitTests/Layout/LayoutManagerTests.cs @@ -88,8 +88,8 @@ public void Measures_In_Correct_Order() } }; - var order = new List(); - Size MeasureOverride(ILayoutable control, Size size) + var order = new List(); + Size MeasureOverride(Layoutable control, Size size) { order.Add(control); return new Size(10, 10); @@ -107,7 +107,7 @@ Size MeasureOverride(ILayoutable control, Size size) order.Clear(); root.LayoutManager.ExecuteLayoutPass(); - Assert.Equal(new ILayoutable[] { root, control1, control2 }, order); + Assert.Equal(new Layoutable[] { root, control1, control2 }, order); } [Fact] @@ -123,8 +123,8 @@ public void Measures_Root_And_Grandparent_In_Correct_Order() } }; - var order = new List(); - Size MeasureOverride(ILayoutable control, Size size) + var order = new List(); + Size MeasureOverride(Layoutable control, Size size) { order.Add(control); return new Size(10, 10); @@ -141,7 +141,7 @@ Size MeasureOverride(ILayoutable control, Size size) order.Clear(); root.LayoutManager.ExecuteLayoutPass(); - Assert.Equal(new ILayoutable[] { root, control2 }, order); + Assert.Equal(new Layoutable[] { root, control2 }, order); } [Fact] diff --git a/tests/Avalonia.Base.UnitTests/Layout/LayoutTestControl.cs b/tests/Avalonia.Base.UnitTests/Layout/LayoutTestControl.cs index ca593cc6656..62de81006ed 100644 --- a/tests/Avalonia.Base.UnitTests/Layout/LayoutTestControl.cs +++ b/tests/Avalonia.Base.UnitTests/Layout/LayoutTestControl.cs @@ -8,8 +8,8 @@ internal class LayoutTestControl : Decorator { public bool Measured { get; set; } public bool Arranged { get; set; } - public Func DoMeasureOverride { get; set; } - public Func DoArrangeOverride { get; set; } + public Func DoMeasureOverride { get; set; } + public Func DoArrangeOverride { get; set; } protected override Size MeasureOverride(Size availableSize) { diff --git a/tests/Avalonia.Base.UnitTests/Layout/LayoutTestRoot.cs b/tests/Avalonia.Base.UnitTests/Layout/LayoutTestRoot.cs index 19ab54a339d..c8fe0eb89f6 100644 --- a/tests/Avalonia.Base.UnitTests/Layout/LayoutTestRoot.cs +++ b/tests/Avalonia.Base.UnitTests/Layout/LayoutTestRoot.cs @@ -4,27 +4,16 @@ namespace Avalonia.Base.UnitTests.Layout { - internal class LayoutTestRoot : TestRoot, ILayoutable + internal class LayoutTestRoot : TestRoot { public bool Measured { get; set; } public bool Arranged { get; set; } - public Func DoMeasureOverride { get; set; } - public Func DoArrangeOverride { get; set; } - - void ILayoutable.Measure(Size availableSize) - { - Measured = true; - Measure(availableSize); - } - - void ILayoutable.Arrange(Rect rect) - { - Arranged = true; - Arrange(rect); - } + public Func DoMeasureOverride { get; set; } + public Func DoArrangeOverride { get; set; } protected override Size MeasureOverride(Size availableSize) { + Measured = true; return DoMeasureOverride != null ? DoMeasureOverride(this, availableSize) : base.MeasureOverride(availableSize); diff --git a/tests/Avalonia.Base.UnitTests/Layout/NonVirtualizingStackLayoutTests.cs b/tests/Avalonia.Base.UnitTests/Layout/NonVirtualizingStackLayoutTests.cs index 78cf63ed3f0..ffcbbb4b2eb 100644 --- a/tests/Avalonia.Base.UnitTests/Layout/NonVirtualizingStackLayoutTests.cs +++ b/tests/Avalonia.Base.UnitTests/Layout/NonVirtualizingStackLayoutTests.cs @@ -318,7 +318,7 @@ private NonVirtualizingLayoutContext CreateContext(Control[] children) private class TestLayoutContext : NonVirtualizingLayoutContext { public TestLayoutContext(Control[] children) => ChildrenCore = children; - protected override IReadOnlyList ChildrenCore { get; } + protected override IReadOnlyList ChildrenCore { get; } } private class TestControl : Control diff --git a/tests/Avalonia.Base.UnitTests/Logging/LoggingTests.cs b/tests/Avalonia.Base.UnitTests/Logging/LoggingTests.cs index d1607130231..d70f269b386 100644 --- a/tests/Avalonia.Base.UnitTests/Logging/LoggingTests.cs +++ b/tests/Avalonia.Base.UnitTests/Logging/LoggingTests.cs @@ -34,7 +34,7 @@ public void Control_Should_Not_Log_Binding_Errors_When_Detached_From_Visual_Tree var panel = window.FindControl("panel"); var rect = window.FindControl("rect"); window.ApplyTemplate(); - window.Presenter.ApplyTemplate(); + ((Control)window.Presenter).ApplyTemplate(); panel.Children.Remove(rect); Assert.Equal(0, calledTimes); } @@ -63,7 +63,7 @@ public void Control_Should_Log_Binding_Errors_When_No_Ancestor_With_Such_Name() }); var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml); window.ApplyTemplate(); - window.Presenter.ApplyTemplate(); + ((Control)window.Presenter).ApplyTemplate(); Assert.Equal(1, calledTimes); } } diff --git a/tests/Avalonia.Base.UnitTests/RenderTests_Culling.cs b/tests/Avalonia.Base.UnitTests/RenderTests_Culling.cs index c7421c58273..d75bf9fe8c9 100644 --- a/tests/Avalonia.Base.UnitTests/RenderTests_Culling.cs +++ b/tests/Avalonia.Base.UnitTests/RenderTests_Culling.cs @@ -171,7 +171,7 @@ public void Negative_Margin_Should_Be_Respected() } } - private void Render(IControl control) + private void Render(Control control) { var ctx = CreateDrawingContext(); control.Measure(Size.Infinity); diff --git a/tests/Avalonia.Base.UnitTests/Rendering/CompositorTestsBase.cs b/tests/Avalonia.Base.UnitTests/Rendering/CompositorTestsBase.cs index fa722a23b86..7b987d8e68d 100644 --- a/tests/Avalonia.Base.UnitTests/Rendering/CompositorTestsBase.cs +++ b/tests/Avalonia.Base.UnitTests/Rendering/CompositorTestsBase.cs @@ -176,16 +176,16 @@ public void AssertRects(params Rect[] rects) Events.Rects.Clear(); } - public void AssertHitTest(double x, double y, Func filter, params object[] expected) + public void AssertHitTest(double x, double y, Func filter, params object[] expected) => AssertHitTest(new Point(x, y), filter, expected); - public void AssertHitTest(Point pt, Func filter, params object[] expected) + public void AssertHitTest(Point pt, Func filter, params object[] expected) { RunJobs(); var tested = Renderer.HitTest(pt, TopLevel, filter); Assert.Equal(expected, tested); } - public void AssertHitTestFirst(Point pt, Func filter, object expected) + public void AssertHitTestFirst(Point pt, Func filter, object expected) { RunJobs(); var tested = Renderer.HitTest(pt, TopLevel, filter).First(); @@ -205,4 +205,4 @@ public CompositorCanvas() Events.Reset(); } } -} \ No newline at end of file +} diff --git a/tests/Avalonia.Base.UnitTests/Rendering/DeferredRendererTests.cs b/tests/Avalonia.Base.UnitTests/Rendering/DeferredRendererTests.cs index c345b9a7ea8..08e5955ec5b 100644 --- a/tests/Avalonia.Base.UnitTests/Rendering/DeferredRendererTests.cs +++ b/tests/Avalonia.Base.UnitTests/Rendering/DeferredRendererTests.cs @@ -92,14 +92,14 @@ public void Should_Update_Dirty_Controls_In_Order() target.AddDirty(root); target.AddDirty(decorator); - var result = new List(); + var result = new List(); - sceneBuilder.Setup(x => x.Update(It.IsAny(), It.IsAny())) - .Callback((_, v) => result.Add(v)); + sceneBuilder.Setup(x => x.Update(It.IsAny(), It.IsAny())) + .Callback((_, v) => result.Add(v)); RunFrame(target); - Assert.Equal(new List { root, decorator, border, canvas }, result); + Assert.Equal(new List { root, decorator, border, canvas }, result); } } @@ -587,7 +587,7 @@ public void Should_Create_And_Delete_Layers_For_Controls_With_Animated_Opacity() border.Bind(Border.OpacityProperty, animation, BindingPriority.Animation); RunFrame(target); - Assert.Equal(new IVisual[] { root, border }, target.Layers.Select(x => x.LayerRoot)); + Assert.Equal(new Visual[] { root, border }, target.Layers.Select(x => x.LayerRoot)); animation.OnCompleted(); RunFrame(target); @@ -745,7 +745,7 @@ private DeferredRenderer CreateTargetAndRunFrame( return target; } - private Mock GetLayerContext(DeferredRenderer renderer, IControl layerRoot) + private Mock GetLayerContext(DeferredRenderer renderer, Control layerRoot) { return Mock.Get(renderer.Layers[layerRoot].Bitmap.Item.CreateDrawingContext(null)); } @@ -772,7 +772,7 @@ private Mock MockSceneBuilder(IRenderRoot root) { var result = new Mock(); result.Setup(x => x.UpdateAll(It.IsAny())) - .Callback(x => x.Layers.Add(root).Dirty.Add(new Rect(root.ClientSize))); + .Callback(x => x.Layers.Add((Visual)root).Dirty.Add(new Rect(root.ClientSize))); return result; } } diff --git a/tests/Avalonia.Base.UnitTests/Rendering/DeferredRendererTests_HitTesting.cs b/tests/Avalonia.Base.UnitTests/Rendering/DeferredRendererTests_HitTesting.cs index d3fdbb63dba..fa8db25a254 100644 --- a/tests/Avalonia.Base.UnitTests/Rendering/DeferredRendererTests_HitTesting.cs +++ b/tests/Avalonia.Base.UnitTests/Rendering/DeferredRendererTests_HitTesting.cs @@ -35,7 +35,7 @@ public void HitTest_Should_Find_Controls_At_Point() } }; - root.Renderer = new DeferredRenderer(root, null); + root.Renderer = new DeferredRenderer((IRenderRoot)root, null); root.Measure(Size.Infinity); root.Arrange(new Rect(root.DesiredSize)); @@ -63,7 +63,7 @@ public void HitTest_Should_Not_Find_Empty_Controls_At_Point() } }; - root.Renderer = new DeferredRenderer(root, null); + root.Renderer = new DeferredRenderer((IRenderRoot)root, null); root.Measure(Size.Infinity); root.Arrange(new Rect(root.DesiredSize)); @@ -100,7 +100,7 @@ public void HitTest_Should_Not_Find_Invisible_Controls_At_Point() } }; - root.Renderer = new DeferredRenderer(root, null); + root.Renderer = new DeferredRenderer((IRenderRoot)root, null); root.Measure(Size.Infinity); root.Arrange(new Rect(root.DesiredSize)); @@ -129,7 +129,7 @@ public void HitTest_Should_Not_Find_Control_Outside_Point() } }; - root.Renderer = new DeferredRenderer(root, null); + root.Renderer = new DeferredRenderer((IRenderRoot)root, null); root.Measure(Size.Infinity); root.Arrange(new Rect(root.DesiredSize)); @@ -173,7 +173,7 @@ public void HitTest_Should_Return_Top_Controls_First() } }; - root.Renderer = new DeferredRenderer(root, null); + root.Renderer = new DeferredRenderer((IRenderRoot)root, null); root.Measure(Size.Infinity); root.Arrange(new Rect(container.DesiredSize)); @@ -227,7 +227,7 @@ public void HitTest_Should_Return_Top_Controls_First_With_ZIndex() } }; - root.Renderer = new DeferredRenderer(root, null); + root.Renderer = new DeferredRenderer((IRenderRoot)root, null); root.Measure(Size.Infinity); root.Arrange(new Rect(container.DesiredSize)); @@ -276,13 +276,13 @@ public void HitTest_Should_Find_Control_Translated_Outside_Parent_Bounds() } }; - root.Renderer = new DeferredRenderer(root, null); + root.Renderer = new DeferredRenderer((IRenderRoot)root, null); container.Measure(Size.Infinity); container.Arrange(new Rect(container.DesiredSize)); var result = root.Renderer.HitTest(new Point(120, 120), root, null); - Assert.Equal(new IVisual[] { target, container }, result); + Assert.Equal(new Visual[] { target, container }, result); } } @@ -324,7 +324,7 @@ public void HitTest_Should_Not_Find_Control_Outside_Parent_Bounds_When_Clipped() } }; - root.Renderer = new DeferredRenderer(root, null); + root.Renderer = new DeferredRenderer((IRenderRoot)root, null); root.Measure(Size.Infinity); root.Arrange(new Rect(container.DesiredSize)); @@ -399,7 +399,7 @@ public void HitTest_Should_Not_Find_Control_Outside_Scroll_Viewport() scroll.UpdateChild(); - root.Renderer = new DeferredRenderer(root, null); + root.Renderer = new DeferredRenderer((IRenderRoot)root, null); root.Measure(Size.Infinity); root.Arrange(new Rect(container.DesiredSize)); @@ -447,7 +447,7 @@ public void HitTest_Should_Not_Find_Path_When_Outside_Fill() } }; - root.Renderer = new DeferredRenderer(root, null); + root.Renderer = new DeferredRenderer((IRenderRoot)root, null); root.Measure(Size.Infinity); root.Arrange(new Rect(root.DesiredSize)); @@ -486,7 +486,7 @@ public void HitTest_Should_Respect_Geometry_Clip() } }; - root.Renderer = new DeferredRenderer(root, null); + root.Renderer = new DeferredRenderer((IRenderRoot)root, null); root.Measure(Size.Infinity); root.Arrange(new Rect(root.DesiredSize)); Assert.Equal(new Rect(100, 100, 200, 200), border.Bounds); @@ -494,7 +494,7 @@ public void HitTest_Should_Respect_Geometry_Clip() var context = new DrawingContext(Mock.Of()); var result = root.Renderer.HitTest(new Point(200, 200), root, null); - Assert.Equal(new IVisual[] { canvas, border }, result); + Assert.Equal(new Visual[] { canvas, border }, result); result = root.Renderer.HitTest(new Point(110, 110), root, null); Assert.Empty(result); @@ -522,7 +522,7 @@ public void HitTest_Should_Accommodate_ICustomHitTest() } }; - root.Renderer = new DeferredRenderer(root, null); + root.Renderer = new DeferredRenderer((IRenderRoot)root, null); root.Measure(Size.Infinity); root.Arrange(new Rect(root.DesiredSize)); @@ -560,7 +560,7 @@ public void HitTest_Should_Not_Hit_Controls_Next_Pixel() } }; - root.Renderer = new DeferredRenderer(root, null); + root.Renderer = new DeferredRenderer((IRenderRoot)root, null); root.Measure(Size.Infinity); root.Arrange(new Rect(root.DesiredSize)); diff --git a/tests/Avalonia.Base.UnitTests/Rendering/ImmediateRendererTests.cs b/tests/Avalonia.Base.UnitTests/Rendering/ImmediateRendererTests.cs index 84bb9b00cdc..26a155d2033 100644 --- a/tests/Avalonia.Base.UnitTests/Rendering/ImmediateRendererTests.cs +++ b/tests/Avalonia.Base.UnitTests/Rendering/ImmediateRendererTests.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using Avalonia.Collections; using Avalonia.Controls; using Avalonia.Layout; using Avalonia.Media; @@ -19,165 +18,107 @@ public void AddDirty_Call_RenderRoot_Invalidate() { using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface)) { - var visual = new Mock(); - var child = new Mock() { CallBase = true }; - var renderRoot = visual.As(); + var child = new Border + { + Width = 100, + Height = 100, + Margin = new(10), + HorizontalAlignment = HorizontalAlignment.Left, + VerticalAlignment = VerticalAlignment.Top, + }; - visual.As().Setup(v => v.Bounds).Returns(new Rect(0, 0, 400, 400)); + var root = new RenderRoot + { + Child = child, + Width = 400, + Height = 400, + }; - child.As().Setup(v => v.Bounds).Returns(new Rect(10, 10, 100, 100)); - child.As().Setup(v => v.VisualParent).Returns(visual.Object); + root.LayoutManager.ExecuteInitialLayoutPass(); - var target = new ImmediateRenderer(visual.Object); + var target = new ImmediateRenderer(root); - target.AddDirty(child.Object); + target.AddDirty(child); - renderRoot.Verify(v => v.Invalidate(new Rect(10, 10, 100, 100))); + Assert.Equal(new[] { new Rect(10, 10, 100, 100) }, root.Invalidations); } } - [Fact(Skip = "https://github.com/moq/moq4/issues/988")] + [Fact] public void AddDirty_With_RenderTransform_Call_RenderRoot_Invalidate() { using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface)) { - var visual = new Mock(); - var child = new Mock() { CallBase = true }; - var renderRoot = visual.As(); + var child = new Border + { + Width = 100, + Height = 100, + Margin = new(100), + HorizontalAlignment = HorizontalAlignment.Left, + VerticalAlignment = VerticalAlignment.Top, + }; + + var root = new RenderRoot + { + Child = child, + Width = 400, + Height = 400, + }; - visual.As().Setup(v => v.Bounds).Returns(new Rect(0, 0, 400, 400)); + root.LayoutManager.ExecuteInitialLayoutPass(); - child.As().Setup(v => v.Bounds).Returns(new Rect(100, 100, 100, 100)); - child.As().Setup(v => v.VisualParent).Returns(visual.Object); - child.Object.RenderTransform = new ScaleTransform() { ScaleX = 2, ScaleY = 2 }; + child.RenderTransform = new ScaleTransform() { ScaleX = 2, ScaleY = 2 }; - var target = new ImmediateRenderer(visual.Object); + var target = new ImmediateRenderer(root); - target.AddDirty(child.Object); + target.AddDirty(child); - renderRoot.Verify(v => v.Invalidate(new Rect(50, 50, 200, 200))); + Assert.Equal(new[] { new Rect(50, 50, 200, 200) }, root.Invalidations); } } - [Fact(Skip = "https://github.com/moq/moq4/issues/988")] + [Fact] public void AddDirty_For_Child_Moved_Should_Invalidate_Previous_Bounds() { using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface)) { - var visual = new Mock() { CallBase = true }; - var child = new Mock() { CallBase = true }; - var renderRoot = visual.As(); - var renderTarget = visual.As(); - - renderRoot.Setup(r => r.CreateRenderTarget()).Returns(renderTarget.Object); - - renderTarget.Setup(r => r.CreateDrawingContext(It.IsAny())) - .Returns(Mock.Of()); - - visual.As().Setup(v => v.Bounds).Returns(new Rect(0, 0, 400, 400)); - - visual.As().Setup(v => v.VisualChildren) - .Returns(new AvaloniaList() { child.As().Object }); - - Rect childBounds = new Rect(0, 0, 100, 100); - child.As().Setup(v => v.Bounds).Returns(() => childBounds); - child.As().Setup(v => v.VisualParent).Returns(visual.Object); - child.As().Setup(v => v.VisualChildren).Returns(new AvaloniaList()); - - var invalidationCalls = new List(); + var child = new Border + { + Width = 100, + Height = 100, + HorizontalAlignment = HorizontalAlignment.Left, + VerticalAlignment = VerticalAlignment.Top, + }; - renderRoot.Setup(v => v.Invalidate(It.IsAny())).Callback(v => invalidationCalls.Add(v)); + var root = new RenderRoot + { + Child = child, + Width = 400, + Height = 400, + }; - var target = new ImmediateRenderer(visual.Object); + var target = new ImmediateRenderer(root); - target.AddDirty(child.Object); + root.LayoutManager.ExecuteInitialLayoutPass(); + target.AddDirty(child); - Assert.Equal(new Rect(0, 0, 100, 100), invalidationCalls[0]); + Assert.Equal(new Rect(0, 0, 100, 100), root.Invalidations[0]); target.Paint(new Rect(0, 0, 100, 100)); //move child 100 pixels bottom/right - childBounds = new Rect(100, 100, 100, 100); + child.Margin = new(100, 100); + root.LayoutManager.ExecuteLayoutPass(); //renderer should invalidate old child bounds with new one //as on old area there can be artifacts - target.AddDirty(child.Object); + target.AddDirty(child); //invalidate first old position - Assert.Equal(new Rect(0, 0, 100, 100), invalidationCalls[1]); + Assert.Equal(new Rect(0, 0, 100, 100), root.Invalidations[1]); //then new position - Assert.Equal(new Rect(100, 100, 100, 100), invalidationCalls[2]); - } - } - - [Fact(Skip = "https://github.com/moq/moq4/issues/988")] - public void Should_Render_Child_In_Parent_With_RenderTransform() - { - using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface)) - { - var targetMock = new Mock() { CallBase = true }; - var target = targetMock.Object; - target.Width = 100; - target.Height = 50; - - var child = new Panel() - { - RenderTransform = new RotateTransform() { Angle = 90 }, - Children = { new Panel() { Children = { target } } } - }; - - var visualTarget = targetMock.As(); - int rendered = 0; - visualTarget.Setup(v => v.Render(It.IsAny())).Callback(() => rendered++); - - var root = new TestRoot(child); - root.Renderer = new ImmediateRenderer(root); - - root.LayoutManager.ExecuteInitialLayoutPass(); - - root.Measure(new Size(50, 100)); - root.Arrange(new Rect(new Size(50, 100))); - - root.Renderer.Paint(root.Bounds); - - Assert.Equal(1, rendered); - } - } - - [Fact(Skip = "https://github.com/moq/moq4/issues/988")] - public void Should_Render_Child_In_Parent_With_RenderTransform2() - { - using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface)) - { - var targetMock = new Mock() { CallBase = true }; - var target = targetMock.Object; - - target.Width = 100; - target.Height = 50; - target.HorizontalAlignment = HorizontalAlignment.Center; - target.VerticalAlignment = VerticalAlignment.Center; - - var child = new Panel() - { - RenderTransform = new RotateTransform() { Angle = 90 }, - Children = { new Panel() { Children = { target } } } - }; - - var visualTarget = targetMock.As(); - int rendered = 0; - visualTarget.Setup(v => v.Render(It.IsAny())).Callback(() => rendered++); - - var root = new TestRoot(child); - root.Renderer = new ImmediateRenderer(root); - - root.LayoutManager.ExecuteInitialLayoutPass(); - - root.Measure(new Size(300, 100)); - root.Arrange(new Rect(new Size(300, 100))); - root.Renderer.Paint(root.Bounds); - - Assert.Equal(1, rendered); + Assert.Equal(new Rect(100, 100, 100, 100), root.Invalidations[2]); } } @@ -209,7 +150,10 @@ public void Should_Not_Clip_Children_With_RenderTransform_When_In_Bounds() TestControl CreateControl() => new TestControl { - Width = 80, Height = 40, Margin = new Thickness(0, 0, 5, 0), ClipToBounds = true + Width = 80, + Height = 40, + Margin = new Thickness(0, 0, 5, 0), + ClipToBounds = true }; var control1 = CreateControl(); @@ -264,7 +208,10 @@ public void Should_Not_Render_Clipped_Child_With_RenderTransform_When_Not_In_Bou TestControl CreateControl() => new TestControl { - Width = 160, Height = 40, Margin = new Thickness(0, 0, 5, 0), ClipToBounds = true + Width = 160, + Height = 40, + Margin = new Thickness(0, 0, 5, 0), + ClipToBounds = true }; var control1 = CreateControl(); @@ -299,9 +246,9 @@ public void Static_Render_Method_Does_Not_Update_TransformedBounds() var target = new Border(); var expected = new TransformedBounds(new Rect(1, 2, 3, 4), new Rect(4, 5, 6, 7), Matrix.CreateRotation(0.8)); - ((IVisual)target).TransformedBounds = expected; + target.SetTransformedBounds(expected); - var renderTarget = Mock.Of(x => + var renderTarget = Mock.Of(x => x.CreateDrawingContext(It.IsAny()) == Mock.Of()); ImmediateRenderer.Render(target, renderTarget); @@ -309,6 +256,12 @@ public void Static_Render_Method_Does_Not_Update_TransformedBounds() } } + private class RenderRoot : TestRoot, IRenderRoot + { + public List Invalidations { get; } = new(); + void IRenderRoot.Invalidate(Rect rect) => Invalidations.Add(rect); + } + private class TestControl : Control { public bool Rendered { get; private set; } diff --git a/tests/Avalonia.Base.UnitTests/Rendering/ImmediateRendererTests_HitTesting.cs b/tests/Avalonia.Base.UnitTests/Rendering/ImmediateRendererTests_HitTesting.cs index 1a9822e2597..5b5883c9508 100644 --- a/tests/Avalonia.Base.UnitTests/Rendering/ImmediateRendererTests_HitTesting.cs +++ b/tests/Avalonia.Base.UnitTests/Rendering/ImmediateRendererTests_HitTesting.cs @@ -266,7 +266,7 @@ public void HitTest_Should_Find_Control_Translated_Outside_Parent_Bounds() var result = root.Renderer.HitTest(new Point(120, 120), root, null); - Assert.Equal(new IVisual[] { target, container }, result); + Assert.Equal(new Visual[] { target, container }, result); } } @@ -315,7 +315,7 @@ public void HitTest_Should_Not_Find_Control_Outside_Parent_Bounds_When_Clipped() var result = root.Renderer.HitTest(new Point(50, 50), root, null); - Assert.Equal(new IVisual[] { container, root }, result); + Assert.Equal(new Visual[] { container, root }, result); } } diff --git a/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/DeferredDrawingContextImplTests.cs b/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/DeferredDrawingContextImplTests.cs index 8f307978f25..4cdb11b4685 100644 --- a/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/DeferredDrawingContextImplTests.cs +++ b/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/DeferredDrawingContextImplTests.cs @@ -15,7 +15,7 @@ public class DeferredDrawingContextImplTests public void Should_Add_VisualNode() { var parent = new VisualNode(new TestRoot(), null); - var child = new VisualNode(Mock.Of(), parent); + var child = new VisualNode(Mock.Of(), parent); var layers = new SceneLayers(parent.Visual); var target = new DeferredDrawingContextImpl(null, layers); @@ -30,7 +30,7 @@ public void Should_Add_VisualNode() public void Should_Not_Replace_Identical_VisualNode() { var parent = new VisualNode(new TestRoot(), null); - var child = new VisualNode(Mock.Of(), parent); + var child = new VisualNode(Mock.Of(), parent); var layers = new SceneLayers(parent.Visual); parent.AddChild(child); @@ -48,8 +48,8 @@ public void Should_Not_Replace_Identical_VisualNode() public void Should_Replace_Different_VisualNode() { var parent = new VisualNode(new TestRoot(), null); - var child1 = new VisualNode(Mock.Of(), parent); - var child2 = new VisualNode(Mock.Of(), parent); + var child1 = new VisualNode(Mock.Of(), parent); + var child2 = new VisualNode(Mock.Of(), parent); var layers = new SceneLayers(parent.Visual); parent.AddChild(child1); @@ -69,15 +69,15 @@ public void TrimChildren_Should_Trim_Children() var root = new TestRoot(); var node = new VisualNode(root, null) { LayerRoot = root }; - node.AddChild(new VisualNode(Mock.Of(), node) { LayerRoot = root }); - node.AddChild(new VisualNode(Mock.Of(), node) { LayerRoot = root }); - node.AddChild(new VisualNode(Mock.Of(), node) { LayerRoot = root }); - node.AddChild(new VisualNode(Mock.Of(), node) { LayerRoot = root }); + node.AddChild(new VisualNode(Mock.Of(), node) { LayerRoot = root }); + node.AddChild(new VisualNode(Mock.Of(), node) { LayerRoot = root }); + node.AddChild(new VisualNode(Mock.Of(), node) { LayerRoot = root }); + node.AddChild(new VisualNode(Mock.Of(), node) { LayerRoot = root }); var layers = new SceneLayers(root); var target = new DeferredDrawingContextImpl(null, layers); - var child1 = new VisualNode(Mock.Of(), node) { LayerRoot = root }; - var child2 = new VisualNode(Mock.Of(), node) { LayerRoot = root }; + var child1 = new VisualNode(Mock.Of(), node) { LayerRoot = root }; + var child2 = new VisualNode(Mock.Of(), node) { LayerRoot = root }; target.BeginUpdate(node); using (target.BeginUpdate(child1)) { } diff --git a/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs b/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs index 502575702a3..a3d11a76aac 100644 --- a/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs +++ b/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs @@ -238,8 +238,8 @@ public void Should_Respect_ZIndex() sceneBuilder.UpdateAll(result); var panelNode = result.FindNode(tree.Child); - var expected = new IVisual[] { back, front }; - var actual = panelNode.Children.OfType().Select(x => x.Visual).ToArray(); + var expected = new Visual[] { back, front }; + var actual = panelNode.Children.OfType().Select(x => x.Visual).ToArray(); Assert.Equal(expected, actual); } } @@ -267,7 +267,7 @@ public void Should_Respect_Uniform_ZIndex() var panelNode = result.FindNode(tree.Child); var expected = panel.Children.ToArray(); - var actual = panelNode.Children.OfType().Select(x => x.Visual).ToArray(); + var actual = panelNode.Children.OfType().Select(x => x.Visual).ToArray(); Assert.Equal(expected, actual); } } diff --git a/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/SceneBuilderTests_Layers.cs b/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/SceneBuilderTests_Layers.cs index 9f5a0363ed7..48ddef8bf4f 100644 --- a/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/SceneBuilderTests_Layers.cs +++ b/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/SceneBuilderTests_Layers.cs @@ -57,7 +57,7 @@ public void Control_With_Animated_Opacity_And_Children_Should_Start_New_Layer() Assert.Equal(0.5, scene.Layers[border].Opacity); Assert.Equal(2, scene.Layers.Count()); - Assert.Empty(scene.Layers.Select(x => x.LayerRoot).Except(new IVisual[] { tree, border })); + Assert.Empty(scene.Layers.Select(x => x.LayerRoot).Except(new Visual[] { tree, border })); animation.OnCompleted(); scene = scene.CloneScene(); diff --git a/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/SceneLayersTests.cs b/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/SceneLayersTests.cs index 9d25a3aa44e..7e515e7ef9b 100644 --- a/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/SceneLayersTests.cs +++ b/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/SceneLayersTests.cs @@ -29,7 +29,7 @@ public void Layers_Should_Be_Ordered() var result = target.Select(x => x.LayerRoot).ToArray(); - Assert.Equal(new IVisual[] { root, border, decorator }, result); + Assert.Equal(new Visual[] { root, border, decorator }, result); } } } diff --git a/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/VisualNodeTests.cs b/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/VisualNodeTests.cs index 93266c428c5..b6920dc381c 100644 --- a/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/VisualNodeTests.cs +++ b/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/VisualNodeTests.cs @@ -1,6 +1,6 @@ -using Avalonia.Rendering.SceneGraph; +using Avalonia.Controls; +using Avalonia.Rendering.SceneGraph; using Avalonia.Utilities; -using Avalonia.VisualTree; using Moq; using Xunit; @@ -11,8 +11,8 @@ public class VisualNodeTests [Fact] public void Empty_Children_Collections_Should_Be_Shared() { - var node1 = new VisualNode(Mock.Of(), null); - var node2 = new VisualNode(Mock.Of(), null); + var node1 = new VisualNode(new Control(), null); + var node2 = new VisualNode(new Control(), null); Assert.Same(node1.Children, node2.Children); } @@ -20,10 +20,10 @@ public void Empty_Children_Collections_Should_Be_Shared() [Fact] public void Adding_Child_Should_Create_Collection() { - var node = new VisualNode(Mock.Of(), null); + var node = new VisualNode(new Control(), null); var collection = node.Children; - node.AddChild(Mock.Of(x => x.Parent == node)); + node.AddChild(new VisualNode(new Border(), node)); Assert.NotSame(collection, node.Children); } @@ -31,8 +31,8 @@ public void Adding_Child_Should_Create_Collection() [Fact] public void Empty_DrawOperations_Collections_Should_Be_Shared() { - var node1 = new VisualNode(Mock.Of(), null); - var node2 = new VisualNode(Mock.Of(), null); + var node1 = new VisualNode(new Control(), null); + var node2 = new VisualNode(new Control(), null); Assert.Same(node1.DrawOperations, node2.DrawOperations); } @@ -40,7 +40,7 @@ public void Empty_DrawOperations_Collections_Should_Be_Shared() [Fact] public void Adding_DrawOperation_Should_Create_Collection() { - var node = new VisualNode(Mock.Of(), null); + var node = new VisualNode(new Control(), null); var collection = node.DrawOperations; node.AddDrawOperation(RefCountable.Create(Mock.Of())); @@ -51,7 +51,7 @@ public void Adding_DrawOperation_Should_Create_Collection() [Fact] public void Cloned_Nodes_Should_Share_DrawOperations_Collection() { - var node1 = new VisualNode(Mock.Of(), null); + var node1 = new VisualNode(new Control(), null); node1.AddDrawOperation(RefCountable.Create(Mock.Of())); var node2 = node1.Clone(null); @@ -62,7 +62,7 @@ public void Cloned_Nodes_Should_Share_DrawOperations_Collection() [Fact] public void Adding_DrawOperation_To_Cloned_Node_Should_Create_New_Collection() { - var node1 = new VisualNode(Mock.Of(), null); + var node1 = new VisualNode(new Control(), null); var operation1 = RefCountable.Create(Mock.Of()); node1.AddDrawOperation(operation1); @@ -80,14 +80,14 @@ public void Adding_DrawOperation_To_Cloned_Node_Should_Create_New_Collection() [Fact] public void DrawOperations_In_Cloned_Node_Are_Cloned() { - var node1 = new VisualNode(Mock.Of(), null); + var node1 = new VisualNode(new Control(), null); var operation1 = RefCountable.Create(Mock.Of()); node1.AddDrawOperation(operation1); var node2 = node1.Clone(null); var operation2 = RefCountable.Create(Mock.Of()); node2.AddDrawOperation(operation2); - + Assert.Same(node1.DrawOperations[0].Item, node2.DrawOperations[0].Item); Assert.NotSame(node1.DrawOperations[0], node2.DrawOperations[0]); } @@ -95,8 +95,8 @@ public void DrawOperations_In_Cloned_Node_Are_Cloned() [Fact] public void SortChildren_Does_Not_Throw_On_Null_Children() { - var node = new VisualNode(Mock.Of(), null); - var scene = new Scene(Mock.Of()); + var node = new VisualNode(new Control(), null); + var scene = new Scene(new Control()); node.SortChildren(scene); } @@ -104,10 +104,10 @@ public void SortChildren_Does_Not_Throw_On_Null_Children() [Fact] public void TrimChildren_Should_Work_Correctly() { - var parent = new VisualNode(Mock.Of(), null); - var child1 = new VisualNode(Mock.Of(), parent); - var child2 = new VisualNode(Mock.Of(), parent); - var child3 = new VisualNode(Mock.Of(), parent); + var parent = new VisualNode(new Control(), null); + var child1 = new VisualNode(new Control(), parent); + var child2 = new VisualNode(new Control(), parent); + var child3 = new VisualNode(new Control(), parent); parent.AddChild(child1); parent.AddChild(child2); diff --git a/tests/Avalonia.Base.UnitTests/Styling/SelectorTests_Class.cs b/tests/Avalonia.Base.UnitTests/Styling/SelectorTests_Class.cs index 376e2b23d0a..841798d39d1 100644 --- a/tests/Avalonia.Base.UnitTests/Styling/SelectorTests_Class.cs +++ b/tests/Avalonia.Base.UnitTests/Styling/SelectorTests_Class.cs @@ -62,7 +62,7 @@ public async Task Class_Matches_Control_With_TemplatedParent() var control = new Control1 { Classes = { "foo" }, - TemplatedParent = new Mock().Object, + TemplatedParent = new Button(), }; var target = default(Selector).Class("foo"); diff --git a/tests/Avalonia.Base.UnitTests/Styling/SelectorTests_Multiple.cs b/tests/Avalonia.Base.UnitTests/Styling/SelectorTests_Multiple.cs index 258a4a44a19..393caf16274 100644 --- a/tests/Avalonia.Base.UnitTests/Styling/SelectorTests_Multiple.cs +++ b/tests/Avalonia.Base.UnitTests/Styling/SelectorTests_Multiple.cs @@ -36,7 +36,7 @@ public void Named_Template_Child_Of_Control_With_Two_Classes() .Template() .Name("border"); - var border = (Border)((IVisual)control).VisualChildren.Single(); + var border = (Border)control.VisualChildren.Single(); var values = new List(); var match = selector.Match(border); @@ -76,7 +76,7 @@ public void Named_OfType_Template_Child_Of_Control_With_Two_Classes_Wrong_Type() .OfType() .Name("baz"); - var border = (Border)((IVisual)control).VisualChildren.Single(); + var border = (Border)control.VisualChildren.Single(); var values = new List(); var match = selector.Match(border); @@ -136,7 +136,7 @@ public void Named_Class_Template_Child_Of_Control() .Name("border") .Class("foo"); - var border = (Border)((IVisual)control).VisualChildren.Single(); + var border = (Border)control.VisualChildren.Single(); var values = new List(); var match = selector.Match(border); diff --git a/tests/Avalonia.Base.UnitTests/Styling/SelectorTests_Name.cs b/tests/Avalonia.Base.UnitTests/Styling/SelectorTests_Name.cs index 46b97cf3849..9bf288dbac8 100644 --- a/tests/Avalonia.Base.UnitTests/Styling/SelectorTests_Name.cs +++ b/tests/Avalonia.Base.UnitTests/Styling/SelectorTests_Name.cs @@ -28,7 +28,7 @@ public void Name_Doesnt_Match_Control_Of_Wrong_Name() [Fact] public void Name_Doesnt_Match_Control_With_TemplatedParent() { - var control = new Control1 { TemplatedParent = new Mock().Object }; + var control = new Control1 { TemplatedParent = new Button() }; var target = default(Selector).Name("foo"); var activator = target.Match(control); diff --git a/tests/Avalonia.Base.UnitTests/Styling/SelectorTests_OfType.cs b/tests/Avalonia.Base.UnitTests/Styling/SelectorTests_OfType.cs index e86a323c715..790c5494f30 100644 --- a/tests/Avalonia.Base.UnitTests/Styling/SelectorTests_OfType.cs +++ b/tests/Avalonia.Base.UnitTests/Styling/SelectorTests_OfType.cs @@ -37,7 +37,7 @@ public void OfType_Class_Doesnt_Match_Control_Of_Wrong_Type() [Fact] public void OfType_Matches_Control_With_TemplatedParent() { - var control = new Control1 { TemplatedParent = new Mock().Object }; + var control = new Control1 { TemplatedParent = new Button() }; var target = default(Selector).OfType(); Assert.Equal(SelectorMatchResult.AlwaysThisType, target.Match(control).Result); diff --git a/tests/Avalonia.Base.UnitTests/Styling/SelectorTests_Template.cs b/tests/Avalonia.Base.UnitTests/Styling/SelectorTests_Template.cs index 176fa07f196..738469bc6f7 100644 --- a/tests/Avalonia.Base.UnitTests/Styling/SelectorTests_Template.cs +++ b/tests/Avalonia.Base.UnitTests/Styling/SelectorTests_Template.cs @@ -1,7 +1,8 @@ using System.Linq; using System.Threading.Tasks; +using Avalonia.Collections; using Avalonia.Controls; -using Avalonia.Diagnostics; +using Avalonia.Controls.Primitives; using Avalonia.Styling; using Avalonia.VisualTree; using Moq; @@ -14,14 +15,10 @@ public class SelectorTests_Template [Fact] public void Control_In_Template_Is_Matched_With_Template_Selector() { - var target = new Mock(); - var templatedControl = target.As(); - var styleable = target.As(); - BuildVisualTree(target); - - var border = (Border)target.Object.GetVisualChildren().Single(); + var target = new TestTemplatedControl(); + var border = (Border)target.GetVisualChildren().Single(); var selector = default(Selector) - .OfType(target.Object.GetType()) + .OfType(target.GetType()) .Template() .OfType(); @@ -31,30 +28,23 @@ public void Control_In_Template_Is_Matched_With_Template_Selector() [Fact] public void Control_Not_In_Template_Is_Not_Matched_With_Template_Selector() { - var target = new Mock(); - var templatedControl = target.As(); - var styleable = target.As(); - BuildVisualTree(target); - - var border = (Border)target.Object.GetVisualChildren().Single(); - border.SetValue(Control.TemplatedParentProperty, null); + var target = new TestTemplatedControl(); + var border = (Border)target.GetVisualChildren().Single(); var selector = default(Selector) - .OfType(target.Object.GetType()) + .OfType(target.GetType()) .Template() .OfType(); + border.SetValue(StyledElement.TemplatedParentProperty, null); + Assert.Equal(SelectorMatchResult.NeverThisInstance, selector.Match(border).Result); } [Fact] public void Control_In_Template_Of_Wrong_Type_Is_Not_Matched_With_Template_Selector() { - var target = new Mock(); - var templatedControl = target.As(); - var styleable = target.As(); - BuildVisualTree(target); - - var border = (Border)target.Object.GetVisualChildren().Single(); + var target = new TestTemplatedControl(); + var border = (Border)target.GetVisualChildren().Single(); var selector = default(Selector) .OfType