Color picker - Avoid overlapping colors

This commit is contained in:
Robert committed 2022-08-22 20:24:08 +02:00
1 parent 212d13c1c8
commit 3efb97eedd
4 files changed
+104 -3

No files matched your search

@@ -51,6 +51,7 @@ public class ColorGradient : IList<ColorGradientStop>, IList, INotifyCollectionC
{
ColorGradientStop stop = new(colorGradientStop.Color, colorGradientStop.Position);
stop.PropertyChanged += ItemOnPropertyChanged;
stop.ColorGradient = this;
_stops.Add(stop);
}
}
@@ -66,6 +67,7 @@ public class ColorGradient : IList<ColorGradientStop>, IList, INotifyCollectionC
{
ColorGradientStop stop = new(colorGradientStop.Color, colorGradientStop.Position);
stop.PropertyChanged += ItemOnPropertyChanged;
stop.ColorGradient = this;
_stops.Add(stop);
}
}
@@ -465,6 +467,7 @@ public class ColorGradient : IList<ColorGradientStop>, IList, INotifyCollectionC
public void Add(ColorGradientStop item)
{
_stops.Add(item);
item.ColorGradient = this;
item.PropertyChanged += ItemOnPropertyChanged;
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, _stops.IndexOf(item)));
@@ -1,4 +1,5 @@
using System;
using System.Linq;
using SkiaSharp;
namespace Artemis.Core;
@@ -35,9 +36,11 @@ public class ColorGradientStop : CorePropertyChanged
public float Position
{
get => _position;
set => SetAndNotify(ref _position, value);
set => SetAndNotify(ref _position, GetUpdatedPosition(value));
}
internal ColorGradient? ColorGradient { get; set; }
#region Equality members
/// <inheritdoc cref="object.Equals(object)" />
@@ -64,5 +67,32 @@ public class ColorGradientStop : CorePropertyChanged
return HashCode.Combine(_color, _position);
}
/// <summary>
/// Gets the position of the given color stop in a safe manner that avoids overlap with other stops.
/// </summary>
/// <param name="stopPosition">The new position.</param>
private float GetUpdatedPosition(float stopPosition)
{
if (ColorGradient == null)
return stopPosition;
// Find the first available spot going down
while (ColorGradient.Any(s => !ReferenceEquals(s, this) && Math.Abs(s.Position - stopPosition) < 0.001f))
stopPosition -= 0.001f;
// If we ran out of space, try going up
if (stopPosition < 0)
{
stopPosition = 0;
while (ColorGradient.Any(s => !ReferenceEquals(s, this) && Math.Abs(s.Position - stopPosition) < 0.001f))
stopPosition += 0.001f;
}
// If we ran out of space there too, movement isn't possible
if (stopPosition > 1)
stopPosition = Position;
return stopPosition;
}
#endregion
}