Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove AvaloniaProperty.Initialized and PseudoClass static methods #3292

Merged
merged 9 commits into from
Feb 12, 2020
1 change: 0 additions & 1 deletion src/Avalonia.Base/AvaloniaObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ public class AvaloniaObject : IAvaloniaObject, IAvaloniaObjectDebug, INotifyProp
public AvaloniaObject()
{
VerifyAccess();
AvaloniaPropertyRegistry.Instance.NotifyInitialized(this);
}

/// <summary>
Expand Down
39 changes: 0 additions & 39 deletions src/Avalonia.Base/AvaloniaProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ public abstract class AvaloniaProperty : IEquatable<AvaloniaProperty>
public static readonly object UnsetValue = new UnsetValueType();

private static int s_nextId;
private readonly Subject<AvaloniaPropertyChangedEventArgs> _initialized;
private readonly Subject<AvaloniaPropertyChangedEventArgs> _changed;
private readonly PropertyMetadata _defaultMetadata;
private readonly Dictionary<Type, PropertyMetadata> _metadata;
Expand Down Expand Up @@ -53,7 +52,6 @@ protected AvaloniaProperty(
throw new ArgumentException("'name' may not contain periods.");
}

_initialized = new Subject<AvaloniaPropertyChangedEventArgs>();
_changed = new Subject<AvaloniaPropertyChangedEventArgs>();
_metadata = new Dictionary<Type, PropertyMetadata>();

Expand Down Expand Up @@ -81,7 +79,6 @@ protected AvaloniaProperty(
Contract.Requires<ArgumentNullException>(source != null);
Contract.Requires<ArgumentNullException>(ownerType != null);

_initialized = source._initialized;
_changed = source._changed;
_metadata = new Dictionary<Type, PropertyMetadata>();

Expand Down Expand Up @@ -136,22 +133,6 @@ protected AvaloniaProperty(
/// </summary>
public virtual bool IsReadOnly => false;

/// <summary>
/// Gets an observable that is fired when this property is initialized on a
/// new <see cref="AvaloniaObject"/> instance.
/// </summary>
/// <remarks>
/// This observable is fired each time a new <see cref="AvaloniaObject"/> is constructed
/// for all properties registered on the object's type. The default value of the property
/// for the object is passed in the args' NewValue (OldValue will always be
/// <see cref="UnsetValue"/>.
/// </remarks>
/// <value>
/// An observable that is fired when this property is initialized on a new
/// <see cref="AvaloniaObject"/> instance.
/// </value>
public IObservable<AvaloniaPropertyChangedEventArgs> Initialized => _initialized;

/// <summary>
/// Gets an observable that is fired when this property changes on any
/// <see cref="AvaloniaObject"/> instance.
Expand Down Expand Up @@ -488,26 +469,6 @@ public override string ToString()
return Name;
}

/// <summary>
/// True if <see cref="Initialized"/> has any observers.
/// </summary>
internal bool HasNotifyInitializedObservers => _initialized.HasObservers;

/// <summary>
/// Notifies the <see cref="Initialized"/> observable.
/// </summary>
/// <param name="o">The object being initialized.</param>
internal abstract void NotifyInitialized(IAvaloniaObject o);

/// <summary>
/// Notifies the <see cref="Initialized"/> observable.
/// </summary>
/// <param name="e">The observable arguments.</param>
internal void NotifyInitialized(AvaloniaPropertyChangedEventArgs e)
{
_initialized.OnNext(e);
}

/// <summary>
/// Notifies the <see cref="Changed"/> observable.
/// </summary>
Expand Down
45 changes: 0 additions & 45 deletions src/Avalonia.Base/AvaloniaPropertyRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -415,51 +415,6 @@ public void RegisterAttached(Type type, AvaloniaProperty property)
_inheritedCache.Clear();
}

