diff --git a/Dashboard.Common/Gradient.cs b/Dashboard.Common/Drawing/Gradient.cs
similarity index 67%
rename from Dashboard.Common/Gradient.cs
rename to Dashboard.Common/Drawing/Gradient.cs
index cf27537..ff59c7e 100644
--- a/Dashboard.Common/Gradient.cs
+++ b/Dashboard.Common/Drawing/Gradient.cs
@@ -1,9 +1,11 @@
using System.Collections;
-using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.ComponentModel;
using System.Drawing;
using System.Numerics;
+using System.Runtime.CompilerServices;
-namespace Dashboard
+namespace Dashboard.Drawing
{
///
/// Enumeration of the kinds of gradients available.
@@ -25,29 +27,41 @@ namespace Dashboard
///
/// The position of the gradient stop. Must be [0,1].
/// The color value for the stop.
- public record struct GradientStop(float Position, Color Color);
+ public readonly record struct GradientStop(float Position, Color Color);
///
/// Represents a linear gradient.
///
- public struct Gradient : ICollection, ICloneable, IEquatable
+ public class Gradient : ICollection, ICloneable, IEquatable, INotifyPropertyChanged, INotifyCollectionChanged
{
private readonly List _stops = new List();
///
/// Gradient type.
///
- public GradientType Type { get; set; } = GradientType.Axial;
+ public GradientType Type
+ {
+ get;
+ set => SetField(ref field, value);
+ } = GradientType.Axial;
///
/// First gradient control point.
///
- public Vector2 C0 { get; set; } = Vector2.Zero;
+ public Vector2 C0
+ {
+ get;
+ set => SetField(ref field, value);
+ } = Vector2.Zero;
///
/// Second gradient control point.
///
- public Vector2 C1 { get; set; } = Vector2.One;
+ public Vector2 C1
+ {
+ get;
+ set => SetField(ref field, value);
+ } = Vector2.One;
///
/// Number of stops in a gradient.
@@ -69,6 +83,10 @@ namespace Dashboard
}
}
+ public event PropertyChangedEventHandler? PropertyChanged;
+ public event NotifyCollectionChangedEventHandler? CollectionChanged;
+
+
public Gradient()
{
}
@@ -164,11 +182,13 @@ namespace Dashboard
index = _stops.Count;
_stops.Insert(index, item);
+ OnCollectionChanged(NotifyCollectionChangedAction.Add);
}
public void Clear()
{
_stops.Clear();
+ OnCollectionChanged(NotifyCollectionChangedAction.Reset);
}
public bool Contains(GradientStop item)
@@ -183,30 +203,51 @@ namespace Dashboard
public bool Remove(GradientStop item)
{
- return _stops.Remove(item);
+ if (!_stops.Remove(item))
+ return false;
+
+ OnCollectionChanged(NotifyCollectionChangedAction.Remove);
+ return true;
}
public void RemoveAt(int index)
{
_stops.RemoveAt(index);
+ OnCollectionChanged(NotifyCollectionChangedAction.Remove);
}
public override int GetHashCode()
{
HashCode code = new HashCode();
+
code.Add(Count);
+ code.Add(Type);
+ code.Add(C0);
+ code.Add(C1);
+
foreach (GradientStop item in this)
code.Add(item.GetHashCode());
return code.ToHashCode();
}
- public bool Equals(Gradient other)
+ public bool Equals(Gradient? other)
{
return
+ other != null &&
Type == other.Type &&
C0 == other.C0 &&
C1 == other.C1 &&
- _stops.Equals(other._stops);
+ _stops.SequenceEqual(other._stops);
+ }
+
+ private bool NotEquals(Gradient? other)
+ {
+ return
+ other == null ||
+ Type != other.Type ||
+ C0 != other.C0 ||
+ C1 != other.C1 ||
+ !_stops.SequenceEqual(other._stops);
}
public override bool Equals(object? obj)
@@ -214,14 +255,30 @@ namespace Dashboard
return obj is Gradient other && Equals(other);
}
- public static bool operator ==(Gradient left, Gradient right)
+ public static bool operator ==(Gradient? left, Gradient? right)
{
- return left.Equals(right);
+ return left?.Equals(right) ?? right == null;
}
- public static bool operator !=(Gradient left, Gradient right)
+ public static bool operator !=(Gradient? left, Gradient? right)
{
- return !left.Equals(right);
+ return left?.NotEquals(right) ?? right != null;
+ }
+
+ protected void SetField(ref T field, T value, [CallerMemberName] string name = "")
+ {
+ field = value;
+ OnPropertyChanged(name);
+ }
+
+ protected virtual void OnPropertyChanged(string property)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
+ }
+
+ protected virtual void OnCollectionChanged(NotifyCollectionChangedAction action)
+ {
+ CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(action));
}
}
}