mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Data bindings - Finished main functionality
This commit is contained in:
parent
fea454ad12
commit
f03ea410d4
@ -30,14 +30,14 @@ namespace Artemis.Core
|
||||
/// <inheritdoc />
|
||||
public override float Interpolate(float a, float b, double progress)
|
||||
{
|
||||
var diff = a - b;
|
||||
var diff = b - a;
|
||||
return (float) (a + diff * progress);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void ApplyValue(float value)
|
||||
{
|
||||
if (SetExpression == null)
|
||||
if (ValueTypeSetExpression == null)
|
||||
return;
|
||||
|
||||
if (DataBinding.LayerProperty.PropertyDescription.MaxInputValue is float max)
|
||||
@ -45,21 +45,7 @@ namespace Artemis.Core
|
||||
if (DataBinding.LayerProperty.PropertyDescription.MinInputValue is float min)
|
||||
value = Math.Max(value, min);
|
||||
|
||||
var test = new SKSize(5,5);
|
||||
test.Width = 10;
|
||||
|
||||
SetExpression(DataBinding.LayerProperty.CurrentValue, value);
|
||||
}
|
||||
|
||||
private void Mehtest(ref SKSize test)
|
||||
{
|
||||
test.Width = 20;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override float GetValue()
|
||||
{
|
||||
return GetExpression(DataBinding.LayerProperty.CurrentValue);
|
||||
base.ApplyValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -22,17 +22,5 @@ namespace Artemis.Core
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void ApplyValue(object value)
|
||||
{
|
||||
SetExpression?.Invoke(DataBinding.LayerProperty.CurrentValue, value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override object GetValue()
|
||||
{
|
||||
return GetExpression(DataBinding.LayerProperty.CurrentValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -37,17 +37,5 @@ namespace Artemis.Core
|
||||
var diff = b - a;
|
||||
return (int) Math.Round(a + diff * progress, InterpolationRoundingMode);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void ApplyValue(int value)
|
||||
{
|
||||
SetExpression?.Invoke(DataBinding.LayerProperty.CurrentValue, value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetValue()
|
||||
{
|
||||
return GetExpression(DataBinding.LayerProperty.CurrentValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -24,7 +24,7 @@ namespace Artemis.Core
|
||||
public override byte Interpolate(byte a, byte b, double progress)
|
||||
{
|
||||
var diff = b - a;
|
||||
return ClampToByte(diff * progress);
|
||||
return ClampToByte(a + diff * progress);
|
||||
}
|
||||
|
||||
public override void ApplyValue(byte value)
|
||||
@ -48,21 +48,10 @@ namespace Artemis.Core
|
||||
}
|
||||
}
|
||||
|
||||
public override byte GetValue()
|
||||
public override byte ConvertFromObject(object source)
|
||||
{
|
||||
switch (_channel)
|
||||
{
|
||||
case Channel.Alpha:
|
||||
return DataBinding.LayerProperty.CurrentValue.Alpha;
|
||||
case Channel.Red:
|
||||
return DataBinding.LayerProperty.CurrentValue.Red;
|
||||
case Channel.Green:
|
||||
return DataBinding.LayerProperty.CurrentValue.Green;
|
||||
case Channel.Blue:
|
||||
return DataBinding.LayerProperty.CurrentValue.Blue;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
var saveValue = Convert.ToDouble(source);
|
||||
return ClampToByte(saveValue);
|
||||
}
|
||||
|
||||
private static byte ClampToByte(double value)
|
||||
|
||||
@ -206,8 +206,8 @@ namespace Artemis.Core
|
||||
foreach (var dataBindingModifier in Modifiers)
|
||||
dataBindingValue = dataBindingModifier.Apply(dataBindingValue);
|
||||
|
||||
var value = (TProperty) Convert.ChangeType(dataBindingValue, typeof(TProperty));
|
||||
|
||||
TProperty value = Converter.ConvertFromObject(dataBindingValue);
|
||||
|
||||
// If no easing is to be applied simple return whatever the current value is
|
||||
if (EasingTime == TimeSpan.Zero || !Converter.SupportsInterpolate)
|
||||
return value;
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
@ -19,7 +18,9 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// A dynamically compiled setter pointing to the data bound property
|
||||
/// </summary>
|
||||
public Action<TLayerProperty, TProperty> SetExpression { get; private set; }
|
||||
public Action<TProperty> ValueTypeSetExpression { get; private set; }
|
||||
|
||||
public Action<TLayerProperty, TProperty> ReferenceTypeSetExpression { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the data binding this converter is applied to
|
||||
@ -59,12 +60,29 @@ namespace Artemis.Core
|
||||
/// Applies the <paramref name="value" /> to the layer property
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public abstract void ApplyValue(TProperty value);
|
||||
public virtual void ApplyValue(TProperty value)
|
||||
{
|
||||
if (ReferenceTypeSetExpression != null)
|
||||
ReferenceTypeSetExpression(DataBinding.LayerProperty.CurrentValue, value);
|
||||
else if (ValueTypeSetExpression != null)
|
||||
ValueTypeSetExpression(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current base value of the data binding
|
||||
/// </summary>
|
||||
public abstract TProperty GetValue();
|
||||
public virtual TProperty GetValue()
|
||||
{
|
||||
return GetExpression(DataBinding.LayerProperty.CurrentValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the provided object to a type of <typeparamref name="TProperty" />
|
||||
/// </summary>
|
||||
public virtual TProperty ConvertFromObject(object source)
|
||||
{
|
||||
return (TProperty) Convert.ChangeType(source, typeof(TProperty));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the data binding converter has been initialized and the <see cref="DataBinding" /> is available
|
||||
@ -77,40 +95,76 @@ namespace Artemis.Core
|
||||
{
|
||||
DataBinding = dataBinding;
|
||||
GetExpression = dataBinding.Registration.PropertyExpression.Compile();
|
||||
SetExpression = CreateValueSetter();
|
||||
CreateSetExpression();
|
||||
|
||||
OnInitialized();
|
||||
}
|
||||
|
||||
private Action<TLayerProperty, TProperty> CreateValueSetter()
|
||||
private void CreateSetExpression()
|
||||
{
|
||||
MethodInfo setterMethod = null;
|
||||
|
||||
if (DataBinding.Registration.Member != null)
|
||||
// If the registration does not point towards a member of LayerProperty<T>.CurrentValue, assign directly to LayerProperty<T>.CurrentValue
|
||||
if (DataBinding.Registration.Member == null)
|
||||
{
|
||||
if (DataBinding.Registration.Member is PropertyInfo propertyInfo)
|
||||
setterMethod = propertyInfo.GetSetMethod();
|
||||
CreateSetCurrentValueExpression();
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure the member of LayerProperty<T>.CurrentValue has a setter
|
||||
MethodInfo setterMethod = null;
|
||||
if (DataBinding.Registration.Member is PropertyInfo propertyInfo)
|
||||
setterMethod = propertyInfo.GetSetMethod();
|
||||
// If there is no setter, the built-in data binding cannot do its job, stay null
|
||||
if (setterMethod == null)
|
||||
return null;
|
||||
return;
|
||||
|
||||
var parameter = Expression.Parameter(typeof(TLayerProperty), "currentValue");
|
||||
// If LayerProperty<T>.CurrentValue is a value type, assign it directly to LayerProperty<T>.CurrentValue after applying the changes
|
||||
if (typeof(TLayerProperty).IsValueType)
|
||||
CreateSetValueTypeExpression();
|
||||
// If it is a reference type it can safely be updated by its reference
|
||||
else
|
||||
CreateSetReferenceTypeExpression();
|
||||
}
|
||||
|
||||
private void CreateSetReferenceTypeExpression()
|
||||
{
|
||||
var propertyValue = Expression.Parameter(typeof(TProperty), "propertyValue");
|
||||
|
||||
|
||||
var parameter = Expression.Parameter(typeof(TLayerProperty), "currentValue");
|
||||
var memberAccess = Expression.MakeMemberAccess(parameter, DataBinding.Registration.Member);
|
||||
var assignment = Expression.Assign(memberAccess, propertyValue);
|
||||
var lambda = Expression.Lambda<Action<TLayerProperty, TProperty>>(assignment, parameter, propertyValue);
|
||||
var referenceTypeLambda = Expression.Lambda<Action<TLayerProperty, TProperty>>(assignment, parameter, propertyValue);
|
||||
|
||||
if (typeof(TLayerProperty).IsValueType)
|
||||
{
|
||||
// var layerProperty = Expression.Constant(DataBinding.LayerProperty);
|
||||
// var layerPropertyMemberAccess = Expression.MakeMemberAccess(layerProperty, DataBinding.LayerProperty.GetType().GetMember(nameof(DataBinding.LayerProperty.CurrentValue))[0]);
|
||||
// var assingment = Expression.Assign()
|
||||
}
|
||||
ReferenceTypeSetExpression = referenceTypeLambda.Compile();
|
||||
}
|
||||
|
||||
return lambda.Compile();
|
||||
private void CreateSetValueTypeExpression()
|
||||
{
|
||||
var propertyValue = Expression.Parameter(typeof(TProperty), "propertyValue");
|
||||
var variableCurrent = Expression.Variable(typeof(TLayerProperty), "current");
|
||||
var layerProperty = Expression.Constant(DataBinding.LayerProperty);
|
||||
var layerPropertyMemberAccess = Expression.MakeMemberAccess(layerProperty,
|
||||
DataBinding.LayerProperty.GetType().GetMember(nameof(DataBinding.LayerProperty.CurrentValue))[0]);
|
||||
|
||||
var body = Expression.Block(
|
||||
new[] {variableCurrent},
|
||||
Expression.Assign(variableCurrent, layerPropertyMemberAccess),
|
||||
Expression.Assign(Expression.MakeMemberAccess(variableCurrent, DataBinding.Registration.Member), propertyValue),
|
||||
Expression.Assign(layerPropertyMemberAccess, variableCurrent)
|
||||
);
|
||||
|
||||
var valueTypeLambda = Expression.Lambda<Action<TProperty>>(body, propertyValue);
|
||||
ValueTypeSetExpression = valueTypeLambda.Compile();
|
||||
}
|
||||
|
||||
private void CreateSetCurrentValueExpression()
|
||||
{
|
||||
var propertyValue = Expression.Parameter(typeof(TProperty), "propertyValue");
|
||||
var layerProperty = Expression.Constant(DataBinding.LayerProperty);
|
||||
var layerPropertyMemberAccess = Expression.MakeMemberAccess(layerProperty,
|
||||
DataBinding.LayerProperty.GetType().GetMember(nameof(DataBinding.LayerProperty.CurrentValue))[0]);
|
||||
|
||||
var body = Expression.Assign(layerPropertyMemberAccess, propertyValue);
|
||||
var lambda = Expression.Lambda<Action<TProperty>>(body, propertyValue);
|
||||
ValueTypeSetExpression = lambda.Compile();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -16,18 +16,20 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="DataBindingModifier{TLayerProperty,TProperty}" /> class
|
||||
/// </summary>
|
||||
/// <param name="dataBinding">The data binding the modifier is to be applied to</param>
|
||||
/// <param name="parameterType">The type of the parameter, can either be dynamic (based on a data model value) or static</param>
|
||||
public DataBindingModifier(ProfileRightSideType parameterType)
|
||||
public DataBindingModifier(DataBinding<TLayerProperty, TProperty> dataBinding, ProfileRightSideType parameterType)
|
||||
{
|
||||
_dataBinding = dataBinding ?? throw new ArgumentNullException(nameof(dataBinding));
|
||||
ParameterType = parameterType;
|
||||
Entity = new DataBindingModifierEntity();
|
||||
Save();
|
||||
Initialize();
|
||||
Save();
|
||||
}
|
||||
|
||||
internal DataBindingModifier(DataBinding<TLayerProperty, TProperty> dataBinding, DataBindingModifierEntity entity)
|
||||
{
|
||||
DataBinding = dataBinding;
|
||||
_dataBinding = dataBinding;
|
||||
Entity = entity;
|
||||
Load();
|
||||
Initialize();
|
||||
|
||||
@ -31,10 +31,16 @@ namespace Artemis.Core
|
||||
public abstract string Icon { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether this modifier supports a parameter, defaults to true
|
||||
/// Gets or sets whether this modifier supports a parameter, defaults to <c>true</c>
|
||||
/// </summary>
|
||||
public bool SupportsParameter { get; protected set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the preferred parameter type
|
||||
/// <para>If <c>null</c>, the parameter type will match the source property</para>
|
||||
/// </summary>
|
||||
public Type PreferredParameterType { get; protected set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the given type is supported by the modifier
|
||||
/// </summary>
|
||||
|
||||
@ -5,6 +5,11 @@ namespace Artemis.Core
|
||||
{
|
||||
internal class DivideModifierType : DataBindingModifierType
|
||||
{
|
||||
public DivideModifierType()
|
||||
{
|
||||
PreferredParameterType = typeof(float);
|
||||
}
|
||||
|
||||
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
|
||||
|
||||
public override string Description => "Divide by";
|
||||
|
||||
@ -5,6 +5,11 @@ namespace Artemis.Core
|
||||
{
|
||||
internal class MultiplicationModifierType : DataBindingModifierType
|
||||
{
|
||||
public MultiplicationModifierType()
|
||||
{
|
||||
PreferredParameterType = typeof(float);
|
||||
}
|
||||
|
||||
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
|
||||
|
||||
public override string Description => "Multiply by";
|
||||
|
||||
@ -682,9 +682,9 @@ namespace Artemis.Core
|
||||
}
|
||||
|
||||
// Ensure the brush reference matches the brush
|
||||
var current = General.BrushReference.CurrentValue;
|
||||
var current = General.BrushReference.BaseValue;
|
||||
if (!descriptor.MatchesLayerBrushReference(current))
|
||||
General.BrushReference.CurrentValue = new LayerBrushReference(descriptor);
|
||||
General.BrushReference.BaseValue = new LayerBrushReference(descriptor);
|
||||
|
||||
ActivateLayerBrush();
|
||||
}
|
||||
|
||||
@ -13,7 +13,7 @@ using Stylet;
|
||||
|
||||
namespace Artemis.UI.Shared.Input
|
||||
{
|
||||
public class DataModelDynamicViewModel : PropertyChangedBase
|
||||
public class DataModelDynamicViewModel : PropertyChangedBase, IDisposable
|
||||
{
|
||||
private readonly IDataModelUIService _dataModelUIService;
|
||||
private readonly Module _module;
|
||||
@ -127,5 +127,12 @@ namespace Artemis.UI.Shared.Input
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_updateTimer.Stop();
|
||||
_updateTimer.Dispose();
|
||||
_updateTimer.Elapsed -= OnUpdateTimerOnElapsed;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -29,7 +29,7 @@ namespace Artemis.UI.Screens.Modules
|
||||
AddTabs();
|
||||
base.OnActivate();
|
||||
}
|
||||
|
||||
|
||||
private void AddTabs()
|
||||
{
|
||||
// Create the profile editor and module VMs
|
||||
|
||||
@ -18,14 +18,6 @@
|
||||
<ResourceDictionary>
|
||||
<converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
|
||||
<utilities:BindingProxy x:Key="DataContextProxy" Data="{Binding}" />
|
||||
<DataTemplate x:Key="DataModelDataTemplate">
|
||||
<Control x:Name="TemplateControl" Focusable="False" Template="{StaticResource DataModelSelectionTemplate}" />
|
||||
<DataTemplate.Triggers>
|
||||
<DataTrigger Binding="{Binding Data.ShowDataModelValues.Value, Source={StaticResource DataContextProxy}}" Value="True">
|
||||
<Setter TargetName="TemplateControl" Property="Template" Value="{StaticResource DataModelSelectionTemplateWithValues}" />
|
||||
</DataTrigger>
|
||||
</DataTemplate.Triggers>
|
||||
</DataTemplate>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
@ -62,7 +54,6 @@
|
||||
Style="{StaticResource DisplayConditionButtonLeftClickMenu}"
|
||||
Background="#7B7B7B"
|
||||
BorderBrush="#7B7B7B"
|
||||
Content="{Binding SelectedModifierType.Description}"
|
||||
Click="PropertyButton_OnClick">
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu ItemsSource="{Binding ModifierTypes}">
|
||||
@ -83,6 +74,15 @@
|
||||
</ContextMenu.ItemContainerStyle>
|
||||
</ContextMenu>
|
||||
</Button.ContextMenu>
|
||||
<Grid>
|
||||
<TextBlock Text="{Binding SelectedModifierType.Description}"
|
||||
Visibility="{Binding SelectedModifierType, Converter={StaticResource NullToVisibilityConverter}}" />
|
||||
<TextBlock FontStyle="Italic"
|
||||
Visibility="{Binding SelectedModifierType, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted}">
|
||||
« Select a modifier »
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
|
||||
</Button>
|
||||
|
||||
<ContentControl Grid.Column="3" s:View.Model="{Binding DynamicSelectionViewModel}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Artemis.Core;
|
||||
using System;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Exceptions;
|
||||
using Artemis.UI.Shared;
|
||||
@ -8,7 +9,7 @@ using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
||||
{
|
||||
public class DataBindingModifierViewModel<TLayerProperty, TProperty> : PropertyChangedBase
|
||||
public class DataBindingModifierViewModel<TLayerProperty, TProperty> : PropertyChangedBase, IDisposable
|
||||
{
|
||||
private readonly IDataBindingService _dataBindingService;
|
||||
private readonly IDataModelUIService _dataModelUIService;
|
||||
@ -34,8 +35,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
||||
|
||||
SelectModifierTypeCommand = new DelegateCommand(ExecuteSelectModifierTypeCommand);
|
||||
|
||||
// Initialize async, no need to wait for it
|
||||
Execute.PostToUIThread(Update);
|
||||
Update();
|
||||
}
|
||||
|
||||
public DelegateCommand SelectModifierTypeCommand { get; }
|
||||
@ -92,6 +92,12 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
||||
if (sourceType == null)
|
||||
throw new ArtemisUIException("Cannot use a data binding modifier VM for a data binding without a source");
|
||||
|
||||
if (DynamicSelectionViewModel != null)
|
||||
{
|
||||
DynamicSelectionViewModel.Dispose();
|
||||
DynamicSelectionViewModel.PropertySelected -= ParameterSelectionViewModelOnPropertySelected;
|
||||
}
|
||||
|
||||
if (Modifier.ModifierType == null || !Modifier.ModifierType.SupportsParameter)
|
||||
{
|
||||
StaticInputViewModel = null;
|
||||
@ -101,14 +107,22 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
||||
{
|
||||
StaticInputViewModel = null;
|
||||
DynamicSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule());
|
||||
DynamicSelectionViewModel.PropertySelected += ParameterSelectionViewModelOnPropertySelected;
|
||||
DynamicSelectionViewModel.FilterTypes = new[] {sourceType};
|
||||
if (DynamicSelectionViewModel != null)
|
||||
{
|
||||
DynamicSelectionViewModel.PropertySelected += ParameterSelectionViewModelOnPropertySelected;
|
||||
DynamicSelectionViewModel.FilterTypes = new[] {sourceType};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DynamicSelectionViewModel = null;
|
||||
StaticInputViewModel = _dataModelUIService.GetStaticInputViewModel(sourceType);
|
||||
StaticInputViewModel.ValueUpdated += StaticInputViewModelOnValueUpdated;
|
||||
if (Modifier.ModifierType.PreferredParameterType != null && sourceType.IsCastableFrom(Modifier.ModifierType.PreferredParameterType))
|
||||
StaticInputViewModel = _dataModelUIService.GetStaticInputViewModel(Modifier.ModifierType.PreferredParameterType);
|
||||
else
|
||||
StaticInputViewModel = _dataModelUIService.GetStaticInputViewModel(sourceType);
|
||||
|
||||
if (StaticInputViewModel != null)
|
||||
StaticInputViewModel.ValueUpdated += StaticInputViewModelOnValueUpdated;
|
||||
}
|
||||
|
||||
// Modifier type
|
||||
@ -118,7 +132,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
||||
|
||||
// Parameter
|
||||
if (DynamicSelectionViewModel != null)
|
||||
DynamicSelectionViewModel?.PopulateSelectedPropertyViewModel(Modifier.ParameterDataModel, Modifier.ParameterPropertyPath);
|
||||
DynamicSelectionViewModel.PopulateSelectedPropertyViewModel(Modifier.ParameterDataModel, Modifier.ParameterPropertyPath);
|
||||
else if (StaticInputViewModel != null)
|
||||
StaticInputViewModel.Value = Modifier.ParameterStaticValue;
|
||||
}
|
||||
@ -133,5 +147,14 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (DynamicSelectionViewModel != null)
|
||||
{
|
||||
DynamicSelectionViewModel.Dispose();
|
||||
DynamicSelectionViewModel.PropertySelected -= ParameterSelectionViewModelOnPropertySelected;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -126,7 +126,7 @@
|
||||
FontSize="12"
|
||||
Padding="6 4"
|
||||
Height="22"
|
||||
IsEnabled="{Binding IsDataBindingEnabled}"
|
||||
IsEnabled="{Binding CanAddModifier}"
|
||||
Command="{s:Action AddModifier}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon Margin="0 -1 4 0" Kind="Plus" />
|
||||
|
||||
@ -6,6 +6,7 @@ using Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Input;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Ninject.Planning.Targets;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
||||
@ -25,6 +26,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
||||
private TProperty _testInputValue;
|
||||
private TProperty _testResultValue;
|
||||
private bool _updating;
|
||||
private bool _canAddModifier;
|
||||
|
||||
public DataBindingViewModel(DataBindingRegistration<TLayerProperty, TProperty> registration,
|
||||
IProfileEditorService profileEditorService,
|
||||
@ -51,8 +53,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
||||
|
||||
_isDataBindingEnabled = DataBinding != null;
|
||||
|
||||
// Initialize async, no need to wait for it
|
||||
Execute.PostToUIThread(Initialize);
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public DataBindingRegistration<TLayerProperty, TProperty> Registration { get; }
|
||||
@ -116,6 +117,12 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanAddModifier
|
||||
{
|
||||
get => _canAddModifier;
|
||||
private set => SetAndNotify(ref _canAddModifier, value);
|
||||
}
|
||||
|
||||
public DataBinding<TLayerProperty, TProperty> DataBinding
|
||||
{
|
||||
get => _dataBinding;
|
||||
@ -169,7 +176,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
||||
if (DataBinding == null)
|
||||
return;
|
||||
|
||||
var modifier = new DataBindingModifier<TLayerProperty, TProperty>(ProfileRightSideType.Dynamic);
|
||||
var modifier = new DataBindingModifier<TLayerProperty, TProperty>(DataBinding, ProfileRightSideType.Dynamic);
|
||||
DataBinding.AddModifier(modifier);
|
||||
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
@ -190,6 +197,8 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
||||
if (_updating)
|
||||
return;
|
||||
|
||||
CanAddModifier = IsDataBindingEnabled && DataBinding.SourceDataModel != null;
|
||||
|
||||
if (DataBinding == null)
|
||||
{
|
||||
TargetSelectionViewModel.IsEnabled = false;
|
||||
@ -218,9 +227,12 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
||||
if (_updating)
|
||||
return;
|
||||
|
||||
DataBinding.Mode = SelectedDataBindingMode;
|
||||
DataBinding.EasingTime = TimeSpan.FromMilliseconds(EasingTime);
|
||||
DataBinding.EasingFunction = SelectedEasingViewModel?.EasingFunction ?? Easings.Functions.Linear;
|
||||
if (DataBinding != null)
|
||||
{
|
||||
DataBinding.Mode = SelectedDataBindingMode;
|
||||
DataBinding.EasingTime = TimeSpan.FromMilliseconds(EasingTime);
|
||||
DataBinding.EasingFunction = SelectedEasingViewModel?.EasingFunction ?? Easings.Functions.Linear;
|
||||
}
|
||||
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
Update();
|
||||
@ -238,8 +250,8 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
||||
var currentValue = TargetSelectionViewModel.SelectedPropertyViewModel?.GetCurrentValue();
|
||||
if (currentValue == null)
|
||||
currentValue = default(TProperty);
|
||||
|
||||
TestInputValue = (TProperty) Convert.ChangeType(currentValue, typeof(TProperty));
|
||||
|
||||
TestInputValue = Registration.Converter.ConvertFromObject(currentValue);
|
||||
if (DataBinding != null)
|
||||
TestResultValue = DataBinding.GetValue(TestInputValue);
|
||||
else
|
||||
@ -248,7 +260,10 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
||||
|
||||
private void UpdateModifierViewModels()
|
||||
{
|
||||
foreach (var dataBindingModifierViewModel in ModifierViewModels)
|
||||
dataBindingModifierViewModel.Dispose();
|
||||
ModifierViewModels.Clear();
|
||||
|
||||
if (DataBinding == null)
|
||||
return;
|
||||
|
||||
@ -269,6 +284,8 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
||||
private void TargetSelectionViewModelOnPropertySelected(object sender, DataModelInputDynamicEventArgs e)
|
||||
{
|
||||
DataBinding.UpdateSource(e.DataModelVisualizationViewModel.DataModel, e.DataModelVisualizationViewModel.PropertyPath);
|
||||
Update();
|
||||
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
}
|
||||
|
||||
@ -276,8 +293,14 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
||||
{
|
||||
_profileEditorService.ProfilePreviewUpdated -= ProfileEditorServiceOnProfilePreviewUpdated;
|
||||
TargetSelectionViewModel.PropertySelected -= TargetSelectionViewModelOnPropertySelected;
|
||||
TargetSelectionViewModel.Dispose();
|
||||
if (DataBinding != null)
|
||||
DataBinding.ModifiersUpdated -= DataBindingOnModifiersUpdated;
|
||||
|
||||
foreach (var dataBindingModifierViewModel in ModifierViewModels)
|
||||
dataBindingModifierViewModel.Dispose();
|
||||
ModifierViewModels.Clear();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -52,6 +52,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
TimelineGroupViewModel.Dispose();
|
||||
LayerPropertyGroup.VisibilityChanged -= LayerPropertyGroupOnVisibilityChanged;
|
||||
foreach (var child in Children)
|
||||
{
|
||||
|
||||
@ -3,10 +3,11 @@ using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Core;
|
||||
using Humanizer;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
|
||||
{
|
||||
public class TimelineEasingViewModel
|
||||
public class TimelineEasingViewModel : PropertyChangedBase
|
||||
{
|
||||
private bool _isEasingModeSelected;
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
|
||||
{
|
||||
public class TimelineGroupViewModel : IDisposable
|
||||
public class TimelineGroupViewModel : PropertyChangedBase, IDisposable
|
||||
{
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
|
||||
|
||||
@ -22,6 +22,8 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
|
||||
{
|
||||
_profileEditorService = profileEditorService;
|
||||
_profileTreeVmFactory = profileTreeVmFactory;
|
||||
|
||||
CreateRootFolderViewModel();
|
||||
}
|
||||
|
||||
public TreeItemViewModel SelectedTreeItem
|
||||
@ -94,17 +96,16 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
|
||||
ActiveItem?.AddLayer();
|
||||
}
|
||||
|
||||
protected override void OnInitialActivate()
|
||||
protected override void OnActivate()
|
||||
{
|
||||
Subscribe();
|
||||
CreateRootFolderViewModel();
|
||||
base.OnInitialActivate();
|
||||
base.OnActivate();
|
||||
}
|
||||
|
||||
protected override void OnClose()
|
||||
protected override void OnDeactivate()
|
||||
{
|
||||
Unsubscribe();
|
||||
base.OnClose();
|
||||
base.OnDeactivate();
|
||||
}
|
||||
|
||||
private void CreateRootFolderViewModel()
|
||||
@ -140,7 +141,7 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
|
||||
{
|
||||
if (parent == source)
|
||||
return DragDropType.None;
|
||||
parent = (TreeItemViewModel) parent.Parent;
|
||||
parent = parent.Parent as TreeItemViewModel;
|
||||
}
|
||||
|
||||
switch (dropInfo.InsertPosition)
|
||||
|
||||
@ -173,8 +173,10 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
|
||||
.ToList();
|
||||
}
|
||||
|
||||
protected override void OnInitialActivate()
|
||||
protected override void OnActivate()
|
||||
{
|
||||
ApplyActiveProfile();
|
||||
|
||||
OnlyShowSelectedShape = _settingsService.GetSetting("ProfileEditor.OnlyShowSelectedShape", true);
|
||||
HighlightSelectedLayer = _settingsService.GetSetting("ProfileEditor.HighlightSelectedLayer", true);
|
||||
|
||||
@ -184,10 +186,10 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
|
||||
_profileEditorService.ProfileElementSelected += OnProfileElementSelected;
|
||||
_profileEditorService.SelectedProfileElementUpdated += OnSelectedProfileElementUpdated;
|
||||
|
||||
base.OnInitialActivate();
|
||||
base.OnActivate();
|
||||
}
|
||||
|
||||
protected override void OnClose()
|
||||
protected override void OnDeactivate()
|
||||
{
|
||||
HighlightSelectedLayer.SettingChanged -= HighlightSelectedLayerOnSettingChanged;
|
||||
_surfaceService.ActiveSurfaceConfigurationSelected -= OnActiveSurfaceConfigurationSelected;
|
||||
@ -204,12 +206,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
|
||||
canvasViewModel.Dispose();
|
||||
CanvasViewModels.Clear();
|
||||
|
||||
base.OnClose();
|
||||
}
|
||||
|
||||
protected override void OnActivate()
|
||||
{
|
||||
ApplyActiveProfile();
|
||||
base.OnDeactivate();
|
||||
}
|
||||
|
||||
private void OnActiveSurfaceConfigurationSelected(object sender, SurfaceConfigurationEventArgs e)
|
||||
|
||||
@ -247,13 +247,14 @@ namespace Artemis.UI.Screens
|
||||
_colorScheme.SettingChanged -= ColorSchemeOnSettingChanged;
|
||||
_themeWatcher.ThemeChanged -= ThemeWatcherOnThemeChanged;
|
||||
SidebarViewModel.PropertyChanged -= SidebarViewModelOnPropertyChanged;
|
||||
|
||||
base.OnDeactivate();
|
||||
}
|
||||
|
||||
protected override void OnClose()
|
||||
{
|
||||
SidebarViewModel.Dispose();
|
||||
|
||||
|
||||
|
||||
// Lets force the GC to run after closing the window so it is obvious to users watching task manager
|
||||
// that closing the UI will decrease the memory footprint of the application.
|
||||
Task.Run(async () =>
|
||||
@ -263,6 +264,8 @@ namespace Artemis.UI.Screens
|
||||
GC.WaitForPendingFinalizers();
|
||||
GC.Collect();
|
||||
});
|
||||
|
||||
base.OnClose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user