mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-31 17:53:32 +00:00
Gradient editor - Initial implementation
This commit is contained in:
parent
09e7bb5168
commit
1262f84a56
@ -11,7 +11,7 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A gradient containing a list of <see cref="ColorGradientStop" />s
|
/// A gradient containing a list of <see cref="ColorGradientStop" />s
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ColorGradient : IList<ColorGradientStop>, INotifyCollectionChanged
|
public class ColorGradient : IList<ColorGradientStop>, IList, INotifyCollectionChanged
|
||||||
{
|
{
|
||||||
private static readonly SKColor[] FastLedRainbow =
|
private static readonly SKColor[] FastLedRainbow =
|
||||||
{
|
{
|
||||||
@ -173,13 +173,25 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
internal void Sort()
|
internal void Sort()
|
||||||
{
|
{
|
||||||
_stops.Sort((a, b) => a.Position.CompareTo(b.Position));
|
int requiredIndex = 0;
|
||||||
|
foreach (ColorGradientStop colorGradientStop in _stops.OrderBy(s => s.Position).ToList())
|
||||||
|
{
|
||||||
|
int actualIndex = _stops.IndexOf(colorGradientStop);
|
||||||
|
if (requiredIndex != actualIndex)
|
||||||
|
{
|
||||||
|
_stops.RemoveAt(actualIndex);
|
||||||
|
_stops.Insert(requiredIndex, colorGradientStop);
|
||||||
|
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, colorGradientStop, requiredIndex, actualIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
requiredIndex++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ItemOnPropertyChanged(object? sender, PropertyChangedEventArgs e)
|
private void ItemOnPropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
Sort();
|
Sort();
|
||||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
OnStopChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Implementation of IEnumerable
|
#region Implementation of IEnumerable
|
||||||
@ -209,8 +221,16 @@ namespace Artemis.Core
|
|||||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, _stops.IndexOf(item)));
|
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, _stops.IndexOf(item)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
public int Add(object? value)
|
||||||
|
{
|
||||||
|
if (value is ColorGradientStop stop)
|
||||||
|
_stops.Add(stop);
|
||||||
|
|
||||||
|
return IndexOf(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IList.Clear" />
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
foreach (ColorGradientStop item in _stops)
|
foreach (ColorGradientStop item in _stops)
|
||||||
@ -219,6 +239,32 @@ namespace Artemis.Core
|
|||||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public bool Contains(object? value)
|
||||||
|
{
|
||||||
|
return _stops.Contains(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public int IndexOf(object? value)
|
||||||
|
{
|
||||||
|
return _stops.IndexOf(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Insert(int index, object? value)
|
||||||
|
{
|
||||||
|
if (value is ColorGradientStop stop)
|
||||||
|
_stops.Insert(index, stop);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Remove(object? value)
|
||||||
|
{
|
||||||
|
if (value is ColorGradientStop stop)
|
||||||
|
_stops.Remove(stop);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool Contains(ColorGradientStop item)
|
public bool Contains(ColorGradientStop item)
|
||||||
{
|
{
|
||||||
@ -244,11 +290,29 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
public void CopyTo(Array array, int index)
|
||||||
|
{
|
||||||
|
_stops.CopyTo((ColorGradientStop[]) array, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="ICollection{T}.Count" />
|
||||||
public int Count => _stops.Count;
|
public int Count => _stops.Count;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
public bool IsSynchronized => false;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public object SyncRoot => this;
|
||||||
|
|
||||||
|
/// <inheritdoc cref="ICollection{T}.IsReadOnly" />
|
||||||
public bool IsReadOnly => false;
|
public bool IsReadOnly => false;
|
||||||
|
|
||||||
|
object? IList.this[int index]
|
||||||
|
{
|
||||||
|
get => this[index];
|
||||||
|
set => this[index] = (ColorGradientStop) value!;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Implementation of IList<ColorGradientStop>
|
#region Implementation of IList<ColorGradientStop>
|
||||||
@ -268,7 +332,7 @@ namespace Artemis.Core
|
|||||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, _stops.IndexOf(item)));
|
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, _stops.IndexOf(item)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc cref="IList{T}.RemoveAt" />
|
||||||
public void RemoveAt(int index)
|
public void RemoveAt(int index)
|
||||||
{
|
{
|
||||||
_stops[index].PropertyChanged -= ItemOnPropertyChanged;
|
_stops[index].PropertyChanged -= ItemOnPropertyChanged;
|
||||||
@ -276,6 +340,8 @@ namespace Artemis.Core
|
|||||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, index));
|
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsFixedSize { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ColorGradientStop this[int index]
|
public ColorGradientStop this[int index]
|
||||||
{
|
{
|
||||||
@ -304,5 +370,15 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when any of the stops has changed in some way
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler? StopChanged;
|
||||||
|
|
||||||
|
private void OnStopChanged()
|
||||||
|
{
|
||||||
|
StopChanged?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,135 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.Linq;
|
||||||
|
using Artemis.Core;
|
||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls.Primitives;
|
||||||
|
using Avalonia.Data;
|
||||||
|
using Avalonia.Input;
|
||||||
|
using Avalonia.Media;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Shared.Controls.GradientPicker;
|
||||||
|
|
||||||
|
public class GradientPicker : TemplatedControl
|
||||||
|
{
|
||||||
|
private LinearGradientBrush _linearGradientBrush = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the color gradient.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly StyledProperty<ColorGradient> ColorGradientProperty =
|
||||||
|
AvaloniaProperty.Register<GradientPicker, ColorGradient>(nameof(Core.ColorGradient), notifying: ColorGradientChanged, defaultValue: ColorGradient.GetUnicornBarf());
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the currently selected color stop.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly StyledProperty<ColorGradientStop?> SelectedColorStopProperty =
|
||||||
|
AvaloniaProperty.Register<GradientPicker, ColorGradientStop?>(nameof(SelectedColorStop), defaultBindingMode: BindingMode.TwoWay);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the linear gradient brush representing the color gradient.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DirectProperty<GradientPicker, LinearGradientBrush> LinearGradientBrushProperty =
|
||||||
|
AvaloniaProperty.RegisterDirect<GradientPicker, LinearGradientBrush>(nameof(LinearGradientBrush), g => g.LinearGradientBrush);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the color gradient.
|
||||||
|
/// </summary>
|
||||||
|
public ColorGradient ColorGradient
|
||||||
|
{
|
||||||
|
get => GetValue(ColorGradientProperty);
|
||||||
|
set => SetValue(ColorGradientProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the currently selected color stop.
|
||||||
|
/// </summary>
|
||||||
|
public ColorGradientStop? SelectedColorStop
|
||||||
|
{
|
||||||
|
get => GetValue(SelectedColorStopProperty);
|
||||||
|
set => SetValue(SelectedColorStopProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the linear gradient brush representing the color gradient.
|
||||||
|
/// </summary>
|
||||||
|
public LinearGradientBrush LinearGradientBrush
|
||||||
|
{
|
||||||
|
get => _linearGradientBrush;
|
||||||
|
private set => SetAndRaise(LinearGradientBrushProperty, ref _linearGradientBrush, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ColorGradientChanged(IAvaloniaObject sender, bool before)
|
||||||
|
{
|
||||||
|
if (before)
|
||||||
|
(sender as GradientPicker)?.Unsubscribe();
|
||||||
|
else
|
||||||
|
(sender as GradientPicker)?.Subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Subscribe()
|
||||||
|
{
|
||||||
|
ColorGradient.CollectionChanged += ColorGradientOnCollectionChanged;
|
||||||
|
ColorGradient.StopChanged += ColorGradientOnStopChanged;
|
||||||
|
|
||||||
|
UpdateGradient();
|
||||||
|
SelectedColorStop = ColorGradient.FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Unsubscribe()
|
||||||
|
{
|
||||||
|
ColorGradient.CollectionChanged -= ColorGradientOnCollectionChanged;
|
||||||
|
ColorGradient.StopChanged -= ColorGradientOnStopChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ColorGradientOnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
UpdateGradient();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ColorGradientOnStopChanged(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
UpdateGradient();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateGradient()
|
||||||
|
{
|
||||||
|
// Remove old stops
|
||||||
|
|
||||||
|
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
|
||||||
|
if (ColorGradient == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Add new stops
|
||||||
|
|
||||||
|
// Update the display gradient
|
||||||
|
GradientStops collection = new();
|
||||||
|
foreach (ColorGradientStop c in ColorGradient.OrderBy(s => s.Position))
|
||||||
|
collection.Add(new GradientStop(Color.FromArgb(c.Color.Alpha, c.Color.Red, c.Color.Green, c.Color.Blue), c.Position));
|
||||||
|
LinearGradientBrush = new LinearGradientBrush {GradientStops = collection};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SelectColorStop(object? sender, PointerReleasedEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is IDataContextProvider dataContextProvider && dataContextProvider.DataContext is ColorGradientStop colorStop)
|
||||||
|
SelectedColorStop = colorStop;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Overrides of Visual
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
|
||||||
|
{
|
||||||
|
Subscribe();
|
||||||
|
base.OnAttachedToVisualTree(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
|
||||||
|
{
|
||||||
|
Unsubscribe();
|
||||||
|
base.OnDetachedFromVisualTree(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@ -0,0 +1,199 @@
|
|||||||
|
using System;
|
||||||
|
using Artemis.Core;
|
||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Controls.Metadata;
|
||||||
|
using Avalonia.Controls.Primitives;
|
||||||
|
using Avalonia.Input;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Shared.Controls.GradientPicker;
|
||||||
|
|
||||||
|
public class GradientPickerColorStop : TemplatedControl
|
||||||
|
{
|
||||||
|
private static ColorGradientStop? _draggingStop;
|
||||||
|
private static IPointer? _dragPointer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the gradient picker.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly StyledProperty<GradientPicker?> GradientPickerProperty =
|
||||||
|
AvaloniaProperty.Register<GradientPickerColorStop, GradientPicker?>(nameof(GradientPicker), notifying: Notifying);
|
||||||
|
|
||||||
|
private static void Notifying(IAvaloniaObject sender, bool before)
|
||||||
|
{
|
||||||
|
if (sender is not GradientPickerColorStop self)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (before && self.GradientPicker != null)
|
||||||
|
self.GradientPicker.PropertyChanged -= self.GradientPickerOnPropertyChanged;
|
||||||
|
else if (self.GradientPicker != null)
|
||||||
|
self.GradientPicker.PropertyChanged += self.GradientPickerOnPropertyChanged;
|
||||||
|
|
||||||
|
self.IsSelected = self.GradientPicker?.SelectedColorStop == self.ColorStop;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the color stop.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly StyledProperty<ColorGradientStop> ColorStopProperty =
|
||||||
|
AvaloniaProperty.Register<GradientPickerColorStop, ColorGradientStop>(nameof(ColorStop));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the position reference to use when positioning and dragging this color stop.
|
||||||
|
/// <para>If <see langword="null" /> then dragging is not enabled.</para>
|
||||||
|
/// </summary>
|
||||||
|
public static readonly StyledProperty<IControl?> PositionReferenceProperty =
|
||||||
|
AvaloniaProperty.Register<GradientPickerColorStop, IControl?>(nameof(PositionReference));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the linear gradient brush representing the color gradient.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DirectProperty<GradientPickerColorStop, bool> IsSelectedProperty =
|
||||||
|
AvaloniaProperty.RegisterDirect<GradientPickerColorStop, bool>(nameof(IsSelected), g => g.IsSelected);
|
||||||
|
|
||||||
|
private bool _isSelected;
|
||||||
|
private double _dragOffset;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the gradient picker.
|
||||||
|
/// </summary>
|
||||||
|
public GradientPicker? GradientPicker
|
||||||
|
{
|
||||||
|
get => GetValue(GradientPickerProperty);
|
||||||
|
set => SetValue(GradientPickerProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the color stop.
|
||||||
|
/// </summary>
|
||||||
|
public ColorGradientStop ColorStop
|
||||||
|
{
|
||||||
|
get => GetValue(ColorStopProperty);
|
||||||
|
set => SetValue(ColorStopProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the position reference to use when positioning and dragging this color stop.
|
||||||
|
/// <para>If <see langword="null" /> then dragging is not enabled.</para>
|
||||||
|
/// </summary>
|
||||||
|
public IControl? PositionReference
|
||||||
|
{
|
||||||
|
get => GetValue(PositionReferenceProperty);
|
||||||
|
set => SetValue(PositionReferenceProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the linear gradient brush representing the color gradient.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsSelected
|
||||||
|
{
|
||||||
|
get => _isSelected;
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
SetAndRaise(IsSelectedProperty, ref _isSelected, value);
|
||||||
|
if (IsSelected)
|
||||||
|
PseudoClasses.Add(":selected");
|
||||||
|
else
|
||||||
|
PseudoClasses.Remove(":selected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GradientPickerOnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (GradientPicker != null && e.Property == GradientPicker.SelectedColorStopProperty)
|
||||||
|
{
|
||||||
|
IsSelected = GradientPicker.SelectedColorStop == ColorStop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPointerPressed(object? sender, PointerPressedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!e.GetCurrentPoint(this).Properties.IsLeftButtonPressed || PositionReference == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_dragOffset = e.GetCurrentPoint(PositionReference).Position.X - GetPixelPosition();
|
||||||
|
e.Pointer.Capture(this);
|
||||||
|
|
||||||
|
// Store these in case the control is being recreated due to an array resort
|
||||||
|
// it's a bit ugly but it gives us a way to pick up dragging again with the new control
|
||||||
|
_dragPointer = e.Pointer;
|
||||||
|
_draggingStop = ColorStop;
|
||||||
|
e.Handled = true;
|
||||||
|
|
||||||
|
if (GradientPicker != null)
|
||||||
|
GradientPicker.SelectedColorStop = ColorStop;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPointerMoved(object? sender, PointerEventArgs e)
|
||||||
|
{
|
||||||
|
if (!e.GetCurrentPoint(this).Properties.IsLeftButtonPressed || !ReferenceEquals(e.Pointer.Captured, this) || PositionReference == null)
|
||||||
|
{
|
||||||
|
if (_draggingStop != ColorStop)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_dragOffset = e.GetCurrentPoint(PositionReference).Position.X - GetPixelPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
double position = e.GetCurrentPoint(PositionReference).Position.X - _dragOffset;
|
||||||
|
ColorStop.Position = MathF.Round((float) Math.Clamp(position / PositionReference.Bounds.Width, 0, 1), 3, MidpointRounding.AwayFromZero);
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPointerReleased(object? sender, PointerReleasedEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.InitialPressMouseButton != MouseButton.Left)
|
||||||
|
return;
|
||||||
|
|
||||||
|
e.Pointer.Capture(null);
|
||||||
|
e.Handled = true;
|
||||||
|
_draggingStop = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private double GetPixelPosition()
|
||||||
|
{
|
||||||
|
if (PositionReference == null)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return PositionReference.Bounds.Width * ColorStop.Position;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Overrides of Visual
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
|
||||||
|
{
|
||||||
|
if (GradientPicker != null)
|
||||||
|
GradientPicker.PropertyChanged += GradientPickerOnPropertyChanged;
|
||||||
|
|
||||||
|
if (PositionReference != null)
|
||||||
|
{
|
||||||
|
PointerPressed += OnPointerPressed;
|
||||||
|
PointerMoved += OnPointerMoved;
|
||||||
|
PointerReleased += OnPointerReleased;
|
||||||
|
|
||||||
|
// If this stop was previously being dragged, carry on dragging again
|
||||||
|
// This can happen if the control was recreated due to an array sort
|
||||||
|
if (_draggingStop == ColorStop && _dragPointer != null)
|
||||||
|
{
|
||||||
|
_dragPointer.Capture(this);
|
||||||
|
IsSelected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnAttachedToVisualTree(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
|
||||||
|
{
|
||||||
|
if (GradientPicker != null)
|
||||||
|
GradientPicker.PropertyChanged -= GradientPickerOnPropertyChanged;
|
||||||
|
PointerPressed -= OnPointerPressed;
|
||||||
|
PointerMoved -= OnPointerMoved;
|
||||||
|
PointerReleased -= OnPointerReleased;
|
||||||
|
|
||||||
|
base.OnDetachedFromVisualTree(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using Artemis.Core;
|
||||||
|
using Avalonia.Data.Converters;
|
||||||
|
using Avalonia.Media;
|
||||||
|
using SkiaSharp;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Shared.Converters;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts <see cref="T:Artemis.Core.ColorGradient" /> into a <see cref="T:Avalonia.Media.GradientStops" />.
|
||||||
|
/// </summary>
|
||||||
|
public class ColorGradientToGradientStopsConverter : IValueConverter
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
ColorGradient? colorGradient = value as ColorGradient;
|
||||||
|
GradientStops collection = new();
|
||||||
|
if (colorGradient == null)
|
||||||
|
return collection;
|
||||||
|
|
||||||
|
foreach (ColorGradientStop c in colorGradient.OrderBy(s => s.Position))
|
||||||
|
collection.Add(new GradientStop(Color.FromArgb(c.Color.Alpha, c.Color.Red, c.Color.Green, c.Color.Blue), c.Position));
|
||||||
|
return collection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
GradientStops? collection = value as GradientStops;
|
||||||
|
ColorGradient colorGradients = new();
|
||||||
|
if (collection == null)
|
||||||
|
return colorGradients;
|
||||||
|
|
||||||
|
foreach (GradientStop c in collection.OrderBy(s => s.Offset))
|
||||||
|
colorGradients.Add(new ColorGradientStop(new SKColor(c.Color.R, c.Color.G, c.Color.B, c.Color.A), (float) c.Offset));
|
||||||
|
return colorGradients;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Data.Converters;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Shared.Converters;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts the width in percentage to a real number based on the width of the given parent
|
||||||
|
/// </summary>
|
||||||
|
public class ParentWidthPercentageConverter : IValueConverter
|
||||||
|
{
|
||||||
|
#region Implementation of IValueConverter
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
if (parameter is not IControl parent || value is not double percentage)
|
||||||
|
return value;
|
||||||
|
|
||||||
|
return parent.Width / 100.0 * percentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
if (parameter is not IControl parent || value is not double real)
|
||||||
|
return value;
|
||||||
|
|
||||||
|
return real / parent.Width * 100.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@ -3,7 +3,7 @@ using System.Globalization;
|
|||||||
using Avalonia.Data.Converters;
|
using Avalonia.Data.Converters;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
|
|
||||||
namespace Artemis.UI.Converters;
|
namespace Artemis.UI.Shared.Converters;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Data.Converters;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Shared.Converters;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts the width in percentage to a real number based on the width of the given parent
|
||||||
|
/// </summary>
|
||||||
|
public class WidthNormalizedConverter : IMultiValueConverter
|
||||||
|
{
|
||||||
|
#region Implementation of IMultiValueConverter
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public object? Convert(IList<object?> values, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
object? first = values.FirstOrDefault();
|
||||||
|
object? second = values.Skip(1).FirstOrDefault();
|
||||||
|
if (first is float value && second is double totalWidth)
|
||||||
|
return (totalWidth / 1.0) * value;
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
using Artemis.UI.Shared.Services.Interfaces;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Shared.Services;
|
||||||
|
|
||||||
|
public class GradientPickerService : IGradientPickerService
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IGradientPickerService : IArtemisSharedUIService
|
||||||
|
{
|
||||||
|
}
|
||||||
@ -32,6 +32,8 @@
|
|||||||
<StyleInclude Source="/Styles/NumberBox.axaml" />
|
<StyleInclude Source="/Styles/NumberBox.axaml" />
|
||||||
<StyleInclude Source="/Styles/TreeView.axaml" />
|
<StyleInclude Source="/Styles/TreeView.axaml" />
|
||||||
|
|
||||||
|
<StyleInclude Source="/Styles/Controls/GradientPicker.axaml" />
|
||||||
|
|
||||||
<Style Selector="Window:windows:windows10 /template/ Border#RootBorder">
|
<Style Selector="Window:windows:windows10 /template/ Border#RootBorder">
|
||||||
<!-- This will show if custom accent color setting is used in Settings page-->
|
<!-- This will show if custom accent color setting is used in Settings page-->
|
||||||
<Setter Property="BorderBrush" Value="{DynamicResource SystemAccentColor}" />
|
<Setter Property="BorderBrush" Value="{DynamicResource SystemAccentColor}" />
|
||||||
|
|||||||
@ -0,0 +1,192 @@
|
|||||||
|
<Styles xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:controls="using:Artemis.UI.Shared.Controls.GradientPicker"
|
||||||
|
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
|
||||||
|
xmlns:core="clr-namespace:Artemis.Core;assembly=Artemis.Core"
|
||||||
|
xmlns:controls1="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||||
|
xmlns:converters="clr-namespace:Artemis.UI.Shared.Converters">
|
||||||
|
<Design.PreviewWith>
|
||||||
|
<controls:GradientPicker Width="800" />
|
||||||
|
</Design.PreviewWith>
|
||||||
|
|
||||||
|
<Style Selector="controls|GradientPickerColorStop /template/ Border.stop-handle">
|
||||||
|
<Setter Property="CornerRadius" Value="18" />
|
||||||
|
<Setter Property="Width" Value="18" />
|
||||||
|
<Setter Property="Height" Value="60" />
|
||||||
|
<Setter Property="Margin" Value="-9 -10 0 0"></Setter>
|
||||||
|
<Setter Property="BorderThickness" Value="2" />
|
||||||
|
<Setter Property="BorderBrush" Value="{DynamicResource SolidBackgroundFillColorSecondaryBrush}" />
|
||||||
|
<Setter Property="Cursor" Value="Hand" />
|
||||||
|
</Style>
|
||||||
|
<Style Selector="controls|GradientPickerColorStop /template/ Border.stop-handle > Border">
|
||||||
|
<Setter Property="CornerRadius" Value="18" />
|
||||||
|
<Setter Property="BorderThickness" Value="2" />
|
||||||
|
<Setter Property="BorderBrush" Value="{DynamicResource SolidBackgroundFillColorQuarternaryBrush}" />
|
||||||
|
</Style>
|
||||||
|
<Style Selector="controls|GradientPickerColorStop /template/ Border.stop-handle > Border > Border">
|
||||||
|
<Setter Property="CornerRadius" Value="18" />
|
||||||
|
<Setter Property="BorderThickness" Value="2" />
|
||||||
|
<Setter Property="BorderBrush" Value="{DynamicResource SolidBackgroundFillColorSecondaryBrush}" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style Selector="controls|GradientPickerColorStop:selected /template/ Border.stop-handle > Border">
|
||||||
|
<Setter Property="BorderBrush" Value="{DynamicResource SystemAccentColorLight2}" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style Selector="Border.stop-position">
|
||||||
|
<Setter Property="Background" Value="{DynamicResource SolidBackgroundFillColorBaseBrush}" />
|
||||||
|
<Setter Property="BorderBrush" Value="{DynamicResource ButtonBorderBrush}" />
|
||||||
|
<Setter Property="BorderThickness" Value="1" />
|
||||||
|
<Setter Property="Width" Value="40" />
|
||||||
|
<Setter Property="Height" Value="30" />
|
||||||
|
<Setter Property="Margin" Value="-20 -15 0 0"></Setter>
|
||||||
|
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style Selector="Border.stop-position TextBlock">
|
||||||
|
<Setter Property="VerticalAlignment" Value="Center" />
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Center" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style Selector="controls|GradientPicker">
|
||||||
|
<Style.Resources>
|
||||||
|
<converters:ColorGradientToGradientStopsConverter x:Key="ColorGradientToGradientStopsConverter" />
|
||||||
|
<converters:SKColorToColorConverter x:Key="SKColorToColorConverter" />
|
||||||
|
<converters:SKColorToStringConverter x:Key="SKColorToStringConverter" />
|
||||||
|
<converters:WidthNormalizedConverter x:Key="WidthNormalizedConverter" />
|
||||||
|
</Style.Resources>
|
||||||
|
<Setter Property="Template">
|
||||||
|
<ControlTemplate>
|
||||||
|
<Grid>
|
||||||
|
<Border Name="Background" Background="{TemplateBinding LinearGradientBrush}" />
|
||||||
|
<Border Classes="card" Margin="20" Padding="20" Background="{DynamicResource SolidBackgroundFillColorBaseBrush}">
|
||||||
|
<Grid RowDefinitions="Auto,Auto,*" ColumnDefinitions="Auto,*">
|
||||||
|
<Border Name="Gradient" Grid.Row="0" Grid.ColumnSpan="2" Height="40" CornerRadius="4" Background="{TemplateBinding LinearGradientBrush}">
|
||||||
|
<ItemsControl Items="{TemplateBinding ColorGradient}" ClipToBounds="False">
|
||||||
|
<ItemsControl.Styles>
|
||||||
|
<Style Selector="ContentPresenter">
|
||||||
|
<Setter Property="Canvas.Left">
|
||||||
|
<Setter.Value>
|
||||||
|
<MultiBinding Converter="{StaticResource WidthNormalizedConverter}">
|
||||||
|
<Binding Path="Position" />
|
||||||
|
<Binding Path="Bounds.Width" ElementName="Gradient" />
|
||||||
|
</MultiBinding>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
</ItemsControl.Styles>
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate DataType="core:ColorGradientStop">
|
||||||
|
<controls:GradientPickerColorStop ColorStop="{Binding}"
|
||||||
|
GradientPicker="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type controls:GradientPicker}}}"
|
||||||
|
PositionReference="{Binding $parent[Border]}">
|
||||||
|
<controls:GradientPickerColorStop.Styles>
|
||||||
|
<Style Selector="controls|GradientPickerColorStop">
|
||||||
|
<Setter Property="ClipToBounds" Value="False"></Setter>
|
||||||
|
<Setter Property="Template">
|
||||||
|
<ControlTemplate>
|
||||||
|
<Border Classes="stop-handle">
|
||||||
|
<Border>
|
||||||
|
<Border>
|
||||||
|
<Border.Background>
|
||||||
|
<SolidColorBrush Color="{CompiledBinding Color, Converter={StaticResource SKColorToColorConverter}}" />
|
||||||
|
</Border.Background>
|
||||||
|
</Border>
|
||||||
|
</Border>
|
||||||
|
</Border>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
</controls:GradientPickerColorStop.Styles>
|
||||||
|
</controls:GradientPickerColorStop>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
<ItemsControl.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<Canvas />
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ItemsControl.ItemsPanel>
|
||||||
|
</ItemsControl>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<Border Grid.Row="1"
|
||||||
|
Grid.Column="0"
|
||||||
|
Grid.ColumnSpan="2"
|
||||||
|
BorderBrush="{DynamicResource ButtonBorderBrush}"
|
||||||
|
BorderThickness="0 0 0 1"
|
||||||
|
Margin="-20 30"
|
||||||
|
Height="2"
|
||||||
|
VerticalAlignment="Center">
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<ItemsControl Grid.Row="1"
|
||||||
|
Grid.Column="0"
|
||||||
|
Grid.ColumnSpan="2"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Items="{TemplateBinding ColorGradient}"
|
||||||
|
ClipToBounds="False">
|
||||||
|
<ItemsControl.Styles>
|
||||||
|
<Style Selector="ContentPresenter">
|
||||||
|
<Setter Property="Canvas.Left">
|
||||||
|
<Setter.Value>
|
||||||
|
<MultiBinding Converter="{StaticResource WidthNormalizedConverter}">
|
||||||
|
<Binding Path="Position" />
|
||||||
|
<Binding Path="Bounds.Width" ElementName="Gradient" />
|
||||||
|
</MultiBinding>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
</ItemsControl.Styles>
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate DataType="core:ColorGradientStop">
|
||||||
|
<Border Classes="stop-position">
|
||||||
|
<TextBlock Text="{Binding Position}"></TextBlock>
|
||||||
|
</Border>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
<ItemsControl.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<Canvas />
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ItemsControl.ItemsPanel>
|
||||||
|
</ItemsControl>
|
||||||
|
|
||||||
|
<controls1:ColorPicker Grid.Row="2" Grid.Column="0"
|
||||||
|
ColorTextType="HexAlpha"
|
||||||
|
UseColorWheel="True"
|
||||||
|
UseColorTriangle="True"
|
||||||
|
IsMoreButtonVisible="True"
|
||||||
|
IsCompact="True"
|
||||||
|
IsVisible="{TemplateBinding SelectedColorStop, Converter={x:Static ObjectConverters.IsNotNull}}"
|
||||||
|
Color="{Binding SelectedColorStop.Color, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource SKColorToColorConverter}}" />
|
||||||
|
|
||||||
|
<ListBox Grid.Row="2"
|
||||||
|
Grid.Column="1"
|
||||||
|
BorderBrush="{DynamicResource ButtonBorderBrush}"
|
||||||
|
Items="{TemplateBinding ColorGradient}"
|
||||||
|
BorderThickness="1 0 0 0"
|
||||||
|
Margin="10 0 0 0">
|
||||||
|
<ListBox.ItemTemplate>
|
||||||
|
<DataTemplate DataType="core:ColorGradientStop">
|
||||||
|
<Grid VerticalAlignment="Center" ColumnDefinitions="34,*,Auto,Auto">
|
||||||
|
<Border Grid.Column="0" Width="28" Height="28" CornerRadius="4" HorizontalAlignment="Left">
|
||||||
|
<Border.Background>
|
||||||
|
<SolidColorBrush Color="{Binding Color, Converter={StaticResource SKColorToColorConverter}}"></SolidColorBrush>
|
||||||
|
</Border.Background>
|
||||||
|
</Border>
|
||||||
|
<TextBox Grid.Column="1" Text="{Binding Color, Converter={StaticResource SKColorToStringConverter}}"></TextBox>
|
||||||
|
<NumericUpDown Grid.Column="2" Value="{Binding Position}" FormatString="F3" ShowButtonSpinner="False" Margin="5 0"></NumericUpDown>
|
||||||
|
<Button Grid.Column="3" Classes="icon-button">
|
||||||
|
<avalonia:MaterialIcon Kind="Close"></avalonia:MaterialIcon>
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.ItemTemplate>
|
||||||
|
</ListBox>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
</Styles>
|
||||||
@ -5,6 +5,7 @@
|
|||||||
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||||
xmlns:converters="clr-namespace:Artemis.UI.Converters"
|
xmlns:converters="clr-namespace:Artemis.UI.Converters"
|
||||||
xmlns:propertyInput="clr-namespace:Artemis.UI.DefaultTypes.PropertyInput"
|
xmlns:propertyInput="clr-namespace:Artemis.UI.DefaultTypes.PropertyInput"
|
||||||
|
xmlns:shared="clr-namespace:Artemis.UI.Shared.Converters;assembly=Artemis.UI.Shared"
|
||||||
mc:Ignorable="d" d:DesignWidth="200" d:DesignHeight="450"
|
mc:Ignorable="d" d:DesignWidth="200" d:DesignHeight="450"
|
||||||
x:Class="Artemis.UI.DefaultTypes.PropertyInput.SKColorPropertyInputView"
|
x:Class="Artemis.UI.DefaultTypes.PropertyInput.SKColorPropertyInputView"
|
||||||
x:DataType="propertyInput:SKColorPropertyInputViewModel">
|
x:DataType="propertyInput:SKColorPropertyInputViewModel">
|
||||||
@ -44,7 +45,7 @@
|
|||||||
</Style>
|
</Style>
|
||||||
</UserControl.Styles>
|
</UserControl.Styles>
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
<converters:SKColorToStringConverter x:Key="SKColorToStringConverter" />
|
<shared:SKColorToStringConverter x:Key="SKColorToStringConverter" />
|
||||||
<converters:SKColorToColor2Converter x:Key="SKColorToColor2Converter" />
|
<converters:SKColorToColor2Converter x:Key="SKColorToColor2Converter" />
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
<Grid Height="24" ColumnDefinitions="*">
|
<Grid Height="24" ColumnDefinitions="*">
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
xmlns:controls1="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
xmlns:controls1="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||||
xmlns:attachedProperties="clr-namespace:Artemis.UI.Shared.AttachedProperties;assembly=Artemis.UI.Shared"
|
xmlns:attachedProperties="clr-namespace:Artemis.UI.Shared.AttachedProperties;assembly=Artemis.UI.Shared"
|
||||||
xmlns:workshop="clr-namespace:Artemis.UI.Screens.Workshop"
|
xmlns:workshop="clr-namespace:Artemis.UI.Screens.Workshop"
|
||||||
|
xmlns:gradientPicker="clr-namespace:Artemis.UI.Shared.Controls.GradientPicker;assembly=Artemis.UI.Shared"
|
||||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
x:Class="Artemis.UI.Screens.Workshop.WorkshopView"
|
x:Class="Artemis.UI.Screens.Workshop.WorkshopView"
|
||||||
x:DataType="workshop:WorkshopViewModel">
|
x:DataType="workshop:WorkshopViewModel">
|
||||||
@ -45,6 +46,8 @@
|
|||||||
</Border>
|
</Border>
|
||||||
<controls:EnumComboBox Value="{CompiledBinding SelectedCursor}"></controls:EnumComboBox>
|
<controls:EnumComboBox Value="{CompiledBinding SelectedCursor}"></controls:EnumComboBox>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
|
<gradientPicker:GradientPicker ColorGradient="{CompiledBinding ColorGradient}"></gradientPicker:GradientPicker>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using System.Reactive;
|
using System.Reactive;
|
||||||
using System.Reactive.Linq;
|
using System.Reactive.Linq;
|
||||||
|
using Artemis.Core;
|
||||||
using Artemis.UI.Shared.Services.Builders;
|
using Artemis.UI.Shared.Services.Builders;
|
||||||
using Artemis.UI.Shared.Services.Interfaces;
|
using Artemis.UI.Shared.Services.Interfaces;
|
||||||
using Avalonia.Input;
|
using Avalonia.Input;
|
||||||
@ -32,6 +33,8 @@ namespace Artemis.UI.Screens.Workshop
|
|||||||
|
|
||||||
public Cursor Cursor => _cursor.Value;
|
public Cursor Cursor => _cursor.Value;
|
||||||
|
|
||||||
|
public ColorGradient ColorGradient { get; set; } = ColorGradient.GetUnicornBarf();
|
||||||
|
|
||||||
private void ExecuteShowNotification(NotificationSeverity severity)
|
private void ExecuteShowNotification(NotificationSeverity severity)
|
||||||
{
|
{
|
||||||
_notificationService.CreateNotification().WithTitle("Test title").WithMessage("Test message").WithSeverity(severity).Show();
|
_notificationService.CreateNotification().WithTitle("Test title").WithMessage("Test message").WithSeverity(severity).Show();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user