mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Data binding modifiers - Finished color saturate/desaturate
Data binding modifiers - Added color invert Layer properties - Added FloatRange and IntRange layer properties
This commit is contained in:
parent
925bedc0a6
commit
0795069af2
@ -1,4 +1,5 @@
|
|||||||
using SkiaSharp;
|
using System;
|
||||||
|
using SkiaSharp;
|
||||||
|
|
||||||
namespace Artemis.Core.DefaultTypes
|
namespace Artemis.Core.DefaultTypes
|
||||||
{
|
{
|
||||||
@ -10,10 +11,11 @@ namespace Artemis.Core.DefaultTypes
|
|||||||
|
|
||||||
public override SKColor Apply(SKColor currentValue, float parameterValue)
|
public override SKColor Apply(SKColor currentValue, float parameterValue)
|
||||||
{
|
{
|
||||||
// TODO: Not so straightforward ^^
|
|
||||||
currentValue.ToHsl(out float h, out float s, out float l);
|
currentValue.ToHsl(out float h, out float s, out float l);
|
||||||
s *= (parameterValue * -1 + 100f) / 100f;
|
s -= parameterValue;
|
||||||
return SKColor.FromHsl(h, s, l);
|
s = Math.Clamp(s, 0, 100);
|
||||||
|
|
||||||
|
return SKColor.FromHsl(h, s, l, currentValue.Alpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
using SkiaSharp;
|
||||||
|
|
||||||
|
namespace Artemis.Core.DefaultTypes
|
||||||
|
{
|
||||||
|
internal class SKColorInvertModifierType : DataBindingModifierType<SKColor>
|
||||||
|
{
|
||||||
|
public override string Name => "Invert color";
|
||||||
|
public override string Icon => "InvertColors";
|
||||||
|
public override string Description => "Inverts the color by rotating its hue by a 180°";
|
||||||
|
|
||||||
|
public override SKColor Apply(SKColor currentValue)
|
||||||
|
{
|
||||||
|
currentValue.ToHsl(out float h, out float s, out float l);
|
||||||
|
h += 180;
|
||||||
|
return SKColor.FromHsl(h % 360, s, l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
using SkiaSharp;
|
using System;
|
||||||
|
using SkiaSharp;
|
||||||
|
|
||||||
namespace Artemis.Core.DefaultTypes
|
namespace Artemis.Core.DefaultTypes
|
||||||
{
|
{
|
||||||
@ -10,9 +11,11 @@ namespace Artemis.Core.DefaultTypes
|
|||||||
|
|
||||||
public override SKColor Apply(SKColor currentValue, float parameterValue)
|
public override SKColor Apply(SKColor currentValue, float parameterValue)
|
||||||
{
|
{
|
||||||
// TODO: Not so straightforward ^^
|
currentValue.ToHsv(out float h, out float s, out float v);
|
||||||
currentValue.ToHsl(out float h, out float s, out float l);
|
s += parameterValue;
|
||||||
return SKColor.FromHsl(h, parameterValue, l);
|
s = Math.Clamp(s, 0, 100);
|
||||||
|
|
||||||
|
return SKColor.FromHsv(h, s, v, currentValue.Alpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,4 +1,6 @@
|
|||||||
namespace Artemis.Core.DefaultTypes
|
using System;
|
||||||
|
|
||||||
|
namespace Artemis.Core.DefaultTypes
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public class FloatLayerProperty : LayerProperty<float>
|
public class FloatLayerProperty : LayerProperty<float>
|
||||||
|
|||||||
@ -0,0 +1,31 @@
|
|||||||
|
namespace Artemis.Core.DefaultTypes
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public class FloatRangeLayerProperty : LayerProperty<FloatRange>
|
||||||
|
{
|
||||||
|
internal FloatRangeLayerProperty()
|
||||||
|
{
|
||||||
|
RegisterDataBindingProperty(range => range.Start, new FloatDataBindingConverter<FloatRange>());
|
||||||
|
RegisterDataBindingProperty(range => range.End, new FloatDataBindingConverter<FloatRange>());
|
||||||
|
|
||||||
|
CurrentValueSet += OnCurrentValueSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCurrentValueSet(object sender, LayerPropertyEventArgs<FloatRange> e)
|
||||||
|
{
|
||||||
|
// Don't allow the int range to be null
|
||||||
|
BaseValue ??= DefaultValue ?? new FloatRange(0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Artemis.Core.DefaultTypes
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public class IntRangeLayerProperty : LayerProperty<IntRange>
|
||||||
|
{
|
||||||
|
internal IntRangeLayerProperty()
|
||||||
|
{
|
||||||
|
RegisterDataBindingProperty(range => range.Start, new IntDataBindingConverter<IntRange>());
|
||||||
|
RegisterDataBindingProperty(range => range.End, new IntDataBindingConverter<IntRange>());
|
||||||
|
|
||||||
|
CurrentValueSet += OnCurrentValueSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased)
|
||||||
|
{
|
||||||
|
float startDiff = NextKeyframe.Value.Start - CurrentKeyframe.Value.Start;
|
||||||
|
float endDiff = NextKeyframe.Value.End - CurrentKeyframe.Value.End;
|
||||||
|
CurrentValue = new IntRange(
|
||||||
|
(int) (CurrentKeyframe.Value.Start + startDiff * keyframeProgressEased),
|
||||||
|
(int) (CurrentKeyframe.Value.End + endDiff * keyframeProgressEased)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCurrentValueSet(object sender, LayerPropertyEventArgs<IntRange> e)
|
||||||
|
{
|
||||||
|
// Don't allow the int range to be null
|
||||||
|
BaseValue ??= DefaultValue ?? new IntRange(0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,63 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Artemis.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a range between two single-precision floating point numbers
|
||||||
|
/// </summary>
|
||||||
|
public class FloatRange
|
||||||
|
{
|
||||||
|
private readonly Random _rand;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="FloatRange" /> class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="start">The start value of the range</param>
|
||||||
|
/// <param name="end">The end value of the range</param>
|
||||||
|
public FloatRange(float start, float end)
|
||||||
|
{
|
||||||
|
Start = start;
|
||||||
|
End = end;
|
||||||
|
|
||||||
|
_rand = new Random();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the start value of the range
|
||||||
|
/// </summary>
|
||||||
|
public float Start { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the end value of the range
|
||||||
|
/// </summary>
|
||||||
|
public float End { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the given value is in this range
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The value to check</param>
|
||||||
|
/// <param name="inclusive">
|
||||||
|
/// Whether the value may be equal to <see cref="Start" /> or <see cref="End" />
|
||||||
|
/// <para>Defaults to <see langword="true" /></para>
|
||||||
|
/// </param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool IsInRange(float value, bool inclusive = true)
|
||||||
|
{
|
||||||
|
if (inclusive)
|
||||||
|
return value >= Start && value <= End;
|
||||||
|
return value > Start && value < End;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a pseudo-random value between <see cref="Start" /> and <see cref="End" />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inclusive">Whether the value may be equal to <see cref="Start" /></param>
|
||||||
|
/// <returns>The pseudo-random value</returns>
|
||||||
|
public float GetRandomValue(bool inclusive = true)
|
||||||
|
{
|
||||||
|
if (inclusive)
|
||||||
|
return _rand.Next((int) (Start * 100), (int) (End * 100)) / 100f;
|
||||||
|
return _rand.Next((int) (Start * 100) + 1, (int) (End * 100)) / 100f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
63
src/Artemis.Core/Models/Profile/LayerProperties/IntRange.cs
Normal file
63
src/Artemis.Core/Models/Profile/LayerProperties/IntRange.cs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Artemis.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a range between two signed integers
|
||||||
|
/// </summary>
|
||||||
|
public class IntRange
|
||||||
|
{
|
||||||
|
private readonly Random _rand;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="IntRange" /> class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="start">The start value of the range</param>
|
||||||
|
/// <param name="end">The end value of the range</param>
|
||||||
|
public IntRange(int start, int end)
|
||||||
|
{
|
||||||
|
Start = start;
|
||||||
|
End = end;
|
||||||
|
|
||||||
|
_rand = new Random();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the start value of the range
|
||||||
|
/// </summary>
|
||||||
|
public int Start { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the end value of the range
|
||||||
|
/// </summary>
|
||||||
|
public int End { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the given value is in this range
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The value to check</param>
|
||||||
|
/// <param name="inclusive">
|
||||||
|
/// Whether the value may be equal to <see cref="Start" /> or <see cref="End" />
|
||||||
|
/// <para>Defaults to <see langword="true" /></para>
|
||||||
|
/// </param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool IsInRange(int value, bool inclusive = true)
|
||||||
|
{
|
||||||
|
if (inclusive)
|
||||||
|
return value >= Start && value <= End;
|
||||||
|
return value > Start && value < End;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a pseudo-random value between <see cref="Start" /> and <see cref="End" />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inclusive">Whether the value may be equal to <see cref="Start" /></param>
|
||||||
|
/// <returns>The pseudo-random value</returns>
|
||||||
|
public int GetRandomValue(bool inclusive = true)
|
||||||
|
{
|
||||||
|
if (inclusive)
|
||||||
|
return _rand.Next(Start, End + 1);
|
||||||
|
return _rand.Next(Start + 1, End);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -77,6 +77,7 @@ namespace Artemis.Core.Services
|
|||||||
RegisterModifierType(Constants.CorePluginInfo, new SKColorBrightenModifierType());
|
RegisterModifierType(Constants.CorePluginInfo, new SKColorBrightenModifierType());
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new SKColorDarkenModifierType());
|
RegisterModifierType(Constants.CorePluginInfo, new SKColorDarkenModifierType());
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new SKColorRotateHueModifierType());
|
RegisterModifierType(Constants.CorePluginInfo, new SKColorRotateHueModifierType());
|
||||||
|
RegisterModifierType(Constants.CorePluginInfo, new SKColorInvertModifierType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -332,5 +332,8 @@
|
|||||||
<Page Update="DefaultTypes\DataModel\Input\StringDataModelInputView.xaml">
|
<Page Update="DefaultTypes\DataModel\Input\StringDataModelInputView.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
|
<Page Update="DefaultTypes\PropertyInput\FloatRangePropertyInputView.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
<UserControl x:Class="Artemis.UI.PropertyInput.FloatRangePropertyInputView"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="clr-namespace:Artemis.UI.PropertyInput"
|
||||||
|
xmlns:s="https://github.com/canton7/Stylet"
|
||||||
|
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
d:DesignHeight="450" d:DesignWidth="800"
|
||||||
|
d:DataContext="{d:DesignInstance local:FloatRangePropertyInputViewModel}">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<TextBlock Width="10" Text="{Binding LayerProperty.PropertyDescription.InputPrefix}" />
|
||||||
|
<shared:DraggableFloat ToolTip="Start"
|
||||||
|
Value="{Binding Start}"
|
||||||
|
StepSize="{Binding LayerProperty.PropertyDescription.InputStepSize}"
|
||||||
|
Max="{Binding End}"
|
||||||
|
Min="{Binding LayerProperty.PropertyDescription.MinInputValue}"
|
||||||
|
DragStarted="{s:Action InputDragStarted}"
|
||||||
|
DragEnded="{s:Action InputDragEnded}"
|
||||||
|
IsEnabled="{Binding IsStartEnabled}"/>
|
||||||
|
<TextBlock Margin="5 0" VerticalAlignment="Bottom">-</TextBlock>
|
||||||
|
<shared:DraggableFloat ToolTip="End"
|
||||||
|
Value="{Binding End}"
|
||||||
|
StepSize="{Binding LayerProperty.PropertyDescription.InputStepSize}"
|
||||||
|
Max="{Binding LayerProperty.PropertyDescription.MaxInputValue}"
|
||||||
|
Min="{Binding Start}"
|
||||||
|
DragStarted="{s:Action InputDragStarted}"
|
||||||
|
DragEnded="{s:Action InputDragEnded}"
|
||||||
|
IsEnabled="{Binding IsEndEnabled}"/>
|
||||||
|
<TextBlock Width="10" Text="{Binding LayerProperty.PropertyDescription.InputAffix}" />
|
||||||
|
</StackPanel>
|
||||||
|
</UserControl>
|
||||||
@ -0,0 +1,82 @@
|
|||||||
|
using System;
|
||||||
|
using Artemis.Core;
|
||||||
|
using Artemis.UI.Shared;
|
||||||
|
using Artemis.UI.Shared.Services;
|
||||||
|
using FluentValidation;
|
||||||
|
using Stylet;
|
||||||
|
|
||||||
|
namespace Artemis.UI.PropertyInput
|
||||||
|
{
|
||||||
|
public class FloatRangePropertyInputViewModel : PropertyInputViewModel<FloatRange>
|
||||||
|
{
|
||||||
|
private readonly DataBindingRegistration<FloatRange, float> _startRegistration;
|
||||||
|
private readonly DataBindingRegistration<FloatRange, float> _endRegistration;
|
||||||
|
|
||||||
|
public FloatRangePropertyInputViewModel(LayerProperty<FloatRange> layerProperty,
|
||||||
|
IProfileEditorService profileEditorService,
|
||||||
|
IModelValidator<FloatRangePropertyInputViewModel> validator) : base(layerProperty, profileEditorService, validator)
|
||||||
|
{
|
||||||
|
_startRegistration = layerProperty.GetDataBindingRegistration(range => range.Start);
|
||||||
|
_endRegistration = layerProperty.GetDataBindingRegistration(range => range.End);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float Start
|
||||||
|
{
|
||||||
|
get => InputValue?.Start ?? 0f;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (InputValue == null)
|
||||||
|
InputValue = new FloatRange(value, value + 1f);
|
||||||
|
else
|
||||||
|
InputValue.Start = value;
|
||||||
|
|
||||||
|
NotifyOfPropertyChange(nameof(Start));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float End
|
||||||
|
{
|
||||||
|
get => InputValue?.End ?? 0f;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (InputValue == null)
|
||||||
|
InputValue = new FloatRange(value - 1f, value);
|
||||||
|
else
|
||||||
|
InputValue.End = value;
|
||||||
|
|
||||||
|
NotifyOfPropertyChange(nameof(End));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsStartEnabled => _startRegistration.DataBinding == null;
|
||||||
|
public bool IsEndEnabled => _endRegistration.DataBinding == null;
|
||||||
|
|
||||||
|
protected override void OnInputValueChanged()
|
||||||
|
{
|
||||||
|
NotifyOfPropertyChange(nameof(Start));
|
||||||
|
NotifyOfPropertyChange(nameof(End));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDataBindingsChanged()
|
||||||
|
{
|
||||||
|
NotifyOfPropertyChange(nameof(IsStartEnabled));
|
||||||
|
NotifyOfPropertyChange(nameof(IsEndEnabled));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FloatRangePropertyInputViewModelValidator : AbstractValidator<FloatRangePropertyInputViewModel>
|
||||||
|
{
|
||||||
|
public FloatRangePropertyInputViewModelValidator()
|
||||||
|
{
|
||||||
|
RuleFor(vm => vm.Start).LessThanOrEqualTo(vm => vm.End);
|
||||||
|
RuleFor(vm => vm.End).GreaterThanOrEqualTo(vm => vm.Start);
|
||||||
|
|
||||||
|
RuleFor(vm => vm.Start)
|
||||||
|
.GreaterThanOrEqualTo(vm => Convert.ToSingle(vm.LayerProperty.PropertyDescription.MinInputValue))
|
||||||
|
.When(vm => vm.LayerProperty.PropertyDescription.MinInputValue.IsNumber());
|
||||||
|
RuleFor(vm => vm.End)
|
||||||
|
.LessThanOrEqualTo(vm => Convert.ToSingle(vm.LayerProperty.PropertyDescription.MaxInputValue))
|
||||||
|
.When(vm => vm.LayerProperty.PropertyDescription.MaxInputValue.IsNumber());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
<UserControl x:Class="Artemis.UI.PropertyInput.IntRangePropertyInputView"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="clr-namespace:Artemis.UI.PropertyInput"
|
||||||
|
xmlns:s="https://github.com/canton7/Stylet"
|
||||||
|
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
d:DesignHeight="450" d:DesignWidth="800"
|
||||||
|
d:DataContext="{d:DesignInstance local:IntRangePropertyInputViewModel}">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<TextBlock Width="10" Text="{Binding LayerProperty.PropertyDescription.InputPrefix}" />
|
||||||
|
<shared:DraggableFloat ToolTip="Start"
|
||||||
|
Value="{Binding Start}"
|
||||||
|
StepSize="{Binding LayerProperty.PropertyDescription.InputStepSize}"
|
||||||
|
Max="{Binding End}"
|
||||||
|
Min="{Binding LayerProperty.PropertyDescription.MinInputValue}"
|
||||||
|
DragStarted="{s:Action InputDragStarted}"
|
||||||
|
DragEnded="{s:Action InputDragEnded}"
|
||||||
|
IsEnabled="{Binding IsStartEnabled}"/>
|
||||||
|
<TextBlock Margin="5 0" VerticalAlignment="Bottom">-</TextBlock>
|
||||||
|
<shared:DraggableFloat ToolTip="End"
|
||||||
|
Value="{Binding End}"
|
||||||
|
StepSize="{Binding LayerProperty.PropertyDescription.InputStepSize}"
|
||||||
|
Max="{Binding LayerProperty.PropertyDescription.MaxInputValue}"
|
||||||
|
Min="{Binding Start}"
|
||||||
|
DragStarted="{s:Action InputDragStarted}"
|
||||||
|
DragEnded="{s:Action InputDragEnded}"
|
||||||
|
IsEnabled="{Binding IsEndEnabled}"/>
|
||||||
|
<TextBlock Width="10" Text="{Binding LayerProperty.PropertyDescription.InputAffix}" />
|
||||||
|
</StackPanel>
|
||||||
|
</UserControl>
|
||||||
@ -0,0 +1,82 @@
|
|||||||
|
using System;
|
||||||
|
using Artemis.Core;
|
||||||
|
using Artemis.UI.Shared;
|
||||||
|
using Artemis.UI.Shared.Services;
|
||||||
|
using FluentValidation;
|
||||||
|
using Stylet;
|
||||||
|
|
||||||
|
namespace Artemis.UI.PropertyInput
|
||||||
|
{
|
||||||
|
public class IntRangePropertyInputViewModel : PropertyInputViewModel<IntRange>
|
||||||
|
{
|
||||||
|
private readonly DataBindingRegistration<IntRange, int> _startRegistration;
|
||||||
|
private readonly DataBindingRegistration<IntRange, int> _endRegistration;
|
||||||
|
|
||||||
|
public IntRangePropertyInputViewModel(LayerProperty<IntRange> layerProperty,
|
||||||
|
IProfileEditorService profileEditorService,
|
||||||
|
IModelValidator<IntRangePropertyInputViewModel> validator) : base(layerProperty, profileEditorService, validator)
|
||||||
|
{
|
||||||
|
_startRegistration = layerProperty.GetDataBindingRegistration(range => range.Start);
|
||||||
|
_endRegistration = layerProperty.GetDataBindingRegistration(range => range.End);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Start
|
||||||
|
{
|
||||||
|
get => InputValue?.Start ?? 0;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (InputValue == null)
|
||||||
|
InputValue = new IntRange(value, value + 1);
|
||||||
|
else
|
||||||
|
InputValue.Start = value;
|
||||||
|
|
||||||
|
NotifyOfPropertyChange(nameof(Start));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int End
|
||||||
|
{
|
||||||
|
get => InputValue?.End ?? 0;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (InputValue == null)
|
||||||
|
InputValue = new IntRange(value - 1, value);
|
||||||
|
else
|
||||||
|
InputValue.End = value;
|
||||||
|
|
||||||
|
NotifyOfPropertyChange(nameof(End));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsStartEnabled => _startRegistration.DataBinding == null;
|
||||||
|
public bool IsEndEnabled => _endRegistration.DataBinding == null;
|
||||||
|
|
||||||
|
protected override void OnInputValueChanged()
|
||||||
|
{
|
||||||
|
NotifyOfPropertyChange(nameof(Start));
|
||||||
|
NotifyOfPropertyChange(nameof(End));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDataBindingsChanged()
|
||||||
|
{
|
||||||
|
NotifyOfPropertyChange(nameof(IsStartEnabled));
|
||||||
|
NotifyOfPropertyChange(nameof(IsEndEnabled));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IntRangePropertyInputViewModelValidator : AbstractValidator<IntRangePropertyInputViewModel>
|
||||||
|
{
|
||||||
|
public IntRangePropertyInputViewModelValidator()
|
||||||
|
{
|
||||||
|
RuleFor(vm => vm.Start).LessThanOrEqualTo(vm => vm.End);
|
||||||
|
RuleFor(vm => vm.End).GreaterThanOrEqualTo(vm => vm.Start);
|
||||||
|
|
||||||
|
RuleFor(vm => vm.Start)
|
||||||
|
.GreaterThanOrEqualTo(vm => Convert.ToInt32(vm.LayerProperty.PropertyDescription.MinInputValue))
|
||||||
|
.When(vm => vm.LayerProperty.PropertyDescription.MinInputValue.IsNumber());
|
||||||
|
RuleFor(vm => vm.End)
|
||||||
|
.LessThanOrEqualTo(vm => Convert.ToInt32(vm.LayerProperty.PropertyDescription.MaxInputValue))
|
||||||
|
.When(vm => vm.LayerProperty.PropertyDescription.MaxInputValue.IsNumber());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -67,6 +67,8 @@ namespace Artemis.UI.Services
|
|||||||
_profileEditorService.RegisterPropertyInput<SKSizePropertyInputViewModel>(Constants.CorePluginInfo);
|
_profileEditorService.RegisterPropertyInput<SKSizePropertyInputViewModel>(Constants.CorePluginInfo);
|
||||||
_profileEditorService.RegisterPropertyInput(typeof(EnumPropertyInputViewModel<>), Constants.CorePluginInfo);
|
_profileEditorService.RegisterPropertyInput(typeof(EnumPropertyInputViewModel<>), Constants.CorePluginInfo);
|
||||||
_profileEditorService.RegisterPropertyInput<BoolPropertyInputViewModel>(Constants.CorePluginInfo);
|
_profileEditorService.RegisterPropertyInput<BoolPropertyInputViewModel>(Constants.CorePluginInfo);
|
||||||
|
_profileEditorService.RegisterPropertyInput<FloatRangePropertyInputViewModel>(Constants.CorePluginInfo);
|
||||||
|
_profileEditorService.RegisterPropertyInput<IntRangePropertyInputViewModel>(Constants.CorePluginInfo);
|
||||||
|
|
||||||
_registeredBuiltInPropertyEditors = true;
|
_registeredBuiltInPropertyEditors = true;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user