Brushes - Added brush presets

ColorGradient - Refactored so it implements IList
This commit is contained in:
Robert committed 2021-04-05 22:05:45 +02:00
1 parent e32b181d9f
commit 3d38461bdd
18 files changed
+722 -419

No files matched your search

@@ -1,4 +1,5 @@
using System.ComponentModel;
using System.Collections.Specialized;
using System.ComponentModel;
using SkiaSharp;
namespace Artemis.Core
@@ -23,17 +24,16 @@ namespace Artemis.Core
if (CurrentValue == null)
return;
for (int index = 0; index < CurrentValue.Stops.Count; index++)
for (int index = 0; index < CurrentValue.Count; index++)
{
int stopIndex = index;
void Setter(SKColor value)
{
CurrentValue.Stops[stopIndex].Color = value;
CurrentValue.OnColorValuesUpdated();
CurrentValue[stopIndex].Color = value;
}
RegisterDataBindingProperty(() => CurrentValue.Stops[stopIndex].Color, Setter, new ColorStopDataBindingConverter(), $"Color #{stopIndex + 1}");
RegisterDataBindingProperty(() => CurrentValue[stopIndex].Color, Setter, new ColorStopDataBindingConverter(), $"Color #{stopIndex + 1}");
}
}
@@ -61,17 +61,17 @@ namespace Artemis.Core
if (_subscribedGradient != BaseValue)
{
if (_subscribedGradient != null)
_subscribedGradient.PropertyChanged -= SubscribedGradientOnPropertyChanged;
_subscribedGradient.CollectionChanged -= SubscribedGradientOnPropertyChanged;
_subscribedGradient = BaseValue;
_subscribedGradient.PropertyChanged += SubscribedGradientOnPropertyChanged;
_subscribedGradient.CollectionChanged += SubscribedGradientOnPropertyChanged;
}
CreateDataBindingRegistrations();
}
private void SubscribedGradientOnPropertyChanged(object? sender, PropertyChangedEventArgs e)
private void SubscribedGradientOnPropertyChanged(object? sender, NotifyCollectionChangedEventArgs args)
{
if (CurrentValue.Stops.Count != GetAllDataBindingRegistrations().Count)
if (CurrentValue.Count != GetAllDataBindingRegistrations().Count)
CreateDataBindingRegistrations();
}
@@ -1,5 +1,8 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using SkiaSharp;
@@ -8,7 +11,7 @@ namespace Artemis.Core
/// <summary>
/// A gradient containing a list of <see cref="ColorGradientStop" />s
/// </summary>
public class ColorGradient : CorePropertyChanged
public class ColorGradient : IList<ColorGradientStop>, INotifyCollectionChanged
{
private static readonly SKColor[] FastLedRainbow =
{
@@ -23,19 +26,16 @@ namespace Artemis.Core
new(0xFFFF0000) // and back to Red
};
private readonly List<ColorGradientStop> _stops;
/// <summary>
/// Creates a new instance of the <see cref="ColorGradient" /> class
/// </summary>
public ColorGradient()
{
Stops = new List<ColorGradientStop>();
_stops = new List<ColorGradientStop>();
}
/// <summary>
/// Gets a list of all the <see cref="ColorGradientStop" />s in the gradient
/// </summary>
public List<ColorGradientStop> Stops { get; }
/// <summary>
/// Gets all the colors in the color gradient
/// </summary>
@@ -49,13 +49,16 @@ namespace Artemis.Core
{
List<SKColor> result = new();
if (timesToRepeat == 0)
result = Stops.Select(c => c.Color).ToList();
{
result = this.Select(c => c.Color).ToList();
}
else
{
List<SKColor> colors = Stops.Select(c => c.Color).ToList();
List<SKColor> colors = this.Select(c => c.Color).ToList();
for (int i = 0; i <= timesToRepeat; i++)
result.AddRange(colors);
}
if (seamless && !IsSeamless())
result.Add(result[0]);
@@ -77,11 +80,13 @@ namespace Artemis.Core
{
List<float> result = new();
if (timesToRepeat == 0)
result = Stops.Select(c => c.Position).ToList();
{
result = this.Select(c => c.Position).ToList();
}
else
{
// Create stops and a list of divided stops
List<float> stops = Stops.Select(c => c.Position / (timesToRepeat + 1)).ToList();
List<float> stops = this.Select(c => c.Position / (timesToRepeat + 1)).ToList();
// For each repeat cycle, add the base stops to the end result
for (int i = 0; i <= timesToRepeat; i++)
@@ -104,25 +109,16 @@ namespace Artemis.Core
return result.ToArray();
}
/// <summary>
/// Triggers a property changed event of the <see cref="Stops" /> collection
/// </summary>
public void OnColorValuesUpdated()
{
Stops.Sort((a, b) => a.Position.CompareTo(b.Position));
OnPropertyChanged(nameof(Stops));
}
/// <summary>
/// Gets a color at any position between 0.0 and 1.0 using interpolation
/// </summary>
/// <param name="position">A position between 0.0 and 1.0</param>
public SKColor GetColor(float position)
{
if (!Stops.Any())
if (!this.Any())
return SKColor.Empty;
ColorGradientStop[] stops = Stops.ToArray();
ColorGradientStop[] stops = this.ToArray();
if (position <= 0) return stops[0].Color;
if (position >= 1) return stops[^1].Color;
ColorGradientStop left = stops[0];
@@ -160,7 +156,7 @@ namespace Artemis.Core
{
SKColor skColor = FastLedRainbow[index];
float position = 1f / (FastLedRainbow.Length - 1f) * index;
gradient.Stops.Add(new ColorGradientStop(skColor, position));
gradient.Add(new ColorGradientStop(skColor, position));
}
return gradient;
@@ -172,7 +168,141 @@ namespace Artemis.Core
/// <returns><see langword="true" /> if the gradient is seamless; <see langword="false" /> otherwise</returns>
public bool IsSeamless()
{
return Stops.Count == 0 || Stops.First().Color.Equals(Stops.Last().Color);
return Count == 0 || this.First().Color.Equals(this.Last().Color);
}
internal void Sort()
{
_stops.Sort((a, b) => a.Position.CompareTo(b.Position));
}
private void ItemOnPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
Sort();
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
#region Implementation of IEnumerable
/// <inheritdoc />
public IEnumerator<ColorGradientStop> GetEnumerator()
{
return _stops.GetEnumerator();
}
/// <inheritdoc />
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
#region Implementation of ICollection<ColorGradientStop>
/// <inheritdoc />
public void Add(ColorGradientStop item)
{
_stops.Add(item);
item.PropertyChanged += ItemOnPropertyChanged;
Sort();
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, _stops.IndexOf(item)));
}
/// <inheritdoc />
public void Clear()
{
foreach (ColorGradientStop item in _stops)
item.PropertyChanged -= ItemOnPropertyChanged;
_stops.Clear();
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
/// <inheritdoc />
public bool Contains(ColorGradientStop item)
{
return _stops.Contains(item);
}
/// <inheritdoc />
public void CopyTo(ColorGradientStop[] array, int arrayIndex)
{
_stops.CopyTo(array, arrayIndex);
}
/// <inheritdoc />
public bool Remove(ColorGradientStop item)
{
item.PropertyChanged -= ItemOnPropertyChanged;
int index = _stops.IndexOf(item);
bool removed = _stops.Remove(item);
if (removed)
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index));
return removed;
}
/// <inheritdoc />
public int Count => _stops.Count;
/// <inheritdoc />
public bool IsReadOnly => false;
#endregion
#region Implementation of IList<ColorGradientStop>
/// <inheritdoc />
public int IndexOf(ColorGradientStop item)
{
return _stops.IndexOf(item);
}
/// <inheritdoc />
public void Insert(int index, ColorGradientStop item)
{
_stops.Insert(index, item);
item.PropertyChanged += ItemOnPropertyChanged;
Sort();
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, _stops.IndexOf(item)));
}
/// <inheritdoc />
public void RemoveAt(int index)
{
_stops[index].PropertyChanged -= ItemOnPropertyChanged;
_stops.RemoveAt(index);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, index));
}
/// <inheritdoc />
public ColorGradientStop this[int index]
{
get => _stops[index];
set
{
ColorGradientStop? oldValue = _stops[index];
oldValue.PropertyChanged -= ItemOnPropertyChanged;
_stops[index] = value;
_stops[index].PropertyChanged += ItemOnPropertyChanged;
Sort();
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, value, oldValue));
}
}
#endregion
#region Implementation of INotifyCollectionChanged
/// <inheritdoc />
public event NotifyCollectionChangedEventHandler? CollectionChanged;
private void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
CollectionChanged?.Invoke(this, e);
}
#endregion
}
}
+3
View File
@@ -297,6 +297,9 @@ namespace Artemis.Core
private void ApplyTimeline(Timeline timeline)
{
if (timeline.Delta == TimeSpan.Zero)
return;
General.Update(timeline);
Transform.Update(timeline);
if (LayerBrush != null)
@@ -33,6 +33,11 @@ namespace Artemis.Core
/// </summary>
Type PropertyType { get; }
/// <summary>
/// Indicates whether the BaseValue was loaded from storage, useful to check whether a default value must be applied
/// </summary>
bool IsLoadedFromStorage { get; }
/// <summary>
/// Initializes the layer property
/// <para>
@@ -0,0 +1,28 @@
namespace Artemis.Core.LayerBrushes
{
/// <summary>
/// Represents a brush preset for a brush.
/// </summary>
public interface ILayerBrushPreset
{
/// <summary>
/// Gets the name of the preset
/// </summary>
string Name { get; }
/// <summary>
/// Gets the description of the preset
/// </summary>
string Description { get; }
/// <summary>
/// Gets the icon of the preset
/// </summary>
string Icon { get; }
/// <summary>
/// Applies the preset to the layer brush
/// </summary>
void Apply();
}
}
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using SkiaSharp;
namespace Artemis.Core.LayerBrushes
@@ -70,6 +72,16 @@ namespace Artemis.Core.LayerBrushes
/// </summary>
public virtual LayerPropertyGroup? BaseProperties => null;
/// <summary>
/// Gets a list of presets available to this layer brush
/// </summary>
public virtual List<ILayerBrushPreset>? Presets => null;
/// <summary>
/// Gets the default preset used for new instances of this layer brush
/// </summary>
public virtual ILayerBrushPreset? DefaultPreset => Presets?.FirstOrDefault();
/// <summary>
/// Gets or sets whether the brush supports transformations
/// <para>Note: RGB.NET brushes can never be transformed and setting this to true will throw an exception</para>
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Artemis.Core.LayerBrushes
{