mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 03:48:56 +00:00
Nodes - Added gradient nodes
Nodes - Added color gradient pin type Data bindings - Changed color gradient data bindings to now take a color gradient
This commit is contained in:
1 parent
32a444fbeb
commit
9c117d2773
48 files changed
+830
-344
No files matched your search
@@ -129,7 +129,7 @@ public class ArtemisIcon : UserControl
|
||||
/// theme
|
||||
/// </summary>
|
||||
public static readonly StyledProperty<bool> FillProperty =
|
||||
AvaloniaProperty.Register<ArtemisIcon, bool>(nameof(Icon), true, notifying: IconChanging);
|
||||
AvaloniaProperty.Register<ArtemisIcon, bool>(nameof(Icon), false, notifying: IconChanging);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean indicating whether or not the icon should be filled in with the primary text color of the
|
||||
|
||||
@@ -59,22 +59,29 @@ public class GradientPicker : TemplatedControl
|
||||
public static readonly DirectProperty<GradientPicker, ICommand> DeleteStopProperty =
|
||||
AvaloniaProperty.RegisterDirect<GradientPicker, ICommand>(nameof(DeleteStop), g => g.DeleteStop);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the color gradient currently being edited, for internal use only
|
||||
/// </summary>
|
||||
public static readonly DirectProperty<GradientPicker, ColorGradient> EditingColorGradientProperty =
|
||||
AvaloniaProperty.RegisterDirect<GradientPicker, ColorGradient>(nameof(EditingColorGradient), g => g.EditingColorGradient);
|
||||
|
||||
private readonly ICommand _deleteStop;
|
||||
private ColorPicker? _colorPicker;
|
||||
private Button? _flipStops;
|
||||
private Border? _gradient;
|
||||
private ColorGradient? _lastColorGradient;
|
||||
private Button? _randomize;
|
||||
private Button? _rotateStops;
|
||||
private bool _shiftDown;
|
||||
private Button? _spreadStops;
|
||||
private Button? _toggleSeamless;
|
||||
private ColorGradient _colorGradient = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="GradientPicker" /> class.
|
||||
/// </summary>
|
||||
public GradientPicker()
|
||||
{
|
||||
EditingColorGradient = ColorGradient.GetUnicornBarf();
|
||||
_deleteStop = ReactiveCommand.Create<ColorGradientStop>(s =>
|
||||
{
|
||||
if (ColorGradient.Count <= 2)
|
||||
@@ -143,6 +150,15 @@ public class GradientPicker : TemplatedControl
|
||||
get => _deleteStop;
|
||||
private init => SetAndRaise(DeleteStopProperty, ref _deleteStop, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the color gradient backing the editor, this is a copy of <see cref="ColorGradient"/>.
|
||||
/// </summary>
|
||||
public ColorGradient EditingColorGradient
|
||||
{
|
||||
get => _colorGradient;
|
||||
private set => SetAndRaise(EditingColorGradientProperty, ref _colorGradient, value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
@@ -167,7 +183,7 @@ public class GradientPicker : TemplatedControl
|
||||
_flipStops = e.NameScope.Find<Button>("FlipStops");
|
||||
_rotateStops = e.NameScope.Find<Button>("RotateStops");
|
||||
_randomize = e.NameScope.Find<Button>("Randomize");
|
||||
|
||||
|
||||
if (_gradient != null)
|
||||
_gradient.PointerPressed += GradientOnPointerPressed;
|
||||
if (_spreadStops != null)
|
||||
@@ -188,7 +204,7 @@ public class GradientPicker : TemplatedControl
|
||||
/// <inheritdoc />
|
||||
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
Subscribe();
|
||||
ApplyToField();
|
||||
|
||||
KeyUp += OnKeyUp;
|
||||
KeyDown += OnKeyDown;
|
||||
@@ -197,60 +213,72 @@ public class GradientPicker : TemplatedControl
|
||||
/// <inheritdoc />
|
||||
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
Unsubscribe();
|
||||
ApplyToProperty();
|
||||
KeyUp -= OnKeyUp;
|
||||
KeyDown -= OnKeyDown;
|
||||
|
||||
_shiftDown = false;
|
||||
}
|
||||
|
||||
|
||||
private static void ColorGradientChanged(IAvaloniaObject sender, bool before)
|
||||
{
|
||||
(sender as GradientPicker)?.Subscribe();
|
||||
(sender as GradientPicker)?.ApplyToField();
|
||||
}
|
||||
|
||||
private static void StorageProviderChanged(IAvaloniaObject sender, bool before)
|
||||
{
|
||||
}
|
||||
|
||||
private void Subscribe()
|
||||
private void ApplyToField()
|
||||
{
|
||||
Unsubscribe();
|
||||
|
||||
ColorGradient.CollectionChanged += ColorGradientOnCollectionChanged;
|
||||
ColorGradient.StopChanged += ColorGradientOnStopChanged;
|
||||
SelectedColorStop = ColorGradient.FirstOrDefault();
|
||||
|
||||
EditingColorGradient = new ColorGradient(ColorGradient);
|
||||
EditingColorGradient.CollectionChanged += ColorGradientOnCollectionChanged;
|
||||
EditingColorGradient.StopChanged += ColorGradientOnStopChanged;
|
||||
SelectedColorStop = EditingColorGradient.FirstOrDefault();
|
||||
UpdateGradient();
|
||||
|
||||
_lastColorGradient = ColorGradient;
|
||||
}
|
||||
|
||||
private void Unsubscribe()
|
||||
private void ApplyToProperty()
|
||||
{
|
||||
if (_lastColorGradient == null)
|
||||
return;
|
||||
// Remove extra color gradients
|
||||
while (ColorGradient.Count > EditingColorGradient.Count)
|
||||
ColorGradient.RemoveAt(ColorGradient.Count - 1);
|
||||
|
||||
_lastColorGradient.CollectionChanged -= ColorGradientOnCollectionChanged;
|
||||
_lastColorGradient.StopChanged -= ColorGradientOnStopChanged;
|
||||
_lastColorGradient = null;
|
||||
for (int index = 0; index < EditingColorGradient.Count; index++)
|
||||
{
|
||||
ColorGradientStop colorGradientStop = EditingColorGradient[index];
|
||||
// Add missing color gradients
|
||||
if (index >= ColorGradient.Count)
|
||||
{
|
||||
ColorGradient.Add(new ColorGradientStop(colorGradientStop.Color, colorGradientStop.Position));
|
||||
}
|
||||
// Update existing color gradients
|
||||
else
|
||||
{
|
||||
ColorGradient[index].Color = colorGradientStop.Color;
|
||||
ColorGradient[index].Position = colorGradientStop.Position;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ColorGradientOnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
UpdateGradient();
|
||||
ApplyToProperty();
|
||||
}
|
||||
|
||||
private void ColorGradientOnStopChanged(object? sender, EventArgs e)
|
||||
{
|
||||
UpdateGradient();
|
||||
ApplyToProperty();
|
||||
}
|
||||
|
||||
private void UpdateGradient()
|
||||
{
|
||||
// Update the display gradient
|
||||
GradientStops collection = new();
|
||||
foreach (ColorGradientStop c in ColorGradient.OrderBy(s => s.Position))
|
||||
foreach (ColorGradientStop c in EditingColorGradient.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.GradientStops = collection;
|
||||
@@ -263,8 +291,8 @@ public class GradientPicker : TemplatedControl
|
||||
|
||||
float position = (float) (e.GetPosition(_gradient).X / _gradient.Bounds.Width);
|
||||
|
||||
ColorGradientStop newStop = new(ColorGradient.GetColor(position), position);
|
||||
ColorGradient.Add(newStop);
|
||||
ColorGradientStop newStop = new(EditingColorGradient.GetColor(position), position);
|
||||
EditingColorGradient.Add(newStop);
|
||||
SelectedColorStop = newStop;
|
||||
}
|
||||
|
||||
@@ -279,50 +307,50 @@ public class GradientPicker : TemplatedControl
|
||||
if (e.Key is Key.LeftShift or Key.RightShift)
|
||||
_shiftDown = false;
|
||||
|
||||
if (e.Key != Key.Delete || SelectedColorStop == null || ColorGradient.Count <= 2)
|
||||
if (e.Key != Key.Delete || SelectedColorStop == null || EditingColorGradient.Count <= 2)
|
||||
return;
|
||||
|
||||
int index = ColorGradient.IndexOf(SelectedColorStop);
|
||||
ColorGradient.Remove(SelectedColorStop);
|
||||
if (index > ColorGradient.Count - 1)
|
||||
int index = EditingColorGradient.IndexOf(SelectedColorStop);
|
||||
EditingColorGradient.Remove(SelectedColorStop);
|
||||
if (index > EditingColorGradient.Count - 1)
|
||||
index--;
|
||||
|
||||
SelectedColorStop = ColorGradient.ElementAtOrDefault(index);
|
||||
SelectedColorStop = EditingColorGradient.ElementAtOrDefault(index);
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void SpreadStopsOnClick(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
ColorGradient.SpreadStops();
|
||||
EditingColorGradient.SpreadStops();
|
||||
}
|
||||
|
||||
private void ToggleSeamlessOnClick(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (SelectedColorStop == null || ColorGradient.Count < 2)
|
||||
if (SelectedColorStop == null || EditingColorGradient.Count < 2)
|
||||
return;
|
||||
|
||||
ColorGradient.ToggleSeamless();
|
||||
EditingColorGradient.ToggleSeamless();
|
||||
}
|
||||
|
||||
private void FlipStopsOnClick(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (SelectedColorStop == null || ColorGradient.Count < 2)
|
||||
if (SelectedColorStop == null || EditingColorGradient.Count < 2)
|
||||
return;
|
||||
|
||||
ColorGradient.FlipStops();
|
||||
EditingColorGradient.FlipStops();
|
||||
}
|
||||
|
||||
private void RotateStopsOnClick(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (SelectedColorStop == null || ColorGradient.Count < 2)
|
||||
if (SelectedColorStop == null || EditingColorGradient.Count < 2)
|
||||
return;
|
||||
|
||||
ColorGradient.RotateStops(_shiftDown);
|
||||
EditingColorGradient.RotateStops(_shiftDown);
|
||||
}
|
||||
|
||||
private void RandomizeOnClick(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
ColorGradient.Randomize(6);
|
||||
SelectedColorStop = ColorGradient.First();
|
||||
EditingColorGradient.Randomize(6);
|
||||
SelectedColorStop = EditingColorGradient.First();
|
||||
}
|
||||
}
|
||||
@@ -46,9 +46,6 @@ public class GradientPickerButton : TemplatedControl
|
||||
AvaloniaProperty.RegisterDirect<GradientPickerButton, LinearGradientBrush>(nameof(LinearGradientBrush), g => g.LinearGradientBrush);
|
||||
|
||||
private Button? _button;
|
||||
private GradientPickerFlyout? _flyout;
|
||||
private bool _flyoutActive;
|
||||
|
||||
private ColorGradient? _lastColorGradient;
|
||||
|
||||
/// <summary>
|
||||
@@ -150,27 +147,23 @@ public class GradientPickerButton : TemplatedControl
|
||||
|
||||
private void OnButtonClick(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (_flyout == null || ColorGradient == null)
|
||||
if (ColorGradient == null)
|
||||
return;
|
||||
|
||||
// Logic here is taken from Fluent Avalonia's ColorPicker which also reuses the same control since it's large
|
||||
_flyout.GradientPicker.ColorGradient = ColorGradient;
|
||||
_flyout.GradientPicker.IsCompact = IsCompact;
|
||||
_flyout.GradientPicker.StorageProvider = StorageProvider;
|
||||
|
||||
_flyout.ShowAt(this);
|
||||
_flyoutActive = true;
|
||||
GradientPickerFlyout flyout = new();
|
||||
flyout.FlyoutPresenterClasses.Add("gradient-picker-presenter");
|
||||
flyout.GradientPicker.ColorGradient = ColorGradient;
|
||||
flyout.GradientPicker.IsCompact = IsCompact;
|
||||
flyout.GradientPicker.StorageProvider = StorageProvider;
|
||||
|
||||
flyout.Closed += FlyoutOnClosed;
|
||||
flyout.ShowAt(this);
|
||||
FlyoutOpened?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
|
||||
private void OnFlyoutClosed(object? sender, EventArgs e)
|
||||
{
|
||||
if (_flyoutActive)
|
||||
void FlyoutOnClosed(object? closedSender, EventArgs closedEventArgs)
|
||||
{
|
||||
flyout.Closed -= FlyoutOnClosed;
|
||||
FlyoutClosed?.Invoke(this, EventArgs.Empty);
|
||||
_flyoutActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,22 +184,12 @@ public class GradientPickerButton : TemplatedControl
|
||||
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
Subscribe();
|
||||
|
||||
if (_flyout == null)
|
||||
{
|
||||
_flyout = new GradientPickerFlyout();
|
||||
_flyout.FlyoutPresenterClasses.Add("gradient-picker-presenter");
|
||||
}
|
||||
|
||||
_flyout.Closed += OnFlyoutClosed;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
Unsubscribe();
|
||||
if (_flyout != null)
|
||||
_flyout.Closed -= OnFlyoutClosed;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -19,7 +19,7 @@ public class UpdateColorGradient : IProfileEditorCommand
|
||||
public UpdateColorGradient(ColorGradient colorGradient, List<ColorGradientStop> stops, List<ColorGradientStop>? originalStops)
|
||||
{
|
||||
_colorGradient = colorGradient;
|
||||
_stops = stops;
|
||||
_stops = stops.Select(s => new ColorGradientStop(s.Color, s.Position)).ToList();
|
||||
_originalStops = originalStops ?? _colorGradient.Select(s => new ColorGradientStop(s.Color, s.Position)).ToList();
|
||||
}
|
||||
|
||||
@@ -31,18 +31,36 @@ public class UpdateColorGradient : IProfileEditorCommand
|
||||
/// <inheritdoc />
|
||||
public void Execute()
|
||||
{
|
||||
_colorGradient.Clear();
|
||||
foreach (ColorGradientStop colorGradientStop in _stops)
|
||||
_colorGradient.Add(colorGradientStop);
|
||||
ApplyStops(_stops);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Undo()
|
||||
{
|
||||
_colorGradient.Clear();
|
||||
foreach (ColorGradientStop colorGradientStop in _originalStops)
|
||||
_colorGradient.Add(colorGradientStop);
|
||||
ApplyStops(_originalStops);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void ApplyStops(List<ColorGradientStop> stops)
|
||||
{
|
||||
while (_colorGradient.Count > stops.Count)
|
||||
_colorGradient.RemoveAt(_colorGradient.Count - 1);
|
||||
|
||||
for (int index = 0; index < stops.Count; index++)
|
||||
{
|
||||
ColorGradientStop colorGradientStop = stops[index];
|
||||
// Add missing color gradients
|
||||
if (index >= _colorGradient.Count)
|
||||
{
|
||||
_colorGradient.Add(new ColorGradientStop(colorGradientStop.Color, colorGradientStop.Position));
|
||||
}
|
||||
// Update existing color gradients
|
||||
else
|
||||
{
|
||||
_colorGradient[index].Color = colorGradientStop.Color;
|
||||
_colorGradient[index].Position = colorGradientStop.Position;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,7 +73,6 @@
|
||||
|
||||
<Style Selector="gradientPicker|GradientPicker">
|
||||
<Style.Resources>
|
||||
<converters:ColorGradientToGradientStopsConverter x:Key="ColorGradientToGradientStopsConverter" />
|
||||
<converters:SKColorToColorConverter x:Key="SKColorToColorConverter" />
|
||||
<converters:SKColorToBrushConverter x:Key="SKColorToBrushConverter" />
|
||||
<converters:SKColorToStringConverter x:Key="SKColorToStringConverter" />
|
||||
@@ -89,7 +88,7 @@
|
||||
Background="{DynamicResource LightCheckerboardBrush}"
|
||||
Margin="5 0">
|
||||
<Border Background="{TemplateBinding LinearGradientBrush}">
|
||||
<ItemsControl Name="GradientStops" Items="{TemplateBinding ColorGradient}" ClipToBounds="False">
|
||||
<ItemsControl Name="GradientStops" Items="{TemplateBinding EditingColorGradient}" ClipToBounds="False">
|
||||
<ItemsControl.Styles>
|
||||
<Style Selector="ItemsControl#GradientStops > ContentPresenter">
|
||||
<Setter Property="Canvas.Left">
|
||||
@@ -105,9 +104,9 @@
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate DataType="core:ColorGradientStop">
|
||||
<gradientPicker:GradientPickerColorStop ColorStop="{Binding}"
|
||||
PositionReference="{Binding $parent[Border]}"
|
||||
Classes="gradient-handle"
|
||||
GradientPicker="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type gradientPicker:GradientPicker}}}">
|
||||
PositionReference="{Binding $parent[Border]}"
|
||||
Classes="gradient-handle"
|
||||
GradientPicker="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type gradientPicker:GradientPicker}}}">
|
||||
</gradientPicker:GradientPickerColorStop>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
@@ -135,7 +134,7 @@
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
VerticalAlignment="Center"
|
||||
Items="{TemplateBinding ColorGradient}"
|
||||
Items="{TemplateBinding EditingColorGradient}"
|
||||
ClipToBounds="False"
|
||||
Margin="5 0">
|
||||
<ItemsControl.Styles>
|
||||
@@ -180,9 +179,10 @@
|
||||
</Border>
|
||||
|
||||
<Grid Grid.Row="2" Grid.Column="1" RowDefinitions="*,Auto">
|
||||
<ListBox Grid.Row="0"
|
||||
<ListBox Name="GradientColors"
|
||||
Grid.Row="0"
|
||||
MaxHeight="280"
|
||||
Items="{TemplateBinding ColorGradient}"
|
||||
Items="{TemplateBinding EditingColorGradient}"
|
||||
SelectedItem="{TemplateBinding SelectedColorStop, Mode=TwoWay}"
|
||||
Padding="10 0 15 0">
|
||||
<ListBox.ItemTemplate>
|
||||
@@ -201,7 +201,7 @@
|
||||
<TextBox Grid.Column="1" Text="{Binding Color, Converter={StaticResource SKColorToStringConverter}}" />
|
||||
<NumericUpDown Grid.Column="2" FormatString="F3" ShowButtonSpinner="False" Margin="5 0" Minimum="0" Maximum="1" Increment="0.01">
|
||||
<Interaction.Behaviors>
|
||||
<behaviors:LostFocusNumericUpDownBindingBehavior Value="{Binding Position}"/>
|
||||
<behaviors:LostFocusNumericUpDownBindingBehavior Value="{Binding Position}" />
|
||||
</Interaction.Behaviors>
|
||||
</NumericUpDown>
|
||||
<Button Name="DeleteButton"
|
||||
|
||||
Reference in new issue
Block a user