Merge branch 'development' into feature/avalonia

Code cleanup
This commit is contained in:
Robert committed 2022-05-14 00:14:03 +02:00
1 parent 6f75683c4d
commit 35f83e58e5
22 files changed
+176 -95

No files matched your search

+54 -1
View File
@@ -154,6 +154,27 @@
"Ninject": "3.3.3"
}
},
"RGB.NET.Core": {
"type": "Transitive",
"resolved": "1.0.0-prerelease.32",
"contentHash": "HlhhikrkV7OQIRszn6RT6+6N4QGGHaN6NDHK1YssZEJTtE2MIdeRajeQFFziPc4OVOvMgxY13unw/v25r/YALw=="
},
"RGB.NET.Layout": {
"type": "Transitive",
"resolved": "1.0.0-prerelease.32",
"contentHash": "O7I8zR5Hy+joSLCJW10lkIPNMDS1gXe8hQuwm+T5DEDDpykVyc4tnO55WlO5GDmDCS/cXhcwq+qNpLez5Th4Xw==",
"dependencies": {
"RGB.NET.Core": "1.0.0-prerelease.32"
}
},
"RGB.NET.Presets": {
"type": "Transitive",
"resolved": "1.0.0-prerelease.32",
"contentHash": "tqPUA/KUG1hw5pT4D7OLXI6buXxpUIUYNET90gHnVXbadYi0C0OJZ703XDsaPpj4Db8/B2k8f1T4tM4s2KCJhw==",
"dependencies": {
"RGB.NET.Core": "1.0.0-prerelease.32"
}
},
"runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.0",
@@ -1091,7 +1112,39 @@
}
},
"artemis.core": {
"type": "Project"
"type": "Project",
"dependencies": {
"Artemis.Storage": "1.0.0",
"EmbedIO": "3.4.3",
"HidSharp": "2.1.0",
"Humanizer.Core": "2.11.10",
"LiteDB": "5.0.10",
"McMaster.NETCore.Plugins": "1.4.0",
"Newtonsoft.Json": "13.0.1",
"Ninject": "3.3.4",
"Ninject.Extensions.ChildKernel": "3.3.0",
"Ninject.Extensions.Conventions": "3.3.0",
"RGB.NET.Core": "1.0.0-prerelease.32",
"RGB.NET.Layout": "1.0.0-prerelease.32",
"RGB.NET.Presets": "1.0.0-prerelease.32",
"Serilog": "2.10.0",
"Serilog.Sinks.Console": "4.0.0",
"Serilog.Sinks.Debug": "2.0.0",
"Serilog.Sinks.File": "5.0.0",
"SkiaSharp": "2.80.3",
"System.Buffers": "4.5.1",
"System.IO.FileSystem.AccessControl": "5.0.0",
"System.Numerics.Vectors": "4.5.0",
"System.Reflection.Metadata": "5.0.0",
"System.ValueTuple": "4.5.0"
}
},
"artemis.storage": {
"type": "Project",
"dependencies": {
"LiteDB": "5.0.10",
"Serilog": "2.10.0"
}
}
}
}
+4 -14
View File
@@ -50,7 +50,7 @@ namespace Artemis.Core
/// <param name="type">The type to check</param>
/// <param name="genericType">The generic type to match</param>
/// <returns>True if the <paramref name="type" /> is generic and of generic type <paramref name="genericType" /></returns>
public static bool IsGenericType(this Type type, Type genericType)
public static bool IsGenericType(this Type? type, Type genericType)
{
if (type == null)
return false;
@@ -95,17 +95,7 @@ namespace Artemis.Core
/// <returns><see langword="true" /> if the value is of a numeric type, otherwise <see langword="false" /></returns>
public static bool IsNumber([NotNullWhenAttribute(true)] this object? value)
{
return value is sbyte
|| value is byte
|| value is short
|| value is ushort
|| value is int
|| value is uint
|| value is long
|| value is ulong
|| value is float
|| value is double
|| value is decimal;
return value is sbyte or byte or short or ushort or int or uint or long or ulong or float or double or decimal;
}
// From https://stackoverflow.com/a/2224421/5015269 but inverted and renamed to match similar framework methods
@@ -199,10 +189,10 @@ namespace Artemis.Core
/// <param name="genericType">The generic type it should be or implement</param>
public static bool IsOfGenericType(this Type typeToCheck, Type genericType)
{
return typeToCheck.IsOfGenericType(genericType, out Type _);
return typeToCheck.IsOfGenericType(genericType, out Type? _);
}
private static bool IsOfGenericType(this Type typeToCheck, Type genericType, out Type concreteGenericType)
private static bool IsOfGenericType(this Type? typeToCheck, Type genericType, out Type? concreteGenericType)
{
while (true)
{
@@ -73,9 +73,8 @@ public class ColorGradient : IList<ColorGradientStop>, IList, INotifyCollectionC
}
else
{
List<SKColor> colors = this.Select(c => c.Color).ToList();
for (int i = 0; i <= timesToRepeat; i++)
result.AddRange(colors);
result.AddRange(this.Select(c => c.Color));
}
if (seamless && !IsSeamless())
@@ -87,9 +86,7 @@ public class ColorGradient : IList<ColorGradientStop>, IList, INotifyCollectionC
/// <summary>
/// Gets all the positions in the color gradient
/// </summary>
/// <param name="timesToRepeat">
/// The amount of times to repeat the positions
/// </param>
/// <param name="timesToRepeat">The amount of times to repeat the positions</param>
/// <param name="seamless">
/// A boolean indicating whether to make the gradient seamless by adding the first color behind the
/// last color
@@ -120,7 +117,7 @@ public class ColorGradient : IList<ColorGradientStop>, IList, INotifyCollectionC
// Compress current points evenly
float compression = 1f - 1f / result.Count;
for (int index = 0; index < result.Count; index++)
result[index] = result[index] * compression;
result[index] *= compression;
// Add one extra point at the end
result.Add(1f);
}
@@ -132,19 +129,30 @@ public class ColorGradient : IList<ColorGradientStop>, IList, INotifyCollectionC
/// Gets a color at any position between 0.0 and 1.0 using interpolation
/// </summary>
/// <param name="position">A position between 0.0 and 1.0</param>
public SKColor GetColor(float position)
/// <param name="timesToRepeat">The amount of times to repeat the positions</param>
/// <param name="seamless">
/// A boolean indicating whether to make the gradient seamless by adding the first color behind the
/// last color
/// </param>
public SKColor GetColor(float position, int timesToRepeat = 0, bool seamless = false)
{
if (!this.Any())
return new SKColor(255, 255, 255);
ColorGradientStop[] stops = this.ToArray();
if (position <= 0) return stops[0].Color;
if (position >= 1) return stops[^1].Color;
ColorGradientStop left = stops[0];
ColorGradientStop? right = null;
foreach (ColorGradientStop stop in stops)
SKColor[] colors = GetColorsArray(timesToRepeat, seamless);
float[] stops = GetPositionsArray(timesToRepeat, seamless);
// If at or over the edges, return the corresponding edge
if (position <= 0) return colors[0];
if (position >= 1) return colors[^1];
// Walk through the stops until we find the one at or after the requested position, that becomes the right stop
// The left stop is the previous stop before the right one was found.
float left = stops[0];
float? right = null;
foreach (float stop in stops)
{
if (stop.Position >= position)
if (stop >= position)
{
right = stop;
break;
@@ -153,14 +161,22 @@ public class ColorGradient : IList<ColorGradientStop>, IList, INotifyCollectionC
left = stop;
}
if (right == null || left == right)
return left.Color;
// Get the left stop's color
SKColor leftColor = colors[Array.IndexOf(stops, left)];
position = (float) Math.Round((position - left.Position) / (right.Position - left.Position), 2);
byte a = (byte) ((right.Color.Alpha - left.Color.Alpha) * position + left.Color.Alpha);
byte r = (byte) ((right.Color.Red - left.Color.Red) * position + left.Color.Red);
byte g = (byte) ((right.Color.Green - left.Color.Green) * position + left.Color.Green);
byte b = (byte) ((right.Color.Blue - left.Color.Blue) * position + left.Color.Blue);
// If no right stop was found or the left and right stops are on the same spot, return the left stop's color
if (right == null || left == right)
return leftColor;
// Get the right stop's color
SKColor rightColor = colors[Array.IndexOf(stops, right)];
// Interpolate the position between the left and right color
position = MathF.Round((position - left) / (right.Value - left), 2);
byte a = (byte) ((rightColor.Alpha - leftColor.Alpha) * position + leftColor.Alpha);
byte r = (byte) ((rightColor.Red - leftColor.Red) * position + leftColor.Red);
byte g = (byte) ((rightColor.Green - leftColor.Green) * position + leftColor.Green);
byte b = (byte) ((rightColor.Blue - leftColor.Blue) * position + leftColor.Blue);
return new SKColor(r, g, b, a);
}
@@ -561,7 +577,8 @@ public class ColorGradient : IList<ColorGradientStop>, IList, INotifyCollectionC
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, index));
}
public bool IsFixedSize { get; }
/// <inheritdoc />
public bool IsFixedSize => false;
/// <inheritdoc />
public ColorGradientStop this[int index]
@@ -4,14 +4,26 @@ using Artemis.Storage.Entities.Profile.Conditions;
namespace Artemis.Core
{
/// <summary>
/// Represents a condition that is always true.
/// </summary>
public class AlwaysOnCondition : ICondition
{
/// <summary>
/// Creates a new instance of the <see cref="AlwaysOnCondition" /> class.
/// </summary>
/// <param name="profileElement">The profile element this condition applies to.</param>
public AlwaysOnCondition(RenderProfileElement profileElement)
{
ProfileElement = profileElement;
Entity = new AlwaysOnConditionEntity();
}
/// <summary>
/// Creates a new instance of the <see cref="AlwaysOnCondition" /> class.
/// </summary>
/// <param name="alwaysOnConditionEntity">The entity used to store this condition.</param>
/// <param name="profileElement">The profile element this condition applies to.</param>
public AlwaysOnCondition(AlwaysOnConditionEntity alwaysOnConditionEntity, RenderProfileElement profileElement)
{
ProfileElement = profileElement;
@@ -34,6 +34,9 @@ public interface ICondition : IDisposable, IStorageModel
/// </summary>
void UpdateTimeline(double deltaTime);
/// <summary>
/// Overrides the timeline to the provided <paramref name="position"/> as the display condition sees fit.
/// </summary>
void OverrideTimeline(TimeSpan position);
}
@@ -4,14 +4,26 @@ using Artemis.Storage.Entities.Profile.Conditions;
namespace Artemis.Core
{
/// <summary>
/// Represents a condition that plays once when its script evaluates to <see langword="true"/>.
/// </summary>
public class PlayOnceCondition : ICondition
{
/// <summary>
/// Creates a new instance of the <see cref="PlayOnceCondition" /> class.
/// </summary>
/// <param name="profileElement">The profile element this condition applies to.</param>
public PlayOnceCondition(RenderProfileElement profileElement)
{
ProfileElement = profileElement;
Entity = new PlayOnceConditionEntity();
}
/// <summary>
/// Creates a new instance of the <see cref="PlayOnceCondition" /> class.
/// </summary>
/// <param name="entity">The entity used to store this condition.</param>
/// <param name="profileElement">The profile element this condition applies to.</param>
public PlayOnceCondition(PlayOnceConditionEntity entity, RenderProfileElement profileElement)
{
ProfileElement = profileElement;
@@ -30,6 +30,7 @@ namespace Artemis.Core
protected LayerPropertyGroup()
{
// These are set right after construction to keep the constructor (and inherited constructs) clean
ProfileElement = null!;
GroupDescription = null!;
Path = "";
@@ -11,7 +11,6 @@ namespace Artemis.Core.LayerEffects
{
private ILayerEffectConfigurationDialog? _configurationDialog;
private LayerEffectDescriptor _descriptor;
private bool _suspended;
private bool _hasBeenRenamed;
private string _name;
private int _order;
@@ -3,8 +3,20 @@ using Artemis.Core.SkiaSharp;
namespace Artemis.Core.Services;
/// <summary>
/// Represents a class that can provide one or more graphics <see cref="IManagedGraphicsContext"/> instances by name.
/// </summary>
public interface IGraphicsContextProvider
{
/// <summary>
/// Gets a read only collection containing the names of all the graphics contexts supported by this provider.
/// </summary>
IReadOnlyCollection<string> GraphicsContextNames { get; }
/// <summary>
/// Gets a managed graphics context by name.
/// </summary>
/// <param name="name">The name of the graphics context.</param>
/// <returns>If found, an instance of the managed graphics context with the given <paramref name="name"/>; otherwise <see langword="null"/>.</returns>
IManagedGraphicsContext? GetGraphicsContext(string name);
}
+1 -1
View File
@@ -85,7 +85,7 @@ namespace Artemis.Core.Services
}
}
private void ActivationUpdateTimerOnElapsed(object sender, ElapsedEventArgs e)
private void ActivationUpdateTimerOnElapsed(object? sender, ElapsedEventArgs e)
{
UpdateModuleActivation();
}
@@ -24,10 +24,14 @@ namespace Artemis.Core.Services
List<LayerBrushDescriptor> GetLayerBrushes();
/// <summary>
/// Returns the descriptor of the default layer brush
/// Returns the descriptor of the default layer brush
/// </summary>
LayerBrushDescriptor? GetDefaultLayerBrush();
/// <summary>
/// Applies the configured default brush to the provided <paramref name="layer" />.
/// </summary>
/// <param name="layer">The layer to apply the default brush to.</param>
void ApplyDefaultBrush(Layer layer);
}
}
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net6.0</TargetFramework>
@@ -13,9 +13,6 @@
<DocumentationFile>bin\Artemis.UI.Avalonia.Shared.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<None Remove="Artemis.UI.Avalonia.Shared.csproj.DotSettings" />
<None Remove="Artemis.UI.Shared.csproj.DotSettings" />
<None Remove="DefaultTypes\DataModel\Display\DefaultDataModelDisplayView.xaml" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="0.10.13" />
@@ -12,6 +12,9 @@ namespace Artemis.UI.Shared.Behaviors;
/// </summary>
public class LostFocusNumberBoxBindingBehavior : Behavior<NumberBox>
{
/// <summary>
/// Gets or sets the value of the binding.
/// </summary>
public static readonly StyledProperty<double> ValueProperty = AvaloniaProperty.Register<LostFocusTextBoxBindingBehavior, double>(
nameof(Value), defaultBindingMode: BindingMode.TwoWay);
@@ -20,6 +23,9 @@ public class LostFocusNumberBoxBindingBehavior : Behavior<NumberBox>
ValueProperty.Changed.Subscribe(e => ((LostFocusNumberBoxBindingBehavior) e.Sender).OnBindingValueChanged());
}
/// <summary>
/// Gets or sets the value of the binding.
/// </summary>
public double Value
{
get => GetValue(ValueProperty);
@@ -12,6 +12,9 @@ namespace Artemis.UI.Shared.Behaviors;
/// </summary>
public class LostFocusTextBoxBindingBehavior : Behavior<TextBox>
{
/// <summary>
/// Gets or sets the value of the binding.
/// </summary>
public static readonly StyledProperty<string> TextProperty = AvaloniaProperty.Register<LostFocusTextBoxBindingBehavior, string>(
"Text", defaultBindingMode: BindingMode.TwoWay);
@@ -20,6 +23,9 @@ public class LostFocusTextBoxBindingBehavior : Behavior<TextBox>
TextProperty.Changed.Subscribe(e => ((LostFocusTextBoxBindingBehavior) e.Sender).OnBindingValueChanged());
}
/// <summary>
/// Gets or sets the value of the binding.
/// </summary>
public string Text
{
get => GetValue(TextProperty);
@@ -13,6 +13,9 @@ namespace Artemis.UI.Shared.Behaviors;
/// </summary>
public class SliderPointerReleasedBindingBehavior : Behavior<Slider>
{
/// <summary>
/// Gets or sets the value of the binding.
/// </summary>
public static readonly StyledProperty<double> ValueProperty = AvaloniaProperty.Register<LostFocusTextBoxBindingBehavior, double>(
nameof(Value), defaultBindingMode: BindingMode.TwoWay);
@@ -21,6 +24,9 @@ public class SliderPointerReleasedBindingBehavior : Behavior<Slider>
ValueProperty.Changed.Subscribe(e => ((SliderPointerReleasedBindingBehavior) e.Sender).OnBindingValueChanged());
}
/// <summary>
/// Gets or sets the value of the binding.
/// </summary>
public double Value
{
get => GetValue(ValueProperty);
@@ -24,7 +24,7 @@ namespace Artemis.UI.Shared
private readonly ObservableCollection<(Enum, string)> _currentValues = new();
private ComboBox? _enumComboBox;
private Type _currentType;
private Type? _currentType;
/// <summary>
/// Creates a new instance of the <see cref="EnumComboBox" /> class.
@@ -70,6 +70,9 @@ public class GradientPicker : TemplatedControl
private ColorGradient? _lastColorGradient;
private ColorPicker? _colorPicker;
/// <summary>
/// Creates a new instance of the <see cref="GradientPicker"/> class.
/// </summary>
public GradientPicker()
{
_deleteStop = ReactiveCommand.Create<ColorGradientStop>(s =>
@@ -127,14 +127,14 @@ public class GradientPickerColorStop : TemplatedControl
{
if (!e.GetCurrentPoint(this).Properties.IsLeftButtonPressed || !ReferenceEquals(e.Pointer.Captured, this) || PositionReference == null)
{
if (_draggingStop != ColorStop)
if (!Equals(_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);
ColorStop.Position = MathF.Round((float) Math.Clamp(position / PositionReference?.Bounds.Width ?? 0, 0, 1), 3, MidpointRounding.AwayFromZero);
e.Handled = true;
}
-36
View File
@@ -1,36 +0,0 @@
using System;
using System.Windows.Input;
namespace Artemis.UI.Shared;
/// <summary>
/// Represents a placeholder command that does nothing and can't be executed.
/// </summary>
public class NullCommand : ICommand
{
private static readonly Lazy<NullCommand> _instance = new(() => new NullCommand());
private NullCommand()
{
}
/// <summary>
/// Gets the static instance of this command.
/// </summary>
public static ICommand Instance => _instance.Value;
/// <inheritdoc />
public event EventHandler? CanExecuteChanged;
/// <inheritdoc />
public void Execute(object? parameter)
{
throw new InvalidOperationException("NullCommand cannot be executed");
}
/// <inheritdoc />
public bool CanExecute(object? parameter)
{
return false;
}
}
@@ -9,8 +9,8 @@ namespace Artemis.UI.Shared.Services.ProfileEditor.Commands;
public class ChangeConditionType : IProfileEditorCommand, IDisposable
{
private readonly RenderProfileElement _profileElement;
private readonly ICondition? _condition;
private readonly ICondition? _oldCondition;
private readonly ICondition _condition;
private readonly ICondition _oldCondition;
private bool _executed;
/// <summary>
@@ -18,7 +18,7 @@ public class ChangeConditionType : IProfileEditorCommand, IDisposable
/// </summary>
/// <param name="profileElement">The profile element whose condition type to change.</param>
/// <param name="condition">The new condition type.</param>
public ChangeConditionType(RenderProfileElement profileElement, ICondition? condition)
public ChangeConditionType(RenderProfileElement profileElement, ICondition condition)
{
_profileElement = profileElement;
_condition = condition;
@@ -8,8 +8,8 @@ namespace Artemis.UI.Shared.Services.ProfileEditor.Commands;
/// </summary>
public class ChangeElementDisplayCondition : IProfileEditorCommand, IDisposable
{
private readonly ICondition? _condition;
private readonly ICondition? _oldCondition;
private readonly ICondition _condition;
private readonly ICondition _oldCondition;
private readonly RenderProfileElement _profileElement;
private bool _executed;
@@ -18,7 +18,7 @@ public class ChangeElementDisplayCondition : IProfileEditorCommand, IDisposable
/// </summary>
/// <param name="profileElement">The render profile element whose display condition to change.</param>
/// <param name="condition">The new display condition.</param>
public ChangeElementDisplayCondition(RenderProfileElement profileElement, ICondition? condition)
public ChangeElementDisplayCondition(RenderProfileElement profileElement, ICondition condition)
{
_profileElement = profileElement;
_condition = condition;