using System;
using System.Collections.Specialized;
using System.Linq;
using System.Windows.Input;
using Artemis.Core;
using Artemis.UI.Shared.Providers;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Data;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Media;
using FluentAvalonia.UI.Controls;
using FluentAvalonia.UI.Media;
using ReactiveUI;
using Button = Avalonia.Controls.Button;
namespace Artemis.UI.Shared.GradientPicker;
///
/// Represents a gradient picker that can be used to edit a gradient.
///
public class GradientPicker : TemplatedControl
{
///
/// Gets or sets the color gradient.
///
public static readonly StyledProperty ColorGradientProperty =
AvaloniaProperty.Register(nameof(ColorGradient), notifying: ColorGradientChanged, defaultValue: ColorGradient.GetUnicornBarf());
///
/// Gets or sets the currently selected color stop.
///
public static readonly StyledProperty SelectedColorStopProperty =
AvaloniaProperty.Register(nameof(SelectedColorStop), defaultBindingMode: BindingMode.TwoWay);
///
/// Gets or sets a boolean indicating whether the gradient picker should be in compact mode or not.
///
public static readonly StyledProperty IsCompactProperty =
AvaloniaProperty.Register(nameof(IsCompact), defaultBindingMode: BindingMode.TwoWay);
///
/// Gets or sets a storage provider to use for storing and loading gradients.
///
public static readonly StyledProperty StorageProviderProperty =
AvaloniaProperty.Register(nameof(StorageProvider), notifying: StorageProviderChanged);
///
/// Gets the linear gradient brush representing the color gradient.
///
public static readonly DirectProperty LinearGradientBrushProperty =
AvaloniaProperty.RegisterDirect(nameof(LinearGradientBrush), g => g.LinearGradientBrush);
///
/// Gets the command to execute when deleting stops.
///
public static readonly DirectProperty DeleteStopProperty =
AvaloniaProperty.RegisterDirect(nameof(DeleteStop), g => g.DeleteStop);
private readonly ICommand _deleteStop;
private bool _shiftDown;
private Button? _flipStops;
private Border? _gradient;
private Button? _rotateStops;
private Button? _spreadStops;
private Button? _toggleSeamless;
private Button? _randomize;
private ColorGradient? _lastColorGradient;
private ColorPicker? _colorPicker;
///
/// Creates a new instance of the class.
///
public GradientPicker()
{
_deleteStop = ReactiveCommand.Create(s =>
{
if (ColorGradient.Count <= 2)
return;
int index = ColorGradient.IndexOf(s);
ColorGradient.Remove(s);
if (index > ColorGradient.Count - 1)
index--;
SelectedColorStop = ColorGradient.ElementAtOrDefault(index);
});
}
///
/// Gets or sets the color gradient.
///
public ColorGradient ColorGradient
{
get => GetValue(ColorGradientProperty);
set => SetValue(ColorGradientProperty, value);
}
///
/// Gets or sets the currently selected color stop.
///
public ColorGradientStop? SelectedColorStop
{
get => GetValue(SelectedColorStopProperty);
set
{
if (_colorPicker != null && SelectedColorStop != null)
_colorPicker.PreviousColor = new Color2(SelectedColorStop.Color.Red, SelectedColorStop.Color.Green, SelectedColorStop.Color.Blue, SelectedColorStop.Color.Alpha);
SetValue(SelectedColorStopProperty, value);
}
}
///
/// Gets or sets a boolean indicating whether the gradient picker should be in compact mode or not.
///
public bool IsCompact
{
get => GetValue(IsCompactProperty);
set => SetValue(IsCompactProperty, value);
}
///
/// Gets or sets a storage provider to use for storing and loading gradients.
///
public IColorGradientStorageProvider? StorageProvider
{
get => GetValue(StorageProviderProperty);
set => SetValue(StorageProviderProperty, value);
}
///
/// Gets the linear gradient brush representing the color gradient.
///
public LinearGradientBrush LinearGradientBrush { get; } = new();
///
/// Gets the command to execute when deleting stops.
///
public ICommand DeleteStop
{
get => _deleteStop;
private init => SetAndRaise(DeleteStopProperty, ref _deleteStop, value);
}
///
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
if (_gradient != null)
_gradient.PointerPressed -= GradientOnPointerPressed;
if (_spreadStops != null)
_spreadStops.Click -= SpreadStopsOnClick;
if (_toggleSeamless != null)
_toggleSeamless.Click -= ToggleSeamlessOnClick;
if (_flipStops != null)
_flipStops.Click -= FlipStopsOnClick;
if (_rotateStops != null)
_rotateStops.Click -= RotateStopsOnClick;
if (_randomize != null)
_randomize.Click -= RandomizeOnClick;
_colorPicker = e.NameScope.Find("ColorPicker");
_gradient = e.NameScope.Find("Gradient");
_spreadStops = e.NameScope.Find