mirror of
https://github.com/DarthAffe/RGB.NET.git
synced 2026-11-11 04:57:15 +00:00
Changed all namespaces to file-scope
This commit is contained in:
1 parent
a0c6ccebea
commit
30624035f1
353 files changed
+35775
-36129
No files matched your search
@@ -10,142 +10,141 @@ using System.Linq;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Presets.Decorators;
|
||||
|
||||
namespace RGB.NET.Presets.Textures.Gradients
|
||||
namespace RGB.NET.Presets.Textures.Gradients;
|
||||
|
||||
/// <inheritdoc cref="AbstractDecoratable{T}" />
|
||||
/// <inheritdoc cref="IGradient" />
|
||||
/// <summary>
|
||||
/// Represents a basic gradient.
|
||||
/// </summary>
|
||||
public abstract class AbstractGradient : AbstractDecoratable<IGradientDecorator>, IGradient
|
||||
{
|
||||
/// <inheritdoc cref="AbstractDecoratable{T}" />
|
||||
/// <inheritdoc cref="IGradient" />
|
||||
#region Properties & Fields
|
||||
|
||||
/// <summary>
|
||||
/// Represents a basic gradient.
|
||||
/// Gets a list of the stops used by this <see cref="AbstractGradient"/>.
|
||||
/// </summary>
|
||||
public abstract class AbstractGradient : AbstractDecoratable<IGradientDecorator>, IGradient
|
||||
public ObservableCollection<GradientStop> GradientStops { get; } = new();
|
||||
|
||||
private bool _wrapGradient;
|
||||
/// <summary>
|
||||
/// Gets or sets if the Gradient wraps around if there isn't a second stop to take.
|
||||
/// Example: There is a stop at offset 0.0, 0.5 and 0.75.
|
||||
/// Without wrapping offset 1.0 will be calculated the same as 0.75; with wrapping it would be the same as 0.0.
|
||||
/// </summary>
|
||||
public bool WrapGradient
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of the stops used by this <see cref="AbstractGradient"/>.
|
||||
/// </summary>
|
||||
public ObservableCollection<GradientStop> GradientStops { get; } = new();
|
||||
|
||||
private bool _wrapGradient;
|
||||
/// <summary>
|
||||
/// Gets or sets if the Gradient wraps around if there isn't a second stop to take.
|
||||
/// Example: There is a stop at offset 0.0, 0.5 and 0.75.
|
||||
/// Without wrapping offset 1.0 will be calculated the same as 0.75; with wrapping it would be the same as 0.0.
|
||||
/// </summary>
|
||||
public bool WrapGradient
|
||||
{
|
||||
get => _wrapGradient;
|
||||
set => SetProperty(ref _wrapGradient, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler? GradientChanged;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AbstractGradient"/> class.
|
||||
/// </summary>
|
||||
protected AbstractGradient()
|
||||
{
|
||||
GradientStops.CollectionChanged += GradientCollectionChanged;
|
||||
PropertyChanged += (_, _) => OnGradientChanged();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AbstractGradient"/> class.
|
||||
/// </summary>
|
||||
/// <param name="gradientStops">The stops with which the gradient should be initialized.</param>
|
||||
protected AbstractGradient(params GradientStop[] gradientStops)
|
||||
{
|
||||
GradientStops.CollectionChanged += GradientCollectionChanged;
|
||||
PropertyChanged += (_, _) => OnGradientChanged();
|
||||
|
||||
foreach (GradientStop gradientStop in gradientStops)
|
||||
GradientStops.Add(gradientStop);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AbstractGradient"/> class.
|
||||
/// </summary>
|
||||
/// <param name="wrapGradient">Specifies whether the gradient should wrapp or not (see <see cref="WrapGradient"/> for an example of what this means).</param>
|
||||
/// <param name="gradientStops">The stops with which the gradient should be initialized.</param>
|
||||
protected AbstractGradient(bool wrapGradient, params GradientStop[] gradientStops)
|
||||
{
|
||||
this.WrapGradient = wrapGradient;
|
||||
|
||||
GradientStops.CollectionChanged += GradientCollectionChanged;
|
||||
PropertyChanged += (_, _) => OnGradientChanged();
|
||||
|
||||
foreach (GradientStop gradientStop in gradientStops)
|
||||
GradientStops.Add(gradientStop);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Clips the offset and ensures, that it is inside the bounds of the stop list.
|
||||
/// </summary>
|
||||
/// <param name="offset">The offset to clip.</param>
|
||||
/// <returns>The clipped offset.</returns>
|
||||
protected float ClipOffset(float offset)
|
||||
{
|
||||
float max = GradientStops.Max(stop => stop.Offset);
|
||||
if (offset > max)
|
||||
return max;
|
||||
|
||||
float min = GradientStops.Min(stop => stop.Offset);
|
||||
return offset < min ? min : offset;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract Color GetColor(float offset);
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void Move(float offset)
|
||||
{
|
||||
offset /= 360.0f;
|
||||
|
||||
foreach (GradientStop gradientStop in GradientStops)
|
||||
gradientStop.Offset += offset;
|
||||
|
||||
while (GradientStops.All(stop => stop.Offset > 1))
|
||||
foreach (GradientStop gradientStop in GradientStops)
|
||||
gradientStop.Offset -= 1;
|
||||
|
||||
while (GradientStops.All(stop => stop.Offset < 0))
|
||||
foreach (GradientStop gradientStop in GradientStops)
|
||||
gradientStop.Offset += 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Should be called to indicate that the gradient was changed.
|
||||
/// </summary>
|
||||
protected void OnGradientChanged() => GradientChanged?.Invoke(this, EventArgs.Empty);
|
||||
|
||||
private void GradientCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (e.OldItems != null)
|
||||
foreach (GradientStop gradientStop in e.OldItems)
|
||||
gradientStop.PropertyChanged -= GradientStopChanged;
|
||||
|
||||
if (e.NewItems != null)
|
||||
foreach (GradientStop gradientStop in e.NewItems)
|
||||
gradientStop.PropertyChanged += GradientStopChanged;
|
||||
|
||||
OnGradientChanged();
|
||||
}
|
||||
|
||||
private void GradientStopChanged(object? sender, PropertyChangedEventArgs propertyChangedEventArgs) => OnGradientChanged();
|
||||
|
||||
#endregion
|
||||
get => _wrapGradient;
|
||||
set => SetProperty(ref _wrapGradient, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler? GradientChanged;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AbstractGradient"/> class.
|
||||
/// </summary>
|
||||
protected AbstractGradient()
|
||||
{
|
||||
GradientStops.CollectionChanged += GradientCollectionChanged;
|
||||
PropertyChanged += (_, _) => OnGradientChanged();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AbstractGradient"/> class.
|
||||
/// </summary>
|
||||
/// <param name="gradientStops">The stops with which the gradient should be initialized.</param>
|
||||
protected AbstractGradient(params GradientStop[] gradientStops)
|
||||
{
|
||||
GradientStops.CollectionChanged += GradientCollectionChanged;
|
||||
PropertyChanged += (_, _) => OnGradientChanged();
|
||||
|
||||
foreach (GradientStop gradientStop in gradientStops)
|
||||
GradientStops.Add(gradientStop);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AbstractGradient"/> class.
|
||||
/// </summary>
|
||||
/// <param name="wrapGradient">Specifies whether the gradient should wrapp or not (see <see cref="WrapGradient"/> for an example of what this means).</param>
|
||||
/// <param name="gradientStops">The stops with which the gradient should be initialized.</param>
|
||||
protected AbstractGradient(bool wrapGradient, params GradientStop[] gradientStops)
|
||||
{
|
||||
this.WrapGradient = wrapGradient;
|
||||
|
||||
GradientStops.CollectionChanged += GradientCollectionChanged;
|
||||
PropertyChanged += (_, _) => OnGradientChanged();
|
||||
|
||||
foreach (GradientStop gradientStop in gradientStops)
|
||||
GradientStops.Add(gradientStop);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Clips the offset and ensures, that it is inside the bounds of the stop list.
|
||||
/// </summary>
|
||||
/// <param name="offset">The offset to clip.</param>
|
||||
/// <returns>The clipped offset.</returns>
|
||||
protected float ClipOffset(float offset)
|
||||
{
|
||||
float max = GradientStops.Max(stop => stop.Offset);
|
||||
if (offset > max)
|
||||
return max;
|
||||
|
||||
float min = GradientStops.Min(stop => stop.Offset);
|
||||
return offset < min ? min : offset;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract Color GetColor(float offset);
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void Move(float offset)
|
||||
{
|
||||
offset /= 360.0f;
|
||||
|
||||
foreach (GradientStop gradientStop in GradientStops)
|
||||
gradientStop.Offset += offset;
|
||||
|
||||
while (GradientStops.All(stop => stop.Offset > 1))
|
||||
foreach (GradientStop gradientStop in GradientStops)
|
||||
gradientStop.Offset -= 1;
|
||||
|
||||
while (GradientStops.All(stop => stop.Offset < 0))
|
||||
foreach (GradientStop gradientStop in GradientStops)
|
||||
gradientStop.Offset += 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Should be called to indicate that the gradient was changed.
|
||||
/// </summary>
|
||||
protected void OnGradientChanged() => GradientChanged?.Invoke(this, EventArgs.Empty);
|
||||
|
||||
private void GradientCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (e.OldItems != null)
|
||||
foreach (GradientStop gradientStop in e.OldItems)
|
||||
gradientStop.PropertyChanged -= GradientStopChanged;
|
||||
|
||||
if (e.NewItems != null)
|
||||
foreach (GradientStop gradientStop in e.NewItems)
|
||||
gradientStop.PropertyChanged += GradientStopChanged;
|
||||
|
||||
OnGradientChanged();
|
||||
}
|
||||
|
||||
private void GradientStopChanged(object? sender, PropertyChangedEventArgs propertyChangedEventArgs) => OnGradientChanged();
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -3,50 +3,49 @@
|
||||
|
||||
using RGB.NET.Core;
|
||||
|
||||
namespace RGB.NET.Presets.Textures.Gradients
|
||||
namespace RGB.NET.Presets.Textures.Gradients;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a stop on a gradient.
|
||||
/// </summary>
|
||||
public class GradientStop : AbstractBindable
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
private float _offset;
|
||||
/// <summary>
|
||||
/// Represents a stop on a gradient.
|
||||
/// Gets or sets the percentage offset to place this <see cref="GradientStop"/>. This should be inside the range of [0..1] but it's not necessary.
|
||||
/// </summary>
|
||||
public class GradientStop : AbstractBindable
|
||||
public float Offset
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
private float _offset;
|
||||
/// <summary>
|
||||
/// Gets or sets the percentage offset to place this <see cref="GradientStop"/>. This should be inside the range of [0..1] but it's not necessary.
|
||||
/// </summary>
|
||||
public float Offset
|
||||
{
|
||||
get => _offset;
|
||||
set => SetProperty(ref _offset, value);
|
||||
}
|
||||
|
||||
private Color _color;
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="Color"/> of this <see cref="GradientStop"/>.
|
||||
/// </summary>
|
||||
public Color Color
|
||||
{
|
||||
get => _color;
|
||||
set => SetProperty(ref _color, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GradientStop"/> class.
|
||||
/// </summary>
|
||||
/// <param name="offset">The percentage offset to place this <see cref="GradientStop"/>.</param>
|
||||
/// <param name="color">The <see cref="Color"/> of the <see cref="GradientStop"/>.</param>
|
||||
public GradientStop(float offset, Color color)
|
||||
{
|
||||
this.Offset = offset;
|
||||
this.Color = color;
|
||||
}
|
||||
|
||||
#endregion
|
||||
get => _offset;
|
||||
set => SetProperty(ref _offset, value);
|
||||
}
|
||||
}
|
||||
|
||||
private Color _color;
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="Color"/> of this <see cref="GradientStop"/>.
|
||||
/// </summary>
|
||||
public Color Color
|
||||
{
|
||||
get => _color;
|
||||
set => SetProperty(ref _color, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GradientStop"/> class.
|
||||
/// </summary>
|
||||
/// <param name="offset">The percentage offset to place this <see cref="GradientStop"/>.</param>
|
||||
/// <param name="color">The <see cref="Color"/> of the <see cref="GradientStop"/>.</param>
|
||||
public GradientStop(float offset, Color color)
|
||||
{
|
||||
this.Offset = offset;
|
||||
this.Color = color;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -4,29 +4,28 @@ using System;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Presets.Decorators;
|
||||
|
||||
namespace RGB.NET.Presets.Textures.Gradients
|
||||
namespace RGB.NET.Presets.Textures.Gradients;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a basic gradient.
|
||||
/// </summary>
|
||||
public interface IGradient : IDecoratable<IGradientDecorator>
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a basic gradient.
|
||||
/// Occurs if the <see cref="IGradient"/> is changed.
|
||||
/// </summary>
|
||||
public interface IGradient : IDecoratable<IGradientDecorator>
|
||||
{
|
||||
/// <summary>
|
||||
/// Occurs if the <see cref="IGradient"/> is changed.
|
||||
/// </summary>
|
||||
event EventHandler GradientChanged;
|
||||
event EventHandler GradientChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="Color"/> of the <see cref="IGradient"/> on the specified offset.
|
||||
/// </summary>
|
||||
/// <param name="offset">The percentage offset to take the <see cref="Color"/> from.</param>
|
||||
/// <returns>The <see cref="Color"/> at the specific offset.</returns>
|
||||
Color GetColor(float offset);
|
||||
/// <summary>
|
||||
/// Gets the <see cref="Color"/> of the <see cref="IGradient"/> on the specified offset.
|
||||
/// </summary>
|
||||
/// <param name="offset">The percentage offset to take the <see cref="Color"/> from.</param>
|
||||
/// <returns>The <see cref="Color"/> at the specific offset.</returns>
|
||||
Color GetColor(float offset);
|
||||
|
||||
/// <summary>
|
||||
/// Moves the <see cref="IGradient"/> by the provided offset.
|
||||
/// </summary>
|
||||
/// <param name="offset">The offset the <see cref="IGradient"/> should be moved.</param>
|
||||
void Move(float offset);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Moves the <see cref="IGradient"/> by the provided offset.
|
||||
/// </summary>
|
||||
/// <param name="offset">The offset the <see cref="IGradient"/> should be moved.</param>
|
||||
void Move(float offset);
|
||||
}
|
||||
@@ -5,148 +5,147 @@ using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using RGB.NET.Core;
|
||||
|
||||
namespace RGB.NET.Presets.Textures.Gradients
|
||||
namespace RGB.NET.Presets.Textures.Gradients;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Represents a linear interpolated gradient with n stops.
|
||||
/// </summary>
|
||||
public class LinearGradient : AbstractGradient
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
private bool _isOrderedGradientListDirty = true;
|
||||
private LinkedList<GradientStop> _orderedGradientStops = new();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Represents a linear interpolated gradient with n stops.
|
||||
/// Initializes a new instance of the <see cref="T:RGB.NET.Presets.Textures.Gradients.LinearGradient" /> class.
|
||||
/// </summary>
|
||||
public class LinearGradient : AbstractGradient
|
||||
public LinearGradient()
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
private bool _isOrderedGradientListDirty = true;
|
||||
private LinkedList<GradientStop> _orderedGradientStops = new();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:RGB.NET.Presets.Textures.Gradients.LinearGradient" /> class.
|
||||
/// </summary>
|
||||
public LinearGradient()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:RGB.NET.Presets.Textures.Gradients.LinearGradient" /> class.
|
||||
/// </summary>
|
||||
/// <param name="gradientStops">The stops with which the gradient should be initialized.</param>
|
||||
public LinearGradient(params GradientStop[] gradientStops)
|
||||
: base(gradientStops)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:RGB.NET.Presets.Textures.Gradients.AbstractGradient" /> class.
|
||||
/// </summary>
|
||||
/// <param name="wrapGradient">Specifies whether the gradient should wrapp or not (see <see cref="P:RGB.NET.Presets.Textures.Gradients.AbstractGradient.WrapGradient" /> for an example of what this means).</param>
|
||||
/// <param name="gradientStops">The stops with which the gradient should be initialized.</param>
|
||||
public LinearGradient(bool wrapGradient, params GradientStop[] gradientStops)
|
||||
: base(wrapGradient, gradientStops)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
void OnGradientStopOnPropertyChanged(object? sender, PropertyChangedEventArgs args) => _isOrderedGradientListDirty = true;
|
||||
|
||||
foreach (GradientStop gradientStop in GradientStops)
|
||||
gradientStop.PropertyChanged += OnGradientStopOnPropertyChanged;
|
||||
|
||||
GradientStops.CollectionChanged += (_, args) =>
|
||||
{
|
||||
if (args.OldItems != null)
|
||||
foreach (GradientStop gradientStop in args.OldItems)
|
||||
gradientStop.PropertyChanged -= OnGradientStopOnPropertyChanged;
|
||||
|
||||
if (args.NewItems != null)
|
||||
foreach (GradientStop gradientStop in args.NewItems)
|
||||
gradientStop.PropertyChanged += OnGradientStopOnPropertyChanged;
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Gets the linear interpolated <see cref="T:RGB.NET.Core.Color" /> at the specified offset.
|
||||
/// </summary>
|
||||
/// <param name="offset">The percentage offset to take the color from.</param>
|
||||
/// <returns>The <see cref="T:RGB.NET.Core.Color" /> at the specific offset.</returns>
|
||||
public override Color GetColor(float offset)
|
||||
{
|
||||
if (GradientStops.Count == 0) return Color.Transparent;
|
||||
if (GradientStops.Count == 1) return GradientStops[0].Color;
|
||||
|
||||
if (_isOrderedGradientListDirty)
|
||||
_orderedGradientStops = new LinkedList<GradientStop>(GradientStops.OrderBy(x => x.Offset));
|
||||
|
||||
(GradientStop gsBefore, GradientStop gsAfter) = GetEnclosingGradientStops(offset, _orderedGradientStops, WrapGradient);
|
||||
|
||||
float blendFactor = 0;
|
||||
if (!gsBefore.Offset.Equals(gsAfter.Offset))
|
||||
blendFactor = ((offset - gsBefore.Offset) / (gsAfter.Offset - gsBefore.Offset));
|
||||
|
||||
float colA = ((gsAfter.Color.A - gsBefore.Color.A) * blendFactor) + gsBefore.Color.A;
|
||||
float colR = ((gsAfter.Color.R - gsBefore.Color.R) * blendFactor) + gsBefore.Color.R;
|
||||
float colG = ((gsAfter.Color.G - gsBefore.Color.G) * blendFactor) + gsBefore.Color.G;
|
||||
float colB = ((gsAfter.Color.B - gsBefore.Color.B) * blendFactor) + gsBefore.Color.B;
|
||||
|
||||
return new Color(colA, colR, colG, colB);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the two <see cref="GradientStop"/>s encapsulating the specified offset.
|
||||
/// </summary>
|
||||
/// <param name="offset">The reference offset.</param>
|
||||
/// <param name="orderedStops">The ordered list of <see cref="GradientStop"/> to choose from.</param>
|
||||
/// <param name="wrap">Bool indicating if the gradient should be wrapped or not.</param>
|
||||
/// <returns>The two <see cref="GradientStop"/>s encapsulating the specified offset.</returns>
|
||||
protected virtual (GradientStop gsBefore, GradientStop gsAfter) GetEnclosingGradientStops(float offset, LinkedList<GradientStop> orderedStops, bool wrap)
|
||||
{
|
||||
LinkedList<GradientStop> gradientStops = new(orderedStops);
|
||||
|
||||
if (wrap)
|
||||
{
|
||||
GradientStop? gsBefore, gsAfter;
|
||||
|
||||
do
|
||||
{
|
||||
gsBefore = gradientStops.LastOrDefault(n => n.Offset <= offset);
|
||||
if (gsBefore == null)
|
||||
{
|
||||
GradientStop lastStop = gradientStops.Last!.Value;
|
||||
gradientStops.AddFirst(new GradientStop(lastStop.Offset - 1, lastStop.Color));
|
||||
gradientStops.RemoveLast();
|
||||
}
|
||||
|
||||
gsAfter = gradientStops.FirstOrDefault(n => n.Offset >= offset);
|
||||
if (gsAfter == null)
|
||||
{
|
||||
GradientStop firstStop = gradientStops.First!.Value;
|
||||
gradientStops.AddLast(new GradientStop(firstStop.Offset + 1, firstStop.Color));
|
||||
gradientStops.RemoveFirst();
|
||||
}
|
||||
|
||||
} while ((gsBefore == null) || (gsAfter == null));
|
||||
|
||||
return (gsBefore, gsAfter);
|
||||
}
|
||||
|
||||
offset = ClipOffset(offset);
|
||||
return (gradientStops.Last(n => n.Offset <= offset), gradientStops.First(n => n.Offset >= offset));
|
||||
}
|
||||
|
||||
#endregion
|
||||
Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:RGB.NET.Presets.Textures.Gradients.LinearGradient" /> class.
|
||||
/// </summary>
|
||||
/// <param name="gradientStops">The stops with which the gradient should be initialized.</param>
|
||||
public LinearGradient(params GradientStop[] gradientStops)
|
||||
: base(gradientStops)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:RGB.NET.Presets.Textures.Gradients.AbstractGradient" /> class.
|
||||
/// </summary>
|
||||
/// <param name="wrapGradient">Specifies whether the gradient should wrapp or not (see <see cref="P:RGB.NET.Presets.Textures.Gradients.AbstractGradient.WrapGradient" /> for an example of what this means).</param>
|
||||
/// <param name="gradientStops">The stops with which the gradient should be initialized.</param>
|
||||
public LinearGradient(bool wrapGradient, params GradientStop[] gradientStops)
|
||||
: base(wrapGradient, gradientStops)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
void OnGradientStopOnPropertyChanged(object? sender, PropertyChangedEventArgs args) => _isOrderedGradientListDirty = true;
|
||||
|
||||
foreach (GradientStop gradientStop in GradientStops)
|
||||
gradientStop.PropertyChanged += OnGradientStopOnPropertyChanged;
|
||||
|
||||
GradientStops.CollectionChanged += (_, args) =>
|
||||
{
|
||||
if (args.OldItems != null)
|
||||
foreach (GradientStop gradientStop in args.OldItems)
|
||||
gradientStop.PropertyChanged -= OnGradientStopOnPropertyChanged;
|
||||
|
||||
if (args.NewItems != null)
|
||||
foreach (GradientStop gradientStop in args.NewItems)
|
||||
gradientStop.PropertyChanged += OnGradientStopOnPropertyChanged;
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Gets the linear interpolated <see cref="T:RGB.NET.Core.Color" /> at the specified offset.
|
||||
/// </summary>
|
||||
/// <param name="offset">The percentage offset to take the color from.</param>
|
||||
/// <returns>The <see cref="T:RGB.NET.Core.Color" /> at the specific offset.</returns>
|
||||
public override Color GetColor(float offset)
|
||||
{
|
||||
if (GradientStops.Count == 0) return Color.Transparent;
|
||||
if (GradientStops.Count == 1) return GradientStops[0].Color;
|
||||
|
||||
if (_isOrderedGradientListDirty)
|
||||
_orderedGradientStops = new LinkedList<GradientStop>(GradientStops.OrderBy(x => x.Offset));
|
||||
|
||||
(GradientStop gsBefore, GradientStop gsAfter) = GetEnclosingGradientStops(offset, _orderedGradientStops, WrapGradient);
|
||||
|
||||
float blendFactor = 0;
|
||||
if (!gsBefore.Offset.Equals(gsAfter.Offset))
|
||||
blendFactor = ((offset - gsBefore.Offset) / (gsAfter.Offset - gsBefore.Offset));
|
||||
|
||||
float colA = ((gsAfter.Color.A - gsBefore.Color.A) * blendFactor) + gsBefore.Color.A;
|
||||
float colR = ((gsAfter.Color.R - gsBefore.Color.R) * blendFactor) + gsBefore.Color.R;
|
||||
float colG = ((gsAfter.Color.G - gsBefore.Color.G) * blendFactor) + gsBefore.Color.G;
|
||||
float colB = ((gsAfter.Color.B - gsBefore.Color.B) * blendFactor) + gsBefore.Color.B;
|
||||
|
||||
return new Color(colA, colR, colG, colB);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the two <see cref="GradientStop"/>s encapsulating the specified offset.
|
||||
/// </summary>
|
||||
/// <param name="offset">The reference offset.</param>
|
||||
/// <param name="orderedStops">The ordered list of <see cref="GradientStop"/> to choose from.</param>
|
||||
/// <param name="wrap">Bool indicating if the gradient should be wrapped or not.</param>
|
||||
/// <returns>The two <see cref="GradientStop"/>s encapsulating the specified offset.</returns>
|
||||
protected virtual (GradientStop gsBefore, GradientStop gsAfter) GetEnclosingGradientStops(float offset, LinkedList<GradientStop> orderedStops, bool wrap)
|
||||
{
|
||||
LinkedList<GradientStop> gradientStops = new(orderedStops);
|
||||
|
||||
if (wrap)
|
||||
{
|
||||
GradientStop? gsBefore, gsAfter;
|
||||
|
||||
do
|
||||
{
|
||||
gsBefore = gradientStops.LastOrDefault(n => n.Offset <= offset);
|
||||
if (gsBefore == null)
|
||||
{
|
||||
GradientStop lastStop = gradientStops.Last!.Value;
|
||||
gradientStops.AddFirst(new GradientStop(lastStop.Offset - 1, lastStop.Color));
|
||||
gradientStops.RemoveLast();
|
||||
}
|
||||
|
||||
gsAfter = gradientStops.FirstOrDefault(n => n.Offset >= offset);
|
||||
if (gsAfter == null)
|
||||
{
|
||||
GradientStop firstStop = gradientStops.First!.Value;
|
||||
gradientStops.AddLast(new GradientStop(firstStop.Offset + 1, firstStop.Color));
|
||||
gradientStops.RemoveFirst();
|
||||
}
|
||||
|
||||
} while ((gsBefore == null) || (gsAfter == null));
|
||||
|
||||
return (gsBefore, gsAfter);
|
||||
}
|
||||
|
||||
offset = ClipOffset(offset);
|
||||
return (gradientStops.Last(n => n.Offset <= offset), gradientStops.First(n => n.Offset >= offset));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -5,105 +5,104 @@ using System;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Presets.Decorators;
|
||||
|
||||
namespace RGB.NET.Presets.Textures.Gradients
|
||||
namespace RGB.NET.Presets.Textures.Gradients;
|
||||
|
||||
/// <inheritdoc cref="AbstractDecoratable{T}" />
|
||||
/// <inheritdoc cref="IGradient" />
|
||||
/// <summary>
|
||||
/// Represents a rainbow gradient which circles through all colors of the HUE-color-space.<br />
|
||||
/// See <see href="http://upload.wikimedia.org/wikipedia/commons/a/ad/HueScale.svg" /> as reference.
|
||||
/// </summary>
|
||||
public class RainbowGradient : AbstractDecoratable<IGradientDecorator>, IGradient
|
||||
{
|
||||
/// <inheritdoc cref="AbstractDecoratable{T}" />
|
||||
/// <inheritdoc cref="IGradient" />
|
||||
#region Properties & Fields
|
||||
|
||||
private float _startHue;
|
||||
/// <summary>
|
||||
/// Represents a rainbow gradient which circles through all colors of the HUE-color-space.<br />
|
||||
/// See <see href="http://upload.wikimedia.org/wikipedia/commons/a/ad/HueScale.svg" /> as reference.
|
||||
/// Gets or sets the hue (in degrees) to start from.
|
||||
/// </summary>
|
||||
public class RainbowGradient : AbstractDecoratable<IGradientDecorator>, IGradient
|
||||
public float StartHue
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
private float _startHue;
|
||||
/// <summary>
|
||||
/// Gets or sets the hue (in degrees) to start from.
|
||||
/// </summary>
|
||||
public float StartHue
|
||||
{
|
||||
get => _startHue;
|
||||
set => SetProperty(ref _startHue, value);
|
||||
}
|
||||
|
||||
private float _endHue;
|
||||
/// <summary>
|
||||
/// Gets or sets the hue (in degrees) to end the with.
|
||||
/// </summary>
|
||||
public float EndHue
|
||||
{
|
||||
get => _endHue;
|
||||
set => SetProperty(ref _endHue, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler? GradientChanged;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RainbowGradient"/> class.
|
||||
/// </summary>
|
||||
/// <param name="startHue">The hue (in degrees) to start from (default: 0)</param>
|
||||
/// <param name="endHue">The hue (in degrees) to end with (default: 360)</param>
|
||||
public RainbowGradient(float startHue = 0, float endHue = 360)
|
||||
{
|
||||
this.StartHue = startHue;
|
||||
this.EndHue = endHue;
|
||||
|
||||
PropertyChanged += (_, _) => OnGradientChanged();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Gets the color on the rainbow at the specified offset.
|
||||
/// </summary>
|
||||
/// <param name="offset">The percentage offset to take the color from.</param>
|
||||
/// <returns>The color at the specific offset.</returns>
|
||||
public Color GetColor(float offset)
|
||||
{
|
||||
float range = EndHue - StartHue;
|
||||
float hue = StartHue + (range * offset);
|
||||
return HSVColor.Create(hue, 1, 1);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Move(float offset)
|
||||
{
|
||||
// RainbowGradient is calculated inverse
|
||||
offset *= -1;
|
||||
|
||||
StartHue += offset;
|
||||
EndHue += offset;
|
||||
|
||||
while ((StartHue > 360) && (EndHue > 360))
|
||||
{
|
||||
StartHue -= 360;
|
||||
EndHue -= 360;
|
||||
}
|
||||
while ((StartHue < -360) && (EndHue < -360))
|
||||
{
|
||||
StartHue += 360;
|
||||
EndHue += 360;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Should be called to indicate that the gradient was changed.
|
||||
/// </summary>
|
||||
protected void OnGradientChanged() => GradientChanged?.Invoke(this, EventArgs.Empty);
|
||||
|
||||
#endregion
|
||||
get => _startHue;
|
||||
set => SetProperty(ref _startHue, value);
|
||||
}
|
||||
}
|
||||
|
||||
private float _endHue;
|
||||
/// <summary>
|
||||
/// Gets or sets the hue (in degrees) to end the with.
|
||||
/// </summary>
|
||||
public float EndHue
|
||||
{
|
||||
get => _endHue;
|
||||
set => SetProperty(ref _endHue, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler? GradientChanged;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RainbowGradient"/> class.
|
||||
/// </summary>
|
||||
/// <param name="startHue">The hue (in degrees) to start from (default: 0)</param>
|
||||
/// <param name="endHue">The hue (in degrees) to end with (default: 360)</param>
|
||||
public RainbowGradient(float startHue = 0, float endHue = 360)
|
||||
{
|
||||
this.StartHue = startHue;
|
||||
this.EndHue = endHue;
|
||||
|
||||
PropertyChanged += (_, _) => OnGradientChanged();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Gets the color on the rainbow at the specified offset.
|
||||
/// </summary>
|
||||
/// <param name="offset">The percentage offset to take the color from.</param>
|
||||
/// <returns>The color at the specific offset.</returns>
|
||||
public Color GetColor(float offset)
|
||||
{
|
||||
float range = EndHue - StartHue;
|
||||
float hue = StartHue + (range * offset);
|
||||
return HSVColor.Create(hue, 1, 1);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Move(float offset)
|
||||
{
|
||||
// RainbowGradient is calculated inverse
|
||||
offset *= -1;
|
||||
|
||||
StartHue += offset;
|
||||
EndHue += offset;
|
||||
|
||||
while ((StartHue > 360) && (EndHue > 360))
|
||||
{
|
||||
StartHue -= 360;
|
||||
EndHue -= 360;
|
||||
}
|
||||
while ((StartHue < -360) && (EndHue < -360))
|
||||
{
|
||||
StartHue += 360;
|
||||
EndHue += 360;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Should be called to indicate that the gradient was changed.
|
||||
/// </summary>
|
||||
protected void OnGradientChanged() => GradientChanged?.Invoke(this, EventArgs.Empty);
|
||||
|
||||
#endregion
|
||||
}
|
||||
Reference in new issue
Block a user