internal void NotifyInitialized(AvaloniaObject o)
{
Contract.Requires<ArgumentNullException>(o != null);

var type = o.GetType();

if (!_initializedCache.TryGetValue(type, out var initializationData))
{
var visited = new HashSet<AvaloniaProperty>();

initializationData = new List<PropertyInitializationData>();

foreach (AvaloniaProperty property in GetRegistered(type))
{
if (property.IsDirect)
{
initializationData.Add(new PropertyInitializationData(property, (IDirectPropertyAccessor)property));
}
else
{
initializationData.Add(new PropertyInitializationData(property, (IStyledPropertyAccessor)property, type));
}

visited.Add(property);
}

foreach (AvaloniaProperty property in GetRegisteredAttached(type))
{
if (!visited.Contains(property))
{
initializationData.Add(new PropertyInitializationData(property, (IStyledPropertyAccessor)property, type));

visited.Add(property);
}
}

_initializedCache.Add(type, initializationData);
}

foreach (PropertyInitializationData data in initializationData)
{
data.Property.NotifyInitialized(o);
}
}

private readonly struct PropertyInitializationData
{
public AvaloniaProperty Property { get; }
Expand Down
15 changes: 0 additions & 15 deletions src/Avalonia.Base/DirectPropertyBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,21 +101,6 @@ public TValue GetUnsetValue(Type type)
return (DirectPropertyMetadata<TValue>)base.GetMetadata(type);
}

/// <inheritdoc/>
internal override void NotifyInitialized(IAvaloniaObject o)
{
if (HasNotifyInitializedObservers)
{
var e = new AvaloniaPropertyChangedEventArgs<TValue>(
o,
this,
default,
InvokeGetter(o),
BindingPriority.Unset);
NotifyInitialized(e);
}
}

/// <inheritdoc/>
internal override void RouteClearValue(IAvaloniaObject o)
{
Expand Down
15 changes: 0 additions & 15 deletions src/Avalonia.Base/StyledPropertyBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,21 +181,6 @@ public override string ToString()
/// <inheritdoc/>
object IStyledPropertyAccessor.GetDefaultValue(Type type) => GetDefaultBoxedValue(type);

/// <inheritdoc/>
internal override void NotifyInitialized(IAvaloniaObject o)
{
if (HasNotifyInitializedObservers)
{
var e = new AvaloniaPropertyChangedEventArgs<TValue>(
o,
this,
default,
o.GetValue(this),
BindingPriority.Unset);
NotifyInitialized(e);
}
}

/// <inheritdoc/>
internal override void RouteClearValue(IAvaloniaObject o)
{
Expand Down
8 changes: 5 additions & 3 deletions src/Avalonia.Controls.DataGrid/DataGrid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,11 @@ private void OnAreRowGroupHeadersFrozenChanged(AvaloniaPropertyChangedEventArgs
public bool IsValid
{
get { return _isValid; }
internal set { SetAndRaise(IsValidProperty, ref _isValid, value); }
internal set
{
SetAndRaise(IsValidProperty, ref _isValid, value);
PseudoClasses.Set(":invalid", !value);
}
}

public static readonly StyledProperty<double> MaxColumnWidthProperty =
Expand Down Expand Up @@ -656,8 +660,6 @@ static DataGrid()
HorizontalScrollBarVisibilityProperty,
VerticalScrollBarVisibilityProperty);

PseudoClass<DataGrid, bool>(IsValidProperty, x => !x, ":invalid");

ItemsProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnItemsPropertyChanged(e));
CanUserResizeColumnsProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnCanUserResizeColumnsChanged(e));
ColumnWidthProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnColumnWidthChanged(e));
Expand Down
25 changes: 24 additions & 1 deletion src/Avalonia.Controls/Button.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,11 @@ static Button()
CommandProperty.Changed.Subscribe(CommandChanged);
IsDefaultProperty.Changed.Subscribe(IsDefaultChanged);
IsCancelProperty.Changed.Subscribe(IsCancelChanged);
PseudoClass<Button>(IsPressedProperty, ":pressed");
}

public Button()
{
UpdatePseudoClasses(IsPressed);
}

/// <summary>
Expand Down Expand Up @@ -312,6 +316,20 @@ protected override void OnPointerCaptureLost(PointerCaptureLostEventArgs e)
IsPressed = false;
}

