Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e2e60bb480 | |||
| 2d312b2a9f | |||
| 121115b108 | |||
| 4f51b4c09c |
@@ -1,7 +1,6 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Dashboard
|
namespace Dashboard.Collections
|
||||||
{
|
{
|
||||||
public class HashList<T> : IReadOnlyList<T>
|
public class HashList<T> : IReadOnlyList<T>
|
||||||
where T : notnull
|
where T : notnull
|
||||||
@@ -1,27 +1,111 @@
|
|||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Numerics;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace Dashboard.Drawing
|
namespace Dashboard.Drawing
|
||||||
{
|
{
|
||||||
public abstract class Brush
|
public abstract class Brush : INotifyPropertyChanged, ICloneable
|
||||||
{
|
{
|
||||||
|
public event PropertyChangedEventHandler? PropertyChanged;
|
||||||
|
|
||||||
|
public virtual object Clone()
|
||||||
|
{
|
||||||
|
return MemberwiseClone();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void SetField<T>(ref T field, T value, [CallerMemberName] string property = "")
|
||||||
|
{
|
||||||
|
field = value;
|
||||||
|
OnPropertyChanged(property);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnPropertyChanged(string property)
|
||||||
|
{
|
||||||
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SolidColorBrush(Color color) : Brush
|
public sealed class SolidColorBrush(Color color) : Brush
|
||||||
{
|
{
|
||||||
public Color Color { get; } = color;
|
public Color Color { get; } = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ImageBrush(Image image) : Brush
|
public class ImageBrush(Image image) : Brush
|
||||||
{
|
{
|
||||||
public Image Image { get; set; } = image;
|
public Image Image
|
||||||
public Box2d TextureCoordinates { get; set; } = new Box2d(0, 0, 1, 1);
|
{
|
||||||
|
get;
|
||||||
|
set => SetField(ref field, value);
|
||||||
|
} = image;
|
||||||
|
|
||||||
|
public Box2d TextureCoordinates
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set => SetField(ref field, value);
|
||||||
|
} = new Box2d(0, 0, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NinePatchImageBrush(Image image) : Brush
|
public class NinePatchImageBrush(Image image) : Brush
|
||||||
{
|
{
|
||||||
public Image Image { get; set; } = image;
|
public Image Image
|
||||||
public Box2d CenterCoordinates { get; set; } = new Box2d(0, 0, 1, 1);
|
{
|
||||||
public Vector4 Extents { get; set; } = Vector4.Zero;
|
get;
|
||||||
|
set => SetField(ref field, value);
|
||||||
|
} = image;
|
||||||
|
|
||||||
|
public Box2d CenterCoordinates
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set => SetField(ref field, value);
|
||||||
|
} = new Box2d(0, 0, 1, 1);
|
||||||
|
|
||||||
|
public Extents Extents
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set => SetField(ref field, value);
|
||||||
|
} = Extents.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GradientBrush : Brush
|
||||||
|
{
|
||||||
|
public Gradient Gradient
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Unsubscribe(field);
|
||||||
|
Subscribe(value);
|
||||||
|
|
||||||
|
SetField(ref field, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public GradientBrush(Gradient gradient)
|
||||||
|
{
|
||||||
|
Gradient = gradient;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Subscribe(Gradient gradient)
|
||||||
|
{
|
||||||
|
gradient.PropertyChanged += GradientPropertyChanged;
|
||||||
|
gradient.CollectionChanged += GradientCollectionChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Unsubscribe(Gradient? gradient)
|
||||||
|
{
|
||||||
|
gradient?.PropertyChanged -= GradientPropertyChanged;
|
||||||
|
gradient?.CollectionChanged -= GradientCollectionChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GradientCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
OnPropertyChanged(nameof(Gradient));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GradientPropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
OnPropertyChanged(nameof(Gradient));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Specialized;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace Dashboard
|
namespace Dashboard.Drawing
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enumeration of the kinds of gradients available.
|
/// Enumeration of the kinds of gradients available.
|
||||||
@@ -25,29 +27,41 @@ namespace Dashboard
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="Position">The position of the gradient stop. Must be [0,1].</param>
|
/// <param name="Position">The position of the gradient stop. Must be [0,1].</param>
|
||||||
/// <param name="Color">The color value for the stop.</param>
|
/// <param name="Color">The color value for the stop.</param>
|
||||||
public record struct GradientStop(float Position, Color Color);
|
public readonly record struct GradientStop(float Position, Color Color);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a linear gradient.
|
/// Represents a linear gradient.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public struct Gradient : ICollection<GradientStop>, ICloneable, IEquatable<Gradient>
|
public class Gradient : ICollection<GradientStop>, ICloneable, IEquatable<Gradient>, INotifyPropertyChanged, INotifyCollectionChanged
|
||||||
{
|
{
|
||||||
private readonly List<GradientStop> _stops = new List<GradientStop>();
|
private readonly List<GradientStop> _stops = new List<GradientStop>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gradient type.
|
/// Gradient type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GradientType Type { get; set; } = GradientType.Axial;
|
public GradientType Type
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set => SetField(ref field, value);
|
||||||
|
} = GradientType.Axial;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// First gradient control point.
|
/// First gradient control point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Vector2 C0 { get; set; } = Vector2.Zero;
|
public Vector2 C0
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set => SetField(ref field, value);
|
||||||
|
} = Vector2.Zero;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Second gradient control point.
|
/// Second gradient control point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Vector2 C1 { get; set; } = Vector2.One;
|
public Vector2 C1
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set => SetField(ref field, value);
|
||||||
|
} = Vector2.One;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Number of stops in a gradient.
|
/// Number of stops in a gradient.
|
||||||
@@ -69,6 +83,10 @@ namespace Dashboard
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public event PropertyChangedEventHandler? PropertyChanged;
|
||||||
|
public event NotifyCollectionChangedEventHandler? CollectionChanged;
|
||||||
|
|
||||||
|
|
||||||
public Gradient()
|
public Gradient()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -164,11 +182,13 @@ namespace Dashboard
|
|||||||
index = _stops.Count;
|
index = _stops.Count;
|
||||||
|
|
||||||
_stops.Insert(index, item);
|
_stops.Insert(index, item);
|
||||||
|
OnCollectionChanged(NotifyCollectionChangedAction.Add);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
_stops.Clear();
|
_stops.Clear();
|
||||||
|
OnCollectionChanged(NotifyCollectionChangedAction.Reset);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Contains(GradientStop item)
|
public bool Contains(GradientStop item)
|
||||||
@@ -183,30 +203,51 @@ namespace Dashboard
|
|||||||
|
|
||||||
public bool Remove(GradientStop item)
|
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)
|
public void RemoveAt(int index)
|
||||||
{
|
{
|
||||||
_stops.RemoveAt(index);
|
_stops.RemoveAt(index);
|
||||||
|
OnCollectionChanged(NotifyCollectionChangedAction.Remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
HashCode code = new HashCode();
|
HashCode code = new HashCode();
|
||||||
|
|
||||||
code.Add(Count);
|
code.Add(Count);
|
||||||
|
code.Add(Type);
|
||||||
|
code.Add(C0);
|
||||||
|
code.Add(C1);
|
||||||
|
|
||||||
foreach (GradientStop item in this)
|
foreach (GradientStop item in this)
|
||||||
code.Add(item.GetHashCode());
|
code.Add(item.GetHashCode());
|
||||||
return code.ToHashCode();
|
return code.ToHashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Equals(Gradient other)
|
public bool Equals(Gradient? other)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
|
other != null &&
|
||||||
Type == other.Type &&
|
Type == other.Type &&
|
||||||
C0 == other.C0 &&
|
C0 == other.C0 &&
|
||||||
C1 == other.C1 &&
|
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)
|
public override bool Equals(object? obj)
|
||||||
@@ -214,14 +255,30 @@ namespace Dashboard
|
|||||||
return obj is Gradient other && Equals(other);
|
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<T>(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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -25,5 +25,7 @@ namespace Dashboard
|
|||||||
public Extents(float value) : this(new Vector4(value))
|
public Extents(float value) : this(new Vector4(value))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static readonly Extents None = new Extents(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user