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