protected override void OnPropertyChanged<T>(
AvaloniaProperty<T> property,
Optional<T> oldValue,
BindingValue<T> newValue,
BindingPriority priority)
{
base.OnPropertyChanged(property, oldValue, newValue, priority);

if (property == IsPressedProperty)
{
UpdatePseudoClasses(newValue.GetValueOrDefault<bool>());
}
}

protected override void UpdateDataValidation<T>(AvaloniaProperty<T> property, BindingValue<T> value)
{
base.UpdateDataValidation(property, value);
Expand Down Expand Up @@ -474,5 +492,10 @@ private void RootCancelKeyDown(object sender, KeyEventArgs e)
OnClick();
}
}

private void UpdatePseudoClasses(bool isPressed)
{
PseudoClasses.Set(":pressed", isPressed);
}
}
}
28 changes: 26 additions & 2 deletions src/Avalonia.Controls/ButtonSpinner.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using Avalonia.Controls.Primitives;
using Avalonia.Data;
using Avalonia.Input;
using Avalonia.Interactivity;

Expand Down Expand Up @@ -34,6 +35,11 @@ public class ButtonSpinner : Spinner
public static readonly StyledProperty<Location> ButtonSpinnerLocationProperty =
AvaloniaProperty.Register<ButtonSpinner, Location>(nameof(ButtonSpinnerLocation), Location.Right);

public ButtonSpinner()
{
UpdatePseudoClasses(ButtonSpinnerLocation);
}

private Button _decreaseButton;
/// <summary>
/// Gets or sets the DecreaseButton template part.
Expand Down Expand Up @@ -85,8 +91,6 @@ private Button IncreaseButton
static ButtonSpinner()
{
AllowSpinProperty.Changed.Subscribe(AllowSpinChanged);
PseudoClass<ButtonSpinner, Location>(ButtonSpinnerLocationProperty, location => location == Location.Left, ":left");
PseudoClass<ButtonSpinner, Location>(ButtonSpinnerLocationProperty, location => location == Location.Right, ":right");
}

/// <summary>
Expand Down Expand Up @@ -201,6 +205,20 @@ protected override void OnPointerWheelChanged(PointerWheelEventArgs e)
}
}

protected override void OnPropertyChanged<T>(
AvaloniaProperty<T> property,
Optional<T> oldValue,
BindingValue<T> newValue,
BindingPriority priority)
{
base.OnPropertyChanged(property, oldValue, newValue, priority);

if (property == ButtonSpinnerLocationProperty)
{
UpdatePseudoClasses(newValue.GetValueOrDefault<Location>());
}
}

protected override void OnValidSpinDirectionChanged(ValidSpinDirections oldValue, ValidSpinDirections newValue)
{
SetButtonUsage();
Expand Down Expand Up @@ -259,5 +277,11 @@ private void OnButtonClick(object sender, RoutedEventArgs e)
OnSpin(new SpinEventArgs(SpinEvent, direction));
}
}

private void UpdatePseudoClasses(Location location)
{
PseudoClasses.Set(":left", location == Location.Left);
PseudoClasses.Set(":right", location == Location.Right);
}
}
}
20 changes: 0 additions & 20 deletions src/Avalonia.Controls/ControlExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,26 +69,6 @@ public static T FindControl<T>(this IControl control, string name) where T : cla
return nameScope.Find<T>(name);
}

/// <summary>
/// Adds or removes a pseudoclass depending on a boolean value.
/// </summary>
/// <param name="classes">The pseudoclasses collection.</param>
/// <param name="name">The name of the pseudoclass to set.</param>
/// <param name="value">True to add the pseudoclass or false to remove.</param>
public static void Set(this IPseudoClasses classes, string name, bool value)
{
Contract.Requires<ArgumentNullException>(classes != null);

if (value)
{
classes.Add(name);
}
else
{
classes.Remove(name);
}
}

/// <summary>
/// Sets a pseudoclass depending on an observable trigger.
/// </summary>
Expand Down
Loading