mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Core - Made FloatRange and IntRange readonly structs
ColorGradient - Fixed missing subscribtions when using object list manipulation API ColorGradient - Fixed editor VM going out of sync
This commit is contained in:
parent
bd26f447c6
commit
e385165200
@ -1,83 +1,79 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<PreserveCompilationContext>false</PreserveCompilationContext>
|
||||
<ShouldIncludeNativeSkiaSharp>false</ShouldIncludeNativeSkiaSharp>
|
||||
<AssemblyTitle>Artemis.Core</AssemblyTitle>
|
||||
<Product>Artemis Core</Product>
|
||||
<Copyright>Copyright © Robert Beekman - 2020</Copyright>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<Platforms>x64</Platforms>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<DocumentationFile>bin\Artemis.Core.xml</DocumentationFile>
|
||||
<NoWarn></NoWarn>
|
||||
<WarningLevel>5</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<PreserveCompilationContext>false</PreserveCompilationContext>
|
||||
<ShouldIncludeNativeSkiaSharp>false</ShouldIncludeNativeSkiaSharp>
|
||||
<AssemblyTitle>Artemis.Core</AssemblyTitle>
|
||||
<Product>Artemis Core</Product>
|
||||
<Copyright>Copyright © Robert Beekman - 2020</Copyright>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<Platforms>x64</Platforms>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<DocumentationFile>bin\Artemis.Core.xml</DocumentationFile>
|
||||
<NoWarn></NoWarn>
|
||||
<WarningLevel>5</WarningLevel>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<NrtRevisionFormat>1.0-{chash:6}</NrtRevisionFormat>
|
||||
<NrtResolveSimpleAttributes>true</NrtResolveSimpleAttributes>
|
||||
<NrtResolveInformationalAttribute>true</NrtResolveInformationalAttribute>
|
||||
<NrtResolveCopyright>true</NrtResolveCopyright>
|
||||
<NrtTagMatch>v[0-9]*</NrtTagMatch>
|
||||
<NrtRemoveTagV>true</NrtRemoveTagV>
|
||||
<NrtRequiredVcs>git</NrtRequiredVcs>
|
||||
<NrtShowRevision>true</NrtShowRevision>
|
||||
<Nullable>enable</Nullable>
|
||||
<AnalysisLevel>latest</AnalysisLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<NrtRevisionFormat>1.0-{chash:6}</NrtRevisionFormat>
|
||||
<NrtResolveSimpleAttributes>true</NrtResolveSimpleAttributes>
|
||||
<NrtResolveInformationalAttribute>true</NrtResolveInformationalAttribute>
|
||||
<NrtResolveCopyright>true</NrtResolveCopyright>
|
||||
<NrtTagMatch>v[0-9]*</NrtTagMatch>
|
||||
<NrtRemoveTagV>true</NrtRemoveTagV>
|
||||
<NrtRequiredVcs>git</NrtRequiredVcs>
|
||||
<NrtShowRevision>true</NrtShowRevision>
|
||||
<Nullable>enable</Nullable>
|
||||
<AnalysisLevel>latest</AnalysisLevel>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<DocumentationFile>bin\Artemis.Core.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Artemis.Storage\Artemis.Storage.csproj">
|
||||
<Private>false</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="EmbedIO" Version="3.4.3" />
|
||||
<PackageReference Include="HidSharp" Version="2.1.0" />
|
||||
<PackageReference Include="Humanizer.Core" Version="2.14.1" />
|
||||
<PackageReference Include="LiteDB" Version="5.0.11" />
|
||||
<PackageReference Include="McMaster.NETCore.Plugins" Version="1.4.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="Ninject" Version="3.3.4" />
|
||||
<PackageReference Include="Ninject.Extensions.ChildKernel" Version="3.3.0" />
|
||||
<PackageReference Include="Ninject.Extensions.Conventions" Version="3.3.0" />
|
||||
<PackageReference Include="RGB.NET.Core" Version="1.0.0-prerelease.32" />
|
||||
<PackageReference Include="RGB.NET.Layout" Version="1.0.0-prerelease.32" />
|
||||
<PackageReference Include="RGB.NET.Presets" Version="1.0.0-prerelease.32" />
|
||||
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" />
|
||||
<PackageReference Include="Serilog.Sinks.Debug" Version="2.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
||||
<PackageReference Include="SkiaSharp" Version="2.88.1-preview.1" />
|
||||
<PackageReference Include="System.Buffers" Version="4.5.1" />
|
||||
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="5.0.0" />
|
||||
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
|
||||
<PackageReference Include="System.Reflection.Metadata" Version="5.0.0" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="Resources\intro-profile.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<DocumentationFile>bin\Artemis.Core.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Artemis.Storage\Artemis.Storage.csproj">
|
||||
<Private>false</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="EmbedIO" Version="3.4.3"/>
|
||||
<PackageReference Include="HidSharp" Version="2.1.0"/>
|
||||
<PackageReference Include="Humanizer.Core" Version="2.14.1"/>
|
||||
<PackageReference Include="LiteDB" Version="5.0.11"/>
|
||||
<PackageReference Include="McMaster.NETCore.Plugins" Version="1.4.0"/>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1"/>
|
||||
<PackageReference Include="Ninject" Version="3.3.4"/>
|
||||
<PackageReference Include="Ninject.Extensions.ChildKernel" Version="3.3.0"/>
|
||||
<PackageReference Include="Ninject.Extensions.Conventions" Version="3.3.0"/>
|
||||
<PackageReference Include="RGB.NET.Core" Version="1.0.0-prerelease.32"/>
|
||||
<PackageReference Include="RGB.NET.Layout" Version="1.0.0-prerelease.32"/>
|
||||
<PackageReference Include="RGB.NET.Presets" Version="1.0.0-prerelease.32"/>
|
||||
<PackageReference Include="Serilog" Version="2.10.0"/>
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.1"/>
|
||||
<PackageReference Include="Serilog.Sinks.Debug" Version="2.0.0"/>
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0"/>
|
||||
<PackageReference Include="SkiaSharp" Version="2.88.1-preview.1"/>
|
||||
<PackageReference Include="System.Buffers" Version="4.5.1"/>
|
||||
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="5.0.0"/>
|
||||
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0"/>
|
||||
<PackageReference Include="System.Reflection.Metadata" Version="5.0.0"/>
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0"/>
|
||||
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="Resources\intro-profile.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="DefaultLayouts\**">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="DefaultTypes\DataBindings\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="DefaultLayouts\**">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -1,91 +1,92 @@
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace Artemis.Core
|
||||
namespace Artemis.Core;
|
||||
|
||||
/// <inheritdoc />
|
||||
public class ColorGradientLayerProperty : LayerProperty<ColorGradient>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public class ColorGradientLayerProperty : LayerProperty<ColorGradient>
|
||||
private ColorGradient? _subscribedGradient;
|
||||
|
||||
internal ColorGradientLayerProperty()
|
||||
{
|
||||
private ColorGradient? _subscribedGradient;
|
||||
KeyframesSupported = false;
|
||||
DefaultValue = new ColorGradient();
|
||||
}
|
||||
|
||||
internal ColorGradientLayerProperty()
|
||||
/// <summary>
|
||||
/// Implicitly converts an <see cref="ColorGradientLayerProperty" /> to a <see cref="ColorGradient" />
|
||||
/// </summary>
|
||||
public static implicit operator ColorGradient(ColorGradientLayerProperty p)
|
||||
{
|
||||
return p.CurrentValue;
|
||||
}
|
||||
|
||||
#region Overrides of LayerProperty<ColorGradient>
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnCurrentValueSet()
|
||||
{
|
||||
// Don't allow color gradients to be null
|
||||
if (BaseValue == null!)
|
||||
BaseValue = new ColorGradient(DefaultValue);
|
||||
|
||||
if (!ReferenceEquals(_subscribedGradient, BaseValue))
|
||||
{
|
||||
KeyframesSupported = false;
|
||||
DefaultValue = new ColorGradient();
|
||||
|
||||
CurrentValueSet += OnCurrentValueSet;
|
||||
if (_subscribedGradient != null)
|
||||
_subscribedGradient.CollectionChanged -= SubscribedGradientOnPropertyChanged;
|
||||
_subscribedGradient = BaseValue;
|
||||
_subscribedGradient.CollectionChanged += SubscribedGradientOnPropertyChanged;
|
||||
}
|
||||
|
||||
private void CreateDataBindingRegistrations()
|
||||
{
|
||||
DataBinding.ClearDataBindingProperties();
|
||||
if (CurrentValue == null!)
|
||||
return;
|
||||
CreateDataBindingRegistrations();
|
||||
base.OnCurrentValueSet();
|
||||
}
|
||||
|
||||
for (int index = 0; index < CurrentValue.Count; index++)
|
||||
#endregion
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased)
|
||||
{
|
||||
throw new ArtemisCoreException("Color Gradients do not support keyframes.");
|
||||
}
|
||||
|
||||
#region Overrides of LayerProperty<ColorGradient>
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnInitialize()
|
||||
{
|
||||
// Don't allow color gradients to be null
|
||||
if (BaseValue == null!)
|
||||
BaseValue = new ColorGradient(DefaultValue);
|
||||
|
||||
base.OnInitialize();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void CreateDataBindingRegistrations()
|
||||
{
|
||||
DataBinding.ClearDataBindingProperties();
|
||||
if (CurrentValue == null!)
|
||||
return;
|
||||
|
||||
for (int index = 0; index < CurrentValue.Count; index++)
|
||||
{
|
||||
int stopIndex = index;
|
||||
|
||||
void Setter(SKColor value)
|
||||
{
|
||||
int stopIndex = index;
|
||||
|
||||
void Setter(SKColor value)
|
||||
{
|
||||
CurrentValue[stopIndex].Color = value;
|
||||
}
|
||||
|
||||
DataBinding.RegisterDataBindingProperty(() => CurrentValue[stopIndex].Color, Setter, $"Color #{stopIndex + 1}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Implicitly converts an <see cref="ColorGradientLayerProperty" /> to a <see cref="ColorGradient" />
|
||||
/// </summary>
|
||||
public static implicit operator ColorGradient(ColorGradientLayerProperty p)
|
||||
{
|
||||
return p.CurrentValue;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased)
|
||||
{
|
||||
throw new ArtemisCoreException("Color Gradients do not support keyframes.");
|
||||
}
|
||||
|
||||
private void OnCurrentValueSet(object? sender, LayerPropertyEventArgs e)
|
||||
{
|
||||
// Don't allow color gradients to be null
|
||||
if (BaseValue == null!)
|
||||
BaseValue = new ColorGradient(DefaultValue);
|
||||
|
||||
if (!ReferenceEquals(_subscribedGradient, BaseValue))
|
||||
{
|
||||
if (_subscribedGradient != null)
|
||||
_subscribedGradient.CollectionChanged -= SubscribedGradientOnPropertyChanged;
|
||||
_subscribedGradient = BaseValue;
|
||||
_subscribedGradient.CollectionChanged += SubscribedGradientOnPropertyChanged;
|
||||
CurrentValue[stopIndex].Color = value;
|
||||
}
|
||||
|
||||
DataBinding.RegisterDataBindingProperty(() => CurrentValue[stopIndex].Color, Setter, $"Color #{stopIndex + 1}");
|
||||
}
|
||||
}
|
||||
|
||||
private void SubscribedGradientOnPropertyChanged(object? sender, NotifyCollectionChangedEventArgs args)
|
||||
{
|
||||
if (CurrentValue.Count != DataBinding.Properties.Count)
|
||||
CreateDataBindingRegistrations();
|
||||
}
|
||||
|
||||
private void SubscribedGradientOnPropertyChanged(object? sender, NotifyCollectionChangedEventArgs args)
|
||||
{
|
||||
if (CurrentValue.Count != DataBinding.Properties.Count)
|
||||
CreateDataBindingRegistrations();
|
||||
}
|
||||
|
||||
#region Overrides of LayerProperty<ColorGradient>
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnInitialize()
|
||||
{
|
||||
// Don't allow color gradients to be null
|
||||
if (BaseValue == null!)
|
||||
BaseValue = new ColorGradient(DefaultValue);
|
||||
|
||||
base.OnInitialize();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -3,17 +3,11 @@
|
||||
/// <inheritdoc />
|
||||
public class FloatRangeLayerProperty : LayerProperty<FloatRange>
|
||||
{
|
||||
internal FloatRangeLayerProperty()
|
||||
{
|
||||
CurrentValueSet += OnCurrentValueSet;
|
||||
DefaultValue = new FloatRange();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnInitialize()
|
||||
{
|
||||
DataBinding.RegisterDataBindingProperty(() => CurrentValue.Start, value => CurrentValue.Start = value, "Start");
|
||||
DataBinding.RegisterDataBindingProperty(() => CurrentValue.End, value => CurrentValue.End = value, "End");
|
||||
DataBinding.RegisterDataBindingProperty(() => CurrentValue.Start, value => CurrentValue = new FloatRange(value, CurrentValue.End), "Start");
|
||||
DataBinding.RegisterDataBindingProperty(() => CurrentValue.End, value => CurrentValue = new FloatRange(CurrentValue.Start, value), "End");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@ -22,15 +16,9 @@
|
||||
float startDiff = NextKeyframe!.Value.Start - CurrentKeyframe!.Value.Start;
|
||||
float endDiff = NextKeyframe!.Value.End - CurrentKeyframe!.Value.End;
|
||||
CurrentValue = new FloatRange(
|
||||
(int) (CurrentKeyframe!.Value.Start + startDiff * keyframeProgressEased),
|
||||
(int) (CurrentKeyframe!.Value.End + endDiff * keyframeProgressEased)
|
||||
(float) (CurrentKeyframe!.Value.Start + startDiff * keyframeProgressEased),
|
||||
(float) (CurrentKeyframe!.Value.End + endDiff * keyframeProgressEased)
|
||||
);
|
||||
}
|
||||
|
||||
private void OnCurrentValueSet(object? sender, LayerPropertyEventArgs e)
|
||||
{
|
||||
// Don't allow the int range to be null
|
||||
BaseValue ??= DefaultValue ?? new FloatRange();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,17 +3,11 @@
|
||||
/// <inheritdoc />
|
||||
public class IntRangeLayerProperty : LayerProperty<IntRange>
|
||||
{
|
||||
internal IntRangeLayerProperty()
|
||||
{
|
||||
CurrentValueSet += OnCurrentValueSet;
|
||||
DefaultValue = new IntRange();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnInitialize()
|
||||
{
|
||||
DataBinding.RegisterDataBindingProperty(() => CurrentValue.Start, value => CurrentValue.Start = value, "Start");
|
||||
DataBinding.RegisterDataBindingProperty(() => CurrentValue.End, value => CurrentValue.End = value, "End");
|
||||
DataBinding.RegisterDataBindingProperty(() => CurrentValue.Start, value => CurrentValue = new IntRange(value, CurrentValue.End), "Start");
|
||||
DataBinding.RegisterDataBindingProperty(() => CurrentValue.End, value => CurrentValue = new IntRange(CurrentValue.Start, value), "End");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@ -26,11 +20,5 @@
|
||||
(int) (CurrentKeyframe!.Value.End + endDiff * keyframeProgressEased)
|
||||
);
|
||||
}
|
||||
|
||||
private void OnCurrentValueSet(object? sender, LayerPropertyEventArgs e)
|
||||
{
|
||||
// Don't allow the int range to be null
|
||||
BaseValue ??= DefaultValue ?? new IntRange();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -55,6 +55,21 @@ public class ColorGradient : IList<ColorGradientStop>, IList, INotifyCollectionC
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="ColorGradient" /> class
|
||||
/// </summary>
|
||||
/// <param name="stops">The stops to copy</param>
|
||||
public ColorGradient(List<ColorGradientStop> stops)
|
||||
{
|
||||
_stops = new List<ColorGradientStop>();
|
||||
foreach (ColorGradientStop colorGradientStop in stops)
|
||||
{
|
||||
ColorGradientStop stop = new(colorGradientStop.Color, colorGradientStop.Position);
|
||||
stop.PropertyChanged += ItemOnPropertyChanged;
|
||||
_stops.Add(stop);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all the colors in the color gradient
|
||||
/// </summary>
|
||||
@ -462,7 +477,7 @@ public class ColorGradient : IList<ColorGradientStop>, IList, INotifyCollectionC
|
||||
public int Add(object? value)
|
||||
{
|
||||
if (value is ColorGradientStop stop)
|
||||
_stops.Add(stop);
|
||||
Add(stop);
|
||||
|
||||
return IndexOf(value);
|
||||
}
|
||||
@ -492,14 +507,14 @@ public class ColorGradient : IList<ColorGradientStop>, IList, INotifyCollectionC
|
||||
public void Insert(int index, object? value)
|
||||
{
|
||||
if (value is ColorGradientStop stop)
|
||||
_stops.Insert(index, stop);
|
||||
Insert(index, stop);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Remove(object? value)
|
||||
{
|
||||
if (value is ColorGradientStop stop)
|
||||
_stops.Remove(stop);
|
||||
Remove(stop);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@ -633,6 +633,7 @@ namespace Artemis.Core
|
||||
if (!baseLayerEffect.Suspended)
|
||||
baseLayerEffect.InternalPreProcess(canvas, bounds, layerPaint);
|
||||
}
|
||||
|
||||
canvas.ClipPath(renderPath);
|
||||
|
||||
// Restore the blend mode before doing the actual render
|
||||
@ -788,10 +789,14 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
public void ChangeLayerBrush(BaseLayerBrush? layerBrush)
|
||||
{
|
||||
BaseLayerBrush? oldLayerBrush = LayerBrush;
|
||||
|
||||
General.BrushReference.SetCurrentValue(layerBrush != null ? new LayerBrushReference(layerBrush.Descriptor) : null, null);
|
||||
LayerBrush = layerBrush;
|
||||
LayerEntity.LayerBrush = new LayerBrushEntity();
|
||||
|
||||
oldLayerBrush?.InternalDisable();
|
||||
|
||||
if (LayerBrush != null)
|
||||
ActivateLayerBrush();
|
||||
else
|
||||
@ -815,7 +820,12 @@ namespace Artemis.Core
|
||||
General.ShapeType.IsHidden = LayerBrush != null && !LayerBrush.SupportsTransformation;
|
||||
General.BlendMode.IsHidden = LayerBrush != null && !LayerBrush.SupportsTransformation;
|
||||
Transform.IsHidden = LayerBrush != null && !LayerBrush.SupportsTransformation;
|
||||
LayerBrush?.Update(0);
|
||||
if (LayerBrush != null)
|
||||
{
|
||||
if (!LayerBrush.Enabled)
|
||||
LayerBrush.InternalEnable();
|
||||
LayerBrush?.Update(0);
|
||||
}
|
||||
|
||||
OnLayerBrushUpdated();
|
||||
ClearBrokenState("Failed to initialize layer brush");
|
||||
|
||||
@ -5,18 +5,10 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Represents a range between two single-precision floating point numbers
|
||||
/// </summary>
|
||||
public class FloatRange
|
||||
public readonly struct FloatRange
|
||||
{
|
||||
private readonly Random _rand;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="FloatRange" /> class
|
||||
/// </summary>
|
||||
public FloatRange()
|
||||
{
|
||||
_rand = new Random();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="FloatRange" /> class
|
||||
/// </summary>
|
||||
@ -31,14 +23,14 @@ namespace Artemis.Core
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the start value of the range
|
||||
/// Gets the start value of the range
|
||||
/// </summary>
|
||||
public float Start { get; set; }
|
||||
public float Start { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the end value of the range
|
||||
/// Gets the end value of the range
|
||||
/// </summary>
|
||||
public float End { get; set; }
|
||||
public float End { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the given value is in this range
|
||||
|
||||
@ -5,18 +5,10 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Represents a range between two signed integers
|
||||
/// </summary>
|
||||
public class IntRange
|
||||
public readonly struct IntRange
|
||||
{
|
||||
private readonly Random _rand;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="IntRange" /> class
|
||||
/// </summary>
|
||||
public IntRange()
|
||||
{
|
||||
_rand = new Random();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="IntRange" /> class
|
||||
/// </summary>
|
||||
@ -31,14 +23,14 @@ namespace Artemis.Core
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the start value of the range
|
||||
/// Gets the start value of the range
|
||||
/// </summary>
|
||||
public int Start { get; set; }
|
||||
public int Start { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the end value of the range
|
||||
/// Gets the end value of the range
|
||||
/// </summary>
|
||||
public int End { get; set; }
|
||||
public int End { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the given value is in this range
|
||||
|
||||
@ -261,7 +261,7 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Gets whether keyframes are supported on this type of property
|
||||
/// </summary>
|
||||
public bool KeyframesSupported { get; protected internal set; } = true;
|
||||
public bool KeyframesSupported { get; protected set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether keyframes are enabled on this property, has no effect if <see cref="KeyframesSupported" /> is
|
||||
|
||||
@ -39,8 +39,6 @@ namespace Artemis.Core.LayerBrushes
|
||||
PropertyGroupDescriptionAttribute groupDescription = new() {Identifier = "Brush", Name = Descriptor.DisplayName, Description = Descriptor.Description};
|
||||
Properties.Initialize(Layer, null, groupDescription, propertyGroupEntity);
|
||||
PropertiesInitialized = true;
|
||||
|
||||
EnableLayerBrush();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,8 +3,8 @@
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ApplicationIcon />
|
||||
<StartupObject />
|
||||
<ApplicationIcon/>
|
||||
<StartupObject/>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<Platforms>x64</Platforms>
|
||||
@ -15,20 +15,20 @@
|
||||
<ItemGroup>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" Version="0.10.15" />
|
||||
<PackageReference Include="Avalonia.Diagnostics" Version="0.10.15" />
|
||||
<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.15" />
|
||||
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="0.10.14" />
|
||||
<PackageReference Include="DynamicData" Version="7.8.6" />
|
||||
<PackageReference Include="FluentAvaloniaUI" Version="1.4.1" />
|
||||
<PackageReference Include="Material.Icons.Avalonia" Version="1.0.2" />
|
||||
<PackageReference Include="ReactiveUI" Version="17.1.50" />
|
||||
<PackageReference Include="ReactiveUI.Validation" Version="2.2.1" />
|
||||
<PackageReference Include="RGB.NET.Core" Version="1.0.0-prerelease.32" />
|
||||
<PackageReference Include="SkiaSharp" Version="2.88.1-preview.1" />
|
||||
<PackageReference Include="Avalonia" Version="0.10.15"/>
|
||||
<PackageReference Include="Avalonia.Diagnostics" Version="0.10.15"/>
|
||||
<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.15"/>
|
||||
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="0.10.14"/>
|
||||
<PackageReference Include="DynamicData" Version="7.8.6"/>
|
||||
<PackageReference Include="FluentAvaloniaUI" Version="1.4.1"/>
|
||||
<PackageReference Include="Material.Icons.Avalonia" Version="1.0.2"/>
|
||||
<PackageReference Include="ReactiveUI" Version="17.1.50"/>
|
||||
<PackageReference Include="ReactiveUI.Validation" Version="2.2.1"/>
|
||||
<PackageReference Include="RGB.NET.Core" Version="1.0.0-prerelease.32"/>
|
||||
<PackageReference Include="SkiaSharp" Version="2.88.1-preview.1"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Artemis.Core\Artemis.Core.csproj" />
|
||||
<ProjectReference Include="..\Artemis.Core\Artemis.Core.csproj"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="Controls\HotkeyBox.axaml.cs">
|
||||
|
||||
@ -24,7 +24,7 @@ public class GradientPickerButton : TemplatedControl
|
||||
/// Gets or sets the color gradient.
|
||||
/// </summary>
|
||||
public static readonly StyledProperty<ColorGradient?> ColorGradientProperty =
|
||||
AvaloniaProperty.Register<GradientPickerButton, ColorGradient?>(nameof(ColorGradient), notifying: ColorGradientChanged, defaultValue: ColorGradient.GetUnicornBarf());
|
||||
AvaloniaProperty.Register<GradientPickerButton, ColorGradient?>(nameof(ColorGradient), notifying: ColorGradientChanged);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean indicating whether the gradient picker should be in compact mode or not.
|
||||
@ -108,7 +108,8 @@ public class GradientPickerButton : TemplatedControl
|
||||
|
||||
private static void ColorGradientChanged(IAvaloniaObject sender, bool before)
|
||||
{
|
||||
(sender as GradientPickerButton)?.Subscribe();
|
||||
if (!before)
|
||||
(sender as GradientPickerButton)?.Subscribe();
|
||||
}
|
||||
|
||||
private void Subscribe()
|
||||
|
||||
@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.Core;
|
||||
|
||||
namespace Artemis.UI.Shared.Services.ProfileEditor.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a profile editor command that can be used to update a layer property of type <typeparamref name="T" />.
|
||||
/// </summary>
|
||||
public class UpdateColorGradient : IProfileEditorCommand
|
||||
{
|
||||
private readonly ColorGradient _colorGradient;
|
||||
private readonly List<ColorGradientStop> _stops;
|
||||
private readonly List<ColorGradientStop> _originalStops;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="UpdateColorGradient" /> class.
|
||||
/// </summary>
|
||||
public UpdateColorGradient(ColorGradient colorGradient, List<ColorGradientStop> stops, List<ColorGradientStop>? originalStops)
|
||||
{
|
||||
_colorGradient = colorGradient;
|
||||
_stops = stops;
|
||||
_originalStops = originalStops ?? _colorGradient.Select(s => new ColorGradientStop(s.Color, s.Position)).ToList();
|
||||
}
|
||||
|
||||
#region Implementation of IProfileEditorCommand
|
||||
|
||||
/// <inheritdoc />
|
||||
public string DisplayName => "Update color gradient";
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Execute()
|
||||
{
|
||||
_colorGradient.Clear();
|
||||
foreach (ColorGradientStop colorGradientStop in _stops)
|
||||
_colorGradient.Add(colorGradientStop);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Undo()
|
||||
{
|
||||
_colorGradient.Clear();
|
||||
foreach (ColorGradientStop colorGradientStop in _originalStops)
|
||||
_colorGradient.Add(colorGradientStop);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@ -8,44 +8,44 @@
|
||||
<Platforms>x64</Platforms>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<AvaloniaResource Include="Assets\**" />
|
||||
<AvaloniaResource Include="Assets\**"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="Artemis.UI.Avalonia.csproj.DotSettings" />
|
||||
<None Remove="Artemis.UI.csproj.DotSettings" />
|
||||
<None Remove="Assets\Images\Logo\application.ico" />
|
||||
<None Remove="Artemis.UI.Avalonia.csproj.DotSettings"/>
|
||||
<None Remove="Artemis.UI.csproj.DotSettings"/>
|
||||
<None Remove="Assets\Images\Logo\application.ico"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" Version="0.10.15" />
|
||||
<PackageReference Include="Avalonia.Controls.PanAndZoom" Version="10.14.0" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="0.10.15" />
|
||||
<PackageReference Include="Avalonia.Diagnostics" Version="0.10.15" />
|
||||
<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.15" />
|
||||
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="0.10.14" />
|
||||
<PackageReference Include="DynamicData" Version="7.8.6" />
|
||||
<PackageReference Include="FluentAvaloniaUI" Version="1.4.1" />
|
||||
<PackageReference Include="Flurl.Http" Version="3.2.4" />
|
||||
<PackageReference Include="Live.Avalonia" Version="1.3.1" />
|
||||
<PackageReference Include="Material.Icons.Avalonia" Version="1.0.2" />
|
||||
<PackageReference Include="ReactiveUI" Version="17.1.50" />
|
||||
<PackageReference Include="ReactiveUI.Validation" Version="2.2.1" />
|
||||
<PackageReference Include="RGB.NET.Core" Version="1.0.0-prerelease.32" />
|
||||
<PackageReference Include="RGB.NET.Layout" Version="1.0.0-prerelease.32" />
|
||||
<PackageReference Include="SkiaSharp" Version="2.88.1-preview.1" />
|
||||
<PackageReference Include="Splat.Ninject" Version="14.1.45" />
|
||||
<PackageReference Include="Avalonia" Version="0.10.15"/>
|
||||
<PackageReference Include="Avalonia.Controls.PanAndZoom" Version="10.14.0"/>
|
||||
<PackageReference Include="Avalonia.Desktop" Version="0.10.15"/>
|
||||
<PackageReference Include="Avalonia.Diagnostics" Version="0.10.15"/>
|
||||
<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.15"/>
|
||||
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="0.10.14"/>
|
||||
<PackageReference Include="DynamicData" Version="7.8.6"/>
|
||||
<PackageReference Include="FluentAvaloniaUI" Version="1.4.1"/>
|
||||
<PackageReference Include="Flurl.Http" Version="3.2.4"/>
|
||||
<PackageReference Include="Live.Avalonia" Version="1.3.1"/>
|
||||
<PackageReference Include="Material.Icons.Avalonia" Version="1.0.2"/>
|
||||
<PackageReference Include="ReactiveUI" Version="17.1.50"/>
|
||||
<PackageReference Include="ReactiveUI.Validation" Version="2.2.1"/>
|
||||
<PackageReference Include="RGB.NET.Core" Version="1.0.0-prerelease.32"/>
|
||||
<PackageReference Include="RGB.NET.Layout" Version="1.0.0-prerelease.32"/>
|
||||
<PackageReference Include="SkiaSharp" Version="2.88.1-preview.1"/>
|
||||
<PackageReference Include="Splat.Ninject" Version="14.1.45"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Artemis.Core\Artemis.Core.csproj" />
|
||||
<ProjectReference Include="..\Artemis.UI.Shared\Artemis.UI.Shared.csproj" />
|
||||
<ProjectReference Include="..\Artemis.VisualScripting\Artemis.VisualScripting.csproj" />
|
||||
<ProjectReference Include="..\Artemis.Core\Artemis.Core.csproj"/>
|
||||
<ProjectReference Include="..\Artemis.UI.Shared\Artemis.UI.Shared.csproj"/>
|
||||
<ProjectReference Include="..\Artemis.VisualScripting\Artemis.VisualScripting.csproj"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Assets\Images\Logo\bow-white.ico" />
|
||||
<Content Include="Assets\Images\Logo\bow.ico" />
|
||||
<Content Include="Assets\Images\Logo\bow-white.ico"/>
|
||||
<Content Include="Assets\Images\Logo\bow.ico"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Assets\Images\Logo\bow-black.ico" />
|
||||
<Resource Include="Assets\Images\Logo\bow-white.ico" />
|
||||
<Resource Include="Assets\Images\Logo\bow-black.ico"/>
|
||||
<Resource Include="Assets\Images\Logo\bow-white.ico"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="DefaultTypes\PropertyInput\StringPropertyInputView.axaml.cs">
|
||||
@ -72,8 +72,8 @@
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Screens\Scripting\Dialogs\ScriptConfigurationEditView.axaml.cs">
|
||||
<DependentUpon>ScriptConfigurationEditView.axaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
<DependentUpon>ScriptConfigurationEditView.axaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
x:DataType="propertyInput:ColorGradientPropertyInputViewModel">
|
||||
<gradientPicker:GradientPickerButton Classes="condensed"
|
||||
Width="200"
|
||||
ColorGradient="{CompiledBinding ColorGradient}"
|
||||
ColorGradient="{CompiledBinding InputValue}"
|
||||
VerticalAlignment="Center"
|
||||
FlyoutOpened="GradientPickerButton_OnFlyoutOpened"
|
||||
FlyoutClosed="GradientPickerButton_OnFlyoutClosed"/>
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
using Artemis.Core;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Shared.Services.ProfileEditor;
|
||||
using Artemis.UI.Shared.Services.ProfileEditor.Commands;
|
||||
using Artemis.UI.Shared.Services.PropertyInput;
|
||||
@ -9,37 +11,19 @@ namespace Artemis.UI.DefaultTypes.PropertyInput;
|
||||
public class ColorGradientPropertyInputViewModel : PropertyInputViewModel<ColorGradient>
|
||||
{
|
||||
private ColorGradient _colorGradient = null!;
|
||||
private ColorGradient? _originalGradient;
|
||||
private List<ColorGradientStop>? _originalStops;
|
||||
|
||||
public ColorGradientPropertyInputViewModel(LayerProperty<ColorGradient> layerProperty, IProfileEditorService profileEditorService, IPropertyInputService propertyInputService)
|
||||
: base(layerProperty, profileEditorService, propertyInputService)
|
||||
{
|
||||
}
|
||||
|
||||
public ColorGradient ColorGradient
|
||||
{
|
||||
get => _colorGradient;
|
||||
set => this.RaiseAndSetIfChanged(ref _colorGradient, value);
|
||||
}
|
||||
|
||||
protected override void OnInputValueChanged()
|
||||
{
|
||||
ColorGradient = new ColorGradient(InputValue);
|
||||
}
|
||||
|
||||
#region Overrides of PropertyInputViewModel<ColorGradient>
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void StartPreview()
|
||||
{
|
||||
_originalGradient = LayerProperty.CurrentValue;
|
||||
|
||||
// Set the property value to the gradient being edited by the picker, this will cause any updates to show right away because
|
||||
// ColorGradient is a reference type
|
||||
LayerProperty.CurrentValue = ColorGradient;
|
||||
|
||||
// This won't fly if we ever support keyframes but at that point ColorGradient would have to be a value type anyway and this
|
||||
// whole VM no longer makes sense
|
||||
_originalStops = InputValue?.Select(s => new ColorGradientStop(s.Color, s.Position)).ToList();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@ -51,28 +35,40 @@ public class ColorGradientPropertyInputViewModel : PropertyInputViewModel<ColorG
|
||||
/// <inheritdoc />
|
||||
public override void ApplyPreview()
|
||||
{
|
||||
if (_originalGradient == null)
|
||||
// If the new stops are equal to the old ones, nothing changes
|
||||
if (InputValue == null || _originalStops == null || !HasPreviewChanges())
|
||||
return;
|
||||
|
||||
// Make sure something actually changed
|
||||
if (Equals(ColorGradient, _originalGradient))
|
||||
LayerProperty.CurrentValue = _originalGradient;
|
||||
else
|
||||
// Update the gradient for realsies, giving the command a reference to the old gradient
|
||||
ProfileEditorService.ExecuteCommand(new UpdateLayerProperty<ColorGradient>(LayerProperty, ColorGradient, _originalGradient, Time));
|
||||
|
||||
_originalGradient = null;
|
||||
ProfileEditorService.ExecuteCommand(new UpdateColorGradient(InputValue, InputValue.ToList(), _originalStops));
|
||||
_originalStops = null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void DiscardPreview()
|
||||
{
|
||||
if (_originalGradient == null)
|
||||
if (InputValue == null || _originalStops == null)
|
||||
return;
|
||||
|
||||
// Put the old gradient back
|
||||
InputValue = _originalGradient;
|
||||
ColorGradient = new ColorGradient(InputValue);
|
||||
InputValue.Clear();
|
||||
foreach (ColorGradientStop colorGradientStop in _originalStops)
|
||||
InputValue.Add(colorGradientStop);
|
||||
_originalStops = null;
|
||||
}
|
||||
|
||||
private bool HasPreviewChanges()
|
||||
{
|
||||
if (InputValue == null || _originalStops == null)
|
||||
return false;
|
||||
|
||||
if (InputValue.Count != _originalStops.Count)
|
||||
return true;
|
||||
|
||||
for (int i = 0; i < InputValue.Count; i++)
|
||||
if (!Equals(InputValue[i], _originalStops[i]))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -30,28 +30,20 @@ public class FloatRangePropertyInputViewModel : PropertyInputViewModel<FloatRang
|
||||
|
||||
public float Start
|
||||
{
|
||||
get => InputValue?.Start ?? 0;
|
||||
get => InputValue.Start;
|
||||
set
|
||||
{
|
||||
if (InputValue == null)
|
||||
InputValue = new FloatRange(value, value + 1);
|
||||
else
|
||||
InputValue.Start = value;
|
||||
|
||||
InputValue = new FloatRange(value, InputValue.End);
|
||||
this.RaisePropertyChanged(nameof(Start));
|
||||
}
|
||||
}
|
||||
|
||||
public float End
|
||||
{
|
||||
get => InputValue?.End ?? 0;
|
||||
get => InputValue.End;
|
||||
set
|
||||
{
|
||||
if (InputValue == null)
|
||||
InputValue = new FloatRange(value - 1, value);
|
||||
else
|
||||
InputValue.End = value;
|
||||
|
||||
InputValue = new FloatRange(InputValue.Start, value);
|
||||
this.RaisePropertyChanged(nameof(End));
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,28 +30,20 @@ public class IntRangePropertyInputViewModel : PropertyInputViewModel<IntRange>
|
||||
|
||||
public int Start
|
||||
{
|
||||
get => InputValue?.Start ?? 0;
|
||||
get => InputValue.Start;
|
||||
set
|
||||
{
|
||||
if (InputValue == null)
|
||||
InputValue = new IntRange(value, value + 1);
|
||||
else
|
||||
InputValue.Start = value;
|
||||
|
||||
InputValue = new IntRange(value, InputValue.End);
|
||||
this.RaisePropertyChanged(nameof(Start));
|
||||
}
|
||||
}
|
||||
|
||||
public int End
|
||||
{
|
||||
get => InputValue?.End ?? 0;
|
||||
get => InputValue.End;
|
||||
set
|
||||
{
|
||||
if (InputValue == null)
|
||||
InputValue = new IntRange(value - 1, value);
|
||||
else
|
||||
InputValue.End = value;
|
||||
|
||||
InputValue = new IntRange(InputValue.Start, value);
|
||||
this.RaisePropertyChanged(nameof(End));
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user